Revision: 201015
authorDremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Fri, 16 Apr 2010 16:24:37 +0300
changeset 90 947f0dc9f7a8
parent 52 2d65c2f76d7b
child 99 6e5f9f6173bc
child 102 ef2a444a7410
child 119 6e99f362aa46
Revision: 201015 Kit: 201015
baseapitest/basesvs/group/basesvs.mrp
brdbootldr/ubootldr/base_ubootldr.mrp
brdbootldr/ubootldr/bld.inf
brdbootldr/ubootldr/inflate.c
brdbootldr/ubootldr/ubootldrldd/ubootldrldd_generic.mmp
bsptemplate/asspandvariant/base_template.mrp
bsptemplate/asspandvariant/template_assp/gpio.cpp
bsptemplate/asspandvariant/template_variant/bld.inf
bsptemplate/asspandvariant/template_variant/exiic.mmp
bsptemplate/asspandvariant/template_variant/specific/keyboard_interrupt.cpp
bsptemplate/asspandvariant/template_variant/specific/xyin.cpp
bsptemplate/asspandvariant/template_variant/variant.mmh
halservices/hal/base_hal.mrp
halservices/hal/bld.inf
kernel/eka/base_e32.mrp
kernel/eka/bld.inf
kernel/eka/bmarm/econs.def
kernel/eka/bmarm/ekernsmp.def
kernel/eka/bmarm/ekernu.def
kernel/eka/bmarm/euseru.def
kernel/eka/bwins/econs.def
kernel/eka/bwins/ekernu.def
kernel/eka/bwins/euseru.def
kernel/eka/bx86/econs.def
kernel/eka/bx86/ekernsmp.def
kernel/eka/bx86/ekernu.def
kernel/eka/bx86/euseru.def
kernel/eka/bx86gcc/ekernsmp.def
kernel/eka/bx86gcc/ekernu.def
kernel/eka/bx86gcc/euseru.def
kernel/eka/common/arm/cheap.cia
kernel/eka/common/des16.cpp
kernel/eka/compsupp/ARM EABI LICENCE.txt
kernel/eka/compsupp/bld.inf
kernel/eka/compsupp/rt_2_2.zip
kernel/eka/compsupp/rt_2_2_export.zip
kernel/eka/compsupp/rt_3_1.zip
kernel/eka/compsupp/rt_3_1_export.zip
kernel/eka/compsupp/rt_4_0_export.zip
kernel/eka/debug/securityServer/inc/c_security_svr_async.h
kernel/eka/debug/securityServer/inc/rm_debug_logging.h
kernel/eka/debug/securityServer/src/c_process_pair.cpp
kernel/eka/debug/securityServer/src/c_security_svr_async.cpp
kernel/eka/debug/securityServer/src/c_security_svr_server.cpp
kernel/eka/debug/securityServer/src/c_security_svr_session.cpp
kernel/eka/doit.cmd
kernel/eka/drivers/adc/base_e32_drivers_adc.mrp
kernel/eka/drivers/bsp/base_e32_drivers_bsp.mrp
kernel/eka/drivers/bsp/bld.inf
kernel/eka/drivers/camerasc/base_drivers_camerasc.mrp
kernel/eka/drivers/debug/group/base_e32_drivers_debug.mrp
kernel/eka/drivers/debug/rmdebug/d_debug_agent.cpp
kernel/eka/drivers/debug/rmdebug/d_debug_agent.h
kernel/eka/drivers/debug/rmdebug/d_debug_agent.inl
kernel/eka/drivers/debug/rmdebug/d_list_manager.cpp
kernel/eka/drivers/debug/rmdebug/d_process_tracker.cpp
kernel/eka/drivers/debug/rmdebug/d_rmd_breakpoints.cpp
kernel/eka/drivers/debug/rmdebug/d_rmd_breakpoints.h
kernel/eka/drivers/debug/rmdebug/d_rmd_breakpoints_debug.inl
kernel/eka/drivers/debug/rmdebug/d_rmd_stepping.cpp
kernel/eka/drivers/debug/rmdebug/d_target_process.cpp
kernel/eka/drivers/debug/rmdebug/rm_debug_eventhandler.cpp
kernel/eka/drivers/debug/rmdebug/rm_debug_kerneldriver.cpp
kernel/eka/drivers/display/base_e32_drivers_display.mrp
kernel/eka/drivers/dma/dma2_pil.cpp
kernel/eka/drivers/dma/dmapil.cpp
kernel/eka/drivers/ecomm/base_e32_drivers_ecomm.mrp
kernel/eka/drivers/ethernet/base_e32_drivers_ethernet.mrp
kernel/eka/drivers/hcr/documents/HCR Design Model.eap
kernel/eka/drivers/hcr/hcr_api.cpp
kernel/eka/drivers/hcr/hcr_hai.h
kernel/eka/drivers/hcr/hcr_pil.h
kernel/eka/drivers/iic/iic_channel.cpp
kernel/eka/drivers/locmedia/base_e32_drivers_locmedia.mrp
kernel/eka/drivers/locmedia/locmedia.cpp
kernel/eka/drivers/media/base_e32_drivers_media.mrp
kernel/eka/drivers/medmmc/bgahsmmcptn.cpp
kernel/eka/drivers/medmmc/bgahsmmcptn.h
kernel/eka/drivers/pbus/mmc/mmccd_init.cpp
kernel/eka/drivers/pbus/mmc/sdcard/Obtaining_PSL_Software_Source_Code.txt
kernel/eka/drivers/pbus/mmc/sdcard/bmarm/sdcard3c/epbusmu.def
kernel/eka/drivers/pbus/mmc/sdcard/bmarm/sdcard3c/sdio/epbusmu.def
kernel/eka/drivers/pbus/mmc/sdcard/bwins/sdcard3c/epbusmu.def
kernel/eka/drivers/pbus/mmc/sdcard/bwins/sdcard3c/sdio/epbusmu.def
kernel/eka/drivers/pbus/mmc/sdcard/bx86/sdcard3c/epbusmu.def
kernel/eka/drivers/pbus/mmc/sdcard/bx86/sdcard3c/sdio/epbusmu.def
kernel/eka/drivers/pbus/mmc/sdcard/eabi/sdcard3c/epbusmu.def
kernel/eka/drivers/pbus/mmc/sdcard/eabi/sdcard3c/sdio/epbusmu.def
kernel/eka/drivers/pbus/mmc/sdcard/sdcard3c/sdcard.cpp
kernel/eka/drivers/pbus/mmc/sdcard/sdcard3c/sdio/sdiostack.cpp
kernel/eka/drivers/pbus/mmc/session.cpp
kernel/eka/drivers/pbus/mmc/stack.cpp
kernel/eka/drivers/pbus/pbusmedia.cpp
kernel/eka/drivers/pbus/spbus.cpp
kernel/eka/drivers/power/smppower/idlehelper.cia
kernel/eka/drivers/power/smppower/idlehelper.cpp
kernel/eka/drivers/power/smppower/idlehelper_lib.mmp
kernel/eka/drivers/power/smppower/sample_idlehandler/smpidlehandler.cpp
kernel/eka/drivers/power/smppower/sample_idlehandler/smpidlehandler_lib.mmp
kernel/eka/drivers/soundsc/base_e32_drivers_sound.mrp
kernel/eka/drivers/trace/base_e32_drivers_trace.mrp
kernel/eka/drivers/usbc/base_e32_drivers_usbcli.mrp
kernel/eka/drivers/usbc/d_usbc.cpp
kernel/eka/drivers/usbcc/chapter9.cpp
kernel/eka/drivers/usbcc/ps_usbc.cpp
kernel/eka/drivers/usbcsc/d_usbcsc.cpp
kernel/eka/eabi/econs.def
kernel/eka/eabi/ekernsmp.def
kernel/eka/eabi/ekernu.def
kernel/eka/eabi/euseru.def
kernel/eka/euser/base_e32_euser.mrp
kernel/eka/euser/unicode/Compare.cpp
kernel/eka/euser/unicode/collate.cpp
kernel/eka/euser/unicode/perl/Unicode, Inc License Agreement - Data Files and Software.txt
kernel/eka/euser/us_exec.cpp
kernel/eka/euser/us_test.cpp
kernel/eka/ewsrv/base_e32_ewsrv.mrp
kernel/eka/ewsrv/co_utl.cpp
kernel/eka/ewsrv/ky_tran.cpp
kernel/eka/ewsrv/ws_win.cpp
kernel/eka/generic.inf
kernel/eka/include/cpudefs.h
kernel/eka/include/drivers/dma_hai.h
kernel/eka/include/drivers/dma_v1.h
kernel/eka/include/drivers/dma_v2.h
kernel/eka/include/drivers/dma_v2.inl
kernel/eka/include/drivers/gpio.h
kernel/eka/include/drivers/iic_channel.h
kernel/eka/include/drivers/iic_transaction.h
kernel/eka/include/drivers/rm_debug_eventhandler.h
kernel/eka/include/drivers/sdcard.h
kernel/eka/include/drivers/smppower/idlehelper.h
kernel/eka/include/drivers/smppower/sample_idlehandler/smpidlehandler.h
kernel/eka/include/drivers/usbcshared.h
kernel/eka/include/drivers/usbcshared.inl
kernel/eka/include/e32atomics.h
kernel/eka/include/e32btrace.h
kernel/eka/include/e32cmn.h
kernel/eka/include/e32des16.h
kernel/eka/include/e32kpan.h
kernel/eka/include/e32math.h
kernel/eka/include/e32std.h
kernel/eka/include/e32std.inl
kernel/eka/include/e32twin.h
kernel/eka/include/e32ver.h
kernel/eka/include/kernel/arm/arm.h
kernel/eka/include/kernel/arm/assp.h
kernel/eka/include/kernel/arm/bootdefs.h
kernel/eka/include/kernel/cache_maintenance.h
kernel/eka/include/kernel/cache_maintenance.inl
kernel/eka/include/kernel/kern_priv.h
kernel/eka/include/kernel/kern_test.h
kernel/eka/include/kernel/kernboot.h
kernel/eka/include/kernel/kerncorestats.h
kernel/eka/include/kernel/kernel.h
kernel/eka/include/kernel/kpower.h
kernel/eka/include/kernel/securerng.h
kernel/eka/include/kernel/sha256.h
kernel/eka/include/kernel/x86/assp.h
kernel/eka/include/memmodel/epoc/flexible/memmodel.h
kernel/eka/include/memmodel/epoc/multiple/memmodel.h
kernel/eka/include/nkern/nk_cpu.h
kernel/eka/include/nkern/nk_priv.h
kernel/eka/include/nkern/nk_trace.h
kernel/eka/include/nkern/nkern.h
kernel/eka/include/nkern/nklib.h
kernel/eka/include/nkernsmp/arm/arm_tmr.h
kernel/eka/include/nkernsmp/arm/entry.h
kernel/eka/include/nkernsmp/arm/ncern.h
kernel/eka/include/nkernsmp/arm/nk_plat.h
kernel/eka/include/nkernsmp/nk_priv.h
kernel/eka/include/nkernsmp/nkern.h
kernel/eka/include/nkernsmp/x86/nk_plat.h
kernel/eka/include/opensystemtrace.h
kernel/eka/include/rm_debug_api.h
kernel/eka/include/sm_debug_api.h
kernel/eka/include/u32hal.h
kernel/eka/include/ws_std.h
kernel/eka/kernel/arm/bootmain.s
kernel/eka/kernel/arm/cache_external.cpp
kernel/eka/kernel/arm/cache_maintenance.cpp
kernel/eka/kernel/arm/cinit.cpp
kernel/eka/kernel/arm/ckernel.cpp
kernel/eka/kernel/arm/cutils.cia
kernel/eka/kernel/arm/cutils.cpp
kernel/eka/kernel/ekern.mmp
kernel/eka/kernel/eventq.cpp
kernel/eka/kernel/execs.txt
kernel/eka/kernel/exmoncommon.mmp
kernel/eka/kernel/kc_exe.mmp
kernel/eka/kernel/kerncorestats.cpp
kernel/eka/kernel/random.cpp
kernel/eka/kernel/sbtrace.cpp
kernel/eka/kernel/scodeseg.cpp
kernel/eka/kernel/securerng.cpp
kernel/eka/kernel/server.cpp
kernel/eka/kernel/sexec.cpp
kernel/eka/kernel/sglobals.cpp
kernel/eka/kernel/sha256.cpp
kernel/eka/kernel/sinit.cpp
kernel/eka/kernel/sipc.cpp
kernel/eka/kernel/skernel.cpp
kernel/eka/kernel/sprocess.cpp
kernel/eka/kernel/srandombuff.cpp
kernel/eka/kernel/stest.cpp
kernel/eka/kernel/sthread.cpp
kernel/eka/kernel/stimer.cpp
kernel/eka/kernel/sutils.cpp
kernel/eka/kernel/win32/cinit.cpp
kernel/eka/kernel/x86/ckernel.cpp
kernel/eka/kernel/x86/cutils.cpp
kernel/eka/memmodel/emul/win32/minit.cpp
kernel/eka/memmodel/emul/win32/mprocess.cpp
kernel/eka/memmodel/emul/win32/mutils.cpp
kernel/eka/memmodel/epoc/direct/arm/xinit.cpp
kernel/eka/memmodel/epoc/direct/minit.cpp
kernel/eka/memmodel/epoc/direct/mutils.cpp
kernel/eka/memmodel/epoc/flexible/mcodeseg.cpp
kernel/eka/memmodel/epoc/flexible/minit.cpp
kernel/eka/memmodel/epoc/flexible/mmu/arm/xmmu.cpp
kernel/eka/memmodel/epoc/flexible/mmu/mcodepaging.cpp
kernel/eka/memmodel/epoc/flexible/mmu/mdatapaging.cpp
kernel/eka/memmodel/epoc/flexible/mmu/mexport.cpp
kernel/eka/memmodel/epoc/flexible/mmu/mm.cpp
kernel/eka/memmodel/epoc/flexible/mmu/mmanager.cpp
kernel/eka/memmodel/epoc/flexible/mmu/mmanager.h
kernel/eka/memmodel/epoc/flexible/mmu/mmapping.cpp
kernel/eka/memmodel/epoc/flexible/mmu/mmu.cpp
kernel/eka/memmodel/epoc/flexible/mmu/mmu.h
kernel/eka/memmodel/epoc/flexible/mmu/mobject.cpp
kernel/eka/memmodel/epoc/flexible/mmu/mobject.h
kernel/eka/memmodel/epoc/flexible/mmu/mpagecleaner.cpp
kernel/eka/memmodel/epoc/flexible/mmu/mpagecleaner.h
kernel/eka/memmodel/epoc/flexible/mmu/mpager.cpp
kernel/eka/memmodel/epoc/flexible/mmu/mpager.h
kernel/eka/memmodel/epoc/flexible/mmu/mrefcntobj.h
kernel/eka/memmodel/epoc/flexible/mmu/mrom.cpp
kernel/eka/memmodel/epoc/mmubase/mmubase.cpp
kernel/eka/memmodel/epoc/moving/arm/xmmu.cpp
kernel/eka/memmodel/epoc/moving/minit.cpp
kernel/eka/memmodel/epoc/moving/mprocess.cpp
kernel/eka/memmodel/epoc/multiple/arm/xmmu.cpp
kernel/eka/memmodel/epoc/multiple/mcodeseg.cpp
kernel/eka/memmodel/epoc/multiple/minit.cpp
kernel/eka/memmodel/epoc/putils.cpp
kernel/eka/memmodel/memmodel.mmp
kernel/eka/nkern/arm/ncmonitor.cpp
kernel/eka/nkern/arm/ncsched.cia
kernel/eka/nkern/arm/ncutils.cpp
kernel/eka/nkern/nk_mon.cpp
kernel/eka/nkern/nk_timer.cpp
kernel/eka/nkern/nkern.cpp
kernel/eka/nkern/sched.cpp
kernel/eka/nkern/win32/ncsched.cpp
kernel/eka/nkern/x86/ncmonitor.cpp
kernel/eka/nkern/x86/ncutils.cia
kernel/eka/nkernsmp/arm/nccpu.cpp
kernel/eka/nkernsmp/arm/ncmonitor.cpp
kernel/eka/nkernsmp/arm/ncsched.cia
kernel/eka/nkernsmp/arm/ncsched.cpp
kernel/eka/nkernsmp/arm/ncthrd.cia
kernel/eka/nkernsmp/arm/ncthrd.cpp
kernel/eka/nkernsmp/arm/ncutilf.cia
kernel/eka/nkernsmp/arm/ncutils.cia
kernel/eka/nkernsmp/arm/ncutils.cpp
kernel/eka/nkernsmp/arm/vectors.cia
kernel/eka/nkernsmp/dfcs.cpp
kernel/eka/nkernsmp/nk_bal.cpp
kernel/eka/nkernsmp/nk_bal.h
kernel/eka/nkernsmp/nk_irq.cpp
kernel/eka/nkernsmp/nk_mon.cpp
kernel/eka/nkernsmp/nk_timer.cpp
kernel/eka/nkernsmp/nkern.cpp
kernel/eka/nkernsmp/nkern.mmp
kernel/eka/nkernsmp/nkerns.cpp
kernel/eka/nkernsmp/sched.cpp
kernel/eka/nkernsmp/x86/nccpu.cpp
kernel/eka/nkernsmp/x86/ncmonitor.cpp
kernel/eka/nkernsmp/x86/ncsched.cia
kernel/eka/nkernsmp/x86/ncsched.cpp
kernel/eka/nkernsmp/x86/ncthrd.cpp
kernel/eka/nkernsmp/x86/ncutilf.cia
kernel/eka/nkernsmp/x86/ncutils.cia
kernel/eka/nkernsmp/x86/ncutils.cpp
kernel/eka/nkernsmp/x86/vectors.cia
kernel/eka/nkernsmp/x86/vectors.cpp
kernel/eka/release.txt
kernel/eka/rombuild/alltests.oby
kernel/eka/rombuild/autotest.oby
kernel/eka/rombuild/autotest_e32tests.oby
kernel/eka/rombuild/autotest_f32tests.oby
kernel/eka/rombuild/f32_perf_tests.oby
kernel/eka/rombuild/f32_perf_tests_fat_exfat.oby
kernel/eka/rombuild/f32tests.oby
kernel/eka/rombuild/h4usbmmctest_load.oby
kernel/eka/rombuild/h4usbmmctest_test.oby
kernel/eka/rombuild/h4usbstress.oby
kernel/eka/rombuild/mmctest_load.oby
kernel/eka/rombuild/mmctest_test.oby
kernel/eka/rombuild/mmctest_test_e32tests.oby
kernel/eka/rombuild/mmctest_test_f32tests.oby
kernel/eka/rombuild/nandtest_erase.oby
kernel/eka/rombuild/nandtest_load.oby
kernel/eka/rombuild/nandtest_test.oby
kernel/eka/rombuild/nandtest_test_e32tests.oby
kernel/eka/rombuild/nandtest_test_f32tests.oby
kernel/eka/rombuild/ost.iby
kernel/eka/rombuild/t_soak.oby
kernel/eka/rombuild/ubootldr.oby
kernel/eka/rombuild/user.iby
kernel/eka/rombuild/utrace.iby
kernelhwsrv_info/kernelhwsrv_metadata/kernelhwsrv_metadata.mrp
kerneltest/e32test/active/t_timerduration.cpp
kerneltest/e32test/bench/t_r64bm.cpp
kerneltest/e32test/bench/t_r64fnc.cpp
kerneltest/e32test/bmarm/i2c_ctrlessu.def
kerneltest/e32test/bmarm/spi_ctrlessu.def
kerneltest/e32test/bmarm/t_wsd_dl1.def
kerneltest/e32test/bmarm/t_wsd_dl2.def
kerneltest/e32test/bmarm/t_wsd_dl3.def
kerneltest/e32test/buffer/Unicode, Inc License Agreement - Data Files and Software.txt
kerneltest/e32test/buffer/t_char.cpp
kerneltest/e32test/buffer/t_des.cpp
kerneltest/e32test/buffer/t_match.cpp
kerneltest/e32test/bwins/t_wsd_dl1.def
kerneltest/e32test/bwins/t_wsd_dl2.def
kerneltest/e32test/bwins/t_wsd_dl3.def
kerneltest/e32test/bx86/t_wsd_dl1.def
kerneltest/e32test/bx86/t_wsd_dl2.def
kerneltest/e32test/bx86/t_wsd_dl3.def
kerneltest/e32test/debug/context.cia
kerneltest/e32test/debug/t_perflogger.cpp
kerneltest/e32test/defrag/t_ramdefrag.cpp
kerneltest/e32test/demandpaging/t_datapaging.cpp
kerneltest/e32test/demandpaging/t_printsysinfo.cpp
kerneltest/e32test/demandpaging/t_thrash.cpp
kerneltest/e32test/device/t_usb.h
kerneltest/e32test/device/t_usbapi.cpp
kerneltest/e32test/device/t_usbco2.cpp
kerneltest/e32test/dma/d_dma.cpp
kerneltest/e32test/dma/dmasim.cpp
kerneltest/e32test/dma/t_dma.cpp
kerneltest/e32test/dmav2/test_cases.cpp
kerneltest/e32test/eabi/i2c_ctrlessu.def
kerneltest/e32test/eabi/spi_ctrlessu.def
kerneltest/e32test/eabi/t_wsd_dl1.def
kerneltest/e32test/eabi/t_wsd_dl2.def
kerneltest/e32test/eabi/t_wsd_dl3.def
kerneltest/e32test/group/base_e32test.mrp
kerneltest/e32test/group/bld.inf
kerneltest/e32test/group/ccthrash.mmp
kerneltest/e32test/group/d_entropysources.mmp
kerneltest/e32test/group/d_kerncorestats.mmp
kerneltest/e32test/group/d_timestamp.mmp
kerneltest/e32test/group/romstuff.mke
kerneltest/e32test/group/t_crashmonitor_lib.mmp
kerneltest/e32test/group/t_entropysources.mmp
kerneltest/e32test/group/t_extendedrescontrolcli.mmp
kerneltest/e32test/group/t_kerncorestats.mmp
kerneltest/e32test/group/t_loadsim.mmp
kerneltest/e32test/group/t_pci.mmp
kerneltest/e32test/group/t_printsysinfo.mmp
kerneltest/e32test/group/t_rmdebug.mmp
kerneltest/e32test/group/t_rmdebug2.mmh
kerneltest/e32test/group/t_rmdebug2.mmp
kerneltest/e32test/group/t_rmdebug2_oem.mmp
kerneltest/e32test/group/t_rmdebug2_oem2.mmp
kerneltest/e32test/group/t_rmdebug2_oemtoken.mmp
kerneltest/e32test/group/t_rmdebug2_oemtoken2.mmp
kerneltest/e32test/group/t_rmdebug_app.mmp
kerneltest/e32test/group/t_rmdebug_dll.mmp
kerneltest/e32test/group/t_rmdebug_security0.mmp
kerneltest/e32test/group/t_rmdebug_security1.mmp
kerneltest/e32test/group/t_rmdebug_security2.mmp
kerneltest/e32test/group/t_rmdebug_security3.mmp
kerneltest/e32test/group/t_schedhook.mmp
kerneltest/e32test/group/t_securerng.mmp
kerneltest/e32test/group/t_sha256.mmp
kerneltest/e32test/group/t_smpsoakspin.mmp
kerneltest/e32test/group/t_timestamp.mmp
kerneltest/e32test/group/t_trkdummyapp.mmp
kerneltest/e32test/group/t_wsd_dl1.mmh
kerneltest/e32test/group/t_wsd_dl1_cp.mmp
kerneltest/e32test/group/t_wsd_dl1_cu.mmp
kerneltest/e32test/group/t_wsd_dl1_xp.mmp
kerneltest/e32test/group/t_wsd_dl1_xu.mmp
kerneltest/e32test/group/t_wsd_dl2.mmh
kerneltest/e32test/group/t_wsd_dl2_cp.mmp
kerneltest/e32test/group/t_wsd_dl2_cu.mmp
kerneltest/e32test/group/t_wsd_dl2_xp.mmp
kerneltest/e32test/group/t_wsd_dl2_xu.mmp
kerneltest/e32test/group/t_wsd_dl3.mmh
kerneltest/e32test/group/t_wsd_dl3_cp.mmp
kerneltest/e32test/group/t_wsd_dl3_cu.mmp
kerneltest/e32test/group/t_wsd_dl3_xp.mmp
kerneltest/e32test/group/t_wsd_dl3_xu.mmp
kerneltest/e32test/group/t_wsd_tst.mmh
kerneltest/e32test/group/t_wsd_tst_cp.mmp
kerneltest/e32test/group/t_wsd_tst_cu.mmp
kerneltest/e32test/group/t_wsd_tst_xp.mmp
kerneltest/e32test/group/t_wsd_tst_xu.mmp
kerneltest/e32test/group/ymodemtx.mmp
kerneltest/e32test/hcr/d_hcrsim.cpp
kerneltest/e32test/hcr/d_hcrsim_testdata.h
kerneltest/e32test/hcr/filerepos_cds.dat
kerneltest/e32test/hcr/filerepos_cds.txt
kerneltest/e32test/hcr/hcr.inf
kerneltest/e32test/hcr/hcr_tests.iby
kerneltest/e32test/hcr/t_hcr.cpp
kerneltest/e32test/heap/t_heap.cpp
kerneltest/e32test/iic/iic_psl/d_iic_client_ctrless.mmp
kerneltest/e32test/iic/iic_psl/d_iic_slaveclient_ctrless.mmp
kerneltest/e32test/iic/iic_psl/i2c.cpp
kerneltest/e32test/iic/iic_psl/i2c.h
kerneltest/e32test/iic/iic_psl/i2c_ctrless.mmp
kerneltest/e32test/iic/iic_psl/iic_client.cpp
kerneltest/e32test/iic/iic_psl/iic_slaveclient.cpp
kerneltest/e32test/iic/iic_psl/spi.cpp
kerneltest/e32test/iic/t_iic.cpp
kerneltest/e32test/iic/t_iic.h
kerneltest/e32test/locl/t_lat1.cpp
kerneltest/e32test/misc/ccthrash.cpp
kerneltest/e32test/misc/cpumeter.cpp
kerneltest/e32test/misc/d_testkerncorestats.cpp
kerneltest/e32test/misc/d_testkerncorestats.h
kerneltest/e32test/misc/inflate.c
kerneltest/e32test/misc/t_cputime.cpp
kerneltest/e32test/misc/t_kerncorestats.cpp
kerneltest/e32test/misc/t_loadsim.cpp
kerneltest/e32test/misc/test_thread.h
kerneltest/e32test/misc/ymodemtx.cpp
kerneltest/e32test/mmu/d_memorytest.h
kerneltest/e32test/mmu/d_shadow.cpp
kerneltest/e32test/mmu/d_shadow.h
kerneltest/e32test/mmu/paging_info.cpp
kerneltest/e32test/mmu/t_cache.cpp
kerneltest/e32test/mmu/t_codepaging.cpp
kerneltest/e32test/mmu/t_shbuf.cpp
kerneltest/e32test/mmu/t_wsd_dl1.cpp
kerneltest/e32test/mmu/t_wsd_dl2.cpp
kerneltest/e32test/mmu/t_wsd_dl3.cpp
kerneltest/e32test/mmu/t_wsd_tst.cpp
kerneltest/e32test/mmu/t_wsd_tst.h
kerneltest/e32test/nkernsa/arm/armutils.cia
kerneltest/e32test/nkernsa/fastmutex.cpp
kerneltest/e32test/nkernsa/kprintf.cpp
kerneltest/e32test/nkernsa/testdfc.cpp
kerneltest/e32test/nkernsa/threadbasic.cpp
kerneltest/e32test/nkernsa/tlsf.cpp
kerneltest/e32test/pccd/t_idrv.cpp
kerneltest/e32test/pci/t_pci.cpp
kerneltest/e32test/pci/t_pci.h
kerneltest/e32test/random/d_entropysources.cpp
kerneltest/e32test/random/d_entropysources.h
kerneltest/e32test/random/t_entropysources.cpp
kerneltest/e32test/random/t_securerng.cpp
kerneltest/e32test/random/t_sha256.cpp
kerneltest/e32test/resourceman/d_rescontrolcli.cpp
kerneltest/e32test/resourceman/dynamicresource.cpp
kerneltest/e32test/resourceman/resourceman_psl/rescontrol_extended_psl.cpp
kerneltest/e32test/resourceman/resourceman_psl/rescontrol_psl.cpp
kerneltest/e32test/rm_debug/basic_tests/r_kernel_low_memory_security_svr_session.cpp
kerneltest/e32test/rm_debug/basic_tests/r_kernel_low_memory_security_svr_session.h
kerneltest/e32test/rm_debug/basic_tests/r_low_memory_security_svr_session.cpp
kerneltest/e32test/rm_debug/basic_tests/r_low_memory_security_svr_session.h
kerneltest/e32test/rm_debug/basic_tests/r_user_low_memory_security_svr_session.cpp
kerneltest/e32test/rm_debug/basic_tests/r_user_low_memory_security_svr_session.h
kerneltest/e32test/rm_debug/basic_tests/t_rmdebug2.cpp
kerneltest/e32test/rm_debug/basic_tests/t_rmdebug2.h
kerneltest/e32test/rm_debug/basic_tests/t_rmdebug2_oemtoken.cpp
kerneltest/e32test/rm_debug/common/t_target_launcher.cpp
kerneltest/e32test/rm_debug/common/t_target_launcher.h
kerneltest/e32test/rm_debug/d_demand_paging.cia
kerneltest/e32test/rm_debug/d_demand_paging.h
kerneltest/e32test/rm_debug/d_rmdebug_step_test.h
kerneltest/e32test/rm_debug/d_rmdebug_step_test.s
kerneltest/e32test/rm_debug/d_rmdebug_step_test_armv4.h
kerneltest/e32test/rm_debug/d_rmdebug_step_test_armv4.s
kerneltest/e32test/rm_debug/d_rmdebugclient.h
kerneltest/e32test/rm_debug/d_rmdebugserver.cpp
kerneltest/e32test/rm_debug/d_rmdebugserver.h
kerneltest/e32test/rm_debug/d_rmdebugthread.cpp
kerneltest/e32test/rm_debug/d_rmdebugthread.h
kerneltest/e32test/rm_debug/d_rmdebugthread2.cpp
kerneltest/e32test/rm_debug/d_rmdebugthread2.h
kerneltest/e32test/rm_debug/d_rmdebugthreadasm.cia
kerneltest/e32test/rm_debug/d_rmdebugthreadasm2.cia
kerneltest/e32test/rm_debug/debug_targets/d_demand_paging.cia
kerneltest/e32test/rm_debug/debug_targets/d_demand_paging.h
kerneltest/e32test/rm_debug/debug_targets/d_rmdebug_bkpt_test.h
kerneltest/e32test/rm_debug/debug_targets/d_rmdebug_bkpt_test.s
kerneltest/e32test/rm_debug/debug_targets/d_rmdebug_step_test.h
kerneltest/e32test/rm_debug/debug_targets/d_rmdebug_step_test.s
kerneltest/e32test/rm_debug/debug_targets/d_rmdebug_step_test_armv4.h
kerneltest/e32test/rm_debug/debug_targets/d_rmdebug_step_test_armv4.s
kerneltest/e32test/rm_debug/debug_targets/d_rmdebugthread.cpp
kerneltest/e32test/rm_debug/debug_targets/d_rmdebugthread.h
kerneltest/e32test/rm_debug/debug_targets/d_rmdebugthread2.cpp
kerneltest/e32test/rm_debug/debug_targets/d_rmdebugthread2.h
kerneltest/e32test/rm_debug/debug_targets/d_rmdebugthreadasm.cia
kerneltest/e32test/rm_debug/debug_targets/d_rmdebugthreadasm2.cia
kerneltest/e32test/rm_debug/debug_targets/t_rmdebug_app.cpp
kerneltest/e32test/rm_debug/debug_targets/t_rmdebug_app.h
kerneltest/e32test/rm_debug/debug_targets/t_rmdebug_dll.cpp
kerneltest/e32test/rm_debug/debug_targets/t_rmdebug_dll.h
kerneltest/e32test/rm_debug/debug_targets/t_rmdebug_security.cpp
kerneltest/e32test/rm_debug/debug_targets/t_rmdebug_security.h
kerneltest/e32test/rm_debug/group/t_crashmonitor_lib.mmp
kerneltest/e32test/rm_debug/group/t_multi_agent_launcher.mmp
kerneltest/e32test/rm_debug/group/t_rmdebug.mmp
kerneltest/e32test/rm_debug/group/t_rmdebug2.mmh
kerneltest/e32test/rm_debug/group/t_rmdebug2.mmp
kerneltest/e32test/rm_debug/group/t_rmdebug2_oem.mmp
kerneltest/e32test/rm_debug/group/t_rmdebug2_oem2.mmp
kerneltest/e32test/rm_debug/group/t_rmdebug2_oemtoken.mmp
kerneltest/e32test/rm_debug/group/t_rmdebug2_oemtoken2.mmp
kerneltest/e32test/rm_debug/group/t_rmdebug_app.mmp
kerneltest/e32test/rm_debug/group/t_rmdebug_app1.mmp
kerneltest/e32test/rm_debug/group/t_rmdebug_app10.mmp
kerneltest/e32test/rm_debug/group/t_rmdebug_app2.mmp
kerneltest/e32test/rm_debug/group/t_rmdebug_app3.mmp
kerneltest/e32test/rm_debug/group/t_rmdebug_app4.mmp
kerneltest/e32test/rm_debug/group/t_rmdebug_app5.mmp
kerneltest/e32test/rm_debug/group/t_rmdebug_app6.mmp
kerneltest/e32test/rm_debug/group/t_rmdebug_app7.mmp
kerneltest/e32test/rm_debug/group/t_rmdebug_app8.mmp
kerneltest/e32test/rm_debug/group/t_rmdebug_app9.mmp
kerneltest/e32test/rm_debug/group/t_rmdebug_dll.mmp
kerneltest/e32test/rm_debug/group/t_rmdebug_multi_agent.mmp
kerneltest/e32test/rm_debug/group/t_rmdebug_multi_target.mmp
kerneltest/e32test/rm_debug/group/t_rmdebug_security0.mmp
kerneltest/e32test/rm_debug/group/t_rmdebug_security1.mmp
kerneltest/e32test/rm_debug/group/t_rmdebug_security2.mmp
kerneltest/e32test/rm_debug/group/t_rmdebug_security3.mmp
kerneltest/e32test/rm_debug/group/t_rmdebug_target_launcher.mmp
kerneltest/e32test/rm_debug/group/t_trkdummyapp.mmp
kerneltest/e32test/rm_debug/metro_trk/d_rmdebugclient.h
kerneltest/e32test/rm_debug/metro_trk/d_rmdebugserver.cpp
kerneltest/e32test/rm_debug/metro_trk/d_rmdebugserver.h
kerneltest/e32test/rm_debug/metro_trk/t_rmdebug.cpp
kerneltest/e32test/rm_debug/metro_trk/t_rmdebug.h
kerneltest/e32test/rm_debug/multi_agent_tests/t_agent_eventhandler.cpp
kerneltest/e32test/rm_debug/multi_agent_tests/t_agent_eventhandler.h
kerneltest/e32test/rm_debug/multi_agent_tests/t_debug_logging.h
kerneltest/e32test/rm_debug/multi_agent_tests/t_multi_agent.cpp
kerneltest/e32test/rm_debug/multi_agent_tests/t_multi_agent.h
kerneltest/e32test/rm_debug/multi_agent_tests/t_multi_agent_launcher.cpp
kerneltest/e32test/rm_debug/multi_agent_tests/t_multi_agent_launcher.h
kerneltest/e32test/rm_debug/multi_target_tests/t_multi_target.cpp
kerneltest/e32test/rm_debug/multi_target_tests/t_multi_target.h
kerneltest/e32test/rm_debug/r_kernel_low_memory_security_svr_session.cpp
kerneltest/e32test/rm_debug/r_kernel_low_memory_security_svr_session.h
kerneltest/e32test/rm_debug/r_low_memory_security_svr_session.cpp
kerneltest/e32test/rm_debug/r_low_memory_security_svr_session.h
kerneltest/e32test/rm_debug/r_user_low_memory_security_svr_session.cpp
kerneltest/e32test/rm_debug/r_user_low_memory_security_svr_session.h
kerneltest/e32test/rm_debug/t_rmdebug.cpp
kerneltest/e32test/rm_debug/t_rmdebug.h
kerneltest/e32test/rm_debug/t_rmdebug2.cpp
kerneltest/e32test/rm_debug/t_rmdebug2.h
kerneltest/e32test/rm_debug/t_rmdebug2_oemtoken.cpp
kerneltest/e32test/rm_debug/t_rmdebug_app.cpp
kerneltest/e32test/rm_debug/t_rmdebug_app.h
kerneltest/e32test/rm_debug/t_rmdebug_dll.cpp
kerneltest/e32test/rm_debug/t_rmdebug_dll.h
kerneltest/e32test/rm_debug/t_rmdebug_security.cpp
kerneltest/e32test/rm_debug/t_rmdebug_security.h
kerneltest/e32test/rm_debug/t_trkdummyapp.cpp
kerneltest/e32test/rm_debug/t_trkdummyapp.h
kerneltest/e32test/rm_debug/trk_blocking/t_trkdummyapp.cpp
kerneltest/e32test/rm_debug/trk_blocking/t_trkdummyapp.h
kerneltest/e32test/system/d_dobject.cpp
kerneltest/e32test/system/d_mstim.cpp
kerneltest/e32test/timestamp/d_timestamp.cpp
kerneltest/e32test/timestamp/d_timestamp.h
kerneltest/e32test/timestamp/d_timestamp_dev.h
kerneltest/e32test/timestamp/t_timestamp.cpp
kerneltest/e32test/usb/t_usb_device/include/activecontrol.h
kerneltest/e32test/usb/t_usb_device/src/activecontrol.cpp
kerneltest/e32test/usb/t_usb_device/src/activedevicestatenotifier.cpp
kerneltest/e32test/usb/t_usb_win/scripts/massstorage/bmwritelargefile.pl
kerneltest/e32test/usb/t_usb_win/scripts/massstorage/bmwritemanyfiles.pl
kerneltest/e32test/usb/t_usb_win/scripts/massstorage/createfilesanddirs.pl
kerneltest/e32test/usb/t_usb_win/scripts/massstorage/createlargefile.pl
kerneltest/e32test/usbho/t_usbdi/inc/PBASE-T_USBDI-1231.h
kerneltest/e32test/usbho/t_usbdi/src/PBASE-T_USBDI-1231.cpp
kerneltest/e32utils/group/base_e32utils.mrp
kerneltest/e32utils/group/bld.inf
kerneltest/e32utils/group/nistsecurerng.mmp
kerneltest/e32utils/trace/btrace_analyse.cpp
kerneltest/f32test/demandpaging/t_wdpstress.cpp
kerneltest/f32test/fileshare/handshare.cpp
kerneltest/f32test/filesystem/automounter/t_automounter.mmp
kerneltest/f32test/filesystem/fat/b_fat32.cpp
kerneltest/f32test/filesystem/fat/t_compat32.cpp
kerneltest/f32test/filesystem/fat/t_scn32dr1.cpp
kerneltest/f32test/filesystem/fat/t_tscan32.cpp
kerneltest/f32test/fileutils/inc/fat_utils.h
kerneltest/f32test/fileutils/src/fat_utils.cpp
kerneltest/f32test/group/b_gen.mmp
kerneltest/f32test/group/base_f32test.mrp
kerneltest/f32test/loader/base_loader.mrp
kerneltest/f32test/locl/localeutils/elocl32_japan/src/t_tlocl32_lat1.cpp
kerneltest/f32test/server/b_gen.cpp
kerneltest/f32test/server/t_falsespace.cpp
kerneltest/f32test/server/t_fman.cpp
kerneltest/f32test/server/t_locate.cpp
kerneltest/f32test/server/t_main.cpp
kerneltest/f32test/server/t_rename.cpp
kerneltest/f32test/shostmassstorage/msman/app/cdisplay.cpp
kerneltest/f32test/shostmassstorage/msman/app/cdisplay.h
kerneltest/f32test/shostmassstorage/msman/app/husbconsapp.cpp
kerneltest/f32test/shostmassstorage/msman/src/cusbhost.cpp
kerneltest/f32test/shostmassstorage/msman/src/cusbhostao.cpp
kerneltest/f32test/shostmassstorage/msman/src/rextfilesystem.cpp
kerneltest/f32test/shostmassstorage/testclient/usbtestmsclient/cmassstoragemountcb.cpp
kerneltest/f32test/shostmassstorage/testclient/usbtestmsclient/inc/cmassstoragefilesystem.h
kerneltest/f32test/shostmassstorage/testclient/usbtestmsclient/inc/cmassstoragemountcb.h
kerneltest/f32test/shostmassstorage/testclient/usbtestmsclient/inc/tfatbootsector.inl
kerneltest/f32test/shostmassstorage/testclient/usbtestmsclient/transport/cbulkonlytransport.cpp
kerneltest/f32test/smassstorage/scripts/usbinterop1.pl
kerneltest/f32test/smassstorage/scripts/usbinterop2.pl
kerneltest/f32test/smassstorage/scripts/usbperformance.pl
kerneltest/f32test/smassstorage/scripts/usbperformance_multifile.pl
kerneltest/f32test/smassstorage/src/t_ms_fsunit.cpp
kerneltest/f32test/smassstorage/src/t_ms_mountstart.cpp
package_definition.xml
userlibandfileserver/domainmgr/group/base_domain.mrp
userlibandfileserver/fileserver/automounter/base_f32_automounter.mrp
userlibandfileserver/fileserver/estart/base_f32_estart.mrp
userlibandfileserver/fileserver/etshell/base_f32_eshell.mrp
userlibandfileserver/fileserver/etshell/ts_com.cpp
userlibandfileserver/fileserver/fs_utils/filesystem_utils.inl
userlibandfileserver/fileserver/group/base_f32.mrp
userlibandfileserver/fileserver/group/release.txt
userlibandfileserver/fileserver/inc/f32dbg.h
userlibandfileserver/fileserver/inc/f32file.h
userlibandfileserver/fileserver/inc/f32ver.h
userlibandfileserver/fileserver/scomp/base_f32_scomp.mrp
userlibandfileserver/fileserver/sfat/base_f32_sfat.mrp
userlibandfileserver/fileserver/sfat/sl_fat16.cpp
userlibandfileserver/fileserver/sfat32/base_f32_sfat32.mrp
userlibandfileserver/fileserver/sfat32/common_constants.h
userlibandfileserver/fileserver/sfat32/fat_config.cpp
userlibandfileserver/fileserver/sfat32/fat_dir_entry.h
userlibandfileserver/fileserver/sfat32/fat_dir_entry.inl
userlibandfileserver/fileserver/sfat32/fat_table32.cpp
userlibandfileserver/fileserver/sfat32/inc/fat_table32.h
userlibandfileserver/fileserver/sfat32/inc/sl_bpb.h
userlibandfileserver/fileserver/sfat32/inc/sl_bpb.inl
userlibandfileserver/fileserver/sfat32/inc/sl_scandrv.h
userlibandfileserver/fileserver/sfat32/inc/sl_std.h
userlibandfileserver/fileserver/sfat32/inc/sl_std.inl
userlibandfileserver/fileserver/sfat32/ram_fat_table32.cpp
userlibandfileserver/fileserver/sfat32/sl_bpb32.cpp
userlibandfileserver/fileserver/sfat32/sl_cache.cpp
userlibandfileserver/fileserver/sfat32/sl_cache.h
userlibandfileserver/fileserver/sfat32/sl_dir_cache.cpp
userlibandfileserver/fileserver/sfat32/sl_dir_cache.h
userlibandfileserver/fileserver/sfat32/sl_disk.cpp
userlibandfileserver/fileserver/sfat32/sl_drv.cpp
userlibandfileserver/fileserver/sfat32/sl_fatcache.cpp
userlibandfileserver/fileserver/sfat32/sl_fatmisc32.cpp
userlibandfileserver/fileserver/sfat32/sl_file.cpp
userlibandfileserver/fileserver/sfat32/sl_fmt.cpp
userlibandfileserver/fileserver/sfat32/sl_leafdir_cache.cpp
userlibandfileserver/fileserver/sfat32/sl_mnt.cpp
userlibandfileserver/fileserver/sfat32/sl_mnt32.cpp
userlibandfileserver/fileserver/sfat32/sl_scan32.cpp
userlibandfileserver/fileserver/sfat32/sl_utl.cpp
userlibandfileserver/fileserver/sfat32/sl_vfat.cpp
userlibandfileserver/fileserver/sfile/sf_dat.cpp
userlibandfileserver/fileserver/sfile/sf_debug.cpp
userlibandfileserver/fileserver/sfile/sf_ext.cpp
userlibandfileserver/fileserver/sfile/sf_file.cpp
userlibandfileserver/fileserver/sfile/sf_file_cache_defs.h
userlibandfileserver/fileserver/sfile/sf_lepoc.cpp
userlibandfileserver/fileserver/sfile/sf_main.cpp
userlibandfileserver/fileserver/sfile/sf_memory_client.cpp
userlibandfileserver/fileserver/sfile/sf_memory_man.cpp
userlibandfileserver/fileserver/sfile/sf_notify.cpp
userlibandfileserver/fileserver/sfile/sf_obj.cpp
userlibandfileserver/fileserver/sfile/sf_request.cpp
userlibandfileserver/fileserver/sfile/sf_ses.cpp
userlibandfileserver/fileserver/sfile/sf_std.h
userlibandfileserver/fileserver/sfile/sf_std.inl
userlibandfileserver/fileserver/sfile/sf_sys.cpp
userlibandfileserver/fileserver/sfsrv/cl_find.cpp
userlibandfileserver/fileserver/sfsrv/cl_parse.cpp
userlibandfileserver/fileserver/shostmassstorage/base_f32_shostmassstorage.mrp
userlibandfileserver/fileserver/shostmassstorage/server/protocol/cmassstoragefsm.cpp
userlibandfileserver/fileserver/shostmassstorage/server/protocol/cscsiprotocol.cpp
userlibandfileserver/fileserver/shostmassstorage/server/protocol/tscsiblockcmds.cpp
userlibandfileserver/fileserver/shostmassstorage/server/shared/msctypes.h
userlibandfileserver/fileserver/shostmassstorage/server/transport/cbulkonlytransport.cpp
userlibandfileserver/fileserver/shostmassstorage/server/transport/cusbifacehandler.cpp
userlibandfileserver/fileserver/shostmassstorage/server/transport/include/cusbifacehandler.h
userlibandfileserver/fileserver/smassstorage/base_f32_smassstorage.mrp
userlibandfileserver/fileserver/smassstorage/cmassstoragefilesystem.cpp
userlibandfileserver/fileserver/smassstorage/cmassstoragemountcb.cpp
userlibandfileserver/fileserver/smassstorage/inc/cmassstoragefilesystem.h
userlibandfileserver/fileserver/smassstorage/inc/cmassstoragemountcb.h
userlibandfileserver/fileserver/smassstorage/inc/scsiprot.h
userlibandfileserver/fileserver/smassstorage/inc/tfatbootsector.inl
userlibandfileserver/fileserver/smassstorage/scsiprot.cpp
userlibandfileserver/fileserver/srofs/base_f32_srofs.mrp
userlibandfileserver/fileserver/srom/base_f32_srom.mrp
--- a/baseapitest/basesvs/group/basesvs.mrp	Tue Feb 02 01:24:03 2010 +0200
+++ b/baseapitest/basesvs/group/basesvs.mrp	Fri Apr 16 16:24:37 2010 +0300
@@ -1,3 +1,19 @@
+#
+# 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 "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: 
+#
+
 component		basesvs
 source			\sf\os\kernelhwsrv\baseapitest\basesvs
 notes_source	\sf\os\kernelhwsrv\baseapitest\basesvs\group\release.txt
--- a/brdbootldr/ubootldr/base_ubootldr.mrp	Tue Feb 02 01:24:03 2010 +0200
+++ b/brdbootldr/ubootldr/base_ubootldr.mrp	Fri Apr 16 16:24:37 2010 +0300
@@ -1,11 +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 "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: 
+#
 # component name "Bootstrap"
 
 component	base_ubootldr
 source	\sf\os\kernelhwsrv\brdbootldr\ubootldr
 
+binary	\sf\os\kernelhwsrv\brdbootldr\ubootldr all
+
 notes_source	\component_defs\release.src
 
-
 ipr E 
 ipr T \sf\os\kernelhwsrv\brdbootldr\ubootldr\inc
 ipr T \sf\os\kernelhwsrv\brdbootldr\ubootldr\ubootldrldd
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/brdbootldr/ubootldr/bld.inf	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,23 @@
+// Copyright (c) 2010 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: Dummy file to keep build tools happy
+//
+
+
+PRJ_PLATFORMS
+ARMV5
+
+
+PRJ_MMPFILES
+ubootldrldd/ubootldrldd_generic.mmp
+
--- a/brdbootldr/ubootldr/inflate.c	Tue Feb 02 01:24:03 2010 +0200
+++ b/brdbootldr/ubootldr/inflate.c	Fri Apr 16 16:24:37 2010 +0300
@@ -1,3 +1,19 @@
+/*
+* 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 "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: 
+*
+*/
 /* inflate.c -- Not copyrighted 1992 by Mark Adler
    version c10p1, 10 January 1993 */
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/brdbootldr/ubootldr/ubootldrldd/ubootldrldd_generic.mmp	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,29 @@
+// Copyright (c) 2005-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: Dummy mmp file to keep build tools happy
+//
+
+#include "kernel/kern_ext.mmh"
+
+target         	_generic_ubootldr.ldd
+targettype		ldd
+sourcepath		.
+source			ubootldrldd.cpp
+epocallowdlldata
+
+capability		all
+vendorid		0x70000001
+macro			__SECURE_API__
+
+SMPSAFE
+
--- a/bsptemplate/asspandvariant/base_template.mrp	Tue Feb 02 01:24:03 2010 +0200
+++ b/bsptemplate/asspandvariant/base_template.mrp	Fri Apr 16 16:24:37 2010 +0300
@@ -1,3 +1,18 @@
+#
+# 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 "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: 
+#
 # component name "Template Variant"
 
 component	base_template
--- a/bsptemplate/asspandvariant/template_assp/gpio.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/bsptemplate/asspandvariant/template_assp/gpio.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -39,6 +39,87 @@
 
 static TInt32	GpioInterruptId; // place to store interrupt handle returned from Interrupt::Bind()
 
+
+/**
+Calculate 16-bit device pin Id from 32-bit pin Id. Use DeviceId() to 
+get device Id.
+@param   aId         32-bit pin Id
+@return  16-bit device specific pin Id
+ */
+static inline TUint16 DevicePinId(TInt aId)
+    {return static_cast<TUint16>(aId & 0x0000FFFF);}
+
+
+//Commented out to satisfy compiler(as method is not used in the code) but can  
+//be usefull later
+/**
+Calculate and return GPIO device Id(either SOC or one of the extenders)
+defined in TGpioBaseId from the 32-bit pin Id
+@param   aId         32-bit pin Id
+@return
+   - EInternalId              SOC GPIO 
+   - EExtender0-15            GPIO extenders from 0-15
+
+static inline GPIO::TGpioBaseId ExtenderId(TInt aId)
+    {return static_cast<GPIO::TGpioBaseId>((aId & 0xFFFF0000));}
+*/
+
+//Commented out to satisfy compiler(as method is not used in the code) but can  
+//be usefull later
+/**
+Generate 32-bit pin Id from the device Id and device specific 16-bit 
+pin Id.
+@param   aExtenderId     Device Id is defined in TGpioBaseId
+@param   aPinId          16-bit device pin Id
+return   32-bit pin Id  
+
+static inline TInt Id(GPIO::TGpioBaseId aExtenderId, TUint16 aPinId)
+    {return static_cast<TInt>(aExtenderId |aPinId);}
+*/
+
+//Commented out to satisfy compiler(as method is not used in the code) but can  
+//be usefull later
+/**
+Find index in extender GPIO device table.
+@param   aExtenderId     Extender Id is defined in TGpioBaseId
+@return  singned 32-bit integer index device, possible value 
+        from 0 to 15
+ 
+static TInt DeviceIndex(GPIO::TGpioBaseId aExtenderId)
+    {
+    TUint16 val = (TUint16)((aExtenderId & 0xFFFF0000) >> 16);
+    if(val == 0) return GPIO::EInternalId;
+
+    //The algorithm steps througth the value until first non-zero bit is
+    //found.
+    //
+    TInt index = 0;
+    if(val & 0xFF00) {index  = 8; val = val >> 8;} // 2 x 8-bits
+    if(val & 0x00F0) {index += 4; val = val >> 4;} // 2 x 4-bits
+    if(val & 0x000C) {index += 2; val = val >> 2;} // 2 x 2 bits
+    if(val & 0x0002) {index += 1; val = val >> 1;} // 2 x 1 bits
+
+    return index;
+    }
+*/
+
+
+//Commented out to satisfy compiler(as method is not used in the code) but can  
+//be usefull later
+/**
+Find index in extender GPIO device table.
+@param   aId    32-bit GPIO pin Id
+@return  singned 32-bit integer index device, possible value 
+         from 0 to 15
+
+static TInt DeviceIndex(TInt aId){return DeviceIndex(ExtenderId(aId));}
+*/
+
+
+
+
+
+
 /**
 GPIO interrupt handler
 generic argument (TAny*) is a pointer to the GpioPins array
@@ -72,7 +153,8 @@
    	TGpioMode aMode
 	)
 	{
-	if (aId < 0 || aId > KHwGpioPinMax)
+    TUint16 pinId = DevicePinId(aId);
+	if (pinId > KHwGpioPinMax)
 		{
 		return KErrArgument;
 		}
@@ -86,7 +168,8 @@
    	TGpioMode & aMode
 	)
 	{
-	if (aId < 0 || aId > KHwGpioPinMax)
+    TUint16 pinId = DevicePinId(aId);
+	if (pinId > KHwGpioPinMax)
 		{
 		return KErrArgument;
 		}
@@ -100,7 +183,8 @@
    	TGpioDirection aDirection
 	)
 	{
-	if (aId < 0 || aId > KHwGpioPinMax || aDirection == ETriStated)
+    TUint16 pinId = DevicePinId(aId);
+	if (pinId > KHwGpioPinMax || aDirection == ETriStated)
 		{
 		return KErrArgument;
 		}
@@ -114,7 +198,8 @@
    	TGpioDirection & aDirection
 	)
 	{
-	if (aId < 0 || aId > KHwGpioPinMax)
+    TUint16 pinId = DevicePinId(aId);
+	if (pinId > KHwGpioPinMax)
 		{
 		return KErrArgument;
 		}
@@ -128,7 +213,8 @@
    	TGpioBias aBias
 	)
 	{
-	if (aId < 0 || aId > KHwGpioPinMax)
+    TUint16 pinId = DevicePinId(aId);
+	if (pinId > KHwGpioPinMax)
 		{
 		return KErrArgument;
 		}
@@ -142,7 +228,8 @@
    	TGpioBias & aBias
 	)
 	{
-	if (aId < 0 || aId > KHwGpioPinMax)
+    TUint16 pinId = DevicePinId(aId);
+	if (pinId > KHwGpioPinMax)
 		{
 		return KErrArgument;
 		}
@@ -156,7 +243,8 @@
    	TInt		/*aConf*/
 	)
 	{
-	if (aId < 0 || aId > KHwGpioPinMax)
+    TUint16 pinId = DevicePinId(aId);
+	if (pinId > KHwGpioPinMax)
 		{
 		return KErrArgument;
 		}
@@ -170,7 +258,8 @@
    	TInt	  & aBias
 	)
 	{
-	if (aId < 0 || aId > KHwGpioPinMax)
+    TUint16 pinId = DevicePinId(aId);
+	if (pinId > KHwGpioPinMax)
 		{
 		return KErrArgument;
 		}
@@ -185,18 +274,19 @@
    	TAny *   aPtr
 	)
 	{
-	if (aId < 0 || aId > KHwGpioPinMax || aIsr == NULL)
+    TUint16 pinId = DevicePinId(aId);
+	if (pinId > KHwGpioPinMax || aIsr == NULL)
 		{
 		return KErrArgument;
 		}
-	if (GpioPins[aId].iIsr != NULL)
+	if (GpioPins[pinId].iIsr != NULL)
 		{
 		// already bound
 		return KErrInUse;
 		}
 	// record isr and arg bound to this pin
-	GpioPins[aId].iIsr = aIsr;
-	GpioPins[aId].iPtr = aPtr;
+	GpioPins[pinId].iIsr = aIsr;
+	GpioPins[pinId].iPtr = aPtr;
 	return KErrNone;
 	}
 
@@ -205,18 +295,19 @@
 	TInt aId
 	)
 	{
-	if (aId < 0 || aId > KHwGpioPinMax)
+    TUint16 pinId = DevicePinId(aId);
+	if (pinId > KHwGpioPinMax)
 		{
 		return KErrArgument;
 		}
-	if (GpioPins[aId].iIsr == NULL)
+	if (GpioPins[pinId].iIsr == NULL)
 		{
 		// nothing bound
 		return KErrGeneral;
 		}
 	// NULL isr bound to this pin
-	GpioPins[aId].iIsr = NULL;
-	GpioPins[aId].iPtr = NULL;
+	GpioPins[pinId].iIsr = NULL;
+	GpioPins[pinId].iPtr = NULL;
 	return KErrNone;
 	}
 
@@ -225,11 +316,12 @@
 	TInt aId
 	)
 	{
-	if (aId < 0 || aId > KHwGpioPinMax)
+    TUint16 pinId = DevicePinId(aId);
+	if (pinId > KHwGpioPinMax)
 		{
 		return KErrArgument;
 		}
-	if (GpioPins[aId].iIsr == NULL)
+	if (GpioPins[pinId].iIsr == NULL)
 		{
 		// nothing bound
 		return KErrGeneral;
@@ -243,11 +335,12 @@
 	TInt aId
 	)
 	{
-	if (aId < 0 || aId > KHwGpioPinMax)
+    TUint16 pinId = DevicePinId(aId);
+	if (pinId > KHwGpioPinMax)
 		{
 		return KErrArgument;
 		}
-	if (GpioPins[aId].iIsr == NULL)
+	if (GpioPins[pinId].iIsr == NULL)
 		{
 		// nothing bound
 		return KErrGeneral;
@@ -262,11 +355,12 @@
    	TBool & aEnable
 	)
 	{
-	if (aId < 0 || aId > KHwGpioPinMax)
+    TUint16 pinId = DevicePinId(aId);
+	if (pinId > KHwGpioPinMax)
 		{
 		return KErrArgument;
 		}
-	if (GpioPins[aId].iIsr == NULL)
+	if (GpioPins[pinId].iIsr == NULL)
 		{
 		// nothing bound
 		return KErrGeneral;
@@ -280,11 +374,12 @@
 	TInt aId
 	)
 	{
-	if (aId < 0 || aId > KHwGpioPinMax)
+    TUint16 pinId = DevicePinId(aId);
+	if (pinId > KHwGpioPinMax)
 		{
 		return KErrArgument;
 		}
-	if (GpioPins[aId].iIsr == NULL)
+	if (GpioPins[pinId].iIsr == NULL)
 		{
 		// nothing bound
 		return KErrGeneral;
@@ -299,7 +394,8 @@
    	TBool & aActive
 	)
 	{
-	if (aId < 0 || aId > KHwGpioPinMax)
+    TUint16 pinId = DevicePinId(aId);
+	if (pinId > KHwGpioPinMax)
 		{
 		return KErrArgument;
 		}
@@ -313,7 +409,8 @@
    	TBool & aActive
 	)
 	{
-	if (aId < 0 || aId > KHwGpioPinMax)
+    TUint16 pinId = DevicePinId(aId);
+	if (pinId > KHwGpioPinMax)
 		{
 		return KErrArgument;
 		}
@@ -327,7 +424,8 @@
    	TGpioDetectionTrigger aTrigger
 	)
 	{
-	if (aId < 0 || aId > KHwGpioPinMax)
+    TUint16 pinId = DevicePinId(aId);
+	if (pinId > KHwGpioPinMax)
 		{
 		return KErrArgument;
 		}
@@ -340,7 +438,8 @@
 	TInt aId
 	)
 	{
-	if (aId < 0 || aId > KHwGpioPinMax)
+    TUint16 pinId = DevicePinId(aId);
+	if (pinId > KHwGpioPinMax)
 		{
 		return KErrArgument;
 		}
@@ -353,7 +452,8 @@
 	TInt aId
 	)
 	{
-	if (aId < 0 || aId > KHwGpioPinMax)
+    TUint16 pinId = DevicePinId(aId);
+	if (pinId > KHwGpioPinMax)
 		{
 		return KErrArgument;
 		}
@@ -367,7 +467,8 @@
    	TBool & aEnable
 	)
 	{
-	if (aId < 0 || aId > KHwGpioPinMax)
+    TUint16 pinId = DevicePinId(aId);
+	if (pinId > KHwGpioPinMax)
 		{
 		return KErrArgument;
 		}
@@ -381,7 +482,8 @@
    	TGpioDetectionTrigger aTrigger
 	)
 	{
-	if (aId < 0 || aId > KHwGpioPinMax)
+    TUint16 pinId = DevicePinId(aId);
+	if (pinId > KHwGpioPinMax)
 		{
 		return KErrArgument;
 		}
@@ -395,7 +497,8 @@
    	TInt aTime
 	)
 	{
-	if (aId < 0 || aId > KHwGpioPinMax)
+    TUint16 pinId = DevicePinId(aId);
+	if (pinId > KHwGpioPinMax)
 		{
 		return KErrArgument;
 		}
@@ -410,7 +513,8 @@
    	TInt & aTime
 	)
 	{
-	if (aId < 0 || aId > KHwGpioPinMax)
+    TUint16 pinId = DevicePinId(aId);
+	if (pinId > KHwGpioPinMax)
 		{
 		return KErrArgument;
 		}
@@ -424,7 +528,8 @@
    	TGpioState & aState
 	)
 	{
-	if (aId < 0 || aId > KHwGpioPinMax)
+    TUint16 pinId = DevicePinId(aId);
+	if (pinId > KHwGpioPinMax)
 		{
 		return KErrArgument;
 		}
@@ -442,7 +547,8 @@
    	TGpioState aState
 	)
 	{
-	if (aId < 0 || aId > KHwGpioPinMax)
+    TUint16 pinId = DevicePinId(aId);
+	if (pinId > KHwGpioPinMax)
 		{
 		return KErrArgument;
 		}
@@ -456,7 +562,8 @@
    	TGpioState & aState
 	)
 	{
-	if (aId < 0 || aId > KHwGpioPinMax)
+    TUint16 pinId = DevicePinId(aId);
+	if (pinId > KHwGpioPinMax)
 		{
 		return KErrArgument;
 		}
@@ -470,7 +577,8 @@
    	TGpioCallback		* aCb
 	)
 	{
-	if (aId < 0 || aId > KHwGpioPinMax)
+    TUint16 pinId = DevicePinId(aId);
+	if (pinId > KHwGpioPinMax)
 		{
 		return KErrArgument;
 		}
@@ -485,7 +593,8 @@
    	TGpioCallback		* aCb
 	)
 	{
-	if (aId < 0 || aId > KHwGpioPinMax)
+    TUint16 pinId = DevicePinId(aId);
+	if (pinId > KHwGpioPinMax)
 		{
 		return KErrArgument;
 		}
@@ -501,7 +610,8 @@
 	TAny	* aArg2
 	)
 	{
-	if (aId < 0 || aId > KHwGpioPinMax)
+    TUint16 pinId = DevicePinId(aId);
+	if (pinId > KHwGpioPinMax)
 		{
 		return KErrArgument;
 		}
--- a/bsptemplate/asspandvariant/template_variant/bld.inf	Tue Feb 02 01:24:03 2010 +0200
+++ b/bsptemplate/asspandvariant/template_variant/bld.inf	Fri Apr 16 16:24:37 2010 +0300
@@ -108,12 +108,29 @@
 //
 
 PRJ_EXTENSIONS
-start		extension		base/bootstrap
+
+#ifdef SBSV2 // If using SBSv2 with bootstrap FLM, MEMMODEL MUST begin with a capital letter
+
+start		extension		base.bootstrap bootstrap
+
+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
+
+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
@@ -126,3 +143,4 @@
 
 end
 
+#endif // !SBSV2
--- a/bsptemplate/asspandvariant/template_variant/exiic.mmp	Tue Feb 02 01:24:03 2010 +0200
+++ b/bsptemplate/asspandvariant/template_variant/exiic.mmp	Fri Apr 16 16:24:37 2010 +0300
@@ -57,7 +57,6 @@
 //SYMBIAN_BASE_SYSTEMINCLUDE(template)
 //SYMBIAN_BASE_SYSTEMINCLUDE(template/specific)
 
-//library			iic.lib			// commented out as this iic.lib is now included from iic_channel.mmh
 
 library     VariantTarget(gpio,lib)
 
--- a/bsptemplate/asspandvariant/template_variant/specific/keyboard_interrupt.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/bsptemplate/asspandvariant/template_variant/specific/keyboard_interrupt.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -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	Tue Feb 02 01:24:03 2010 +0200
+++ b/bsptemplate/asspandvariant/template_variant/specific/xyin.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -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/bsptemplate/asspandvariant/template_variant/variant.mmh	Tue Feb 02 01:24:03 2010 +0200
+++ b/bsptemplate/asspandvariant/template_variant/variant.mmh	Fri Apr 16 16:24:37 2010 +0300
@@ -153,6 +153,3 @@
 library	VariantTarget(katemplate,lib)
 #endif
 
-// Uncomment the following if IIC Controller is required
-// library		iic.lib  // commented out as this iic.lib is now included from iic_channel.mmh
-
--- a/halservices/hal/base_hal.mrp	Tue Feb 02 01:24:03 2010 +0200
+++ b/halservices/hal/base_hal.mrp	Fri Apr 16 16:24:37 2010 +0300
@@ -1,3 +1,18 @@
+#
+# 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 "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: 
+#
 # component name "User Side Hardware Abstraction"
 
 component	base_hal
--- a/halservices/hal/bld.inf	Tue Feb 02 01:24:03 2010 +0200
+++ b/halservices/hal/bld.inf	Fri Apr 16 16:24:37 2010 +0300
@@ -26,9 +26,9 @@
 BASEUSERDEFAULT
 
 PRJ_EXPORTS
-inc/hal_int.h						SYMBIAN_OS_LAYER_PUBLIC_EXPORT_PATH(kernel/)
-inc/hal_data.h						SYMBIAN_OS_LAYER_PUBLIC_EXPORT_PATH(hal_data.h)
-inc/hal.h							SYMBIAN_OS_LAYER_PUBLIC_EXPORT_PATH(hal.h)
+inc/hal_int.h						SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(kernel/)
+inc/hal_data.h						SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(hal_data.h)
+inc/hal.h							SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(hal.h)
 rom/hal.iby		/epoc32/rom/hal/	//
 rom/hal.hby		/epoc32/rom/hal/	//
 
--- a/kernel/eka/base_e32.mrp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/base_e32.mrp	Fri Apr 16 16:24:37 2010 +0300
@@ -1,3 +1,18 @@
+#
+# 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 "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: 
+#
 # component name "Kernel Architecture 2"
 
 component	base_e32
@@ -32,15 +47,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/bld.inf	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/bld.inf	Fri Apr 16 16:24:37 2010 +0300
@@ -115,6 +115,7 @@
 include/kernel/sproperty.h						SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(kernel/)
 include/kernel/kernboot.h						SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(kernel/)
 include/kernel/kbma.h							SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(kernel/)
+include/kernel/kerncorestats.h						SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(kernel/)
 
 // Export a stub localisation header under the old name. This just inclides "localise.h" ...
 include/kernel/ls_std.h							SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(kernel/)
@@ -214,8 +215,8 @@
 include/drivers/iic_channel.h					SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(drivers/)
 include/drivers/iic_channel.inl					SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(drivers/)
 include/drivers/iic_trace.h						SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(drivers/)
-include/drivers/iic_transaction.h				drivers/						//
-include/drivers/iic_transaction.inl				drivers/
+include/drivers/iic_transaction.h				SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(drivers/)
+include/drivers/iic_transaction.inl				SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(drivers/)
 
 include/drivers/gpio.h							SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(drivers/)
 include/drivers/mmccd_ifc.h						SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(drivers/)
--- a/kernel/eka/bmarm/econs.def	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/bmarm/econs.def	Fri Apr 16 16:24:37 2010 +0300
@@ -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	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/bmarm/ekernsmp.def	Fri Apr 16 16:24:37 2010 +0300
@@ -1041,4 +1041,16 @@
 	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 &)
+	NotificationLock__13DPagingDevice @ 1048 NONAME R3UNUSED ; DPagingDevice::NotificationLock(void)
+	Configure__13KernCoreStatsUi @ 1049 NONAME R3UNUSED ; KernCoreStats::Configure(unsigned int)
+	Engage__13KernCoreStatsi @ 1050 NONAME R3UNUSED ; KernCoreStats::Engage(int)
+	Retire__13KernCoreStatsii @ 1051 NONAME R3UNUSED ; KernCoreStats::Retire(int, int)
+	Stats__13KernCoreStatsPv @ 1052 NONAME R3UNUSED ; KernCoreStats::Stats(void *)
+	SetNumberOfActiveCpus__5NKerni @ 1053 NONAME
+	SetIdleHandler__3ArmPFPvUlPVv_vPv @ 1054 NONAME R3UNUSED ; Arm::SetIdleHandler(void (*)(void *, unsigned long, void volatile *), void *)
 
--- a/kernel/eka/bmarm/ekernu.def	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/bmarm/ekernu.def	Fri Apr 16 16:24:37 2010 +0300
@@ -1037,4 +1037,16 @@
 	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 &)
+	NotificationLock__13DPagingDevice @ 1044 NONAME R3UNUSED ; DPagingDevice::NotificationLock(void)
+	Configure__13KernCoreStatsUi @ 1045 NONAME R3UNUSED ; KernCoreStats::Configure(unsigned int)
+	Engage__13KernCoreStatsi @ 1046 NONAME R3UNUSED ; KernCoreStats::Engage(int)
+	EnterIdle__13KernCoreStats @ 1047 NONAME R3UNUSED ; KernCoreStats::EnterIdle()
+	LeaveIdle__13KernCoreStatsUi @ 1048 NONAME R3UNUSED ; KernCoreStats::LeaveIdle(unsigned int)
+	Retire__13KernCoreStatsii @ 1049 NONAME R3UNUSED ; KernCoreStats::Retire(int, int)
+	Stats__13KernCoreStatsPv @ 1050 NONAME R3UNUSED ; KernCoreStats::Stats(void *)
+	SetIdleHandler__3ArmPFPvUl_vPv @ 1051 NONAME R3UNUSED ; Arm::SetIdleHandler(void (*)(void *, unsigned long), void *)
--- a/kernel/eka/bmarm/euseru.def	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/bmarm/euseru.def	Fri Apr 16 16:24:37 2010 +0300
@@ -2231,4 +2231,32 @@
 	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 &)
+	Append2__6TDes16G5TChar @ 2236  NONAME R3UNUSED ; TDes16::Append2(TChar)
+	AppendFill2__6TDes16G5TChari @ 2237  NONAME R3UNUSED ; TDes16::AppendFill2(TChar, int)
+	AppendJustify2__6TDes16PCUsi6TAlignG5TChar @ 2238  NONAME ; TDes16::AppendJustify2(unsigned short const *, int, TAlign, TChar)
+	AppendJustify2__6TDes16PCUsii6TAlignG5TChar @ 2239  NONAME ; TDes16::AppendJustify2(unsigned short const *, int, int, TAlign, TChar)
+	AppendJustify2__6TDes16RC7TDesC16i6TAlignG5TChar @ 2240  NONAME ; TDes16::AppendJustify2(TDesC16 const &, int, TAlign, TChar)
+	AppendJustify2__6TDes16RC7TDesC16ii6TAlignG5TChar @ 2241  NONAME ; TDes16::AppendJustify2(TDesC16 const &, int, int, TAlign, TChar)
+	Capitalize2__6TDes16 @ 2242  NONAME R3UNUSED ; TDes16::Capitalize2(void)
+	Collate2__6TDes16 @ 2243  NONAME R3UNUSED ; TDes16::Collate2(void)
+	CopyC2__6TDes16RC7TDesC16 @ 2244  NONAME R3UNUSED ; TDes16::CopyC2(TDesC16 const &)
+	CopyCP2__6TDes16RC7TDesC16 @ 2245  NONAME R3UNUSED ; TDes16::CopyCP2(TDesC16 const &)
+	CopyF2__6TDes16RC7TDesC16 @ 2246  NONAME R3UNUSED ; TDes16::CopyF2(TDesC16 const &)
+	CopyLC2__6TDes16RC7TDesC16 @ 2247  NONAME R3UNUSED ; TDes16::CopyLC2(TDesC16 const &)
+	CopyUC2__6TDes16RC7TDesC16 @ 2248  NONAME R3UNUSED ; TDes16::CopyUC2(TDesC16 const &)
+	Fill2__6TDes16G5TChar @ 2249  NONAME R3UNUSED ; TDes16::Fill2(TChar)
+	Fill2__6TDes16G5TChari @ 2250  NONAME R3UNUSED ; TDes16::Fill2(TChar, int)
+	FindCorruptSurrogate__C7TDesC16 @ 2251  NONAME R3UNUSED ; TDesC16::FindCorruptSurrogate(void) const
+	Fold2__6TDes16 @ 2252  NONAME R3UNUSED ; TDes16::Fold2(void)
+	Justify2__6TDes16RC7TDesC16i6TAlignG5TChar @ 2253  NONAME ; TDes16::Justify2(TDesC16 const &, int, TAlign, TChar)
+	Locate2__C7TDesC16G5TChar @ 2254  NONAME R3UNUSED ; TDesC16::Locate2(TChar) const
+	LocateF2__C7TDesC16G5TChar @ 2255  NONAME R3UNUSED ; TDesC16::LocateF2(TChar) const
+	LocateReverse2__C7TDesC16G5TChar @ 2256  NONAME R3UNUSED ; TDesC16::LocateReverse2(TChar) const
+	LocateReverseF2__C7TDesC16G5TChar @ 2257  NONAME R3UNUSED ; TDesC16::LocateReverseF2(TChar) const
+	LowerCase2__6TDes16 @ 2258  NONAME R3UNUSED ; TDes16::LowerCase2(void)
+	Match2__C7TDesC16RC7TDesC16 @ 2259  NONAME R3UNUSED ; TDesC16::Match2(TDesC16 const &) const
+	UpperCase2__6TDes16 @ 2260  NONAME R3UNUSED ; TDes16::UpperCase2(void)
+	AgainHighRes__6RTimerR14TRequestStatusG27TTimeIntervalMicroSeconds32 @ 2261 NONAME R3UNUSED ; RTimer::AgainHighRes(TRequestStatus &, TTimeIntervalMicroSeconds32)
--- a/kernel/eka/bwins/econs.def	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/bwins/econs.def	Fri Apr 16 16:24:37 2010 +0300
@@ -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	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/bwins/ekernu.def	Fri Apr 16 16:24:37 2010 +0300
@@ -925,4 +925,13 @@
 	?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 &)
+	?NotificationLock@DPagingDevice@@QAEPAVNFastMutex@@XZ @ 931 NONAME ; public: class NFastMutex * __thiscall DPagingDevice::NotificationLock(void)
+	?Configure@KernCoreStats@@SAHI@Z @ 932 NONAME	;  public: static int KernCoreStats::Configure(unsigned int)
+	?Engage@KernCoreStats@@SAHH@Z @ 933 NONAME	;  public: static int KernCoreStats::Engage(int)
+	?Retire@KernCoreStats@@SAHHH@Z @ 934 NONAME	;  public: static int KernCoreStats::Retire(int, int)
+	?Stats@KernCoreStats@@SAHPAX@Z @ 935 NONAME	;  public: static int KernCoreStats::Stats(void *)
 
--- a/kernel/eka/bwins/euseru.def	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/bwins/euseru.def	Fri Apr 16 16:24:37 2010 +0300
@@ -2179,4 +2179,33 @@
 	?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)
+	?Append2@TDes16@@QAEXVTChar@@@Z @ 2184 NONAME ; void TDes16::Append2(class TChar)
+	?CopyC2@TDes16@@QAEXABVTDesC16@@@Z @ 2185 NONAME ; void TDes16::CopyC2(class TDesC16 const &)
+	?Collate2@TDes16@@QAEXXZ @ 2186 NONAME ; void TDes16::Collate2(void)
+	?CopyF2@TDes16@@QAEXABVTDesC16@@@Z @ 2187 NONAME ; void TDes16::CopyF2(class TDesC16 const &)
+	?Fill2@TDes16@@QAEXVTChar@@@Z @ 2188 NONAME ; void TDes16::Fill2(class TChar)
+	?Locate2@TDesC16@@QBEHVTChar@@@Z @ 2189 NONAME ; int TDesC16::Locate2(class TChar) const
+	?AppendFill2@TDes16@@QAEXVTChar@@H@Z @ 2190 NONAME ; void TDes16::AppendFill2(class TChar, int)
+	?AppendJustify2@TDes16@@QAEXABVTDesC16@@HHW4TAlign@@VTChar@@@Z @ 2191 NONAME ; void TDes16::AppendJustify2(class TDesC16 const &, int, int, enum TAlign, class TChar)
+	?AppendJustify2@TDes16@@QAEXPBGHW4TAlign@@VTChar@@@Z @ 2192 NONAME ; void TDes16::AppendJustify2(unsigned short const *, int, enum TAlign, class TChar)
+	?Fold2@TDes16@@QAEXXZ @ 2193 NONAME ; void TDes16::Fold2(void)
+	?AppendJustify2@TDes16@@QAEXABVTDesC16@@HW4TAlign@@VTChar@@@Z @ 2194 NONAME ; void TDes16::AppendJustify2(class TDesC16 const &, int, enum TAlign, class TChar)
+	?LowerCase2@TDes16@@QAEXXZ @ 2195 NONAME ; void TDes16::LowerCase2(void)
+	?CopyUC2@TDes16@@QAEXABVTDesC16@@@Z @ 2196 NONAME ; void TDes16::CopyUC2(class TDesC16 const &)
+	?FindCorruptSurrogate@TDesC16@@QBEHXZ @ 2197 NONAME ; int TDesC16::FindCorruptSurrogate(void) const
+	?Justify2@TDes16@@QAEXABVTDesC16@@HW4TAlign@@VTChar@@@Z @ 2198 NONAME ; void TDes16::Justify2(class TDesC16 const &, int, enum TAlign, class TChar)
+	?UpperCase2@TDes16@@QAEXXZ @ 2199 NONAME ; void TDes16::UpperCase2(void)
+	?Capitalize2@TDes16@@QAEXXZ @ 2200 NONAME ; void TDes16::Capitalize2(void)
+	?AppendJustify2@TDes16@@QAEXPBGHHW4TAlign@@VTChar@@@Z @ 2201 NONAME ; void TDes16::AppendJustify2(unsigned short const *, int, int, enum TAlign, class TChar)
+	?CopyLC2@TDes16@@QAEXABVTDesC16@@@Z @ 2202 NONAME ; void TDes16::CopyLC2(class TDesC16 const &)
+	?Fill2@TDes16@@QAEXVTChar@@H@Z @ 2203 NONAME ; void TDes16::Fill2(class TChar, int)
+	?LocateF2@TDesC16@@QBEHVTChar@@@Z @ 2204 NONAME ; int TDesC16::LocateF2(class TChar) const
+	?Match2@TDesC16@@QBEHABV1@@Z @ 2205 NONAME ; int TDesC16::Match2(class TDesC16 const &) const
+	?LocateReverse2@TDesC16@@QBEHVTChar@@@Z @ 2206 NONAME ; int TDesC16::LocateReverse2(class TChar) const
+	?LocateReverseF2@TDesC16@@QBEHVTChar@@@Z @ 2207 NONAME ; int TDesC16::LocateReverseF2(class TChar) const
+	?CopyCP2@TDes16@@QAEXABVTDesC16@@@Z @ 2208 NONAME ; void TDes16::CopyCP2(class TDesC16 const &)
+	?AgainHighRes@RTimer@@QAEXAAVTRequestStatus@@VTTimeIntervalMicroSeconds32@@@Z @ 2209 NONAME ; public: void __thiscall RTimer::AgainHighRes(class TRequestStatus &,class TTimeIntervalMicroSeconds32)
 
--- a/kernel/eka/bx86/econs.def	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/bx86/econs.def	Fri Apr 16 16:24:37 2010 +0300
@@ -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	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/bx86/ekernsmp.def	Fri Apr 16 16:24:37 2010 +0300
@@ -999,4 +999,15 @@
 	?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 &)
+	?NotificationLock@DPagingDevice@@QAEPAVNFastMutex@@XZ @ 1006 NONAME ; public: class NFastMutex * __thiscall DPagingDevice::NotificationLock(void)
+	?Configure@KernCoreStats@@SAHI@Z @ 1007 NONAME	;  public: static int KernCoreStats::Configure(unsigned int)
+	?Engage@KernCoreStats@@SAHH@Z @ 1008 NONAME	;  public: static int KernCoreStats::Engage(int)
+	?Retire@KernCoreStats@@SAHHH@Z @ 1009 NONAME	;  public: static int KernCoreStats::Retire(int, int)
+	?Stats@KernCoreStats@@SAHPAX@Z @ 1010 NONAME	;  public: static int KernCoreStats::Stats(void *)
+	?SetNumberOfActiveCpus@NKern@@SAXH@Z @ 1011 NONAME ; public: static void __cdecl NKern::SetNumberOfActiveCpus(int)
 
--- a/kernel/eka/bx86/ekernu.def	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/bx86/ekernu.def	Fri Apr 16 16:24:37 2010 +0300
@@ -943,4 +943,16 @@
 	?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 &)
+	?NotificationLock@DPagingDevice@@QAEPAVNFastMutex@@XZ @ 950 NONAME ; public: class NFastMutex * __thiscall DPagingDevice::NotificationLock(void)
+	?Configure@KernCoreStats@@SAHI@Z @ 951 NONAME	;  public: static int KernCoreStats::Configure(unsigned int)
+	?Engage@KernCoreStats@@SAHH@Z @ 952 NONAME	;  public: static int KernCoreStats::Engage(int)
+	?EnterIdle@KernCoreStats@@SAIXZ @ 953 NONAME	;  public: static unsigned int KernCoreStats::EnterIdle()
+	?LeaveIdle@KernCoreStats@@SAXI@Z @ 954 NONAME	;  public: static void KernCoreStats::LeaveIdle(unsigned int)
+	?Retire@KernCoreStats@@SAHHH@Z @ 955 NONAME	;  public: static int KernCoreStats::Retire(int, int)
+	?Stats@KernCoreStats@@SAHPAX@Z @ 956 NONAME	;  public: static int KernCoreStats::Stats(void *)
 
--- a/kernel/eka/bx86/euseru.def	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/bx86/euseru.def	Fri Apr 16 16:24:37 2010 +0300
@@ -2179,4 +2179,33 @@
 	?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)
+	?Append2@TDes16@@QAEXVTChar@@@Z @ 2184 NONAME ; void TDes16::Append2(class TChar)
+	?CopyC2@TDes16@@QAEXABVTDesC16@@@Z @ 2185 NONAME ; void TDes16::CopyC2(class TDesC16 const &)
+	?Collate2@TDes16@@QAEXXZ @ 2186 NONAME ; void TDes16::Collate2(void)
+	?CopyF2@TDes16@@QAEXABVTDesC16@@@Z @ 2187 NONAME ; void TDes16::CopyF2(class TDesC16 const &)
+	?Fill2@TDes16@@QAEXVTChar@@@Z @ 2188 NONAME ; void TDes16::Fill2(class TChar)
+	?Locate2@TDesC16@@QBEHVTChar@@@Z @ 2189 NONAME ; int TDesC16::Locate2(class TChar) const
+	?AppendFill2@TDes16@@QAEXVTChar@@H@Z @ 2190 NONAME ; void TDes16::AppendFill2(class TChar, int)
+	?AppendJustify2@TDes16@@QAEXABVTDesC16@@HHW4TAlign@@VTChar@@@Z @ 2191 NONAME ; void TDes16::AppendJustify2(class TDesC16 const &, int, int, enum TAlign, class TChar)
+	?AppendJustify2@TDes16@@QAEXPBGHW4TAlign@@VTChar@@@Z @ 2192 NONAME ; void TDes16::AppendJustify2(unsigned short const *, int, enum TAlign, class TChar)
+	?Fold2@TDes16@@QAEXXZ @ 2193 NONAME ; void TDes16::Fold2(void)
+	?AppendJustify2@TDes16@@QAEXABVTDesC16@@HW4TAlign@@VTChar@@@Z @ 2194 NONAME ; void TDes16::AppendJustify2(class TDesC16 const &, int, enum TAlign, class TChar)
+	?LowerCase2@TDes16@@QAEXXZ @ 2195 NONAME ; void TDes16::LowerCase2(void)
+	?CopyUC2@TDes16@@QAEXABVTDesC16@@@Z @ 2196 NONAME ; void TDes16::CopyUC2(class TDesC16 const &)
+	?FindCorruptSurrogate@TDesC16@@QBEHXZ @ 2197 NONAME ; int TDesC16::FindCorruptSurrogate(void) const
+	?Justify2@TDes16@@QAEXABVTDesC16@@HW4TAlign@@VTChar@@@Z @ 2198 NONAME ; void TDes16::Justify2(class TDesC16 const &, int, enum TAlign, class TChar)
+	?UpperCase2@TDes16@@QAEXXZ @ 2199 NONAME ; void TDes16::UpperCase2(void)
+	?Capitalize2@TDes16@@QAEXXZ @ 2200 NONAME ; void TDes16::Capitalize2(void)
+	?AppendJustify2@TDes16@@QAEXPBGHHW4TAlign@@VTChar@@@Z @ 2201 NONAME ; void TDes16::AppendJustify2(unsigned short const *, int, int, enum TAlign, class TChar)
+	?CopyLC2@TDes16@@QAEXABVTDesC16@@@Z @ 2202 NONAME ; void TDes16::CopyLC2(class TDesC16 const &)
+	?Fill2@TDes16@@QAEXVTChar@@H@Z @ 2203 NONAME ; void TDes16::Fill2(class TChar, int)
+	?LocateF2@TDesC16@@QBEHVTChar@@@Z @ 2204 NONAME ; int TDesC16::LocateF2(class TChar) const
+	?Match2@TDesC16@@QBEHABV1@@Z @ 2205 NONAME ; int TDesC16::Match2(class TDesC16 const &) const
+	?LocateReverse2@TDesC16@@QBEHVTChar@@@Z @ 2206 NONAME ; int TDesC16::LocateReverse2(class TChar) const
+	?LocateReverseF2@TDesC16@@QBEHVTChar@@@Z @ 2207 NONAME ; int TDesC16::LocateReverseF2(class TChar) const
+	?CopyCP2@TDes16@@QAEXABVTDesC16@@@Z @ 2208 NONAME ; void TDes16::CopyCP2(class TDesC16 const &)
+	?AgainHighRes@RTimer@@QAEXAAVTRequestStatus@@VTTimeIntervalMicroSeconds32@@@Z @ 2209 NONAME ; public: void __thiscall RTimer::AgainHighRes(class TRequestStatus &,class TTimeIntervalMicroSeconds32)
 
--- a/kernel/eka/bx86gcc/ekernsmp.def	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/bx86gcc/ekernsmp.def	Fri Apr 16 16:24:37 2010 +0300
@@ -1087,4 +1087,15 @@
 	_ZN4Kern19UnmapAndUnpinMemoryEP16TKernelMapObject @ 1086 NONAME
 	_ZN4Kern21CreateKernelMapObjectERP16TKernelMapObjectj @ 1087 NONAME
 	_ZN4Kern22DestroyKernelMapObjectERP16TKernelMapObject @ 1088 NONAME
+	_ZN9Interrupt16AddTimingEntropyEv @ 1089 NONAME
+	_ZN4Kern10RandomSaltEmj @ 1090 NONAME
+	_ZN4Kern10RandomSaltEyj @ 1091 NONAME
+	_ZN4Kern10RandomSaltEPKhjj @ 1092 NONAME
+	_ZN4Kern12SecureRandomER5TDes8 @ 1093 NONAME
+	_ZN13DPagingDevice16NotificationLockEv @ 1094 NONAME
+	_ZN13KernCoreStats5StatsEPv @ 1095 NONAME
+	_ZN13KernCoreStats6EngageEi @ 1096 NONAME
+	_ZN13KernCoreStats6RetireEii @ 1097 NONAME
+	_ZN13KernCoreStats9ConfigureEj @ 1098 NONAME
+	_ZN5NKern21SetNumberOfActiveCpusEi @ 1099 NONAME
 
--- a/kernel/eka/bx86gcc/ekernu.def	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/bx86gcc/ekernu.def	Fri Apr 16 16:24:37 2010 +0300
@@ -1026,4 +1026,16 @@
 	_ZN4Kern19UnmapAndUnpinMemoryEP16TKernelMapObject @ 1025 NONAME
 	_ZN4Kern21CreateKernelMapObjectERP16TKernelMapObjectj @ 1026 NONAME
 	_ZN4Kern22DestroyKernelMapObjectERP16TKernelMapObject @ 1027 NONAME
+	_ZN9Interrupt16AddTimingEntropyEv @ 1028 NONAME
+	_ZN4Kern10RandomSaltEmj @ 1029 NONAME
+	_ZN4Kern10RandomSaltEyj @ 1030 NONAME
+	_ZN4Kern10RandomSaltEPKhjj @ 1031 NONAME
+	_ZN4Kern12SecureRandomER5TDes8 @ 1032 NONAME
+	_ZN13DPagingDevice16NotificationLockEv @ 1033 NONAME
+	_ZN13KernCoreStats5StatsEPv @ 1034 NONAME
+	_ZN13KernCoreStats6EngageEi @ 1035 NONAME
+	_ZN13KernCoreStats6RetireEii @ 1036 NONAME
+	_ZN13KernCoreStats9ConfigureEj @ 1037 NONAME
+	_ZN13KernCoreStats9EnterIdleEv @ 1038 NONAME
+	_ZN13KernCoreStats9LeaveIdleEj @ 1039 NONAME
 
--- a/kernel/eka/bx86gcc/euseru.def	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/bx86gcc/euseru.def	Fri Apr 16 16:24:37 2010 +0300
@@ -2458,3 +2458,32 @@
 	_ZN15TExtendedLocale10LoadLocaleERK7TDesC16S2_S2_ @ 2457 NONAME
 	_ZN15TExtendedLocale16LoadLocaleAspectERK7TDesC16 @ 2458 NONAME
 	_ZN16TChunkCreateInfo11SetReadOnlyEv @ 2459 NONAME
+	_ZN4Math7RandomLER5TDes8 @ 2460 NONAME
+	_ZN4Math6RandomER5TDes8 @ 2461 NONAME
+	_ZN4Math7RandomLEv @ 2462 NONAME
+	_ZN6TDes1610LowerCase2Ev @ 2463 NONAME
+	_ZN6TDes1610UpperCase2Ev @ 2464 NONAME
+	_ZN6TDes1611AppendFill2E5TChari @ 2465 NONAME
+	_ZN6TDes1611Capitalize2Ev @ 2466 NONAME
+	_ZN6TDes1614AppendJustify2EPKti6TAlign5TChar @ 2467 NONAME
+	_ZN6TDes1614AppendJustify2EPKtii6TAlign5TChar @ 2468 NONAME
+	_ZN6TDes1614AppendJustify2ERK7TDesC16i6TAlign5TChar @ 2469 NONAME
+	_ZN6TDes1614AppendJustify2ERK7TDesC16ii6TAlign5TChar @ 2470 NONAME
+	_ZN6TDes165Fill2E5TChar @ 2471 NONAME
+	_ZN6TDes165Fill2E5TChari @ 2472 NONAME
+	_ZN6TDes165Fold2Ev @ 2473 NONAME
+	_ZN6TDes166CopyC2ERK7TDesC16 @ 2474 NONAME
+	_ZN6TDes166CopyF2ERK7TDesC16 @ 2475 NONAME
+	_ZN6TDes167Append2E5TChar @ 2476 NONAME
+	_ZN6TDes167CopyCP2ERK7TDesC16 @ 2477 NONAME
+	_ZN6TDes167CopyLC2ERK7TDesC16 @ 2478 NONAME
+	_ZN6TDes167CopyUC2ERK7TDesC16 @ 2479 NONAME
+	_ZN6TDes168Collate2Ev @ 2480 NONAME
+	_ZN6TDes168Justify2ERK7TDesC16i6TAlign5TChar @ 2481 NONAME
+	_ZNK7TDesC1614LocateReverse2E5TChar @ 2482 NONAME
+	_ZNK7TDesC1615LocateReverseF2E5TChar @ 2483 NONAME
+	_ZNK7TDesC1620FindCorruptSurrogateEv @ 2484 NONAME
+	_ZNK7TDesC166Match2ERKS_ @ 2485 NONAME
+	_ZNK7TDesC167Locate2E5TChar @ 2486 NONAME
+	_ZNK7TDesC168LocateF2E5TChar @ 2487 NONAME
+	_ZN6RTimer12AgainHighResER14TRequestStatus27TTimeIntervalMicroSeconds32 @ 2488 NONAME ; RTimer::AgainHighRes(TRequestStatus&, TTimeIntervalMicroSeconds32)
--- a/kernel/eka/common/arm/cheap.cia	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/common/arm/cheap.cia	Fri Apr 16 16:24:37 2010 +0300
@@ -101,7 +101,7 @@
 	asm("add r5, r1, r4 ");					// r5=pN=pC + pC->len (cell after pC)
 	asm("cmp r5, r3 ");						// compare pN with pE
 	asm("ldmeqia r3, {r5, r12} ");			// if pN==pE, r5=pE->len, r12=pE->next
-	asm("bhi " CSM_Z22RHeap_PanicBadNextCellv );	// if pN>pE, panic
+	asm("blhi " CSM_Z22RHeap_PanicBadNextCellv );	// if pN>pE, panic
 	asm("strne r3, [r1, #4] ");				// if pN<pE, pC->next=pE
 	asm("addeq r4, r4, r5 ");				// if pN==pE r4 = pC->len + pE->len
 	asm("stmeqia r1, {r4,r12} ");			// if pN==pE pC->len+=pE->len, pC->next=pE->next
@@ -110,7 +110,7 @@
 	asm("sub r5, r1, r2 ");					// r5=pC-pP (gap between preceding free cell and this one)
 	asm("cmp r5, r3 ");						// compare gap with predecessor length
 	asm("ldreq r12, [r1, #4] ");			// if predecessor is adjacent, r12=pC->next
-	asm("blo RHeap_PanicBadPrevCell__Fv ");	// if predecessor overlaps, panic
+	asm("bllo RHeap_PanicBadPrevCell__Fv ");	// if predecessor overlaps, panic
 	asm("addeq r4, r4, r3 ");				// if predecessor is adjacent, r4=pC->len + pP->len
 	asm("stmeqia r2, {r4,r12} ");			// if predecessor is adjacent, pP->len+=pC->len, pP->next=pC->next
 	asm("strne r1, [r2, #4] ");				// else pP->next = pC
--- a/kernel/eka/common/des16.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/common/des16.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -765,6 +765,13 @@
 #endif
 	}
 
+// Surrogate-aware version of lookup() above.
+// aChar can be over 0xFFFF.
+inline TUint lookup2(const TUint aChar, const TText *aConv)
+	{
+	return TUnicode(aChar).Fold((TInt)aConv, GetLocaleCharSet()->iCharDataSet);
+	}
+
 TInt DoMatch16(const TDesC16 &aLeftD,const TDesC16 &aRightD,TMatchType aType)
 	{
 	const TText* table=convTable(aType);
@@ -1368,6 +1375,558 @@
 
 #endif  // !defined(__DES16_MACHINE_CODED__)
 
+
+/**
+ * A helper function, which moves a pointer one Unicode character forward.
+ * 
+ * @aStart points to the head of the string to process.
+ * @aEnd   points to the end of the string. Note that aEnd points to the first
+ *         16-bit unit after the string. That is, the string length (i.e, count
+ *         of 16-bit units) is (aEnd-aStart).
+ * 
+ * On return,
+ *      if find valid character, then return KErrNone, with aNewStart pointing
+ *          to the 16-bit unit after the found character;
+ *      if meet corrupt surrogate before find a valid character, then return
+ *          KErrCorruptSurrogateFound, with aNewStart pointing to the corrupt surrogate;
+ *      if meet aEnd before find a valid character, then return KErrNotFound.
+ * 
+ * @return KErrNone if ok;
+ *         KErrNotFound if get to aEnd;
+ *         KErrCorruptSurrogateFound if meet corrupt surrogate.
+ */
+TInt ProceedOneCharacter(const TText16* aStart, const TText16* aEnd, TText16*& aNewStart, TUint& aCurrentChar)
+	{
+	if (!aStart || !aEnd || aStart>=aEnd)
+		return KErrNotFound;
+	if (!TChar::IsSurrogate(aStart[0]))
+		{
+		aCurrentChar = aStart[0];
+		aNewStart = const_cast<TText16*> (aStart + 1);
+		return KErrNone;
+		}
+	else if (TChar::IsHighSurrogate(aStart[0]))
+		{
+		if (aEnd < aStart + 2)
+			return KErrCorruptSurrogateFound;
+		if (!TChar::IsLowSurrogate(aStart[1]))
+			{
+			aNewStart = const_cast<TText16*> (aStart + 2);
+			return KErrCorruptSurrogateFound;
+			}
+		aCurrentChar = TChar::JoinSurrogate(aStart[0], aStart[1]);
+		aNewStart = const_cast<TText16*> (aStart + 2);
+		return KErrNone;
+		}
+	else
+		{
+		aNewStart = const_cast<TText16*> (aStart);
+		return KErrCorruptSurrogateFound;
+		}
+	}
+
+/**
+ * A helper function, which moves a pointer one or more Unicode characters forward.
+ * 
+ * This function starts from aStart, stops when one of below conditions matched:
+ *   1) 16-bit position >= (aEnd - aStart);
+ *   2) 16-bit position >= aMaxInt16Position;
+ *   3) character position >= aMaxCharacterPosition;
+ * 
+ * Specify a huge integer (say KMaskDesLength16) for aMaxInt16Position or 
+ * aMaxCharacterPosition to indicate unlimited 16-bit position or character 
+ * position.
+ * 
+ * When return, aOutInt16Position, aOutCharacterPosition and aLastChar will 
+ *              indicate the same one character, whose 
+ *              16-bit position <= aMaxInt16Position, and 
+ *              character position <= aMaxCharacterPosition.
+ * 
+ * @return KErrNone if no error found;
+ *         KErrNotFound if get to aEnd before find wanted position; or,
+ *                      if aMaxIntPosition<=0 or aMaxCharacterPosition<=0;
+ *         KErrCorruptSurrogateFound if meet corrupt surrogate.
+ */
+TInt ProceedMultiCharacters(const TText16* aStart, const TText16* aEnd,
+							const TInt aMaxInt16Position, const TInt aMaxCharacterPosition,
+							TInt& aOutInt16Position, TInt& aOutCharacterPosition, TUint& aLastChar)
+	{
+	TText16 *next;
+	TInt status = KErrNotFound;
+	aOutInt16Position = 0;
+	aOutCharacterPosition = 0;
+	while (aOutInt16Position <= aMaxInt16Position && aOutCharacterPosition <= aMaxCharacterPosition)
+		{
+		status = ::ProceedOneCharacter(aStart+aOutInt16Position, aEnd, next, aLastChar);
+		if (status == KErrNotFound || status == KErrCorruptSurrogateFound)
+			return status;
+		if (next - aStart > aMaxInt16Position || aOutInt16Position == aMaxInt16Position || aOutCharacterPosition == aMaxCharacterPosition)
+			{
+			return status;
+			}
+		aOutInt16Position = (next - aStart);
+		++aOutCharacterPosition;
+		}
+	return status;
+	}
+
+EXPORT_C TInt TDesC16::FindCorruptSurrogate() const
+/**
+Look for the first corrupt surrogate in the descriptor.
+
+@return The 16-bit position of the first corrupt surrogate. KErrNotFound, if 
+        not found.
+*/
+	{
+	// Do not use TUTF32Iterator, because it hides some characters, including corrupt surrogate.
+	TInt strLength = Length();
+
+	const TText16* start = Ptr();
+	const TText16* end = Ptr() + strLength;
+	TInt int16Pos;
+	TInt charPos;
+	TUint lastChar;
+	TInt status = ::ProceedMultiCharacters(start, end, KMaskDesLength16, KMaskDesLength16, int16Pos, charPos, lastChar);
+	if (status == KErrCorruptSurrogateFound)
+		return int16Pos;
+	return KErrNotFound;
+	}
+
+EXPORT_C TInt TDesC16::Locate2(TChar aChar) const
+/**
+The surrogate aware version of Locate().
+
+Searches for the first occurrence of a character within this descriptor's 
+data.
+
+The search starts at the beginning of the data, i.e. at the leftmost 
+position.
+
+@param aChar The Unicode character to be found. Can be inside or outside BMP.
+
+@return The offset of the character position from the beginning of the data.
+        KErrNotFound, if no matching character can be found.
+        KErrCorruptSurrogateFound, if meet corrupt surrogate in the searching.
+
+@see TDesC16::Locate()
+*/
+	{
+	TInt strLength = Length();
+	const TText16* start = Ptr();
+	const TText16* end = Ptr() + strLength;
+	TText16* next;
+	TUint currentChar;
+	TInt int16Index = 0;
+	TInt status = KErrNone;
+	FOREVER
+		{
+		status = ::ProceedOneCharacter(start+int16Index, end, next, currentChar);
+		if (status != KErrNone)
+			return status;
+		if (currentChar == aChar)
+			return int16Index;
+		int16Index = (next - start);
+		}
+	}
+
+LOCAL_C TInt DoLocateF16_2(const TDesC16& aDes, TUint aChar)
+// Surrogate-aware version of DoLocateF16().
+// Locate character aChar in the descriptor folded.
+	{
+	const TText* table = convTable(EMatchFolded);
+	TUint aChar32 = aChar;
+	aChar = lookup2(aChar32, table);
+	
+	// find aChar in aDes
+	TInt strLength = aDes.Length();
+	const TText16* start = aDes.Ptr();
+	const TText16* end = aDes.Ptr() + strLength;
+	TText16* next;
+	TUint currentChar;
+	TInt int16Index = 0;
+	TInt status = KErrNone;
+	while (status == KErrNone)
+		{
+		status = ::ProceedOneCharacter(start+int16Index, end, next, currentChar);
+        if (status != KErrNone)
+            break;
+		if (lookup2(currentChar, table) == aChar)
+			return int16Index;
+		int16Index = (next - start);
+		}
+	return status;
+	}
+
+EXPORT_C TInt TDesC16::LocateF2(TChar aChar) const
+/**
+The surrogate aware version of LocateF().
+
+Searches for the first occurrence of a folded character within this
+descriptor's folded data.
+
+The search starts at the beginning of the data, i.e. at the leftmost 
+position.
+
+Note that folding is locale-independent behaviour. It is also important to 
+note that there can be no guarantee that folding is in any way culturally 
+appropriate, and should not be used for searching strings in natural language.
+
+@param aChar The Unicode character to be found. Can be inside or outside BMP.
+
+@return The offset of the character position from the beginning of the data.
+        KErrNotFound, if no matching character can be found.
+        KErrCorruptSurrogateFound, if meet corrupt surrogate in the searching.
+
+@see TDesC16::LocateF()
+*/
+	{
+	return DoLocateF16_2(*this, aChar);
+	}
+
+/**
+ * Proceed backward from aEnd toward aStart by one character.
+ * 
+ * @aStart points to the first 16-bit unit in a descriptor.
+ * @aEnd   points to the 16-bit unit after the last one. So, count of 16-bit 
+ *         units to process is (aEnd-aStart).
+ * 
+ * On return,
+ *      if valid character found, then return KErrNone, with aNewEnd pointing 
+ *          to the character found;
+ *      if meet corrupt surrogate before find a valid character, then return 
+ *          KErrCorruptSurrogateFound, with aNewStart point to the corrupt
+ *          surrogate;
+ *      if aStart met, then return KErrNotFound.
+ * 
+ * @return KErrNone if ok;
+ *         KErrNotFound if get to aStart;
+ *         KErrCorruptSurrogateFound if meet corrupt surrogate.
+ */
+TInt RecedeOneCharacter(const TText16* aStart, const TText16* aEnd, TText16*& aNewEnd, TUint& aCurrentChar)
+	{
+	if (!aStart || !aEnd || aStart>=aEnd)
+		return KErrNotFound;
+	if (!TChar::IsSurrogate(aEnd[-1]))
+		{
+		aCurrentChar = aEnd[-1];
+		aNewEnd = const_cast<TText16*> (aEnd - 1);
+		return KErrNone;
+		}
+	else if (TChar::IsLowSurrogate(aEnd[-1]))
+		{
+		if (aEnd < aStart + 2)
+			return KErrNotFound;
+		if (!TChar::IsHighSurrogate(aEnd[-2]))
+			{
+			aNewEnd = const_cast<TText16*> (aEnd - 2);
+			return KErrCorruptSurrogateFound;
+			}
+		aCurrentChar = TChar::JoinSurrogate(aEnd[-2], aEnd[-1]);
+		aNewEnd = const_cast<TText16*> (aEnd - 2);
+		return KErrNone;
+		}
+	else
+		{
+		aNewEnd = const_cast<TText16*> (aEnd);
+		return KErrCorruptSurrogateFound;
+		}
+	}
+
+EXPORT_C TInt TDesC16::LocateReverse2(TChar aChar) const
+/**
+The surrogate aware version of LocateReverse().
+
+Searches for the first occurrence of a character within this descriptor's 
+data, searching from the end of the data.
+
+The search starts at the rightmost position.
+
+@param aChar The Unicode character to be found. Can be inside or outside BMP.
+
+@return The offset of the character position from the beginning of the data.
+        KErrNotFound, if no matching character can be found.
+        KErrCorruptSurrogateFound, if meet corrupt surrogate in the searching.
+
+@see TDesC16::LocateReverse()
+*/
+	{
+	TInt strLength = Length();
+	const TText16* start = Ptr();
+	TText16* newEnd;
+	TUint currentChar;
+	TInt int16Index = strLength;
+	TInt status = KErrNone;
+	FOREVER
+		{
+		status = ::RecedeOneCharacter(start, start+int16Index, newEnd, currentChar);
+		if (status != KErrNone)
+		    return status;
+		int16Index = (newEnd - start);
+		if (currentChar == aChar)
+			return int16Index;
+		}
+	}
+
+EXPORT_C TInt TDesC16::LocateReverseF2(TChar aChar) const
+/**
+The surrogate aware version of LocateReverseF().
+
+Searches for the first occurrence of a folded character within this descriptor's 
+folded data, searching from the end of the data.
+
+The search starts at the rightmost position.
+
+Note that folding is locale-independent behaviour. It is also important to 
+note that there can be no guarantee that folding is in any way culturally 
+appropriate, and should not be used for searching strings in natural language.
+
+@param aChar The Unicode character to be found. Can be inside or outside BMP.
+
+@return The offset of the character position from the beginning of the data.
+        KErrNotFound, if no matching character can be found.
+        KErrCorruptSurrogateFound, if meet corrupt surrogate in the searching.
+
+@see TDesC16::LocateReverseF()
+*/
+	{
+	TInt strLength = Length();
+	const TText16* start = Ptr();
+	const TText16* end = Ptr() + strLength;
+	TText16* newEnd;
+	TUint currentChar;
+	TInt int16Index = 0;
+	TInt status = KErrNone;
+	FOREVER
+		{
+		status = ::RecedeOneCharacter(start, end, newEnd, currentChar);
+        if (status != KErrNone)
+            return status;
+		TCharF c(currentChar);
+		if (c == aChar)
+			return int16Index;
+		int16Index = (newEnd - start);
+		}
+	}
+
+inline TUint conv2(TUint aChar, const TText *aConv, const TUnicodeDataSet* aCharDataSet)
+// Surrogate-aware version of conv().
+// If aConv is not NULL then convert the character.
+	{
+	if (aConv)
+		return TUnicode(aChar).Fold((TInt)aConv, aCharDataSet);
+	else
+		return aChar;
+	}
+
+// Surrogate-aware version of DoMatch16().
+// This helper function uses the same search algorithm as DoMatch16().
+TInt DoMatch16_2(const TDesC16 &aLeftD, const TDesC16 &aRightD, TMatchType aType)
+	{
+	const TText* table=convTable(aType);
+	const TUint16* const pRight=aRightD.Ptr();
+	const TUint16* pM=pRight-1;						// pre-increment addressing
+	const TUint16* const pP=pM+aRightD.Length();
+	const TUint16* const pLeft=aLeftD.Ptr()-1;		// pre-increment addressing
+	const TUint16* pB=pLeft;	
+	const TUint16* pB2=pLeft;						// always points to current char; pB2==pB or pB-1
+	const TUint16* const pE=pB+aLeftD.Length();
+
+	// Note: pM and pB always point to the int16 unit before the character to handle.
+	//       so, pM[0] and pB[0] may be a low surrogate.
+	//       but, pM[1] and pB[1] must be start of a character.
+	// Note: pB2 always points to current character being handled.
+	//       pB2 is used to generated return value.
+	//       if pB[0] is low surrogate, then pB2=pB-1;
+	//       if pB[0] is BMP, then pB2=pB.
+	//
+	// A 'diagram' shows the pointers:
+	//
+	// before search:
+	//     left:       ############################
+	//                ^                           ^
+	//             pLeft/pB/pB2                   pE
+	//
+	//     right:      ############################
+	//                ^^                          ^
+	//              pM  pRight                    pP
+	//
+	//
+	// after several iterations (C is the next character going to be checked):
+    //     left:       ###############C############
+    //                ^              ^            ^
+    //             pLeft             pB/pB2       pE
+    //
+    //     right:      ##########C#################
+    //                 ^        ^                 ^
+    //                 pRight   pM                pP
+	//
+
+	const TUnicodeDataSet* charDataSet = GetLocaleCharSet()->iCharDataSet;
+
+	// Match any pattern up to the first star
+	TUint c;
+	TInt status;
+	TText* newStart;
+	for (;;)
+		{
+		status = ::ProceedOneCharacter(pM+1, pP+1, newStart, c);
+		if (status == KErrCorruptSurrogateFound)
+		    return KErrCorruptSurrogateFound;
+		if (status == KErrNotFound)		// exhausted the pattern
+			return pB==pE ? 0 : KErrNotFound;
+		pM = newStart - 1;
+		c = conv2(c, table, charDataSet);
+		if (c==KMatchAny)
+			break;
+		if (pB==pE)			// no more input
+			return KErrNotFound;
+		TUint c2;
+		pB2 = pB + 1;
+		status = ::ProceedOneCharacter(pB+1, pE+1, newStart, c2);
+        if (status == KErrCorruptSurrogateFound)
+            return KErrCorruptSurrogateFound;
+		pB = newStart - 1;
+		if (c != conv2(c2, table, charDataSet) && c != KMatchOne)	// match failed
+			return KErrNotFound;
+		}
+	// reached a star
+	if (pM==pP)
+		return 0;
+	TInt r=pM==pRight ? -1 : 0;		// r = how many int16 has been matched in candidate (aLeftD)
+	for (;;)
+		{
+		status = ::ProceedOneCharacter(pM+1, pP+1, newStart, c);
+        if (status == KErrCorruptSurrogateFound)
+            return KErrCorruptSurrogateFound;
+		pM = newStart - 1;
+		c = conv2(c, table, charDataSet);
+		if (c==KMatchAny)
+			{
+star:		if (pM==pP)		// star at end of pattern, always matches
+				return Max(r,0);
+			if (r<-1)		// skipped some '?', matches at beginning
+				r=0;
+			continue;
+			}
+		if (pB==pE)			// no more input
+			return KErrNotFound;
+		if (c==KMatchOne)
+			{				// skip a character in the input
+			if (pM==pP)
+				return r+((r>=0) ? 0 : (pE-pLeft));
+			TUint dummyC;
+			pB2 = pB + 1;
+			status = ::ProceedOneCharacter(pB+1, pE+1, newStart, dummyC);
+	        if (status == KErrCorruptSurrogateFound)
+	            return KErrCorruptSurrogateFound;
+			pB = newStart - 1;
+			if (r < 0)
+				r -= (newStart - pB2);	// back r by 1 or 2, depending on dummyC is BMP or non-BMP.
+			continue;
+			}
+	// Matching a non-wild character
+		for (;;)
+			{
+			if (table)
+				{
+				TUint c2;
+				for (;;)
+					{
+					pB2 = pB + 1;
+					status = ::ProceedOneCharacter(pB+1, pE+1, newStart, c2);
+			        if (status == KErrCorruptSurrogateFound)
+			            return KErrCorruptSurrogateFound;
+					pB = newStart - 1;
+					if (lookup2(c2, table) == c)
+						break;
+					if (pB==pE)				// no more input
+						return KErrNotFound;
+					}
+				}
+			else
+				{
+				TUint c2;
+				for (;;)
+					{
+					pB2 = pB + 1;
+					status = ::ProceedOneCharacter(pB+1, pE+1, newStart, c2);
+			        if (status == KErrCorruptSurrogateFound)
+			            return KErrCorruptSurrogateFound;
+					pB = newStart - 1;
+					if (c2 == c)
+						break;
+					if (pB==pE)				// no more input
+						return KErrNotFound;
+					}
+				}
+			// Try to match up to the next star
+			const TUint16* pb=pB;
+			const TUint16* pm=pM;
+			for (;;)
+				{
+				if (pm<pP)
+					{
+					TUint cc;
+					status = ::ProceedOneCharacter(pm+1, pP+1, newStart, cc);
+			        if (status == KErrCorruptSurrogateFound)
+			            return KErrCorruptSurrogateFound;
+					pm = newStart - 1;
+					cc = conv2(cc, table, charDataSet);
+					if (cc==KMatchAny)
+						{	// sub-match successful, back to main loop
+						r+=(r>=0 ? 0 : pB2-pLeft);
+						pB=pb;
+						pM=pm;
+						goto star;
+						}
+					if (pb==pE)
+						return KErrNotFound;	// no more input
+					TUint cc2;
+					status = ::ProceedOneCharacter(pb+1, pE+1, newStart, cc2);
+			        if (status == KErrCorruptSurrogateFound)
+			            return KErrCorruptSurrogateFound;
+					pb = newStart - 1;
+					if (cc != conv2(cc2, table, charDataSet) && cc != KMatchOne)
+						break;	// sub-match failed, try next input character
+					}
+				else if (pb==pE)	// end of matching pattern
+					{
+					return r+(r>=0 ? 0 : pB2-pLeft);	// end of input, so have a match
+					}
+				else
+					break;		// try next input character
+				}
+			}
+		}
+	}
+
+EXPORT_C TInt TDesC16::Match2(const TDesC16 &aDes) const
+/**
+The surrogate aware version of Match().
+
+Searches this descriptor's data for a match with the match pattern supplied 
+in the specified descriptor.
+
+The match pattern can contain the wildcard characters "*" and "?", where "*" 
+matches zero or more consecutive occurrences of any character and "?" matches 
+a single occurrence of any character.
+
+Note that there is no 'escape character', which means that it is not possible
+to match either the "*" character itself or the "?" character itself using
+this function.
+
+@param aDes A 16-bit non-modifable descriptor containing the match pattern.
+
+@return If a match is found, the offset within this descriptor's data where 
+        the match first occurs. KErrNotFound, if there is no match.
+        KErrCorruptSurrogateFound, if meet corrupt surrogate in the searching.
+
+@see TDesC16::Match()
+*/
+	{
+	return DoMatch16_2(*this, aDes, EMatchNormal);
+	}
+
 #if !defined( __DES16_MACHINE_CODED__) | defined(__EABI_CTORS__)
 EXPORT_C TBufCBase16::TBufCBase16()
 //
@@ -3383,6 +3942,930 @@
     AppendFormatList(aFmt,list);
     }
 
+EXPORT_C void TDes16::Append2(TChar aChar)
+/**
+The surrogate aware version of Append().
+
+Appends data onto the end of this descriptor's data.
+
+The length of this descriptor is incremented to reflect the new content. The
+length will be increased by 1 if aChar is inside BMP or 2 if aChar is outside
+BMP.
+
+@param aChar A single character to be appended. Can be inside or outside BMP.
+
+@panic USER 11  if the resulting new length of this descriptor is greater than
+                its maximum length.
+
+@panic USER 217 if corrupt surrogate found in aChar. This functions will not
+                validate already existing surrogate in the descriptor.
+
+@see TDes16::Append()
+*/
+	{
+	__ASSERT_ALWAYS(TChar::IsSupplementary(aChar) || !TChar::IsSurrogate((TText16)aChar), Panic(ECorruptSurrogateFound));
+
+	TInt len = Length();
+	TUint16 *pB = WPtr() + len;
+	if (TChar::IsSupplementary(aChar))
+		{
+		SetLength(len + 2);
+		*pB++ = TChar::GetHighSurrogate(aChar);
+		*pB = TChar::GetLowSurrogate(aChar);
+		}
+	else
+		{
+		SetLength(len + 1);
+		*pB = (TText16)aChar;
+		}
+	}
+
+EXPORT_C void TDes16::Fill2(TChar aChar)
+/**
+The surrogate aware version of Fill().
+
+Fills the descriptor's data area with the specified character, replacing any 
+existing data.
+
+The descriptor is filled from the beginning up to its current length. The 
+descriptor's length does not change. It is not filled to its maximum length.
+If aChar is supplementary character, and available space to fill is odd in
+16-bit unit, then the last 16-bit unit will be left unchanged, and the length
+will keep unchanged.
+
+@param aChar The fill character. Can be inside or outside BMP.
+
+@see TDes16::Fill()
+*/
+	{
+	TUint16 *pB = WPtr();
+	TUint16 *pE = pB + Length();
+	if (!TChar::IsSupplementary(aChar))
+		{
+		while (pB < pE)
+			*pB++ = (TUint16)aChar;
+		}
+	else
+		{
+		while (pB < pE - 1)
+			{
+			*pB++ = TChar::GetHighSurrogate(aChar);
+			*pB++ = TChar::GetLowSurrogate(aChar);
+			}
+		}
+	}
+
+EXPORT_C void TDes16::Fill2(TChar aChar, TInt aLength)
+/**
+The surrogate aware version of Fill().
+
+Fills the descriptor's data area with the specified character, replacing any 
+existing data.
+
+The descriptor is filled with the specified number of characters,
+and its length is changed to reflect this.
+
+If aChar is supplementary character, and available space to fill is odd in
+16-bit unit, then the last 16-bit unit will be left unchanged.
+
+@param aChar   The fill character. Can be inside or outside BMP.
+@param aLength The new length of the descriptor.
+
+@panic USER 11  if aLength is negative or is greater than the maximum length
+                of this descriptor.
+
+@panic USER 217 if corrupt surrogate found in aChar. These functions will not 
+                validate already existing surrogate in the descriptor.
+
+@see TDes16::Fill()
+*/
+	{
+	__ASSERT_ALWAYS(TChar::IsSupplementary(aChar) || !TChar::IsSurrogate((TText16)aChar), Panic(ECorruptSurrogateFound));
+
+	SetLength(aLength);
+	Fill2(aChar);
+	}
+
+EXPORT_C void TDes16::AppendFill2(TChar aChar, TInt aLength)
+/**
+The surrogate aware version of AppendFill().
+
+Appends and fills this descriptor with the specified character.
+
+The descriptor is appended with the specified number of characters, and its
+length is changed to reflect this.
+
+If aChar is supplementary character, and available space to fill is odd in 
+16-bit unit, then the last 16-bit unit will be left unchanged.
+
+@param aChar   The fill character. Can be inside or outside BMP.
+@param aLength The length of additional space to append into.
+
+@panic USER 11  if aLength is negative, or the resulting length of this
+                descriptor is greater than its maximum length.
+
+@panic USER 217 if corrupt surrogate found in aChar. These functions will not 
+                validate already existing surrogate in the descriptor.
+
+@see TDes16::AppendFill()
+*/
+	{
+	__ASSERT_ALWAYS(TChar::IsSupplementary(aChar) || !TChar::IsSurrogate((TText16)aChar), Panic(ECorruptSurrogateFound));
+
+	TInt len=Length();
+	TUint16 *pB=WPtr()+len;
+	SetLength(len+aLength);
+	TUint16 *pE=pB+aLength;
+	if (!TChar::IsSupplementary(aChar))
+		{
+		while (pB < pE)
+			*pB++ = (TUint16)aChar;
+		}
+	else
+		{
+		while (pB < pE - 1)
+			{
+			*pB++ = TChar::GetHighSurrogate(aChar);
+			*pB++ = TChar::GetLowSurrogate(aChar);
+			}
+		}
+	}
+
+EXPORT_C void TDes16::Justify2(const TDesC16 &aDes, TInt aWidth, TAlign anAlignment, TChar aFill)
+/**
+The surrogate aware version of Justify().
+
+Copies data into this descriptor and justifies it, replacing any existing data.
+
+The length of this descriptor is set to reflect the new data.
+
+The target area is considered to be an area of specified width positioned at
+the beginning of this descriptor's data area. Source data is copied into, and
+aligned within this target area according to the specified alignment
+instruction.
+
+If the length of the target area is larger than the length of the source, then
+spare space within the target area is padded with the fill character.
+
+@param aDes        A 16-bit non-modifiable descriptor containing the source data.
+                   The length of the data to be copied is the smaller of:
+                   the length of the source descriptor, and 
+                   the width of the target area (only if this is not the
+                   explicit negative value KDefaultJustifyWidth).
+
+@param aWidth      The width of the target area. If this has the specific
+                   negative value KDefaultJustifyWidth, then the width is
+                   re-set to the length of the data source.
+
+@param anAlignment The alignment of the data within the target area
+
+@param aFill       The fill character used to pad the target area. Can be
+                   inside or outside BMP.
+
+@panic USER 11  if the resulting length of this descriptor is greater than
+                its maximum length or aWidth has a negative value other 
+                than KDefaultJustifyWidth.
+
+@panic USER 217 if corrupt surrogate found in the parameters or in the 
+                descriptor.
+
+@see TDes16::Justify()
+*/
+	{
+    Zero();
+    AppendJustify2(aDes.Ptr(),aDes.Length(),aWidth,anAlignment,aFill);
+	}
+
+EXPORT_C void TDes16::AppendJustify2(const TDesC16 &aDes, TInt aWidth, TAlign anAlignment, TChar aFill)
+/**
+The surrogate aware version of AppendJustify.
+
+Appends data onto the end of this descriptor's data and justifies it.
+    
+The source of the appended data is an existing descriptor.
+    
+The target area is considered to be an area of specified width, immediately 
+following this descriptor's existing data. Source data is copied into, and 
+aligned within this target area according to the specified alignment instruction.
+    
+If the length of the target area is larger than the length of the source, 
+then spare space within the target area is padded with the fill character.
+        
+@param aDes        A 16-bit non-modifiable descriptor containing the source
+                   data. The length of the data to be copied is the smaller of:
+                   the length of the source descriptor, and
+                   the width of the target area (only if this is not the
+                   explicit negative value KDefaultJustifyWidth). 
+    
+@param aWidth      The width of the target area. If this has the specific
+                   negative value KDefaultJustifyWidth, then the width is
+                   re-set to the length of the data source.
+    
+@param anAlignment The alignment of the data within the target area. 
+    
+@param aFill       The fill character used to pad the target area. Can be
+                   inside or outside BMP.
+
+@panic USER 11  if the resulting length of this descriptor is greater than
+                its maximum length or aWidth has a negative value other 
+                than KDefaultJustifyWidth.
+
+@panic USER 217 if corrupt surrogate found in the parameters or in the 
+                descriptor.
+
+@see TDes16::AppendJustify()
+*/
+	{
+    AppendJustify2(aDes.Ptr(),aDes.Length(),aWidth,anAlignment,aFill);
+	}
+
+EXPORT_C void TDes16::AppendJustify2(const TDesC16 &aDes, TInt aLength, TInt aWidth, TAlign anAlignment, TChar aFill)
+/**
+The surrogate aware version of AppendJustify.
+
+Appends data onto the end of this descriptor's data and justifies it.
+    
+The source of the appended data is an existing descriptor.
+    
+The target area is considered to be an area of specified width, immediately 
+following this descriptor's existing data. Source data is copied into, and 
+aligned within this target area according to the specified alignment instruction.
+    
+If the length of the target area is larger than the length of the source, 
+then spare space within the target area is padded with the fill character.
+    
+@param aDes        An 8-bit non-modifiable descriptor containing the source data. 
+
+@param aLength     The length of data to be copied from the source descriptor. 
+                   If this is greater than the width of the target area, then
+                   the length of data copied is limited to the width.
+                   The length of data to be copied must not be  greater than
+                   the length of the source descriptor. Note that this
+                   condition is not automatically tested. 
+                   
+@param aWidth      The width of the target area. If this has the specific negative 
+                   value KDefaultJustifyWidth, then the width is
+                   re-set to the length of the data source.
+
+@param anAlignment The alignment of the data within the target area. 
+
+@param aFill       The fill character used to pad the target area. Can be
+                   inside or outside BMP.
+
+@panic USER 11  if the resulting length of this descriptor is greater than
+                its maximum length or aWidth has a negative value other 
+                than KDefaultJustifyWidth.
+
+@panic USER 217 if corrupt surrogate found in the parameters or in the 
+                descriptor.
+
+@see TDes16::AppendJustify()
+*/
+	{
+    AppendJustify2(aDes.Ptr(),aLength,aWidth,anAlignment,aFill);
+	}
+
+EXPORT_C void TDes16::AppendJustify2(const TUint16 *aString, TInt aWidth, TAlign anAlignment, TChar aFill)
+/**
+The surrogate aware version of AppendJustify.
+
+Appends a zero terminated string onto the end of this descriptor's data and 
+justifies it.
+
+The zero terminator is not copied.
+
+The target area is considered to be an area of specified width, immediately 
+following this descriptor's existing data. Source data is copied into, and 
+aligned within, this target area according to the specified alignment instruction.
+
+If the length of the target area is larger than the length of the source, 
+then spare space within the target area is padded with the fill character.
+
+@param aString     A pointer to a zero terminated string The length of the data 
+                   to be copied is the smaller of: the length of the string (excluding the zero 
+                   terminator), the width of the target area (only if this is not the explicit 
+                   negative value KDefaultJustifyWidth). 
+                    
+@param aWidth      The width of the target area. If this has the specific negative 
+                   value KDefaultJustifyWidth, then the width is re-set to the length of the 
+                   zero terminated string (excluding the zero terminator).
+                    
+@param anAlignment The alignment of the data within the target area. 
+
+@param aFill       The fill character used to pad the target area. Can be
+                   inside or outside BMP.
+
+@panic USER 11  if the resulting length of this descriptor is greater than
+                its maximum length or aWidth has a negative value other 
+                than KDefaultJustifyWidth.
+
+@panic USER 217 if corrupt surrogate found in the parameters or in the 
+                descriptor.
+
+@see TDes16::AppendJustify()
+*/
+	{
+ 	__CHECK_ALIGNMENT(aString,ETDes16AppendJustify1);
+	AppendJustify2(aString,STRING_LENGTH_16(aString),aWidth,anAlignment,aFill);
+	}
+
+EXPORT_C void TDes16::AppendJustify2(const TUint16 *aString, TInt aLength, TInt aWidth, TAlign anAlignment, TChar aFill)
+/**
+The surrogate aware version of AppendJustify.
+
+Appends data onto the end of this descriptor's data and justifies it.
+
+The source of the appended data is a memory location.
+
+The target area is considered to be an area of specified width, immediately 
+following this descriptor's existing data. Source data is copied into, and 
+aligned within, this target area according to the specified alignment instruction.
+
+If the length of the target area is larger than the length of the source, 
+then spare space within the target area is padded with the fill character.
+
+@param aString     A pointer to a source memory location. 
+
+@param aLength     The length of data to be copied. If this is greater than the 
+                   width of the target area, then the length of data copied is
+                   limited to the width.
+               
+@param aWidth      The width of the target area. If this has the specific negative 
+                   value KDefaultJustifyWidth, then the width is
+                   re-set to the length of the data source. 
+               
+@param anAlignment The alignment of the data within the target area. 
+
+@param aFill       The fill character used to pad the target area. Can be
+                   inside or outside BMP.
+
+@panic USER 11  if the resulting length of this descriptor is greater than
+                its maximum length or aWidth has a negative value other 
+                than KDefaultJustifyWidth.
+
+@panic USER 17  if aLength is negative.
+  
+@panic USER 217 if corrupt surrogate found in the parameters or in the 
+                descriptor.
+
+@see TDes16::AppendJustify()
+*/
+	{
+	__ASSERT_ALWAYS(aLength>=0,Panic(ETDes16LengthNegative));
+	__CHECK_ALIGNMENT(aString,ETDes16AppendJustify2);
+	if (aWidth==KDefaultJustifyWidth)
+		aWidth=aLength;
+	if (aLength>aWidth)
+		aLength=aWidth;
+	TInt offset=Length();
+	AppendFill2(aFill,aWidth);
+	TInt r=aWidth-aLength;
+	if (anAlignment==ECenter)
+		r>>=1;
+	else if (anAlignment==ELeft)
+		r=0;
+	memCopy(WPtr()+offset+r,aString,aLength);
+	}
+
+EXPORT_C void TDes16::Fold2()
+/**
+The surrogate aware version of Fold().
+
+Performs folding on the content of this descriptor.
+
+Note that folding is locale-independent behaviour. It is also important to 
+note that there can be no guarantee that folding is in any way culturally 
+appropriate, and should not be used when dealing with strings in natural
+language.
+
+@panic USER 217 if corrupt surrogate found in the descriptor.
+
+@see TDes16::Fold()
+*/
+	{
+	TInt strLength = Length();
+	TText16* start = WPtr();
+	const TText16* end = Ptr() + strLength;
+	TText16* next;
+	TUint currentChar;
+	TInt int16Index = 0;
+	TInt status = KErrNone;
+	FOREVER
+		{
+		status = ::ProceedOneCharacter(start+int16Index, end, next, currentChar);
+		__ASSERT_ALWAYS(status != KErrCorruptSurrogateFound, Panic(ECorruptSurrogateFound));
+		if (status == KErrNotFound)
+			break;
+		TCharF c(currentChar);
+		// at present, c and currentChar always in the same plane
+		if (TChar::IsSupplementary(c))
+			{
+			start[int16Index] = TChar::GetHighSurrogate(c);
+			start[int16Index+1] = TChar::GetLowSurrogate(c);
+			}
+		else
+			{
+			start[int16Index] = (TText16)c;
+			}
+		int16Index = (next - start);
+		}
+	}
+
+EXPORT_C void TDes16::Collate2()
+/**
+The surrogate aware version of Collate().
+
+Performs collation on the content of this descriptor.
+
+@panic USER 217 if corrupt surrogate found in the descriptor.
+
+@see TDes16::Collate()
+*/
+	{
+	TInt strLength = Length();
+	TText16* start = WPtr();
+	const TText16* end = Ptr() + strLength;
+	TText16* next;
+	TUint currentChar;
+	TInt int16Index = 0;
+	TInt status = KErrNone;
+	FOREVER
+		{
+		status = ::ProceedOneCharacter(start+int16Index, end, next, currentChar);
+		__ASSERT_ALWAYS(status != KErrCorruptSurrogateFound, Panic(ECorruptSurrogateFound));
+		if (status == KErrNotFound)
+			break;
+		TChar c = User::Collate(currentChar);
+		// at present, c and currentChar always in the same plane
+		if (TChar::IsSupplementary(c))
+			{
+			start[int16Index] = TChar::GetHighSurrogate(c);
+			start[int16Index+1] = TChar::GetLowSurrogate(c);
+			}
+		else
+			{
+			start[int16Index] = (TText16)c;
+			}
+		int16Index = (next - start);
+		}
+	}
+
+EXPORT_C void TDes16::LowerCase2()
+/**
+The surrogate aware version of LowerCase().
+
+Converts the content of this descriptor to lower case.
+
+Conversion is implemented as appropriate to the current locale.
+
+@panic USER 217 if corrupt surrogate found in the descriptor.
+
+@see TDes16::LowerCase()
+*/
+	{
+	TInt strLength = Length();
+	TText16* start = WPtr();
+	const TText16* end = Ptr() + strLength;
+	TText16* next;
+	TUint currentChar;
+	TInt int16Index = 0;
+	TInt status = KErrNone;
+	FOREVER
+		{
+		status = ::ProceedOneCharacter(start+int16Index, end, next, currentChar);
+		__ASSERT_ALWAYS(status != KErrCorruptSurrogateFound, Panic(ECorruptSurrogateFound));
+		if (status == KErrNotFound)
+			break;
+		TCharLC c(currentChar);
+		// at present, c and currentChar always in the same plane
+		if (TChar::IsSupplementary(c))
+			{
+			start[int16Index] = TChar::GetHighSurrogate(c);
+			start[int16Index+1] = TChar::GetLowSurrogate(c);
+			}
+		else
+			{
+			start[int16Index] = (TText16)c;
+			}
+		int16Index = (next - start);
+		}
+	}
+
+EXPORT_C void TDes16::UpperCase2()
+/**
+The surrogate aware version of UpperCase().
+
+Converts the content of this descriptor to upper case.
+
+Conversion is implemented as appropriate to the current locale.
+
+@panic USER 217 if corrupt surrogate found in the descriptor.
+
+@see TDes16::UpperCase()
+*/
+	{
+	TInt strLength = Length();
+	TText16* start = WPtr();
+	const TText16* end = Ptr() + strLength;
+	TText16* next;
+	TUint currentChar;
+	TInt int16Index = 0;
+	TInt status = KErrNone;
+	FOREVER
+		{
+		status = ::ProceedOneCharacter(start+int16Index, end, next, currentChar);
+		__ASSERT_ALWAYS(status != KErrCorruptSurrogateFound, Panic(ECorruptSurrogateFound));
+		if (status == KErrNotFound)
+			break;
+		TCharUC c(currentChar);
+		// at present, c and currentChar always in the same plane
+		if (TChar::IsSupplementary(c))
+			{
+			start[int16Index] = TChar::GetHighSurrogate(c);
+			start[int16Index+1] = TChar::GetLowSurrogate(c);
+			}
+		else
+			{
+			start[int16Index] = (TText16)c;
+			}
+		int16Index = (next - start);
+		}
+	}
+
+EXPORT_C void TDes16::Capitalize2()
+/**
+The surrogate aware version of Capitalize().
+
+Capitalises the content of this descriptor.
+
+Capitalisation is implemented as appropriate to the current locale.
+
+@panic USER 217 if corrupt surrogate found in the descriptor.
+
+@see TDes16::Capitalize()
+*/
+	{
+	TInt strLength = Length();
+	TText16* start = WPtr();
+	const TText16* end = Ptr() + strLength;
+	TText16* next;
+	TUint currentChar;
+	TInt int16Index = 0;
+	TInt status = KErrNone;
+	
+	// the first character: title case
+	status = ::ProceedOneCharacter(start, end, next, currentChar);
+	__ASSERT_ALWAYS(status != KErrCorruptSurrogateFound, Panic(ECorruptSurrogateFound));
+	TChar c = User::TitleCase(currentChar);
+	// at present, c and currentChar always in the same plane
+	if (TChar::IsSupplementary(c))
+		{
+		start[0] = TChar::GetHighSurrogate(c);
+		start[1] = TChar::GetLowSurrogate(c);
+		}
+	else
+		{
+		start[0] = (TText16)c;
+		}
+	int16Index = (next - start);
+	
+	// following characters: lower case
+	FOREVER
+		{
+		status = ::ProceedOneCharacter(start+int16Index, end, next, currentChar);
+		__ASSERT_ALWAYS(status != KErrCorruptSurrogateFound, Panic(ECorruptSurrogateFound));
+		if (status == KErrNotFound)
+			break;
+		TChar c = User::LowerCase(currentChar);
+		// at present, c and currentChar always in the same plane
+		if (TChar::IsSupplementary(c))
+			{
+			start[int16Index] = TChar::GetHighSurrogate(c);
+			start[int16Index+1] = TChar::GetLowSurrogate(c);
+			}
+		else
+			{
+			start[int16Index] = (TText16)c;
+			}
+		int16Index = (next - start);
+		}
+	}
+
+EXPORT_C void TDes16::CopyF2(const TDesC16 &aDes)
+/**
+The surrogate aware version of CopyF().
+
+Copies and folds data from the specified descriptor into this descriptor replacing 
+any existing data.
+
+The length of this descriptor is set to reflect the new 
+data.
+
+Note that folding is locale-independent behaviour. It is also important to 
+note that there can be no guarantee that folding is in any way culturally 
+appropriate, and should not be used when dealing with strings in natural
+language.
+
+@param aDes A 16-bit non-modifiable descriptor.
+
+@panic USER 11  if the length of aDes is greater than the maximum length of
+                this target descriptor.
+
+@panic USER 217 if corrupt surrogate found in aDes or in the descriptor.
+
+@see TDes16::CopyF()
+*/
+	{
+	TText16* pT = WPtr();
+	TInt len = 0;
+	const TInt maxLen = MaxLength();
+	
+	// iterate through aDes
+	TInt strLength = aDes.Length();
+	const TText16* start = aDes.Ptr();
+	const TText16* end = aDes.Ptr() + strLength;
+	TText16* next;
+	TUint currentChar;
+	TInt int16Index = 0;
+	TInt status = KErrNone;
+	FOREVER
+		{
+		status = ::ProceedOneCharacter(start+int16Index, end, next, currentChar);
+		__ASSERT_ALWAYS(status != KErrCorruptSurrogateFound, Panic(ECorruptSurrogateFound));
+		if (status == KErrNotFound)
+			break;
+		int16Index = (next - start);
+		TCharF c(currentChar);
+		if (TChar::IsSupplementary(c))
+			{
+			len += 2;
+			__ASSERT_ALWAYS(len<=maxLen, Panic(ETDes16Overflow));
+			pT[len-2] = TChar::GetHighSurrogate(c);
+			pT[len-1] = TChar::GetLowSurrogate(c);
+			}
+		else
+			{
+			++len;
+			__ASSERT_ALWAYS(len<=maxLen, Panic(ETDes16Overflow));
+			pT[len-1] = (TText16)c;
+			}
+		}
+	SetLength(len);
+	}
+
+EXPORT_C void TDes16::CopyC2(const TDesC16 &aDes)
+/**
+The surrogate aware version of CopyC().
+
+Copies and collates data from the specified descriptor
+into this descriptor replacing any existing data.
+
+The length of this descriptor is set to reflect the new data.
+
+@param aDes A 16-bit non-modifiable descriptor.
+
+@panic USER 11  if the length of aDes is greater than the maximum length of
+                this target descriptor.
+
+@panic USER 217 if corrupt surrogate found in aDes or in the descriptor.
+
+@see TDes16::CopyC()
+*/
+	{
+	TText16* pT = WPtr();
+	TInt len = 0;
+	const TInt maxLen = MaxLength();
+	
+	// iterate through aDes
+	TInt strLength = aDes.Length();
+	const TText16* start = aDes.Ptr();
+	const TText16* end = aDes.Ptr() + strLength;
+	TText16* next;
+	TUint currentChar;
+	TInt int16Index = 0;
+	TInt status = KErrNone;
+	FOREVER
+		{
+		status = ::ProceedOneCharacter(start+int16Index, end, next, currentChar);
+		__ASSERT_ALWAYS(status != KErrCorruptSurrogateFound, Panic(ECorruptSurrogateFound));
+		if (status == KErrNotFound)
+			break;
+		int16Index = (next - start);
+		TChar c = User::Collate(currentChar);
+		if (TChar::IsSupplementary(c))
+			{
+			len += 2;
+			__ASSERT_ALWAYS(len<=maxLen, Panic(ETDes16Overflow));
+			pT[len-2] = TChar::GetHighSurrogate(c);
+			pT[len-1] = TChar::GetLowSurrogate(c);
+			}
+		else
+			{
+			++len;
+			__ASSERT_ALWAYS(len<=maxLen, Panic(ETDes16Overflow));
+			pT[len-1] = (TText16)c;
+			}
+		}
+	SetLength(len);
+	}
+
+EXPORT_C void TDes16::CopyLC2(const TDesC16 &aDes)
+/**
+The surrogate aware version of CopyLC().
+
+Copies text from the specified descriptor and converts it to lower case before 
+putting it into this descriptor, replacing any existing data.
+
+The length of this descriptor is set to reflect the new data.
+
+Conversion to lower case is implemented as appropriate to the current locale.
+
+@param aDes A 16-bit non modifiable descriptor.
+
+@panic USER 11  if the length of aDes is greater than the maximum length of
+                this target descriptor.
+
+@panic USER 217 if corrupt surrogate found in aDes or in the descriptor.
+
+@see TDes16::CopyLC()
+*/
+	{
+	TText16* pT = WPtr();
+	TInt len = 0;
+	const TInt maxLen = MaxLength();
+	
+	// iterate through aDes
+	TInt strLength = aDes.Length();
+	const TText16* start = aDes.Ptr();
+	const TText16* end = aDes.Ptr() + strLength;
+	TText16* next;
+	TUint currentChar;
+	TInt int16Index = 0;
+	TInt status = KErrNone;
+	FOREVER
+		{
+		status = ::ProceedOneCharacter(start+int16Index, end, next, currentChar);
+		__ASSERT_ALWAYS(status != KErrCorruptSurrogateFound, Panic(ECorruptSurrogateFound));
+		if (status == KErrNotFound)
+			break;
+		int16Index = (next - start);
+		TCharLC c(currentChar);
+		if (TChar::IsSupplementary(c))
+			{
+			len += 2;
+			__ASSERT_ALWAYS(len<=maxLen, Panic(ETDes16Overflow));
+			pT[len-2] = TChar::GetHighSurrogate(c);
+			pT[len-1] = TChar::GetLowSurrogate(c);
+			}
+		else
+			{
+			++len;
+			__ASSERT_ALWAYS(len<=maxLen, Panic(ETDes16Overflow));
+			pT[len-1] = (TText16)c;
+			}
+		}
+	SetLength(len);
+	}
+
+EXPORT_C void TDes16::CopyUC2(const TDesC16 &aDes)
+/**
+The surrogate aware version of CopyUC().
+
+Copies text from the specified descriptor and converts it to upper case before 
+putting it into this descriptor, replacing any existing data.
+
+The length of this descriptor is set to reflect the new data.
+
+Conversion to upper case is implemented as appropriate to the current locale.
+
+@param aDes A 16-bit non modifiable descriptor.
+
+@panic USER 11  if the length of aDes is greater than the maximum length of
+                this target descriptor.
+
+@panic USER 217 if corrupt surrogate found in aDes or in the descriptor.
+
+@see TDes16::CopyUC()
+*/
+	{
+	TText16* pT = WPtr();
+	TInt len = 0;
+	const TInt maxLen = MaxLength();
+	
+	// iterate through aDes
+	TInt strLength = aDes.Length();
+	const TText16* start = aDes.Ptr();
+	const TText16* end = aDes.Ptr() + strLength;
+	TText16* next;
+	TUint currentChar;
+	TInt int16Index = 0;
+	TInt status = KErrNone;
+	FOREVER
+		{
+		status = ::ProceedOneCharacter(start+int16Index, end, next, currentChar);
+		__ASSERT_ALWAYS(status != KErrCorruptSurrogateFound, Panic(ECorruptSurrogateFound));
+		if (status == KErrNotFound)
+			break;
+		int16Index = (next - start);
+		TCharUC c(currentChar);
+		if (TChar::IsSupplementary(c))
+			{
+			len += 2;
+			__ASSERT_ALWAYS(len<=maxLen, Panic(ETDes16Overflow));
+			pT[len-2] = TChar::GetHighSurrogate(c);
+			pT[len-1] = TChar::GetLowSurrogate(c);
+			}
+		else
+			{
+			++len;
+			__ASSERT_ALWAYS(len<=maxLen, Panic(ETDes16Overflow));
+			pT[len-1] = (TText16)c;
+			}
+		}
+	SetLength(len);
+	}
+
+EXPORT_C void TDes16::CopyCP2(const TDesC16 &aDes)
+/**
+The surrogate aware version of CopyCP().
+
+Copies text from the specified descriptor and capitalises it before putting 
+it into this descriptor, replacing any existing data.
+
+The length of this descriptor is set to reflect the new data.
+
+Capitalisation is implemented as appropriate to the current locale.
+
+@param aDes A 16-bit non-modifiable descriptor.
+
+@panic USER 11  if the length of aDes is greater than the maximum length of
+                this target descriptor.
+
+@panic USER 217 if corrupt surrogate found in aDes or in the descriptor.
+
+@see TDes16::CopyCP()
+*/
+	{
+	TText16* pT = WPtr();
+	TInt len = 0;
+	const TInt maxLen = MaxLength();
+	
+	// iterate through aDes
+	TInt strLength = aDes.Length();
+	const TText16* start = aDes.Ptr();
+	const TText16* end = aDes.Ptr() + strLength;
+	TText16* next;
+	TUint currentChar;
+	TInt int16Index = 0;
+	TInt status = KErrNone;
+	
+	// first character: title case
+	status = ::ProceedOneCharacter(start, end, next, currentChar);
+	__ASSERT_ALWAYS(status != KErrCorruptSurrogateFound, Panic(ECorruptSurrogateFound));
+	int16Index = (next - start);
+	TChar c(currentChar);
+	c.TitleCase();
+	if (TChar::IsSupplementary(c))
+		{
+		len += 2;
+		__ASSERT_ALWAYS(len<=maxLen, Panic(ETDes16Overflow));
+		pT[len-2] = TChar::GetHighSurrogate(c);
+		pT[len-1] = TChar::GetLowSurrogate(c);
+		}
+	else
+		{
+		++len;
+		__ASSERT_ALWAYS(len<=maxLen, Panic(ETDes16Overflow));
+		pT[len-1] = (TText16)c;
+		}
+	
+	// following characters: lower case
+	FOREVER
+		{
+		status = ::ProceedOneCharacter(start+int16Index, end, next, currentChar);
+		__ASSERT_ALWAYS(status != KErrCorruptSurrogateFound, Panic(ECorruptSurrogateFound));
+		if (status == KErrNotFound)
+			break;
+		int16Index = (next - start);
+		TCharLC c(currentChar);
+		if (TChar::IsSupplementary(c))
+			{
+			len += 2;
+			__ASSERT_ALWAYS(len<=maxLen, Panic(ETDes16Overflow));
+			pT[len-2] = TChar::GetHighSurrogate(c);
+			pT[len-1] = TChar::GetLowSurrogate(c);
+			}
+		else
+			{
+			++len;
+			__ASSERT_ALWAYS(len<=maxLen, Panic(ETDes16Overflow));
+			pT[len-1] = (TText16)c;
+			}
+		}
+	SetLength(len);
+	}
+
+
 #if !defined(__DES16_MACHINE_CODED__) | defined(__EABI_CTORS__)
 EXPORT_C TPtrC16::TPtrC16()
 	: TDesC16(EPtrC,0),iPtr(0)
--- a/kernel/eka/compsupp/ARM EABI LICENCE.txt	Tue Feb 02 01:24:03 2010 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,130 +0,0 @@
-The Specimen Implementations of the Exception Handling Components of the ABI for the ARM(R) Architecture consists of copyright owned by ARM Limited and copyright owned by Nokia Corporation. Each is licensed to you separately by the respective copyright owner, on the terms set out in this file.
-
-1. LICENSE TO ARM COPYRIGHT
-
-IMPORTANT: THIS IS A LEGAL AGREEMENT ("LICENCE") BETWEEN YOU (AN INDIVIDUAL OR
-SINGLE ENTITY WHO IS RECEIVING THIS SOURCE CODE DIRECTLY FROM ARM LIMITED)
-("LICENSEE") AND ARM LIMITED ("ARM") FOR THE VERSION OF THE SOURCE CODE SUPPLIED
-WITH THIS LICENCE ("SOURCE CODE"). THE SOURCE CODE IS A SPECIMEN IMPLEMENTATION OF
-EXCEPTION HANDLING COMPONENTS COMPLYING WITH THE SPECIFICATION DEFINED IMMEDIATELY
-BELOW. BY DOWNLOADING OR OTHERWISE USING THE SOURCE CODE, YOU AGREE TO BE BOUND BY
-ALL OF THE TERMS OF THIS LICENCE. IF YOU DO NOT AGREE TO THIS, DO NOT DOWNLOAD OR
-USE THE SOURCE CODE.
-
-“Specification” means, and is limited to, version 2 of the specification for the
-Applications Binary Interface for the ARM Architecture published by ARM.
-Notwithstanding the foregoing,  Specification” shall not include (i) the
-implementation of other published specifications referenced in this  Specification;
-(ii) any enabling technologies that may be necessary to make or use any product or
-portion thereof that complies with this Specification, but are not themselves
-expressly set forth in this Specification (e.g. compiler front ends, code
-generators, back ends, libraries or other compiler, assembler or linker
-technologies; validation or debug software or hardware; applications, operating
-system or driver software; RISC architecture; processor microarchitecture);
-(iii) maskworks and physical layouts of integrated circuit designs; or (iv) RTL or
-other high level representations of integrated circuit designs.
-
-Use, copying or disclosure by the US Government is subject to the restrictions set
-out in subparagraph (c)(1)(ii) of the Rights in Technical Data and Computer Software
-clause at DFARS 252.227-7013 or subparagraphs (c)(1) and (2) of the Commercial
-Computer Software - Restricted Rights at 48 C.F.R. 52.227-19, as applicable.
-
-The Source Code is owned by ARM or its licensors and is protected by copyright laws
-and international copyright treaties as well as other intellectual property laws and
-treaties. The Source Code is licensed not sold.
-
-1.  Subject to the provisions of Clauses 2 and 3, ARM hereby grants to LICENSEE,
-under any intellectual property that is (i) owned or freely licensable by ARM
-without payment to unaffiliated third parties and (ii) either embodied in the Source
-Code, or Necessary to copy or implement an applications binary interface compliant
-with the Specification, a perpetual, non-exclusive, non-transferable, fully paid,
-worldwide limited licence to use, copy, modify and sublicense this Source Code (in
-source or object code form) solely for the purpose of developing, having developed,
-manufacturing, having manufactured, offering to sell, selling, supplying or
-otherwise distributing products which comply with the Specification, provided that
-LICENSEE preserves all copyright notices included in the Source Code. All other
-rights are reserved to ARM or its licensors.
-
-2. THIS SOURCE CODE IS PROVIDED "AS IS" WITH NO WARRANTIES EXPRESS, IMPLIED OR
-STATUTORY, INCLUDING BUT NOT LIMITED TO ANY WARRANTY OF SATISFACTORY QUALITY,
-MERCHANTABILITY, NONINFRINGEMENT OR FITNESS FOR A PARTICULAR PURPOSE. THE SOURCE
-CODE MAY INCLUDE ERRORS. ARM RESERVES THE RIGHT TO INCORPORATE MODIFICATIONS TO THE
-SOURCE CODE IN LATER REVISIONS OF IT, AND TO MAKE IMPROVEMENTS OR CHANGES IN THE
-SPECIFICATION OR THE PRODUCTS OR TECHNOLOGIES DESCRIBED THEREIN AT ANY TIME.
-
-3.  This Licence shall immediately terminate and shall be unavailable to LICENSEE if
-LICENSEE or any party affiliated to LICENSEE asserts any patents against ARM, ARM
-affiliates, third parties who have a valid licence from ARM for the Specification or
-the Source Code, or any customers or distributors of any of them based upon a claim
-that a LICENSEE (or LICENSEE affiliate) patent is Necessary to implement the
-Specification. In this Licence; (i) "affiliate" means any entity controlling,
-controlled by or under common control with a party (in fact or in law, via voting
-securities, management control or otherwise) and "affiliated" shall be construed
-accordingly; (ii) "assert" means to allege infringement in legal or administrative
-proceedings, or proceedings before any other competent trade, arbitral or
-international authority; (iii) “Necessary” means with respect to any claims of any
-patent, those claims which, without the appropriate permission of the patent owner,
-will be infringed when implementing the Specification because no alternative,
-commercially reasonable, non-infringing way of implementing the Specification is
-known; and (iv) English law and the jurisdiction of the English courts shall apply
-to all aspects of this Licence, its interpretation and enforcement. The total
-liability of ARM and any of its suppliers and licensors under or in relation to this
-Licence shall be limited to the greater of the amount actually paid by LICENSEE for
-the Specification or US$10.00. The limitations, exclusions and disclaimers in this
-Licence shall apply to the maximum extent allowed by applicable law.
-
-
-ARM contract reference number LEC-ELA-00080-V2.0.
-
-
-2. LICENSE TO NOKIA COPYRIGHT
-
-IMPORTANT: THIS IS A LEGAL AGREEMENT ("LICENCE") BETWEEN YOU (AN INDIVIDUAL OR
-SINGLE ENTITY WHO IS RECEIVING THIS SOURCE CODE FROM NOKIA CORPORATION)
-("LICENSEE") AND NOKIA CORPORATION ("NOKIA") FOR THE VERSION OF THE SOURCE CODE SUPPLIED WITH THIS LICENCE ("SOURCE CODE"). THE SOURCE CODE IS A SPECIMEN IMPLEMENTATION OF EXCEPTION HANDLING COMPONENTS COMPLYING WITH THE SPECIFICATION DEFINED IMMEDIATELY BELOW. BY DOWNLOADING OR OTHERWISE USING THE SOURCE CODE, YOU AGREE TO BE BOUND BY ALL OF THE TERMS OF THIS LICENCE. IF YOU DO NOT AGREE TO THIS, DO NOT DOWNLOAD OR USE THE SOURCE CODE.
-
-“Specification” means, and is limited to, version 2 of the specification for the
-Applications Binary Interface for the ARM Architecture published by ARM LIMITED.
-Notwithstanding the foregoing,  Specification” shall not include (i) the
-implementation of other published specifications referenced in this Specification;
-(ii) any enabling technologies that may be necessary to make or use any product or
-portion thereof that complies with this Specification, but are not themselves
-expressly set forth in this Specification (e.g. compiler front ends, code
-generators, back ends, libraries or other compiler, assembler or linker
-technologies; validation or debug software or hardware; applications, operating
-system or driver software; RISC architecture; processor microarchitecture);
-(iii) maskworks and physical layouts of integrated circuit designs; or (iv) RTL or
-other high level representations of integrated circuit designs.
-
-Use, copying or disclosure by the US Government is subject to the restrictions set
-out in subparagraph (c)(1)(ii) of the Rights in Technical Data and Computer Software
-clause at DFARS 252.227-7013 or subparagraphs (c)(1) and (2) of the Commercial
-Computer Software - Restricted Rights at 48 C.F.R. 52.227-19, as applicable.
-
-The Source Code is owned by Nokia or its licensors and is protected by copyright laws
-and international copyright treaties as well as other intellectual property laws and
-treaties. The Source Code is licensed not sold.
-
-1.  Subject to the provisions of Clauses 2 and 3, Nokia hereby grants to LICENSEE,
-under any intellectual property that is (i) owned or freely licensable by Nokia
-without payment to unaffiliated third parties and (ii) either embodied in the Source
-Code, or Necessary to copy or implement an applications binary interface compliant
-with the Specification, a perpetual, non-exclusive, non-transferable, fully paid,
-worldwide limited licence to use, copy, modify and sublicense this Source Code (in
-source or object code form) solely for the purpose of developing, having developed,
-manufacturing, having manufactured, offering to sell, selling, supplying or
-otherwise distributing products which comply with the Specification, provided that
-LICENSEE preserves all copyright notices included in the Source Code. All other
-rights are reserved to Nokia or its licensors.
-
-2. THIS SOURCE CODE IS PROVIDED "AS IS" WITH NO WARRANTIES EXPRESS, IMPLIED OR
-STATUTORY, INCLUDING BUT NOT LIMITED TO ANY WARRANTY OF SATISFACTORY QUALITY,
-MERCHANTABILITY, NONINFRINGEMENT OR FITNESS FOR A PARTICULAR PURPOSE. THE SOURCE
-CODE MAY INCLUDE ERRORS. ARM RESERVES THE RIGHT TO INCORPORATE MODIFICATIONS TO THE
-SOURCE CODE IN LATER REVISIONS OF IT, AND TO MAKE IMPROVEMENTS OR CHANGES IN THE
-SPECIFICATION OR THE PRODUCTS OR TECHNOLOGIES DESCRIBED THEREIN AT ANY TIME.
-
-3.  English law and the jurisdiction of the English courts shall apply
-to all aspects of this Licence, its interpretation and enforcement. TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, IN NO EVENT SHALL NOKIA, ITS EMPLOYEES OR LICENSORS OR AFFILIATES BE LIABLE FOR ANY LOST PROFITS, REVENUE, SALES, DATA, OR COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, PROPERTY DAMAGE, PERSONAL INJURY, INTERRUPTION OF BUSINESS, LOSS OF BUSINESS INFORMATION, OR FOR ANY SPECIAL, DIRECT, INDIRECT, INCIDENTAL, ECONOMIC, COVER, PUNITIVE, OR CONSEQUENTIAL DAMAGES, HOWEVER CAUSED AND WHETHER ARISING UNDER CONTRACT, TORT, NEGLIGENCE, OR OTHER THEORY OF LIABILITY ARISING OUT OF THE USE OF OR INABILITY TO USE THE SOFTWARE, EVEN IF NOKIA OR ITS LICENSORS OR AFFILIATES ARE ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. BECAUSE SOME COUNTRIES/STATES/JURISDICTIONS DO NOT ALLOW THE EXCLUSION OF LIABILITY, BUT MAY ALLOW LIABILITY TO BE LIMITED, IN SUCH CASES, NOKIA, ITS EMPLOYEES OR LICENSORS OR AFFILIATES' LIABILITY SHALL BE LIMITED TO U.S. $50. Nothing contained in this Agreement shall prejudice the statutory rights of any party dealing as a consumer. Nothing contained in this Agreement limits Nokia's liability to You in the event of death or personal injury resulting from Nokia's negligence. Nokia is acting on behalf of its employees and licensors or affiliates for the purpose of disclaiming, excluding, and/or restricting obligations, warranties, and liability as provided in this clause 9, but in no other respects and for no other purpose.
-
-</End>
--- a/kernel/eka/compsupp/bld.inf	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/compsupp/bld.inf	Fri Apr 16 16:24:37 2010 +0300
@@ -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/debug/securityServer/inc/c_security_svr_async.h	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/debug/securityServer/inc/c_security_svr_async.h	Fri Apr 16 16:24:37 2010 +0300
@@ -53,15 +53,39 @@
 	virtual TInt RunError(TInt aError);
 
 private:
-	RMessagePtr2 iMessage;			// The last GetEvent message details. Needed for completion by RunL()
+
+    /*
+     * The last GetEvent message details. Needed for completion by RunL()
+     */
+    RMessagePtr2 iMessage;			
 
-	Debug::TEventInfo iInfo;				// Temporary storage area for rm_debug.ldd to return data asynchronously.
+    /*
+     * Temporary storage area for rm_debug.ldd to return data asynchronously
+     */
+	Debug::TEventInfo iInfo;
+
+	/*
+	 * Identity of this server session. Used for completing iMessage
+	 */
+	CSecuritySvrSession* iSession;
 
-	CSecuritySvrSession* iSession;	// Identity of this server session. Used for completing iMessage
+	/*
+	 * Name of the process being debugged associated with this AO
+	 */
+	RBuf8 iProcessName;
 
-	RBuf8 iProcessName;				// Name of the process being debugged associated with this AO
-
-	TProcessId iAgentId;				// Debug Agent Id
+	/*
+	 * Debug Agent Id
+	 */
+	TProcessId iAgentId;
+	
+	/*
+	 * Balance between event requests and event deliveries.
+	 * @see GetEvent()
+	 * @see NotifyEvent()
+	 * @see DoCancel()
+	 */
+	TInt iEventBalance;
 };
  
 #endif	// C_SECURITY_SVR_ASYNC_H
--- a/kernel/eka/debug/securityServer/inc/rm_debug_logging.h	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/debug/securityServer/inc/rm_debug_logging.h	Fri Apr 16 16:24:37 2010 +0300
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 2006-2010 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"
@@ -34,30 +34,48 @@
     #include <kernel/kernel.h>
     #include <nkern/nk_trace.h>
 
-    #define LOG_MSG( a )            __KTRACE_OPT(KDEBUGGER, Kern::Printf( a ))
-    #define LOG_MSG2( a, b )        __KTRACE_OPT(KDEBUGGER, Kern::Printf( a, b ))
-    #define LOG_MSG3( a, b, c )     __KTRACE_OPT(KDEBUGGER, Kern::Printf( a, b, c ))
-    #define LOG_MSG4( a, b, c, d )  __KTRACE_OPT(KDEBUGGER, Kern::Printf( a, b, c, d ))
-    #define LOG_MSG5( a, b, c, d, e )  __KTRACE_OPT(KDEBUGGER, Kern::Printf( a, b, c, d, e ))
+    #define LOG_MSG(args...)			__KTRACE_OPT(KDEBUGGER, Kern::Printf(args))
+	#define LOG_ENTRY()					__KTRACE_OPT(KDEBUGGER, Kern::Printf("+%s", __PRETTY_FUNCTION__))
+	#define LOG_EXIT()					__KTRACE_OPT(KDEBUGGER, Kern::Printf("-%s", __PRETTY_FUNCTION__))
+	#define LOG_ARGS(fmt, args...)		__KTRACE_OPT(KDEBUGGER, Kern::Printf("+%s " fmt, __PRETTY_FUNCTION__, args))
+	#define LOG_RETURN(x)				__KTRACE_OPT(KDEBUGGER, Kern::Printf("Returning %d from [%s]", x, __PRETTY_FUNCTION__)
+
+	// These kept for compatability
+    #define LOG_MSG2( a, b )			__KTRACE_OPT(KDEBUGGER, Kern::Printf( a, b ))
+    #define LOG_MSG3( a, b, c )			__KTRACE_OPT(KDEBUGGER, Kern::Printf( a, b, c ))
+    #define LOG_MSG4( a, b, c, d )		__KTRACE_OPT(KDEBUGGER, Kern::Printf( a, b, c, d ))
+    #define LOG_MSG5( a, b, c, d, e )	__KTRACE_OPT(KDEBUGGER, Kern::Printf( a, b, c, d, e ))
   #else
 
     #include <e32debug.h>
 
-    #define LOG_MSG( a )              RDebug::Printf( a )
-    #define LOG_MSG2( a, b )          RDebug::Printf( a, b )
-    #define LOG_MSG3( a, b, c )       RDebug::Printf( a, b, c )
-    #define LOG_MSG4( a, b, c, d )    RDebug::Printf( a, b, c, d )
-    #define LOG_MSG5( a, b, c, d, e )    RDebug::Printf( a, b, c, d, e )
+    #define LOG_MSG(args...)			RDebug::Printf(args)
+	#define LOG_DES(args...)			RDebug::Print(args) // For wide descriptors
+	#define LOG_ENTRY()					RDebug::Printf("+%s", __PRETTY_FUNCTION__)
+	#define LOG_EXIT()					RDebug::Printf("-%s", __PRETTY_FUNCTION__)
+	#define LOG_ARGS(fmt, args...)		RDebug::Printf("+%s " fmt, __PRETTY_FUNCTION__, args)
+	#define LOG_RETURN(x)				RDebug::Printf("Returning %d from [%s]", x, __PRETTY_FUNCTION__)
+
+    #define LOG_MSG2( a, b )			RDebug::Printf( a, b )
+    #define LOG_MSG3( a, b, c )			RDebug::Printf( a, b, c )
+    #define LOG_MSG4( a, b, c, d )		RDebug::Printf( a, b, c, d )
+    #define LOG_MSG5( a, b, c, d, e )	RDebug::Printf( a, b, c, d, e )
 
   #endif
 
 #else
 
-  #define LOG_MSG( a )
-  #define LOG_MSG2( a, b )
-  #define LOG_MSG3( a, b, c )
-  #define LOG_MSG4( a, b, c, d )
-  #define LOG_MSG5( a, b, c, d, e )
+	#define LOG_MSG(args...)
+	#define LOG_DES(args...)
+	#define LOG_ENTRY()
+	#define LOG_EXIT()
+	#define LOG_ARGS(fmt, args...)
+	#define LOG_RETURN(x)
+
+	#define LOG_MSG2( a, b )
+	#define LOG_MSG3( a, b, c )
+	#define LOG_MSG4( a, b, c, d )
+	#define LOG_MSG5( a, b, c, d, e )
 
 #endif
 
--- a/kernel/eka/debug/securityServer/src/c_process_pair.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/debug/securityServer/src/c_process_pair.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -61,7 +61,7 @@
 
 @param aProcessPair a CProcessPair object to match with this one
 
-@return ETrue is process id and name match, EFalse otherwise
+@return 0 if process ids and names do not match, non-zero if they do
 */
 TBool CProcessPair::operator==(const CProcessPair &aProcessPair) const
 	{
@@ -74,7 +74,7 @@
 @param aProcessName process name to check
 @param aProcessId process id to check
 
-@return ETrue is process id and name match, EFalse otherwise
+@return 0 if process ids and names do not match, non-zero if they do
 */
 TBool CProcessPair::Equals(const TDesC& aProcessName, const TProcessId aProcessId) const
 	{
@@ -86,7 +86,7 @@
 
 @param aProcessPair a CProcessPair object to compare with this one
 
-@return ETrue is process id matches, EFalse otherwise
+@return 0 if process ids do not match, non-zero if they do
 */
 TBool CProcessPair::ProcessIdMatches(const CProcessPair &aProcessPair) const
 	{
@@ -98,7 +98,7 @@
 
 @param aProcessId a process ID to compare with this pair's process ID
 
-@return ETrue is process id matches, EFalse otherwise
+@return 0 if process ids do not match, non-zero if they do
 */
 TBool CProcessPair::ProcessIdMatches(const TProcessId &aProcessId) const
 	{
@@ -110,7 +110,7 @@
 
 @param aProcessPair a CProcessPair object to compare with this one
 
-@return ETrue is process names match, EFalse otherwise
+@return 0 if process names do not match, non-zero if they do
 */
 TBool CProcessPair::ProcessNameMatches(const CProcessPair &aProcessPair) const
 	{
@@ -122,11 +122,10 @@
 
 @param aProcessName a process name to compare with this pair's process name
 
-@return ETrue is process names match, EFalse otherwise
+@return 0 if process names do not match, non-zero if they do
 */
 TBool CProcessPair::ProcessNameMatches(const TDesC& aProcessName) const
 	{
-	TInt equal = iProcessName->CompareF(aProcessName);
-	return (equal == 0) ? ETrue : EFalse;
+	return iProcessName->CompareF(aProcessName) == 0;
 	}
 
--- a/kernel/eka/debug/securityServer/src/c_security_svr_async.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/debug/securityServer/src/c_security_svr_async.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -25,10 +25,11 @@
 
 // ctor
 CSecuritySvrAsync::CSecuritySvrAsync(CSecuritySvrSession* aSession, TProcessId aAgentId)
-: CActive(CActive::EPriorityStandard),
-  iSession(aSession),
-  iProcessName(NULL),
-  iAgentId(aAgentId)
+	: CActive(CActive::EPriorityStandard),
+	iSession(aSession),
+	iProcessName(NULL),
+	iAgentId(aAgentId),
+	iEventBalance(0)
 	{
 	LOG_MSG("CSecuritySvrAsync::CSecuritySvrAsync()");
 	CActiveScheduler::Add(this);
@@ -72,7 +73,9 @@
 // RunL() completes a previously issued call (currently only GetEvent() completion)
 void CSecuritySvrAsync::RunL()
 	{
-	LOG_MSG("CSecuritySvrAsync::RunL()");
+
+	LOG_MSG3("CSecuritySvrAsync::RunL() &iInfo=0x%08x, iEventBalance=%d", (TUint8*)&iInfo, iEventBalance);
+
 	// Something bad happened in the driver
 	User::LeaveIfError(iStatus.Int());
 
@@ -96,44 +99,54 @@
 	iMessage.WriteL(1,data,0);
 
 	iMessage.Complete(KErrNone);
+	--iEventBalance;
 	}
 
 // Cancels the oustanding GetEvent call. May cope with other async calls in future.
 void CSecuritySvrAsync::DoCancel()
 	{
-	LOG_MSG("CSecuritySvrAsync::DoCancel()");
+	LOG_MSG2("CSecuritySvrAsync::DoCancel() iEventBalance=%d", iEventBalance);
 	iSession->Server().iKernelDriver.CancelGetEvent(iProcessName,iAgentId.Id());
 
 	iMessage.Complete(KErrCancel);
+	iEventBalance=0;
 	}
 
 // Report any leave to the client if possible.
 TInt CSecuritySvrAsync::RunError(TInt aError)
 	{
-	LOG_MSG("CSecuritySvrAsync::RunError()");
+	LOG_MSG2("CSecuritySvrAsync::RunError()=%d", aError);
 	iMessage.Complete(aError);
 
 	return KErrNone;
 	}
 
-// Start an Asynchronous GetEvent call to the rm_debug.ldd driver
-// and activate this Active Object.
+/*
+ * Start an asynchronous GetEvent call to the debug driver
+ * and activates this active object. 
+ */
 void CSecuritySvrAsync::GetEvent(const RMessage2& aMessage)
 	{
-	LOG_MSG("CSecuritySvrAsync::GetEvent()");
 	iMessage = aMessage;
 
-	iSession->Server().iKernelDriver.GetEvent(iProcessName,iAgentId.Id(),iStatus,iInfo);
+	iEventBalance++;
+	LOG_MSG5("CSecuritySvrAsync::GetEvent() this = 0x%08x, iInfo=0x%08x, iStatus=0x%08x \
+		iEventBalance=%d : >SetActive() > GetEvent() ",
+		this, &iInfo, &iStatus, iEventBalance );
 
+	/* 
+	SetActive is called before sending the message to the driver so 
+	that we do not get stray signal panics, since the driver may complete immediately
+ 	*/
 	SetActive();
+	iSession->Server().iKernelDriver.GetEvent(iProcessName,iAgentId.Id(),iStatus,iInfo);
 	}
 
 // Used for identifying which AO is associated with a debugged process
 const TDesC8& CSecuritySvrAsync::ProcessName(void)
-{
-	LOG_MSG("CSecuritySvrAsync::ProcessName()");
+	{
 	return iProcessName;
-}
+	}
 
 // End of file - c_security_svr_async.cpp
 
--- a/kernel/eka/debug/securityServer/src/c_security_svr_server.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/debug/securityServer/src/c_security_svr_server.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 2006-2010 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"
@@ -113,17 +113,18 @@
 // Session constructor
 //
 	{
-	LOG_MSG("CSecuritySvrServer::NewSessionL()\n");
+	LOG_ARGS("version=%d.%d.%d", aRequiredVersion.iMajor, aRequiredVersion.iMinor, aRequiredVersion.iBuild);
 
 	//assert compatible version
 	TVersion currentVersion(KDebugServMajorVersionNumber, KDebugServMinorVersionNumber, KDebugServPatchVersionNumber);
 	if(!User::QueryVersionSupported(currentVersion, aRequiredVersion))
 		{
-		return NULL;
+		LOG_MSG("Requested version not compatible with this version. Asked for %d.%d.%d but this is %d.%d.%d", aRequiredVersion.iMajor, aRequiredVersion.iMinor, aRequiredVersion.iBuild, KDebugServMajorVersionNumber, KDebugServMinorVersionNumber, KDebugServPatchVersionNumber);
+		User::Leave(KErrNotSupported);
 		}
 
 	//create session
-	LOG_MSG( "  About to call new(ELeave) CSecuritySvrSession()\n" );
+	LOG_MSG("About to call new(ELeave) CSecuritySvrSession()");
 	CSecuritySvrSession* servSession = new(ELeave) CSecuritySvrSession();
 
 	CleanupStack::PushL(servSession);
--- a/kernel/eka/debug/securityServer/src/c_security_svr_session.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/debug/securityServer/src/c_security_svr_session.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 2006-2010 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"
@@ -1040,7 +1040,7 @@
 	{
 	LOG_MSG( "CSecuritySvrSession::AttachProcessL()\n" );
 
-	TBool aPassive = aMessage.Int0() ? ETrue : EFalse;
+	const TBool passive = aMessage.Int0();
 
 	TInt deslen = aMessage.GetDesLengthL(1);
 
@@ -1142,7 +1142,7 @@
 		IsDebuggableL(processName);
 		}
 
-	User::LeaveIfError(Server().AttachProcessL(processName, processId, aPassive));
+	User::LeaveIfError(Server().AttachProcessL(processName, processId, passive));
 
 	// Inform the kernel driver about the attachment, so that it
 	// can track per-agent data about the process.
@@ -1361,10 +1361,16 @@
 		}
 	if ( i == KMaxLocalDrives)
 		{
-			LOG_MSG("No crash log partition found with valid crash log signature found.  Exiting...");
-			User::Leave (KErrNotFound);
+		LOG_MSG("No crash log partition found with valid crash log signature found.  Exiting...");
+		User::Leave (KErrNotFound);
 		}
-	
+
+	// Nand Flash not currently supported.
+	if (iCaps.iType == EMediaNANDFlash)
+		{
+		LOG_MSG( "CSecuritySvrSession::ConnectCrashPartitionL()  Nand Flash not currently supported\n" );
+		User::Leave (KErrNotSupported);
+		}
 	}
 /** Checks that aHeaderData contains enough data to cast it to the
   appropriate header type.
--- a/kernel/eka/doit.cmd	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/doit.cmd	Fri Apr 16 16:24:37 2010 +0300
@@ -18,6 +18,7 @@
 call setupprj
 call bld rel
 
+
 cd \
 perl e32\configure.pl %* >e32rt.txt
 call genbuild e32rt.txt
--- a/kernel/eka/drivers/adc/base_e32_drivers_adc.mrp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/drivers/adc/base_e32_drivers_adc.mrp	Fri Apr 16 16:24:37 2010 +0300
@@ -1,3 +1,18 @@
+#
+# 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 "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: 
+#
 # component name "ADC controller"
 
 component	base_e32_drivers_adc
--- a/kernel/eka/drivers/bsp/base_e32_drivers_bsp.mrp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/drivers/bsp/base_e32_drivers_bsp.mrp	Fri Apr 16 16:24:37 2010 +0300
@@ -1,3 +1,18 @@
+#
+# 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 "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: 
+#
 # component name "Generic Board Support Packages"
 
 component	base_e32_drivers_bsp
--- a/kernel/eka/drivers/bsp/bld.inf	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/drivers/bsp/bld.inf	Fri Apr 16 16:24:37 2010 +0300
@@ -28,6 +28,8 @@
 
 #include "../hcr/hcr.inf"
 
+PRJ_EXPORTS
+../../include/drivers/smppower/idlehelper.h      SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(smppower/idlehelper.h)
 
 PRJ_MMPFILES
 
@@ -48,7 +50,10 @@
 ../resourceman/resman_extended_lib
 ../resmanus/resmanus
 ../resmanus/resmanusextended
-../resmanus/resmanusextendedcore
+
+../power/smppower/idlehelper_lib.mmp
+../power/smppower/sample_idlehandler/smpidlehandler_lib.mmp
+
 #endif
 
 #if !defined(X86)
--- a/kernel/eka/drivers/camerasc/base_drivers_camerasc.mrp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/drivers/camerasc/base_drivers_camerasc.mrp	Fri Apr 16 16:24:37 2010 +0300
@@ -1,3 +1,18 @@
+#
+# 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 "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: 
+#
 # component name "Camera Driver - Shared Chunk"
 
 component	base_drivers_camerasc
--- a/kernel/eka/drivers/debug/group/base_e32_drivers_debug.mrp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/drivers/debug/group/base_e32_drivers_debug.mrp	Fri Apr 16 16:24:37 2010 +0300
@@ -1,3 +1,18 @@
+#
+# 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 "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: 
+#
 # component name "Run mode debugger"
 
 component	base_e32_drivers_debug
--- a/kernel/eka/drivers/debug/rmdebug/d_debug_agent.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/drivers/debug/rmdebug/d_debug_agent.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -31,23 +31,24 @@
 #include "d_debug_agent.h"
 #include "debug_utils.h"
 
-using namespace Debug;
+#include "d_debug_agent.inl"
 
-#define NUMBER_OF_EVENTS_TO_QUEUE 100
-#define CRITICAL_BUFFER_SIZE (NUMBER_OF_EVENTS_TO_QUEUE - 50)
+using namespace Debug;
 
 // ctor
-DDebugAgent::DDebugAgent(TUint64 aId)
-: iId(aId),
-  iEventInfo(NULL),
-  iEventQueue(NUMBER_OF_EVENTS_TO_QUEUE, 0),
-  iRequestGetEventStatus(NULL),
-  iClientThread(0),
-  iHead(0),
-  iTail(0),
-  iIgnoringTrace(EFalse)
+DDebugAgent::DDebugAgent(TUint64 aId) :
+	iId(aId),
+	iRequestGetEventStatus(NULL),
+	iClientThread(0),
+	iEventQueue(KNumberOfEventsToQueue, 0),
+	iHead(0),
+	iTail(0),
+	iEventQueueLock(NULL),
+	iFreeSlots(KNumberOfEventsToQueue),
+	iIgnoringTrace(EFalse),
+	iEventBalance(0)
 	{
-	LOG_MSG("DDebugAgent::DDebugAgent() ");
+	LOG_MSG2("DDebugAgent::DDebugAgent(), this=0x%x ", this);
 
 	// Initialize all the Event Actions to Ignore
 	for(TInt i=0; i<EEventsLast; i++)
@@ -69,32 +70,59 @@
 		delete agent;
 		return (NULL);
 		}
+
+	// Use a semaphore to serialise access
+	TInt err = Kern::SemaphoreCreate(agent->iEventQueueLock, _L("RM_DebugAgentQueueLock"), 1 /* Initial count */);
+	if (err != KErrNone)
+		return NULL;
+
 	return agent;
 	}
 
+/** Standard contructor.
+ * Fills event queue with empty events
+ * @return : standard system error code
+ */
 TInt DDebugAgent::Construct()
 	{
 	// Empty the event queue
 	LOG_MSG("DDebugAgent::Construct()");
 	TDriverEventInfo emptyEvent;
+	TInt err = KErrNone;
 
-	for (TInt i=0; i<NUMBER_OF_EVENTS_TO_QUEUE; i++)
+	for (TInt i=0; i<KNumberOfEventsToQueue; i++)
 		{
-		TInt err = iEventQueue.Append(emptyEvent);
-		if (KErrNone != err)
+		err = iEventQueue.Append(emptyEvent);
+		if (err != KErrNone)
 			{
 			LOG_MSG("Error appending blank event entry");
 			return err;
 			}
 		}
-	return KErrNone;
+
+	err = Kern::CreateClientDataRequest(iRequestGetEventStatus);
+	if(err != KErrNone)
+		{
+		LOG_MSG("Error creating TClientDataRequest");
+		return err;
+		}
+
+	LOG_MSG2("DDebugAgent::Construct() iRequestGetEventStatus=0x%08x", iRequestGetEventStatus);
+
+	return err;
 	}
 
-
 // dtor
 DDebugAgent::~DDebugAgent()
 	{
 	iEventQueue.Reset();
+
+	if (iEventQueueLock)
+		iEventQueueLock->Close(NULL);
+	
+	if(iRequestGetEventStatus)
+		Kern::DestroyClientRequest(iRequestGetEventStatus);
+	
 	}
 
 // Associate an action with a particular kernel event
@@ -112,9 +140,9 @@
 	return KErrNone;
 	}
 
-/* Get the aEventAction associated with aEvent
+/** Get the aEventAction associated with aEvent
  *
- * Returns : aEventAction (always +ve), or KErrArgument.
+ * @return : aEventAction (always +ve), or KErrArgument.
  */
 TInt DDebugAgent::EventAction(TEventType aEvent)
 	{
@@ -129,90 +157,110 @@
 	return iEventActions[aEvent];
 	}
 
-// Obtain the details of the latest kernel event (if it exists) and place the details in aEventInfo
-// If there is no event in the queue for this process+agent combination, store the details
-// so that it can be notified later when an event actually occurs.
-//
-// @param aAsyncGetValueRequest - TClientDataRequest object used for pinning user memory
-// @param aEventInfo - Address of TEventInfo structure to place event data when available
-// @param aClientThread - The ThreadId of the requesting user-side process. In this case the DSS.
-void DDebugAgent::GetEvent(TClientDataRequest<TEventInfo>* aAsyncGetValueRequest, TEventInfo* aEventInfo, DThread* aClientThread)
+/** Obtain the details of the latest kernel event (if it exists) and place the details in aEventInfo
+ * If there is no event in the queue for this process+agent combination, store the details
+ * so that it can be notified later when an event actually occurs.
+ * 
+ * @param aAsyncGetValueRequest - TClientDataRequest object used for pinning user memory
+ * @param aClientThread - The ThreadId of the requesting user-side process. In this case the DSS.
+ */
+void DDebugAgent::GetEvent(TClientDataRequest<TEventInfo>* aAsyncGetValueRequest, DThread* aClientThread)
 	{
+	LockEventQueue();
+
+	iRequestGetEventStatus->Reset();
+	TInt err = iRequestGetEventStatus->SetStatus( aAsyncGetValueRequest->StatusPtr() );
+	if (err != KErrNone)
+		{
+		LOG_MSG2("Error :iRequestGetEventStatus->SetStatus ret %d", err);
+		return;
+		}
+	
+	iRequestGetEventStatus->SetDestPtr( aAsyncGetValueRequest->DestPtr() );
+
+	iEventBalance++;
+	
+	LOG_MSG4("DDebugAgent::GetEvent: this=0x%08x, iRequestGetEventStatus=0x%08x, iEventBalance=%d", 
+		this, iRequestGetEventStatus, iEventBalance );
+	
 	iClientThread = aClientThread;
-
+	
 	if (BufferEmpty())
 		{
-		LOG_MSG("no events available");
-
-		// store the pointer so we can modify it later
-		iEventInfo = (TEventInfo *)aEventInfo;
-		iRequestGetEventStatus = aAsyncGetValueRequest;
+		LOG_MSG2("Event buffer empty, iEventBalance=%d", iEventBalance);		
+		UnlockEventQueue();
 		return;
 		}
 
-	LOG_MSG("Event available");
+	LOG_MSG2("Event already available at queue pos=%d", iTail);
 
 	// returning the event to the client
-	TInt err = iEventQueue[iTail].WriteEventToClientThread(aAsyncGetValueRequest,iClientThread);
-	if (KErrNone != err)
+	err = iEventQueue[iTail].WriteEventToClientThread(iRequestGetEventStatus,iClientThread);
+	if (err != KErrNone)
 		{
 		LOG_MSG2("Error writing event info: %d", err);
+		UnlockEventQueue();
 		return;
 		}
 
 	// signal the DSS thread
-	Kern::QueueRequestComplete(iClientThread, aAsyncGetValueRequest, KErrNone);
+	Kern::QueueRequestComplete(iClientThread, iRequestGetEventStatus, KErrNone);
+	iEventBalance--;
 
 	iEventQueue[iTail].Reset();
 
 	// move to the next slot
-	IncrementPosition(iTail);
+	IncrementTailPosition();
+
+	UnlockEventQueue();
 	}
 
-// Stop waiting for an event to occur. This means events will be placed in the iEventQueue
-// until GetEvent is called.
+/**
+ * Stop waiting for an event to occur. This means events will be placed 
+ * in the iEventQueue (by setting iEventBalance to 0) until GetEvent is called. 
+ */ 
 TInt DDebugAgent::CancelGetEvent(void)
 	{
+	LOG_MSG2("DDebugAgent::CancelGetEvent. iEventBalance=%d. > QueueRequestComplete", iEventBalance);
 	Kern::QueueRequestComplete(iClientThread, iRequestGetEventStatus, KErrCancel);
-	iEventInfo = NULL;
-    iRequestGetEventStatus = 0;
+	iEventBalance=0;
 	iClientThread = 0;
-
 	return KErrNone;
 	}
 
-// Signal a kernel event to the user-side DSS when it occurs, or queue it for later
-// if the user-side has not called GetEvent (see above).
-//
-// @param aEventInfo - the details of the event to queue.
+/** Signal a kernel event to the user-side DSS when it occurs, or queue it for later
+ * if the user-side has not called GetEvent (see above).
+ * 
+ * @param aEventInfo - the details of the event to queue.
+ */
 void DDebugAgent::NotifyEvent(const TDriverEventInfo& aEventInfo)
 	{
-	LOG_MSG("DDebugAgent::NotifyEvent()");
-	// Action depends on the TKernelEvent type in aEventInfo.iType
-	
-	// Added to fix the pass by value issue seen in Coverity.  
-	// Function is changed to pass by reference but temp object is explicitly created.
-	TDriverEventInfo eventInfo = aEventInfo;
 
 	if(aEventInfo.iEventType >= EEventsLast)
 		{
-		// unknown event type so return
+		LOG_MSG3("DDebugAgent::NotifyEvent(),iEventType %d, this=0x%x. Ignoring since > EEventsLast", aEventInfo.iEventType, this);
 		return;
 		}
 
-	TKernelEventAction action = iEventActions[eventInfo.iEventType];
+	LockEventQueue();
+
+	DThread* currentThread = &Kern::CurrentThread();
+	
+	LOG_MSG5("DDebugAgent::NotifyEvent(), iEventType %d, this=0x%x currThrd=0x%08x, iEventBalance=%d",
+		aEventInfo.iEventType, this, currentThread, iEventBalance );
+	TKernelEventAction action = iEventActions[aEventInfo.iEventType];
 
 	switch (action)
 		{
 		case EActionSuspend:
 			{
 			LOG_MSG("DDebugAgent::NotifyEvent() Suspend thread");
-			DThread* currentThread = &Kern::CurrentThread();
-			switch(eventInfo.iEventType)
+
+			switch(aEventInfo.iEventType)
 				{
 				case EEventsAddLibrary:
 				case EEventsRemoveLibrary:
-					currentThread = DebugUtils::OpenThreadHandle(eventInfo.iThreadId);
+					currentThread = DebugUtils::OpenThreadHandle(aEventInfo.iThreadId);
 					if(currentThread)
 						{
 						currentThread->Close(NULL);
@@ -221,8 +269,8 @@
 				default:
 					break;
 				}
-			TInt err = TheDProcessTracker.SuspendThread(currentThread, eventInfo.FreezeOnSuspend());
-			if(!( (err == KErrNone) || (err == KErrAlreadyExists) ))
+			TInt err = TheDProcessTracker.SuspendThread(currentThread, aEventInfo.FreezeOnSuspend());
+			if((err != KErrNone) && (err != KErrAlreadyExists))
 				{
 				// Is there anything we can do in the future to deal with this error having happened?
 				LOG_MSG2("DDebugAgent::NotifyEvent() Problem while suspending thread: %d", err);
@@ -232,42 +280,62 @@
 			// the debug agent of the event
 			}
 		case EActionContinue:
-			LOG_MSG("DDebugAgent::NotifyEvent() Continue");
-
-			// Tell the user about this event
-			if (iEventInfo && iClientThread)
 			{
-				LOG_MSG("Completing event\r\n");
+			// Queue this event
+			QueueEvent(aEventInfo);
 
-				// returning the event to the client
-				TInt err = eventInfo.WriteEventToClientThread(iRequestGetEventStatus,iClientThread);
-				if (KErrNone != err)
+			// Tell the user about the oldest event in the queue
+			if ( iClientThread )
 				{
-					LOG_MSG2("Error writing event info: %d", err);
-				}
+				if( iRequestGetEventStatus && (iEventBalance > 0) )
+					{
+					// Fill the event data
+					TInt err = iEventQueue[iTail].WriteEventToClientThread(iRequestGetEventStatus,iClientThread);
+					if (err != KErrNone)
+						{
+						LOG_MSG2("Error writing event info: %d", err);
+						}
+
+					// signal the debugger thread 
+					LOG_MSG4("> QueueRequestComplete iRequestGetEventStatus=0x%08x, iEventBalance=%d, iTail=%d",
+						iRequestGetEventStatus->iStatus, iEventBalance, iTail );
+					Kern::QueueRequestComplete(iClientThread, iRequestGetEventStatus, KErrNone);
+
+					iEventBalance--;
 
-				// clear this since we've completed the request
-				iEventInfo = NULL;
+					iEventQueue[iTail].Reset();
 
-				// signal the debugger thread
-				Kern::QueueRequestComplete(iClientThread, iRequestGetEventStatus, KErrNone);
-			}
+					// move to the next slot
+					IncrementTailPosition();
+					}
+				else
+					{
+					if( !iRequestGetEventStatus )
+						{
+						LOG_MSG("iRequestGetEventStatus is NULL so not signalling client" );
+						}
+					else
+						{
+						LOG_MSG2("Queued event. iEventBalance=%d (unbalanced event requests vs notifications)", 
+							iEventBalance );
+						}
+					}
+				}
 			else
-			{
-				LOG_MSG("Queuing event\r\n");
-
-				QueueEvent(eventInfo);
-
+				{
+				 LOG_MSG("DDebugAgent::NotifyEvent() : Not informing client since its thread is NULL");
+				}
+			break;
 			}
-			break;
-
 		case EActionIgnore:
 		default:
-			LOG_MSG("DDebugAgent::NotifyEvent() fallen through to default case");
+			LOG_EVENT_MSG("DDebugAgent::NotifyEvent() fallen through to default case");
 			// Ignore everything we don't understand.
-			return;
+
 		}
 
+	UnlockEventQueue();
+
 	}
 
 // Used to identify which Debug Agent this DDebugAgent is associated with.
@@ -276,93 +344,77 @@
 	return iId;
 	}
 
-// Used to add an event to the event queue for this debug agent
-void DDebugAgent::QueueEvent(TDriverEventInfo& aEventInfo)
+/**
+ * Used to add an event to the event queue for this debug agent if event 
+ * queue is not at critical level. If it is at critical and it is trace event, 
+ * we start ignoring trace events and insert a lost trace event.
+ * If the buffer cannot store an event, only insert a buffer full event.
+ * @see EEventsBufferFull
+ * @see EEventsUserTracesLost
+ * @see TDriverEventInfo
+ * @see iEventQueue
+ */
+void DDebugAgent::QueueEvent(const TDriverEventInfo& aEventInfo)
 	{
 	// Have we caught the tail?
 	if(BufferFull())
 		{
+		LOG_MSG("DDebugAgent::QueueEvent : BufferFull. Not queueing");
 		return;
 		}
-	
-	//check to see if we wish to ignore this event - we dump trace events as they are lower priority than the other events
-	if(BufferAtCriticalLevel())
+
+	// Assert if we think there is space but the slot is not marked empty
+	__NK_ASSERT_DEBUG(iEventQueue[iHead].iEventType == EEventsUnknown);
+
+	const TBool bufferAtCritical = BufferAtCriticalLevel();
+
+	if(!bufferAtCritical)
 		{
+		//reset the iIgnoringTrace flag as we are not at 
+		//critical level and can store event
+		iIgnoringTrace = EFalse; 
+		
+		// Insert the event into the ring buffer at iHead
+		iEventQueue[iHead] = aEventInfo;
+		IncrementHeadPosition();
+		}
+	else if(bufferAtCritical && BufferCanStoreEvent())
+		{
+		LOG_MSG("DDebugAgent::QueueEvent : BufferCritical");
 		if(aEventInfo.iEventType == EEventsUserTrace)
 			{
 			if(!iIgnoringTrace)
 				{
-				//if this is the first time we are ignoring trace events, we need to issue a EEventsUserTracesLost event
-				aEventInfo.Reset();
-				aEventInfo.iEventType = EEventsUserTracesLost;
-				
+				//if this is the first time we are ignoring trace events, 
+				//we need to issue a EEventsUserTracesLost event
+				iEventQueue[iHead].Reset();
+				iEventQueue[iHead].iEventType = EEventsUserTracesLost;
+				IncrementHeadPosition();
+
 				iIgnoringTrace = ETrue;
 				}
 			else
 				{
 				//otherwise, ignore this event
-				return;
+				LOG_MSG("DDebugAgent::QueueEvent : Ignore EEventsUserTrace event");
 				}
 			}
+		else
+			{
+			// Store the event since its not a trace event
+			iEventQueue[iHead] = aEventInfo;
+			IncrementHeadPosition();
+			}
 		}
 	else
 		{
-		//reset the iIgnoringTrace flag as we are not at critical level
-		iIgnoringTrace = EFalse; 
-		}	
-
-	// only one space left so store a EEventsBufferFull event
-	if(!BufferCanStoreEvent())
-		{
-		aEventInfo.Reset();
-		aEventInfo.iEventType = EEventsBufferFull;
+		//At critical level and cannot store new events, so 
+		//only one space left. Store a EEventsBufferFull event
+		LOG_MSG("DDebugAgent::QueueEvent : Event Buffer Full, ignoring event");
+		iEventQueue[iHead].Reset();
+		iEventQueue[iHead].iEventType = EEventsBufferFull;
+		IncrementHeadPosition();
 		}
-
-	__NK_ASSERT_DEBUG(iEventQueue[iHead].iEventType == EEventsUnknown); // we think there is space but the slot is not marked empty
-
-	// Insert the event into the ring buffer at iHead
-	iEventQueue[iHead] = aEventInfo;
-	IncrementPosition(iHead);
-	}
-
-// Checks whether the event queue is empty
-TBool DDebugAgent::BufferEmpty() const
-	{
-	return (NumberOfEmptySlots() == NUMBER_OF_EVENTS_TO_QUEUE);
-	}
-
-// Checks whether the event queue is full
-TBool DDebugAgent::BufferFull() const
-	{
-	return (NumberOfEmptySlots() == 0);
 	}
 
-// Checks whether there is room in the event queue to store an event (i.e. at least two free slots)
-TBool DDebugAgent::BufferCanStoreEvent() const
-	{
-	return (NumberOfEmptySlots() > 1);
-	}
-
-//This looks to see if the buffer is close to being full and should only accept higher priority debug events (user trace is the only low priority event) 
-TBool DDebugAgent::BufferAtCriticalLevel() const
-	{
-	return (NumberOfEmptySlots() < NUMBER_OF_EVENTS_TO_QUEUE - CRITICAL_BUFFER_SIZE);
-	}
-
-// increments aPosition, wrapping at NUMBER_OF_EVENTS_TO_QUEUE if necessary
-void DDebugAgent::IncrementPosition(TInt& aPosition)
-	{
-	aPosition = (aPosition + 1) % NUMBER_OF_EVENTS_TO_QUEUE;
-	}
-
-// finds the number of empty slots in the event queue
-TInt DDebugAgent::NumberOfEmptySlots() const
-	{
-	if(iHead < iTail)
-		{
-		return (iTail - iHead) - 1;
-		}
-	// iHead >= iTail
-	return NUMBER_OF_EVENTS_TO_QUEUE - (iHead - iTail);
-	}
-
+// End of file - d_debug_agent.cpp
--- a/kernel/eka/drivers/debug/rmdebug/d_debug_agent.h	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/drivers/debug/rmdebug/d_debug_agent.h	Fri Apr 16 16:24:37 2010 +0300
@@ -22,6 +22,12 @@
 #include <rm_debug_api.h>
 #include "d_driver_event_info.h"
 
+/**
+* Handles events from the kernel, filters them according to the debug agent's requests, 
+* and signals these events to the user side in FIFO-style. 
+* @see TKernelEventAction
+* @see TEventInfo
+*/
 class DDebugAgent : public DBase
 {
 public:
@@ -29,7 +35,7 @@
 	~DDebugAgent();
 
 	TInt SetEventAction(Debug::TEventType aEvent, Debug::TKernelEventAction aEventAction);
-	void GetEvent(TClientDataRequest<Debug::TEventInfo>* aAsyncGetValueRequest, Debug::TEventInfo* aEventInfo, DThread* aClientThread);
+	void GetEvent(TClientDataRequest<Debug::TEventInfo>* aAsyncGetValueRequest, DThread* aClientThread);
 	TInt EventAction(Debug::TEventType aEvent);
 
 	TInt CancelGetEvent(void);
@@ -41,31 +47,99 @@
 	TInt Construct();
 
 private:
-	void QueueEvent(TDriverEventInfo& aEventInfo);
+	void QueueEvent(const TDriverEventInfo& aEventInfo);
 	TBool BufferEmpty() const;
 	TBool BufferFull() const;
 	TBool BufferCanStoreEvent() const;
 	TBool BufferAtCriticalLevel() const;
-	void IncrementPosition(TInt& aPosition);
+	void IncrementHeadPosition(void);
+	void IncrementTailPosition(void);
 	TInt NumberOfEmptySlots() const;
+	void LockEventQueue(void);
+	void UnlockEventQueue(void);
 
 private:
+
 	TUint64	iId;
 	Debug::TKernelEventAction iEventActions[Debug::EEventsLast];
 
-	//iEventInfo is a pointer to an object owned by the security server, so
-	//no clean up needs be performed on it
-	Debug::TEventInfo* iEventInfo;
-	RArray<TDriverEventInfo> iEventQueue;	// ring buffer.
+	/**
+	* Object used to write events back to DSS thread
+	* @see TEventInfo
+	*/
 	TClientDataRequest<Debug::TEventInfo>* iRequestGetEventStatus;
+
 	DThread* iClientThread;
 
-	// Ring buffer data
-	TInt iHead;	// points to the next empty slot in iEventQueue (exc. when iFull == ETrue)
-	TInt iTail; // points to the oldest full slot in iEventQueue (exc. when iEmpty == ETrue)
+	/** 
+	* Ring buffer of pending events. Access to it is controlled by 
+	* @see iEventQueueLock
+	*/
+	RArray<TDriverEventInfo> iEventQueue;
+
+	/**
+	* Ring buffer head. Points to the next empty slot in iEventQueue
+	* @see iEventQueue
+	*/
+	TInt iHead;	
+
+	/**
+	* Ring buffer tail. Points to the oldest full slot in iEventQueue
+	* @see iEventQueue 
+	*/
+	TInt iTail;
+
+	/** 
+	* Control access to event queue.
+	* @see iEventQueue
+	*/
+	DSemaphore* iEventQueueLock;
+
+	/**
+	* Keeps track of how many free slots are available in the event queue.
+	* @see iEventQueue
+	*/
+	TInt iFreeSlots;
+
+	/**
+	* Boolean to indicate if we have told the agent that we are ignoring trace events
+	* @see QueueEvent
+	*/
+	TBool iIgnoringTrace;
 	
-	//if we have told the agent that we are ignoring trace events
-	TBool iIgnoringTrace;
+	/**
+	* Used to control the delivery of events to the client so that only 
+	* when more requests than deliveries have taken place can we deliver the 
+	* next event
+	* 
+	* Incremented when a request for event takes place
+	* @see GetEvent
+	* 
+	* Decremented when an event is delivered. 
+	* @see NotifyEvent
+	* 
+	* Cleared when event requests are cancelled
+	* @see CancelGetEvent
+	* 
+	*/
+	TInt   iEventBalance;
+
+	/**
+	* Length of kernel-event queue.
+	* This is a power of two for efficiency when using the 
+	* remainder operator
+	* @see DDebugAgent::iEventQueue
+	*/
+	static const TUint KNumberOfEventsToQueue = 128;
+
+	/**
+	* This determines the number of events at which we stop accepting 
+	* low priority events into the event queue.
+	* @see DDebugAgent::BufferAtCriticalLevel
+	* @see DDebugAgent::iEventQueue
+	*/
+	static const TUint KCriticalBufferSize = 64;
+
 };
 
 #endif // D_DEBUG_AGENT_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kernel/eka/drivers/debug/rmdebug/d_debug_agent.inl	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,106 @@
+// 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:
+// Inline methods for debug agent class
+//
+
+
+/**
+ @file
+ @internalComponent
+ @released
+*/
+
+#ifndef D_DEBUG_AGENT_INL
+#define D_DEBUG_AGENT_INL
+
+
+/**
+ Checks whether the event queue is empty
+*/
+inline TBool DDebugAgent::BufferEmpty() const
+	{
+	return (NumberOfEmptySlots() == KNumberOfEventsToQueue);
+	}
+
+/**
+ Checks whether the event queue is full
+*/
+inline TBool DDebugAgent::BufferFull() const
+	{
+	return (NumberOfEmptySlots() == 0);
+	}
+
+/**
+ Checks whether there is room in the event queue to store an event
+*/
+inline TBool DDebugAgent::BufferCanStoreEvent() const
+	{
+	return (NumberOfEmptySlots() > 0);
+	}
+
+/**
+ This looks to see if the buffer is close to being full and should only
+ accept higher priority debug events (user trace is the only low priority event) 
+*/
+inline TBool DDebugAgent::BufferAtCriticalLevel() const
+	{
+	return (NumberOfEmptySlots() < KNumberOfEventsToQueue - KCriticalBufferSize);
+	}
+
+/**
+ Increments Head position, wrapping at KNumberOfEventsToQueue if necessary
+*/
+inline void DDebugAgent::IncrementHeadPosition(void)
+	{
+	iHead = (iHead + 1) % KNumberOfEventsToQueue;
+
+	iFreeSlots--;
+	}
+
+/**
+ Increments Tail position, wrapping at KNumberOfEventsToQueue if necessary
+*/
+inline void DDebugAgent::IncrementTailPosition(void)
+	{
+	iTail = (iTail + 1) % KNumberOfEventsToQueue;
+
+	iFreeSlots++;
+}
+
+/**
+ Returns the number of free slots in the event queue
+*/
+inline TInt DDebugAgent::NumberOfEmptySlots() const
+	{
+	return iFreeSlots;
+	}
+
+/**
+ Lock access to this agent's event queue
+*/
+inline void DDebugAgent::LockEventQueue(void)
+	{
+	Kern::SemaphoreWait(*iEventQueueLock);
+	}
+
+/**
+ Release the lock on this agent's event queue
+*/
+inline void DDebugAgent::UnlockEventQueue(void)
+	{
+	Kern::SemaphoreSignal(*iEventQueueLock);
+	}
+
+
+#endif	// D_DEBUG_AGENT_INL
--- a/kernel/eka/drivers/debug/rmdebug/d_list_manager.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/drivers/debug/rmdebug/d_list_manager.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -422,7 +422,7 @@
 				}
 			//calculate data values
 			TFileName fileName(codeSeg->iFileName->Ptr());
-			TBool isXip = (codeSeg->iXIP) ? ETrue : EFalse;
+			TBool isXip = (TBool)(codeSeg->iXIP);
 
 			//get the code seg type, can ignore error as have already checked codeSeg is not NULL
 			TCodeSegType type = EUnknownCodeSegType;
@@ -535,7 +535,7 @@
 				}
 
 			TFileName fileName(codeSeg->iFileName->Ptr());
-			TBool isXip = (codeSeg->iXIP) ? ETrue : EFalse;
+			TBool isXip = (TBool)(codeSeg->iXIP);
 
 			//get the code seg type, can ignore error as have already checked codeSeg is not NULL
 			TCodeSegType type = EUnknownCodeSegType;
--- a/kernel/eka/drivers/debug/rmdebug/d_process_tracker.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/drivers/debug/rmdebug/d_process_tracker.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -76,24 +76,30 @@
 		{
 		return KErrNoMemory;
 		}
-
+	LOG_MSG2(" AttachProcess: < new DTargetProcess=0x%08x", tmpProcess );
+	
 	// Set the name
 	TInt err = KErrNone;
 	err = tmpProcess->SetProcessName(aProcessName);
 	if (err != KErrNone)
 		{
+		LOG_MSG2(" AttachProcess: < SetProcessName returned %d", err );
 		return err;
 		}
 
 	// Is this process being debugged (ie already attached?)
 	TInt index;
 	TBool found = EFalse;
-	for(index=0;index<iProcesses.Count();index++)
+	
+	TInt numberOfProcesses = iProcesses.Count();
+	for(index=0; index<numberOfProcesses; index++)
 		{
 		const TPtr8& tmpPtr8(iProcesses[index]->ProcessName() );
 
 		if ( tmpPtr8.CompareF(aProcessName) == 0)
 			{
+			LOG_MSG3(" Proc count=%d, found proc in iProcesses at %d. Count=%d",
+				index, iProcesses.Count() );
 			found = ETrue;
 			break;
 			}
@@ -104,6 +110,8 @@
 		// Yes, it is being debugged
 
 		// Add the agent to the list of agents for this process
+		LOG_MSG3(" > AddAgent(agent id %d) to existing iProcesses[%d]", I64LOW(aAgentId), index ); 
+
 		iProcesses[index]->AddAgent(aAgentId);
 
 		return KErrNone;
@@ -113,6 +121,8 @@
 		// No, it is not being debugged
 			
 		// Add the agent to the list of agents for this process
+		LOG_MSG2(" > AddAgent(agent %d) to new proc at index 0", I64LOW(aAgentId) ); 
+
 		tmpProcess->AddAgent(aAgentId);
 
 		// Add the process to the list of processes being debugged
@@ -143,7 +153,9 @@
 	TInt i;
 	TBool found = EFalse;
 	DTargetProcess* foundProcess = 0;
-	for(i=0;i<iProcesses.Count();i++)
+
+	TInt numberOfProcesses = iProcesses.Count();
+	for(i=0; i<numberOfProcesses; i++)
 		{
 		foundProcess = iProcesses[i];
 
@@ -186,7 +198,8 @@
 TInt DProcessTracker::DetachAgent(const TUint64 aAgentId)
 	{
 	// Remove this agent from all the processes being tracked.
-	for(TInt i=0;i<iProcesses.Count();i++)
+	TInt numberOfProcesses = iProcesses.Count();
+	for(TInt i=0; i<numberOfProcesses; i++)
 		{
 		// remove the agent from the process (we don't care about the return code)
 		iProcesses[i]->RemoveAgent(aAgentId);
@@ -226,13 +239,15 @@
 	if (aProcessName.Length() < 1 || aProcessName.Length() >= KMaxPath)
 		{
 		return 0;	// not found
-		};
+		}
 
 	// Can we find this in the array?
 	TInt i;
 	TBool found = EFalse;
 	DTargetProcess* foundProcess = 0;
-	for(i=0;i<iProcesses.Count();i++)
+
+	TInt numberOfProcesses = iProcesses.Count();
+	for(i=0; i<numberOfProcesses; i++)
 		{
 		foundProcess = iProcesses[i];
 
@@ -247,6 +262,7 @@
 
 	if (found == EFalse)
 		{
+		LOG_EVENT_MSG("DProcessTracker::FindProcess, not found" );
 		return 0;	// not found
 		}
 
@@ -272,73 +288,58 @@
  */
 DTargetProcess*	DProcessTracker::FuzzyFindProcess(const TDesC8& aProcessName)
 	{
-
 	// Valid ProcessName?
 	if (aProcessName.Length() < 1 || aProcessName.Length() >= KMaxPath)
 		{
 		return 0;	// not found
-		};
+		}
 
 	// Can we find this in the array?
-	TInt i;
 	TBool found = EFalse;
 	DTargetProcess* foundProcess = 0;
-	for(i=0;i<iProcesses.Count();i++)
+	const TChar KBackSlash('\\');
+
+	TInt numberOfProcesses = iProcesses.Count();
+	for(TInt i=0; i < numberOfProcesses; i++)
 		{
 		foundProcess = iProcesses[i];
 
-		const TPtr8& tmpPtr8( foundProcess->ProcessName() );
-
-		if ( tmpPtr8.CompareF(aProcessName) == 0)
+		TInt procListBackSlash = foundProcess->ProcessName().LocateReverse( KBackSlash );
+		if( procListBackSlash == KErrNotFound )
 			{
-			found = ETrue;
-			break;
+			procListBackSlash = 0;
 			}
 		else
 			{
-			// need to compare centre of this string
-			//
-			// e.g. 
-			//		z:\sys\bin\foobar.exe
-			// might be seen as:
-			//		foobar.exe
-			//
-			// Algorithm is start at the right side of foundProcess->ProcessName
-			// move left until we have some backslash, then finish.
-			TInt right= tmpPtr8.Size() - 1;
-			TInt left = right;
+			//Now move to the char after the backlash
+			procListBackSlash++;
+			}
+
+		TInt eventBackSlash = aProcessName.LocateReverse( KBackSlash );
+		if( eventBackSlash == KErrNotFound )
+			{
+			eventBackSlash = 0;
+			}
+		else
+			{
+			//Now move to the char after the backlash
+			eventBackSlash++;
+			}
 
-			// search for the rightmost backslash
-			while(left > 0)
-				{
-				if(tmpPtr8[left] == (TUint8)'\\')
-					break;
-				
-				--left;	// move left one character
-				}
-			// now we have
-			// left = index of rightmost backslash in foundProcess->ProcessName()
-			// right = index of rightmost character in foundProcess->ProcessName()
-
-			// We must expect that the size of names matches
-			TInt foundSize = right - left;	// == sizeof("foobar.exe")
-			TInt suppliedSize = aProcessName.Size();		
+		if( ( procListBackSlash == 0 ) && ( eventBackSlash == 0 ) )
+			{
+			//There were no backslashes on either name, so no point in continuing
+			break;
+			}
 
-			if (foundSize != suppliedSize)
-				{
-				// must be something else
-				break;
-				}
+		TPtrC8 eventCleanName( aProcessName.Mid( eventBackSlash ) );		
+		TPtrC8 procListCleanName( foundProcess->ProcessName().Mid( procListBackSlash ) );
 
-			for(TInt i=0;i< foundSize;i++)
-				{
-				if (tmpPtr8[left+i] != aProcessName[1+i])
-					{
-					break;
-					}
-				}
-			// All the characters match if we get here
+		if ( eventCleanName.CompareF( procListCleanName ) == 0 )
+			{
+			LOG_MSG2("DProcessTracker::FuzzyFindProcess() found a match : process list[%d]", i );
 			found = ETrue;
+			break;
 			}
 		}
 
@@ -360,7 +361,8 @@
 		}
 
 	//iterate through the processes trying to match the name, and check suspended if found
-	for(TInt i=0; i<iProcesses.Count(); i++)
+	TInt numberOfProcesses = iProcesses.Count();
+	for(TInt i=0; i < numberOfProcesses; i++)
 		{
 		if(iProcesses[i]->ProcessName().CompareF(*name) == 0)
 			{
@@ -407,7 +409,8 @@
 		}
 
 	//iterate through the processes trying to match the name, try to suspend the thread if found
-	for(TInt i=0; i<iProcesses.Count(); i++)
+	TInt numberOfProcesses = iProcesses.Count();
+	for(TInt i=0; i < numberOfProcesses; i++)
 		{
 		if(iProcesses[i]->ProcessName().CompareF(*name) == 0)
 			{
@@ -421,7 +424,8 @@
 
 void DProcessTracker::FSWait()
 	{
-	for(TInt i=0; i<iProcesses.Count(); i++)
+	TInt numberOfProcesses = iProcesses.Count();
+	for(TInt i=0; i < numberOfProcesses; i++)
 		{
 		iProcesses[i]->FSWait();
 		}
@@ -447,7 +451,8 @@
 		}
 
 	//iterate through the processes trying to match the name, try to resume the thread if found
-	for(TInt i=0; i<iProcesses.Count(); i++)
+	TInt numberOfProcesses = iProcesses.Count();
+	for(TInt i=0; i < numberOfProcesses; i++)
 		{
 		if(iProcesses[i]->ProcessName().CompareF(*name) == 0)
 			{
--- a/kernel/eka/drivers/debug/rmdebug/d_rmd_breakpoints.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/drivers/debug/rmdebug/d_rmd_breakpoints.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -1,4 +1,4 @@
-// Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 2004-2010 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"
@@ -1566,9 +1566,9 @@
 				{
 				LOG_MSG2("Error returned from DoEnableBreak: %d", err);
 				iBreakPointList[i].iDisabledForStep = EFalse;
+				return err;
 				}
-			return err;
-			}		
+			}
 		}
 	
 	return KErrNone;
--- a/kernel/eka/drivers/debug/rmdebug/d_rmd_breakpoints.h	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/drivers/debug/rmdebug/d_rmd_breakpoints.h	Fri Apr 16 16:24:37 2010 +0300
@@ -1,4 +1,4 @@
-// Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 2004-2010 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"
@@ -169,6 +169,10 @@
 
 	TInt DoGetBreakList(TUint32* aBuffer, const TUint32 aBufSize, const TUint32 aElement, TUint32& aLastElement);
 
+	// Useful helper functions for debugging breakpoint issues
+	inline void print_BreakpointsDisabledForStep();
+	inline void print_BreakpointsList();
+
 private:
 	// Locked versions of public functions
 	TInt priv_DoSetBreak(TInt32 &aBreakId, const TUint64 aId,  const TBool aThreadSpecific, const TUint32 aAddress, const Debug::TArchitectureMode aMode );
@@ -204,4 +208,6 @@
 	TBool iInitialised;
 };
 
+#include "d_rmd_breakpoints_debug.inl" 
+
 #endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kernel/eka/drivers/debug/rmdebug/d_rmd_breakpoints_debug.inl	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,39 @@
+// Copyright (c) 2010 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:
+//
+
+#include "debug_logging.h"
+
+// Print breakpoints disabled for stepping
+inline void D_RMD_Breakpoints::print_BreakpointsDisabledForStep()
+	{
+	for (TInt i = 0; i < iBreakPointList.Count(); i++)
+		{
+		if(iBreakPointList[i].iDisabledForStep)
+			{
+				LOG_MSG2("Breakpoint disabled for stepping: iBreakPointList[%d]", i);
+				LOG_MSG4("iBreakId = %x, iId = %d, iAddress = %x", iBreakPointList[i].iBreakId, iBreakPointList[i].iId, iBreakPointList[i].iAddress );
+			}
+		}
+	}
+
+// Print breakpoint list
+inline void D_RMD_Breakpoints::print_BreakpointsList()
+	{
+	for (TInt i = NUMBER_OF_TEMP_BREAKPOINTS; i < iBreakPointList.Count(); i++)
+		{
+			LOG_MSG2("Breakpoint list: iBreakPointList[%d]", i);
+			LOG_MSG4("iBreakId = %x, iId = %d, iAddress = %x", iBreakPointList[i].iBreakId, iBreakPointList[i].iId, iBreakPointList[i].iAddress );
+		}
+	}
--- a/kernel/eka/drivers/debug/rmdebug/d_rmd_stepping.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/drivers/debug/rmdebug/d_rmd_stepping.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -46,15 +46,15 @@
 // DRMDStepping::~DRM_DebugChannel
 //
 DRMDStepping::~DRMDStepping()
-{
+	{
 	// to do
-}
+	}
 
 //
 // DRMDStepping::IsExecuted
 //
 TBool DRMDStepping::IsExecuted(TUint8 aCondition ,TUint32 aStatusRegister)
-{
+	{
 	LOG_MSG("DRMDStepping::IsExecuted()");
 
 	TBool N = ((aStatusRegister >> 28) & 0x0000000F) & 0x00000008;
@@ -63,7 +63,7 @@
 	TBool V = ((aStatusRegister >> 28) & 0x0000000F) & 0x00000001;
 
 	switch(aCondition)
-	{
+		{
 		case 0:
 			return Z;
 		case 1:
@@ -95,16 +95,16 @@
 		case 14:
 		case 15:
 			return ETrue;
-	}
+		}
 	
 	return EFalse;
-}
+	}
 
 //
 // DRMDStepping::IsPreviousInstructionMovePCToLR
 //
 TBool DRMDStepping::IsPreviousInstructionMovePCToLR(DThread *aThread)
-{
+	{
 	LOG_MSG("DRMDStepping::IsPreviousInstructionMovePCToLR()");
 
 	TInt err = KErrNone;
@@ -122,114 +122,114 @@
 	TUint32 address = 0;
 	err = iChannel->ReadKernelRegisterValue(aThread, PC_REGISTER, address);
 	if(err != KErrNone)
-	{
+		{
 		LOG_MSG2("Non-zero error code discarded: %d", err);
-	}
+		}
 	address -= 4;
 
 	TBuf8<4> previousInstruction;
 	err = iChannel->DoReadMemory(aThread, address, 4, previousInstruction);
 	if (KErrNone != err)
-	{
+		{
 		LOG_MSG2("Error %d reading memory at address %x", address);
 		return EFalse;
-	}
+		}
 
 	const TUint32 movePCToLRIgnoringCondition = 0x01A0E00F;
 
 	TUint32 inst = *(TUint32 *)previousInstruction.Ptr();
 	
 	if ((inst & 0x0FFFFFFF) == movePCToLRIgnoringCondition)
-	{
+		{
 		return ETrue;
-	}
+		}
 		
 	return EFalse;
-}
+	}
 
 //
 // DRMDStepping::DecodeDataProcessingInstruction
 //
 void DRMDStepping::DecodeDataProcessingInstruction(TUint8 aOpcode, TUint32 aOp1, TUint32 aOp2, TUint32 aStatusRegister, TUint32 &aBreakAddress)
-{
+	{
 	LOG_MSG("DRMDStepping::DecodeDataProcessingInstruction()");
 
 	switch(aOpcode)
-	{
+		{
 		case 0:
-		{
+			{
 			// AND
 			aBreakAddress = aOp1 & aOp2;
 			break;
-		}
+			}
 		case 1:
-		{
+			{
 			// EOR
 			aBreakAddress = aOp1 ^ aOp2;
 			break;
-		}
+			}
 		case 2:
-		{
+			{
 			// SUB
 			aBreakAddress = aOp1 - aOp2;
 			break;
-		}
+			}
 		case 3:
-		{
+			{
 			// RSB
 			aBreakAddress = aOp2 - aOp1;
 			break;
-		}
+			}
 		case 4:
-		{
+			{
 			// ADD
 			aBreakAddress = aOp1 + aOp2;
 			break;
-		}
+			}
 		case 5:
-		{
+			{
 			// ADC
 			aBreakAddress = aOp1 + aOp2 + (aStatusRegister & arm_carry_bit()) ? 1 : 0;
 			break;
-		}
+			}
 		case 6:
-		{
+			{
 			// SBC
 			aBreakAddress = aOp1 - aOp2 - (aStatusRegister & arm_carry_bit()) ? 0 : 1;
 			break;
-		}
+			}
 		case 7:
-		{
+			{
 			// RSC
 			aBreakAddress = aOp2 - aOp1 - (aStatusRegister & arm_carry_bit()) ? 0 : 1;
 			break;
-		}
+			}
 		case 12:
-		{
+			{
 			// ORR
 			aBreakAddress = aOp1 | aOp2;
 			break;
-		}
+			}
 		case 13:
-		{
+			{
 			// MOV
 			aBreakAddress = aOp2;
 			break;
-		}
+			}
 		case 14:
-		{
+			{
 			// BIC
 			aBreakAddress = aOp1 & ~aOp2;
 			break;
-		}
+			}
 		case 15:
-		{
+			{
 			// MVN
 			aBreakAddress = ~aOp2;
 			break;
+			}
 		}
 	}
-}
 
 //
 // DRMDStepping::CurrentInstruction
@@ -315,7 +315,7 @@
 // to remove obsolete parameters.
 //
 TUint32 DRMDStepping::PCAfterInstructionExecutes(DThread *aThread, TUint32 aCurrentPC, TUint32 aStatusRegister, TInt aInstSize, /*TBool aStepInto,*/ TUint32 &aNewRangeEnd, TBool &aChangingModes)
-{
+	{
 	LOG_MSG("DRMDStepping::PCAfterInstructionExecutes()");
 
 	// by default we will set the breakpoint at the next instruction
@@ -324,12 +324,12 @@
 	TInt err = KErrNone;
 
 	// determine the architecture
-    TUint32 cpuid;
-   	asm("mrc p15, 0, cpuid, c0, c0, 0 ");
+	TUint32 cpuid;
+	asm("mrc p15, 0, cpuid, c0, c0, 0 ");
 	LOG_MSG2("DRMDStepping::PCAfterInstructionExecutes() - cpuid = 0x%08x\n",cpuid);
 
-    cpuid >>= 8;
-    cpuid &= 0xFF;
+	cpuid >>= 8;
+	cpuid &= 0xFF;
 
 	// determine the architecture mode for the current instruction
 	TArchitectureMode mode = EArmMode;	// Default assumption is ARM 
@@ -345,9 +345,9 @@
 
 	// Decode instruction based on current CPU mode
 	switch(mode)
-	{
+		{
 		case Debug::EArmMode:
-		{
+			{
 			// Obtain the current instruction bit pattern
 			TUint32 inst;
 			ReturnIfError(CurrentInstruction(aThread,inst));
@@ -356,64 +356,64 @@
 
 			// check the conditions to see if this will actually get executed
 			if (IsExecuted(((inst>>28) & 0x0000000F), aStatusRegister)) 
-			{
+				{
 				switch(arm_opcode(inst)) // bits 27-25
-				{
+					{
 					case 0:
-					{
-						switch((inst & 0x00000010) >> 4) // bit 4
 						{
+						switch((inst & 0x00000010) >> 4) // bit 4
+							{
 							case 0:
-							{
+								{
 								switch((inst & 0x01800000) >> 23) // bits 24-23
-								{
+									{
 									case 2:
-									{
+										{
 										// move to/from status register.  pc updates not allowed
 										// or TST, TEQ, CMP, CMN which don't modify the PC
 										break;
-									}
+										}
 									default:
-									{
+										{
 										// Data processing immediate shift
 										if (arm_rd(inst) == PC_REGISTER)
-										{
+											{
 											TUint32 rn = aCurrentPC + 8;
 											if (arm_rn(inst) != PC_REGISTER) // bits 19-16
-											{
+												{
 												err = iChannel->ReadKernelRegisterValue(aThread, arm_rn(inst), rn);
 												if(err != KErrNone)
-												{
+													{
 													LOG_MSG2("Non-zero error code discarded: %d", err);
+													}
 												}
-											}
 
 											TUint32 shifter = ShiftedRegValue(aThread, inst, aCurrentPC, aStatusRegister);
 
 											DecodeDataProcessingInstruction(((inst & 0x01E00000) >> 21), rn, shifter, aStatusRegister, breakAddress);
+											}
+										break;
 										}
-										break;
 									}
+								break;
 								}
-								break;
-							}					
 							case 1:
-							{
+								{
 								switch((inst & 0x00000080) >> 7) // bit 7
-								{
-									case 0:
 									{
-										switch((inst & 0x01900000) >> 20) // bits 24-23 and bit 20
+									case 0:
 										{
+										switch((inst & 0x01900000) >> 20) // bits 24-23 and bit 20
+											{
 											case 0x10:
-											{
+												{
 												// from figure 3-3
 												switch((inst & 0x000000F0) >> 4) // bits 7-4
-												{
+													{
 													case 1:
-													{
+														{
 														if (((inst & 0x00400000) >> 22) == 0) // bit 22
-														{
+															{
 															// BX
 															// this is a strange case.  normally this is used in the epilogue to branch the the link
 															// register.  sometimes it is used to call a function, and the LR is stored in the previous
@@ -421,324 +421,319 @@
 															// we need to read the previous instruction to see what we should do
 															err = iChannel->ReadKernelRegisterValue(aThread, (inst & 0x0000000F), breakAddress);
 															if(err != KErrNone)
-															{
+																{
 																LOG_MSG2("Non-zero error code discarded: %d", err);
-															}
+																}
 
 															if ((breakAddress & 0x00000001) == 1)
-															{
+																{
 																aChangingModes = ETrue;
-															}
+																}
 
 															breakAddress &= 0xFFFFFFFE;
-														}
+															}
 														break;
-													}
+														}
 													case 3:
-													{
+														{
 														// BLX
-														{
+															{
 															err = iChannel->ReadKernelRegisterValue(aThread, (inst & 0x0000000F), breakAddress);
 															if(err != KErrNone)
-															{
+																{
 																LOG_MSG2("Non-zero error code discarded: %d", err);
-															}
+																}
 
 															if ((breakAddress & 0x00000001) == 1)
-															{
+																{
 																aChangingModes = ETrue;
-															}
+																}
 															
 															breakAddress &= 0xFFFFFFFE;
-														}
+															}
 														break;
-													}
+														}
 													default:
-													{
+														{
 														// either doesn't modify the PC or it is illegal to
 														break;
+														}
 													}
-												}
 												break;
-											}
+												}
 											default:
-											{
+												{
 												// Data processing register shift
 												if (((inst & 0x01800000) >> 23) == 2) // bits 24-23
-												{
+													{
 													// TST, TEQ, CMP, CMN don't modify the PC
-												}
+													}
 												else if (arm_rd(inst) == PC_REGISTER)
-												{
+													{
 													// destination register is the PC
 													TUint32 rn = aCurrentPC + 8;
 													if (arm_rn(inst) != PC_REGISTER) // bits 19-16
-													{
+														{
 														err = iChannel->ReadKernelRegisterValue(aThread, arm_rn(inst), rn);
 														if(err != KErrNone)
-														{
+															{
 															LOG_MSG2("Non-zero error code discarded: %d", err);
+															}
 														}
-													}
 													
 													TUint32 shifter = ShiftedRegValue(aThread, inst, aCurrentPC, aStatusRegister);
 													
 													DecodeDataProcessingInstruction(((inst & 0x01E00000) >> 21), rn, shifter, aStatusRegister, breakAddress);
-												}
+													}
 												break;
+												}
 											}
+										break;
 										}
-										break;
-									}
 									default:
-									{
+										{
 										// from figure 3-2, updates to the PC illegal
 										break;
+										}
 									}
-								}
 								break;
+								}
 							}
-						}
 						break;
-					}
+						}
 					case 1:
-					{
+						{
 						if (((inst & 0x01800000) >> 23) == 2) // bits 24-23
-						{
+							{
 							// cannot modify the PC
 							break;
-						}
+							}
 						else if (arm_rd(inst) == PC_REGISTER)
-						{
+							{
 							// destination register is the PC
 							TUint32 rn;
 							err = iChannel->ReadKernelRegisterValue(aThread, arm_rn(inst), rn); // bits 19-16
 							if(err != KErrNone)
-							{
+								{
 								LOG_MSG2("Non-zero error code discarded: %d", err);
-							}
+								}
 							TUint32 shifter = ((arm_data_imm(inst) >> arm_data_rot(inst)) | (arm_data_imm(inst) << (32 - arm_data_rot(inst)))) & 0xffffffff;
 
 							DecodeDataProcessingInstruction(((inst & 0x01E00000) >> 21), rn, shifter, aStatusRegister, breakAddress);
-						}
+							}
 						break;
-					}
+						}
 					case 2:
-					{
+						{
 						// load/store immediate offset
 						if (arm_load(inst)) // bit 20
-						{
+							{
 							// loading a register from memory
 							if (arm_rd(inst) == PC_REGISTER)
-							{
+								{
 								// loading the PC register
 								TUint32 base;
 								err = iChannel->ReadKernelRegisterValue(aThread, arm_rn(inst), base);
 								if(err != KErrNone)
-								{
+									{
 									LOG_MSG2("Non-zero error code discarded: %d", err);
-								}
+									}
 
 								/* Note: At runtime the PC would be 8 further on
 								 */
 								if (arm_rn(inst) == PC_REGISTER)
-								{
+									{
 									base = aCurrentPC + 8;
-								}
+									}
 
 								TUint32 offset = 0;
-					    		
-					    		if (arm_single_pre(inst))
-					    		{
-					    			// Pre-indexing
-					    			offset = arm_single_imm(inst);
-									
-									if (arm_single_u(inst))
+
+								if (arm_single_pre(inst))
 									{
-							    		base += offset;
-									}
+									// Pre-indexing
+									offset = arm_single_imm(inst);
+
+									if (arm_single_u(inst))
+										{
+										base += offset;
+										}
 									else
-									{
-							    		base -= offset;
+										{
+										base -= offset;
+										}
 									}
-								}
 
 								TBuf8<4> destination;
 								err = iChannel->DoReadMemory(aThread, base, 4, destination);
 								
 								if (KErrNone == err)
-								{
+									{
 									breakAddress = *(TUint32 *)destination.Ptr();
-								
+
 									if ((breakAddress & 0x00000001) == 1)
-									{
+										{
 										aChangingModes = ETrue;
-									}								
+										}
 									breakAddress &= 0xFFFFFFFE;
-								}
+									}
 								else
-								{
+									{
 									LOG_MSG("Error reading memory in decoding step instruction");
+									}
 								}
 							}
-						}	
 						break;
-					}
+						}
 					case 3:
-					{
+						{
 						if (((inst & 0xF0000000) != 0xF0000000) && ((inst & 0x00000010) == 0))
-						{
+							{
 							// load/store register offset
 							if (arm_load(inst)) // bit 20
-							{
+								{
 								// loading a register from memory
 								if (arm_rd(inst) == PC_REGISTER)
-								{
+									{
 									// loading the PC register
 									TUint32 base = 0;
 									if(arm_rn(inst) == PC_REGISTER)
-									{
+										{
 										base = aCurrentPC + 8;
-									}
+										}
 									else
-									{
+										{
 										err = iChannel->ReadKernelRegisterValue(aThread, arm_rn(inst), base);
 										if(err != KErrNone)
-										{
+											{
 											LOG_MSG2("Non-zero error code discarded: %d", err);
+											}
 										}
-									}
 
 									TUint32 offset = 0;
 
 									if (arm_single_pre(inst))
-									{
+										{
 										offset = ShiftedRegValue(aThread, inst, aCurrentPC, aStatusRegister);
 
 										if (arm_single_u(inst))
-										{
+											{
 											base += offset;
-										}
+											}
 										else
-										{
+											{
 											base -= offset;
+											}
 										}
-									}
 
 									TBuf8<4> destination;
 									err = iChannel->DoReadMemory(aThread, base, 4, destination);
 
 									if (KErrNone == err)
-									{
+										{
 										breakAddress = *(TUint32 *)destination.Ptr();
 
 										if ((breakAddress & 0x00000001) == 1)
-										{
+											{
 											aChangingModes = ETrue;
-										}								
+											}
 										breakAddress &= 0xFFFFFFFE;
-									}
+										}
 									else
-									{
+										{
 										LOG_MSG("Error reading memory in decoding step instruction");
+										}
 									}
 								}
-							}	
-						}
+							}
 						break;
-					}
+						}
 					case 4:
-					{
+						{
 						if ((inst & 0xF0000000) != 0xF0000000)
-						{
+							{
 							// load/store multiple
 							if (arm_load(inst)) // bit 20
-							{
+								{
 								// loading a register from memory
 								if (((inst & 0x00008000) >> 15))
-								{
+									{
 									// loading the PC register
 									TInt offset = 0;	
 									if (arm_block_u(inst))
-									{
+										{
 										TUint32 reglist = arm_block_reglist(inst);
 										offset = iChannel->Bitcount(reglist) * 4 - 4;
 										if (arm_block_pre(inst))
 											offset += 4;
-									}
+										}
 									else if (arm_block_pre(inst))
-									{
+										{
 										offset = -4;
-									}
-										
+										}
+
 									TUint32 temp = 0;
 									err = iChannel->ReadKernelRegisterValue(aThread, arm_rn(inst), temp);
 									if(err != KErrNone)
-									{
+										{
 										LOG_MSG2("Non-zero error code discarded: %d", err);
-									}
-									
+										}
+
 									temp += offset;
 
 									TBuf8<4> destination;
 									err = iChannel->DoReadMemory(aThread, temp, 4, destination);
-									
+
 									if (KErrNone == err)
-									{
+										{
 										breakAddress = *(TUint32 *)destination.Ptr();
 										if ((breakAddress & 0x00000001) == 1)
-										{
+											{
 											aChangingModes = ETrue;
-										}
+											}
 										breakAddress &= 0xFFFFFFFE;
-									}
+										}
 									else
-									{
+										{
 										LOG_MSG("Error reading memory in decoding step instruction");
+										}
 									}
 								}
-							}					
+							}
+						break;
 						}
-						break;
-					}
 					case 5:
-					{
+						{
 						if ((inst & 0xF0000000) == 0xF0000000)
-						{
+							{
 							// BLX
-							{
-								breakAddress = (TUint32)arm_instr_b_dest(inst, aCurrentPC);
+							breakAddress = (TUint32)arm_instr_b_dest(inst, aCurrentPC);
 
-								// Unconditionally change into Thumb mode
-								aChangingModes = ETrue;
-								
-								breakAddress &= 0xFFFFFFFE;
+							// Unconditionally change into Thumb mode
+							aChangingModes = ETrue;
+							breakAddress &= 0xFFFFFFFE;
 							}
-						}
 						else
-						{
+							{
 							if ((inst & 0x01000000)) // bit 24
-							{
+								{
 								// BL
-								{
 									breakAddress = (TUint32)arm_instr_b_dest(inst, aCurrentPC);
 								}
-							}
 							else
-							{
+								{
 								// B
 								breakAddress = (TUint32)arm_instr_b_dest(inst, aCurrentPC);
+								}
 							}
-						}
 						break;
-					}
-				}	
-			}
-		}
+						} // case 5
+					} //switch(arm_opcode(inst)) // bits 27-25
+				} // if (IsExecuted(((inst>>28) & 0x0000000F), aStatusRegister)) 
+			} // case Debug::EArmMode:
 		break;
 
 		case Debug::EThumbMode:
-		{
+			{
 			// Thumb Mode
 			//
 			// Notes: This now includes the extra code
@@ -758,22 +753,21 @@
 
 			// v6T2 instructions
 
-// Note: v6T2 decoding is only enabled for DEBUG builds or if using an
-// an ARM_V6T2 supporting build system. At the time of writing, no
-// ARM_V6T2 supporting build system exists, so the stepping code cannot
-// be said to be known to work. Hence it is not run for release builds
+			// Note: v6T2 decoding is only enabled for DEBUG builds or if using an
+			// an ARM_V6T2 supporting build system. At the time of writing, no
+			// ARM_V6T2 supporting build system exists, so the stepping code cannot
+			// be said to be known to work. Hence it is not run for release builds
 
 			TBool use_v6t2_decodings = EFalse;
 
 #if defined(DEBUG) || defined(__ARMV6T2__)
 			use_v6t2_decodings = ETrue;
-
 #endif
 			// coverity[dead_error_line]
 			if (use_v6t2_decodings)
-			{
+				{
 				// 16-bit encodings
-	 
+
 				// A6.2.5 Misc 16-bit instructions
 				// DONE Compare and branch on zero (page A8-66)
 				// If then hints
@@ -782,7 +776,7 @@
 				//
 				// Compare and branch on Nonzero and Compare and Branch on Zero.
 				if ((inst & 0xF500) == 0xB100)
-				{
+					{
 					LOG_MSG("ARM ARM DDI0406A - section A8.6.27 CBNZ, CBZ");
 
 					// Decoding as per ARM ARM description
@@ -821,7 +815,7 @@
 				//
 				// If Then instruction
 				if ((inst & 0xFF00) == 0xBF00)
-				{
+					{
 					LOG_MSG("ARM ARM DDI0406A - section A8.6.50 IT");
 
 					// Decoding as per ARM ARM description
@@ -829,18 +823,18 @@
 					TUint32 mask = inst & 0x000F;
 
 					if (firstcond == 0xF)
-					{
+						{
 						// unpredictable
 						LOG_MSG("ARM ARM DDI0406A - section A8.6.50 IT - Unpredictable");
 						break;
-					}
+						}
 
 					if ((firstcond == 0xE) && (BitCount(mask) != 1))
-					{
+						{
 						// unpredictable
 						LOG_MSG("ARM ARM DDI0406A - section A8.6.50 IT - Unpredictable");
 						break;
-					}
+						}
 
 					// should check if 'in-it-block'
 					LOG_MSG("Cannot step IT instructions.");
@@ -861,7 +855,7 @@
 					// perhaps we can just totally ignore this state, and always do the two-instruction
 					// breakpoint thing? Not if there is any possibility that the address target
 					// would be invalid for the non-taken branch address...
-				}
+					}
 
 
 				// 32-bit encodings.
@@ -873,12 +867,12 @@
 
 				// ARM ARM DDI0406A - section A8.6.26
 				if (inst32 & 0xFFF0FFFF == 0xE3C08F00)
-				{
+					{
 					LOG_MSG("ARM ARM DDI0406A - section A8.6.26 - BXJ is not supported");
 
 					// Decoding as per ARM ARM description
 					// TUint32 Rm = inst32 & 0x000F0000;	// not needed yet
-				}
+					}
 
 				// return from exception... SUBS PC,LR. page b6-25
 				//
@@ -886,7 +880,7 @@
 				//
 				// Encoding T1
 				if (inst32 & 0xFFFFFF00 == 0xF3DE8F00)
-				{
+					{
 					LOG_MSG("ARM ARM DDI0406A - section B6.1.13 - SUBS PC,LR Encoding T1");
 
 					// Decoding as per ARM ARM description
@@ -906,13 +900,13 @@
 					TUint32 result = lrVal - operand2;
 					
 					breakAddress = result;
-				}
-				
+					}
+
 				// ARM ARM DDI0406A - section A8.6.16 - B
 				//
 				// Branch Encoding T3
 				if (inst32 & 0xF800D000 == 0xF0008000)
-				{
+					{
 					LOG_MSG("ARM ARM DDI0406A - section A8.6.16 - B Encoding T3");
 
 					// Decoding as per ARM ARM description
@@ -931,13 +925,13 @@
 					imm32 = (imm32 << 1) | 0;
 
 					breakAddress = aCurrentPC + imm32;
-				}
+					}
 
 				// ARM ARM DDI0406A - section A8.6.16 - B
 				//
 				// Branch Encoding T4
 				if (inst32 & 0xF800D000 == 0xF0009000)
-				{
+					{
 					LOG_MSG("ARM ARM DDI0406A - section A8.6.16 - B");
 
 					// Decoding as per ARM ARM description
@@ -959,14 +953,14 @@
 					imm32 = (imm32 << 1) | 0;
 
 					breakAddress = aCurrentPC + imm32;
-				}
+					}
 
 
 				// ARM ARM DDI0406A - section A8.6.225 - TBB, TBH
 				//
 				// Table Branch Byte, Table Branch Halfword
 				if (inst32 & 0xFFF0FFE0 == 0xE8D0F000)
-				{
+						{
 					LOG_MSG("ARM ARM DDI0406A - section A8.6.225 TBB,TBH Encoding T1");
 
 					// Decoding as per ARM ARM description
@@ -976,10 +970,10 @@
 
 					// Unpredictable?
 					if (Rm == 13 || Rm == 15)
-					{
+						{
 						LOG_MSG("ARM ARM DDI0406A - section A8.6.225 TBB,TBH Encoding T1 - Unpredictable");
 						break;
-					}
+						}
 
 					TUint32 halfwords;
 					TUint32 address;
@@ -989,26 +983,25 @@
 					ReturnIfError(RegisterValue(aThread,Rm,offset));
 
 					if (H)
-					{
-
+						{
 						address += offset << 1;
-					}
+						}
 					else
-					{
+						{
 						address += offset;
-					}
+						}
 
 					ReturnIfError(ReadMem32(aThread,address,halfwords));
 
 					breakAddress = aCurrentPC + 2*halfwords;
 					break;
-				}
+					}
 
 				// ARM ARM DDI0406A - section A8.6.55 - LDMDB, LDMEA
 				//
 				// LDMDB Encoding T1
 				if (inst32 & 0xFFD02000 == 0xE9100000)
-				{
+					{
 					LOG_MSG("ARM ARM DDI0406 - section A8.6.55 LDMDB Encoding T1");
 
 					// Decoding as per ARM ARM description
@@ -1022,10 +1015,10 @@
 
 					// Unpredictable?
 					if (Rn == 15 || BitCount(registers) < 2 || ((P == 1) && (M==1)))
-					{
+						{
 						LOG_MSG("ARM ARM DDI0406 - section A8.6.55 LDMDB Encoding T1 - Unpredictable");
 						break;
-					}
+						}
 
 					TUint32 address;
 					ReturnIfError(RegisterValue(aThread,Rn,address));
@@ -1033,28 +1026,28 @@
 					address -= 4*BitCount(registers);
 
 					for(TInt i=0; i<15; i++)
-					{
+						{
 						if (IsBitSet(registers,i))
-						{
+							{
 							address +=4;
+							}
 						}
-					}
 
 					if (IsBitSet(registers,15))
-					{
+						{
 						TUint32 RnVal = 0;
 						ReturnIfError(ReadMem32(aThread,address,RnVal));
 
 						breakAddress = RnVal;
-					}
+						}
 					break;
-				}
+					}
 
 				// ARM ARM DDI0406A - section A8.6.121 POP
 				//
 				// POP.W Encoding T2
 				if (inst32 & 0xFFFF2000 == 0xE8BD0000)
-				{
+					{
 					LOG_MSG("ARM ARM DDI0406A - section A8.6.121 POP Encoding T2");
 
 					// Decoding as per ARM ARM description
@@ -1064,33 +1057,33 @@
 
 					// Unpredictable?
 					if ( (BitCount(registers)<2) || ((P == 1)&&(M == 1)) )
-					{
+						{
 						LOG_MSG("ARM ARM DDI0406A - section A8.6.121 POP Encoding T2 - Unpredictable");
 						break;
-					}
+						}
 
 					TUint32 address;
 					ReturnIfError(RegisterValue(aThread,13,address));
 					
 					for(TInt i=0; i< 15; i++)
-					{
+						{
 						if (IsBitSet(registers,i))
-						{
+							{
 							address += 4;
+							}
 						}
-					}
 
 					// Is the PC written?
 					if (IsBitSet(registers,15))
-					{
+						{
 						// Yes
 						ReturnIfError(ReadMem32(aThread,address,breakAddress));
+						}
 					}
-				}
 
 				// POP Encoding T3
 				if (inst32 & 0xFFFF0FFFF == 0xF85D0B04)
-				{
+					{
 					LOG_MSG("ARM ARM DDI0406A - section A8.6.121 POP Encoding T3");
 
 					// Decoding as per ARM ARM description
@@ -1099,37 +1092,37 @@
 
 					// Unpredictable?
 					if (Rt == 13 || Rt == 15)
-					{
+						{
 						LOG_MSG("ARM ARM DDI0406A - section A8.6.121 POP Encoding T3 - Unpredictable");
 						break;
-					}
+						}
 					
 					TUint32 address;
 					ReturnIfError(RegisterValue(aThread,13,address));
 					
 					for(TInt i=0; i< 15; i++)
-					{
+						{
 						if (IsBitSet(registers,i))
-						{
+							{
 							address += 4;
+							}
 						}
-					}
 
 					// Is the PC written?
 					if (IsBitSet(registers,15))
-					{
+						{
 						// Yes
 						ReturnIfError(ReadMem32(aThread,address,breakAddress));
-					}
+						}
 
 					break;
-				}
+					}
 
 				// ARM ARM DDI0406A - section A8.6.53 LDM
 				//
 				// Load Multiple Encoding T2 
 				if ((inst32 & 0xFFD02000) == 0xE8900000)
-				{
+					{
 					LOG_MSG("ARM ARM DDI0406A - section A8.6.53 LDM Encoding T2");
 
 					// Decoding as per ARM ARM description
@@ -1142,17 +1135,17 @@
 				
 					// POP?
 					if ( (W == 1) && (Rn == 13) )
-					{
+						{
 						// POP instruction
 						LOG_MSG("ARM ARM DDI0406A - section A8.6.53 LDM Encoding T2 - POP");
-					}
+						}
 
 					// Unpredictable?
 					if (Rn == 15 || BitCount(register_list) < 2 || ((P == 1) && (M == 1)) )
-					{
+						{
 						LOG_MSG("ARM ARM DDI0406A - section A8.6.53 LDM Encoding T2 - Unpredictable");
 						break;
-					}
+						}
 					
 					TUint32 RnVal;
 					ReturnIfError(RegisterValue(aThread,Rn,RnVal));
@@ -1161,28 +1154,28 @@
 
 					// Calculate offset of address
 					for(TInt i = 0; i < 15; i++)
-					{
+						{
 						if (IsBitSet(registers,i))
 						{
 							address += 4;
 						}
-					}
+						}
 
 					// Does it load the PC?
 					if (IsBitSet(registers,15))
-					{
+						{
 						// Obtain the value loaded into the PC
 						ReturnIfError(ReadMem32(aThread,address,breakAddress));
-					}
+						}
 					break;
 
-				}
+					}
 
 				// ARM ARM DDI0406A - section B6.1.8 RFE
 				//
 				// Return From Exception Encoding T1 RFEDB
 				if ((inst32 & 0xFFD0FFFF) == 0xE810C000)
-				{
+					{
 					LOG_MSG("ARM ARM DDI0406A - section B6.1.8 RFE Encoding T1");
 
 					// Decoding as per ARM ARM description
@@ -1195,11 +1188,11 @@
 
 					// Do calculation
 					if (Rn == 15)
-					{
+						{
 						// Unpredictable 
 						LOG_MSG("ARM ARM DDI0406A - section B6.1.8 RFE Encoding T1 - Unpredictable");
 						break;
-					}
+						}
 
 					TUint32 RnVal = 0;
 					ReturnIfError(RegisterValue(aThread,Rn,RnVal));
@@ -1208,22 +1201,22 @@
 					ReturnIfError(ReadMem32(aThread,RnVal,address));
 
 					if (increment)
-					{
+						{
 						address -= 8;
-					}
+						}
 
 					if (wordhigher)
-					{
+						{
 						address += 4;
-					}				
+						}
 
 					breakAddress = address;
 					break;
-				}
+					}
 
 				// Return From Exception Encoding T2 RFEIA
 				if ((inst32 & 0xFFD0FFFF) == 0xE990C000)
-				{
+					{
 					LOG_MSG("ARM ARM DDI0406A - section B6.1.8 RFE Encoding T2");
 
 					// Decoding as per ARM ARM description
@@ -1236,11 +1229,11 @@
 
 					// Do calculation
 					if (Rn == 15)
-					{
+						{
 						// Unpredictable 
 						LOG_MSG("ARM ARM DDI0406A - section B6.1.8 RFE Encoding T2 - Unpredictable");
 						break;
-					}
+						}
 
 					TUint32 RnVal = 0;
 					ReturnIfError(RegisterValue(aThread,Rn,RnVal));
@@ -1249,22 +1242,22 @@
 					ReturnIfError(ReadMem32(aThread,RnVal,address));
 
 					if (increment)
-					{
+						{
 						address -= 8;
-					}
+						}
 
 					if (wordhigher)
-					{
+						{
 						address += 4;
-					}				
+						}
 
 					breakAddress = RnVal;
 					break;
-				}
+					}
 
 				// Return From Exception Encoding A1 RFE<amode>
 				if ((inst32 & 0xFE50FFFF) == 0xF8100A00)
-				{
+					{
 					LOG_MSG("ARM ARM DDI0406A - section B6.1.8 RFE Encoding A1");
 
 					// Decoding as per ARM ARM description
@@ -1279,11 +1272,11 @@
 
 					// Do calculation
 					if (Rn == 15)
-					{
+						{
 						// Unpredictable 
 						LOG_MSG("ARM ARM DDI0406A - section B6.1.8 RFE Encoding A1 - Unpredictable");
 						break;
-					}
+						}
 
 					TUint32 RnVal = 0;
 					ReturnIfError(RegisterValue(aThread,Rn,RnVal));
@@ -1292,94 +1285,94 @@
 					ReturnIfError(ReadMem32(aThread,RnVal,address));
 
 					if (increment)
-					{
+						{
 						address -= 8;
-					}
+						}
 
 					if (wordhigher)
-					{
+						{
 						address += 4;
-					}				
+						}
 
 					breakAddress = address;
 					break;
+					}
 				}
-			}
 
 			// v4T/v5T/v6T instructions
 			switch(thumb_opcode(inst))
-			{		
+				{
 				case 0x08:
-				{
+					{
 					// Data-processing. See ARM ARM DDI0406A, section A6-8, A6.2.2.
 
 					if ((thumb_inst_7_15(inst) == 0x08F))
-					{
+						{
 						// BLX(2)
 						err = iChannel->ReadKernelRegisterValue(aThread, ((inst & 0x0078) >> 3), breakAddress);
 						if(err != KErrNone)
-						{
+							{
 							LOG_MSG2("Non-zero error code discarded: %d", err);
-						}
+							}
 
 						if ((breakAddress & 0x00000001) == 0)
-						{
+							{
 							aChangingModes = ETrue;
-						}
-						
+							}
+
 						breakAddress &= 0xFFFFFFFE;
 
 						// Report how we decoded this instruction
 						LOG_MSG("DRMDStepping::PCAfterInstructionExecutes: Decoded as BLX (2)");
-					}
+						}
 					else if (thumb_inst_7_15(inst) == 0x08E)
-					{
+						{
 						// BX
 						err = iChannel->ReadKernelRegisterValue(aThread, ((inst & 0x0078) >> 3), breakAddress);
 						if(err != KErrNone)
-						{
+							{
 							LOG_MSG2("Non-zero error code discarded: %d", err);
-						}
+							}
 
 						if ((breakAddress & 0x00000001) == 0)
-						{
+							{
 							aChangingModes = ETrue;
-						}
+							}
 						
 						breakAddress &= 0xFFFFFFFE;
 
 						// Report how we decoded this instruction
 						LOG_MSG("DRMDStepping::PCAfterInstructionExecutes: Decoded as BX");
-					}
+						}
 					else if ((thumb_inst_8_15(inst) == 0x46) && ((inst & 0x87) == 0x87))
-					{
+						{
 						// MOV with PC as the destination
 						err = iChannel->ReadKernelRegisterValue(aThread, ((inst & 0x0078) >> 3), breakAddress);
 						if(err != KErrNone)
-						{
+							{
 							LOG_MSG2("Non-zero error code discarded: %d", err);
-						}
+							}
 
 						// Report how we decoded this instruction
 						LOG_MSG("DRMDStepping::PCAfterInstructionExecutes: Decoded as MOV with PC as the destination");
-					}
+						}
 					else if ((thumb_inst_8_15(inst) == 0x44) && ((inst & 0x87) == 0x87))
-					{
+						{
 						// ADD with PC as the destination
 						err = iChannel->ReadKernelRegisterValue(aThread, ((inst & 0x0078) >> 3), breakAddress);
 						if(err != KErrNone)
-						{
+							{
 							LOG_MSG2("Non-zero error code discarded: %d", err);
-						}
+							}
 						breakAddress += aCurrentPC + 4; // +4 because we need to use the PC+4 according to ARM ARM DDI0406A, section A6.1.2.
 
 						// Report how we decoded this instruction
 						LOG_MSG("DRMDStepping::PCAfterInstructionExecutes: Decoded as ADD with PC as the destination");
-					}
+						}
 					break;
-				}
+					}
 				case 0x13:
-				{
+					{
 					// Load/Store single data item. See ARM ARM DDI0406A, section A6-10
 
 					//This instruction doesn't modify the PC.
@@ -1393,81 +1386,81 @@
 					// Report how we decoded this instruction
 					LOG_MSG("DRMDStepping::PCAfterInstructionExecutes: Decoded as This instruction doesn't modify the PC.");
 					break;
-				}
+					}
 				case 0x17:
-				{	
+					{
 					// Misc 16-bit instruction. See ARM ARM DDI0406A, section A6-11
 
 					if (thumb_inst_8_15(inst) == 0xBD)
-					{
+						{
 						// POP with the PC in the list
 						TUint32 regList = (inst & 0x00FF);
 						TInt offset = 0;
 						err = iChannel->ReadKernelRegisterValue(aThread,  SP_REGISTER, (T4ByteRegisterValue&)offset);
 						if(err != KErrNone)
-						{
+							{
 							LOG_MSG2("Non-zero error code discarded: %d", err);
-						}
+							}
 						offset += (iChannel->Bitcount(regList) * 4);
 
 						TBuf8<4> destination;
 						err = iChannel->DoReadMemory(aThread, offset, 4, destination);
 						
 						if (KErrNone == err)
-						{
+							{
 							breakAddress = *(TUint32 *)destination.Ptr();
 
 							if ((breakAddress & 0x00000001) == 0)
-							{
+								{
 								aChangingModes = ETrue;
-							}
+								}
 
 							breakAddress &= 0xFFFFFFFE;
-						}
+							}
 						else
-						{
+							{
 							LOG_MSG("Error reading memory in decoding step instruction");
-						}
+							}
 
 						// Report how we decoded this instruction
 						LOG_MSG("DRMDStepping::PCAfterInstructionExecutes: Decoded as POP with the PC in the list");
-					}
+						}
 					break;
-				}
+					}
 				case 0x1A:
 				case 0x1B:
-				{	
+					{
 					// Conditional branch, and supervisor call. See ARM ARM DDI0406A, section A6-13
 
 					if (thumb_inst_8_15(inst) < 0xDE)
-					{
+						{
 						// B(1) conditional branch
 						if (IsExecuted(((inst & 0x0F00) >> 8), aStatusRegister))
-						{
+							{
 							TUint32 offset = ((inst & 0x000000FF) << 1);
 							if (offset & 0x00000100)
-							{
+								{
 								offset |= 0xFFFFFF00;
-							}
+								}
 							
 							breakAddress = aCurrentPC + 4 + offset;
 
 							// Report how we decoded this instruction
 							LOG_MSG("DRMDStepping::PCAfterInstructionExecutes: Decoded as B(1) conditional branch");
+							}
 						}
-					}
 					break;
-				}
+					}
 				case 0x1C:
-				{
+					{
 					// Unconditional branch, See ARM ARM DDI0406A, section A8-44.
 
 					// B(2) unconditional branch
 					TUint32 offset = (inst & 0x000007FF) << 1;
 					if (offset & 0x00000800)
-					{
+						{
 						offset |= 0xFFFFF800;
-					}
+						}
 					
 					breakAddress = aCurrentPC + 4 + offset;
 
@@ -1475,114 +1468,111 @@
 					LOG_MSG("DRMDStepping::PCAfterInstructionExecutes: Decoded as B(2) unconditional branch");
 
 					break;
-				}
+					}
 				case 0x1D:
-				{
+					{
 					if (!(inst & 0x0001))
-					{
+						{
 						// BLX(1)
 						err = iChannel->ReadKernelRegisterValue(aThread, LINK_REGISTER, breakAddress);
 						if(err != KErrNone)
-						{
+							{
 							LOG_MSG2("Non-zero error code discarded: %d", err);
-						}
+							}
 						breakAddress +=  ((inst & 0x07FF) << 1);
 						if ((breakAddress & 0x00000001) == 0)
-						{
+							{
 							aChangingModes = ETrue;
-						}
+							}
 
 						breakAddress &= 0xFFFFFFFC;
 
 						// Report how we decoded this instruction
 						LOG_MSG("DRMDStepping::PCAfterInstructionExecutes: Decoded as BLX(1)");
 
-					}
+						}
 					break;
-				}
+					}
 				case 0x1E:
-				{
-                    // Check for ARMv7 CPU
-                    if(cpuid == 0xC0)
-                    {
-    					// BL/BLX 32-bit instruction
-	    				aNewRangeEnd += 4;
+					{
+					// Check for ARMv7 CPU
+					if(cpuid == 0xC0)
+						{
+						// BL/BLX 32-bit instruction
+						aNewRangeEnd += 4;
 
 						breakAddress = (TUint32)thumb_instr_b_dest(inst32, aCurrentPC);
 
-            			if((inst32 >> 27) == 0x1D)
-            			{
-            			    // BLX(1)
-    						if ((breakAddress & 0x00000001) == 0)
-	    					{
-		    					aChangingModes = ETrue;
-			    			}
-    
-	    					breakAddress &= 0xFFFFFFFC;
+						if((inst32 >> 27) == 0x1D)
+							{
+							// BLX(1)
+							if ((breakAddress & 0x00000001) == 0)
+								{
+								aChangingModes = ETrue;
+								}
+
+							breakAddress &= 0xFFFFFFFC;
 
-    						// Report how we decoded this instruction
-	    					LOG_MSG("DRMDStepping::PCAfterInstructionExecutes: Decoded as 32-bit BLX(1)");
-                        }
-                        else
-                        {                            
-    					    // Report how we decoded this instruction
-	        				LOG_MSG("DRMDStepping::PCAfterInstructionExecutes: 32-bit BL instruction");
-                        }
-        				LOG_MSG2(" 32-bit BL/BLX instruction: breakAddress = 0x%X", breakAddress);
-                    }            
-                    else
-                    {
-					    // BL/BLX prefix - destination is encoded in this and the next instruction
-					    aNewRangeEnd += 2;
+							// Report how we decoded this instruction
+							LOG_MSG("DRMDStepping::PCAfterInstructionExecutes: Decoded as 32-bit BLX(1)");
+							}
+						else
+							{
+							// Report how we decoded this instruction
+							LOG_MSG("DRMDStepping::PCAfterInstructionExecutes: 32-bit BL instruction");
+							}
+						LOG_MSG2(" 32-bit BL/BLX instruction: breakAddress = 0x%X", breakAddress);
+						} // if(cpuid == 0xC0)
+					else
+						{
+						// BL/BLX prefix - destination is encoded in this and the next instruction
+						aNewRangeEnd += 2;
 
-					    // Report how we decoded this instruction
-					    LOG_MSG("DRMDStepping::PCAfterInstructionExecutes: BL/BLX prefix - destination is encoded in this and the next instruction");
-                    }
-
+						// Report how we decoded this instruction
+						LOG_MSG("DRMDStepping::PCAfterInstructionExecutes: BL/BLX prefix - destination is encoded in this and the next instruction");
+						}
 
 					break;
-				}
+					}
 				case 0x1F:
-				{
 					{
-						// BL
-						err = iChannel->ReadKernelRegisterValue(aThread, LINK_REGISTER, breakAddress);
-						if(err != KErrNone)
+					// BL
+					err = iChannel->ReadKernelRegisterValue(aThread, LINK_REGISTER, breakAddress);
+					if(err != KErrNone)
 						{
-							LOG_MSG2("Non-zero error code discarded: %d", err);
+						LOG_MSG2("Non-zero error code discarded: %d", err);
 						}
-						breakAddress += ((inst & 0x07FF) << 1);
+					breakAddress += ((inst & 0x07FF) << 1);
 
-						// Report how we decoded this instruction
-						LOG_MSG("DRMDStepping::PCAfterInstructionExecutes: Decoded as BL");
+					// Report how we decoded this instruction
+					LOG_MSG("DRMDStepping::PCAfterInstructionExecutes: Decoded as BL");
+					break;
+					}
+				default:
+					{
+					// Don't know any better at this point!
+					LOG_MSG("DRMDStepping::PCAfterInstructionExecutes:- default to next instruction");
 					}
 					break;
-				}
-				default:
-					{
-						// Don't know any better at this point!
-						LOG_MSG("DRMDStepping::PCAfterInstructionExecutes:- default to next instruction");
-					}
-					break;
-			}
-		}
+				} // switch(thumb_opcode(inst))
+			} // case Debug::EThumbMode:
 		break;
-		
+
 		case Debug::EThumb2EEMode:
-		{
+			{
 			// Not yet supported
 			LOG_MSG("DRMDStepping::PCAfterInstructionExecutes - Debug::EThumb2Mode is not supported");
 
-		}
-		break;
+			}
+			break;
 
 		default:
 			LOG_MSG("DRMDStepping::PCAfterInstructionExecutes - Cannot determine CPU mode architecture");
-	}	
+		} // switch(mode)
 
 	LOG_MSG2("DRMDStepping::PCAfterInstructionExecutes : return 0x%08x",breakAddress);
 	return breakAddress;
-}
+	}
 
 // Obtain a 32-bit memory value with minimum fuss
 TInt DRMDStepping::ReadMem32(DThread* aThread, const TUint32 aAddress, TUint32& aValue)
@@ -1646,7 +1636,7 @@
 
 // Encodings from ARM ARM DDI0406A, section 9.2.1
 enum TThumb2EEOpcode
-{
+	{
 	EThumb2HDP,		// Handler Branch with Parameter
 	EThumb2UNDEF,	// UNDEFINED
 	EThumb2HB,		// Handler Branch, Handler Branch with Link
@@ -1656,76 +1646,76 @@
 	EThumb2LDRL,	// Load Register from a literal pool
 	EThumb2LDRA,	// Load Register (array operations)
 	EThumb2STR		// Store Register to a frame
-};
+	};
 
 //
 // DRMDStepping::ShiftedRegValue
 //
 TUint32 DRMDStepping::ShiftedRegValue(DThread *aThread, TUint32 aInstruction, TUint32 aCurrentPC, TUint32 aStatusRegister)
-{
-	LOG_MSG("DRM_DebugChannel::ShiftedRegValue()");
+	{
+	LOG_MSG("DRMDStepping::ShiftedRegValue()");
 
 	TUint32 shift = 0;
 	if (aInstruction & 0x10)	// bit 4
-	{
+		{
 		shift = (arm_rs(aInstruction) == PC_REGISTER ? aCurrentPC + 8 : aStatusRegister) & 0xFF;
-	}
+		}
 	else
-	{
+		{
 		shift = arm_data_c(aInstruction);
-	}
+		}
 	
 	TInt rm = arm_rm(aInstruction);
 	
 	TUint32 res = 0;
 	if(rm == PC_REGISTER)
-	{
+		{
 		res = aCurrentPC + ((aInstruction & 0x10) ? 12 : 8);
-	}
+		}
 	else
-	{
+		{
 		TInt err = iChannel->ReadKernelRegisterValue(aThread, rm, res);
 		if(err != KErrNone)
-		{
+			{
 			LOG_MSG2("DRMDStepping::ShiftedRegValue - Non-zero error code discarded: %d", err);
+			}
 		}
-	}
 
 	switch(arm_data_shift(aInstruction))
-	{
+		{
 		case 0:			// LSL
-		{
+			{
 			res = shift >= 32 ? 0 : res << shift;
 			break;
-		}
+			}
 		case 1:			// LSR
-		{
+			{
 			res = shift >= 32 ? 0 : res >> shift;
 			break;
-		}
+			}
 		case 2:			// ASR
-		{
+			{
 			if (shift >= 32)
 			shift = 31;
 			res = ((res & 0x80000000L) ? ~((~res) >> shift) : res >> shift);
 			break;
-		}
+			}
 		case 3:			// ROR/RRX
-		{
+			{
 			shift &= 31;
 			if (shift == 0)
-			{
+				{
 				res = (res >> 1) | ((aStatusRegister & arm_carry_bit()) ? 0x80000000L : 0);
-			}
+				}
 			else
-			{
+				{
 				res = (res >> shift) | (res << (32 - shift));
-			}
+				}
 			break;
-    	}
-    }
+			}
+		}
 
-  	return res & 0xFFFFFFFF;
+	return res & 0xFFFFFFFF;
 }
 
 //
--- a/kernel/eka/drivers/debug/rmdebug/d_target_process.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/drivers/debug/rmdebug/d_target_process.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -16,7 +16,7 @@
 // each process being debugged.
 // Note: Although TheDProcessTracker object is a global, it should be unique
 // as only the Debug Security Server should load and use this driver.
-// 
+//
 //
 
 #include <e32def.h>
@@ -101,12 +101,12 @@
 DDebugAgent* DTargetProcess::Agent(TUint64 aAgentId)
 	{
 	for(TInt i = 0; i < iAgentList.Count(); i++)
-	{
+		{
 		if (iAgentList[i]->Id() == aAgentId)
-		{
+			{
 			return iAgentList[i];
+			}
 		}
-	}
 
 	// what do we return if we don't have any agents?
 	return NULL;
@@ -115,8 +115,11 @@
 // Adds aAgentId as a tracking agent for this process.
 TInt DTargetProcess::AddAgent(TUint64 aAgentId)
 	{
-	LOG_MSG("DTargetProcess::AddAgent()");
+	
 	DDebugAgent* agent = DDebugAgent::New(aAgentId);
+	LOG_MSG4("DTargetProcess::AddAgent(), agentId=%d, curr iAgentList.Count=%d, new agent=0x%08x",
+		I64LOW(aAgentId), iAgentList.Count(), agent );
+
 	if(agent == NULL)
 		{
 		LOG_MSG("DTargetProcess::AddAgent() couldn't allocate memory for DDebugAgent");
@@ -172,19 +175,19 @@
 	//if resuming the suspended thread failed for an obscure reason return it
 	if((err1 != KErrNotFound) && (err1 != KErrNone))
 		{
-		LOG_MSG2("DTargetProcess::ResumeThread() unexpected exit, err1: %d", err1);
+		LOG_MSG2("DTargetProcess::ResumeThread() BUG : unexpected exit, err1: %d", err1);
 		return err1;
 		}
 	//if resuming the frozen thread failed for an obscure reason return it
 	if((err2 != KErrNotFound) && (err2 != KErrNone))
 		{
-		LOG_MSG2("DTargetProcess::ResumeThread() unexpected exit, err2: %d", err2);
+		LOG_MSG2("DTargetProcess::ResumeThread() BUG : unexpected exit, err2: %d", err2);
 		return err2;
 		}
 	// if resuming the suspended thread succeeded in both cases, we have a consistency problem
 	if ((err1 == KErrNone) && (err2 == KErrNone))
 		{
-		LOG_MSG("DTargetProcess::ResumeThread() unexpected exit, err1 == err2 == KErrNone");
+		LOG_MSG("DTargetProcess::ResumeThread() BUG : unexpected exit, err1 == err2 == KErrNone");
 		}
 
 	//if the thread was in neither list return KErrNotFound, otherwise KErrNone
@@ -232,7 +235,7 @@
 		if(iSuspendedThreads[i] == threadId)
 			{
 			iSuspendedThreads.Remove(i);
-			LOG_MSG2("DTargetProcess::ResumeSuspendedThread()> Kern::ThreadResume() 0x%x", aThread);
+			LOG_MSG2("DTargetProcess::ResumeSuspendedThread()> Kern::ThreadResume() 0x%08x", aThread);
 			Kern::ThreadResume(*aThread);
 			return KErrNone;
 			}
@@ -292,7 +295,8 @@
 	NFastSemaphore* sem = new NFastSemaphore();
 	NKern::ThreadLeaveCS();
 	sem->iOwningThread = &(Kern::CurrentThread().iNThread);
-	LOG_EVENT_MSG2("DTargetProcess::FreezeThread(): new NFastSemaphore() curr thread=0x%x", sem->iOwningThread);
+	LOG_MSG3("DTargetProcess::FreezeThread(): new NFastSemaphore() owning thread==curr NThread=0x%08x, DThread=0x%08x", 
+		sem->iOwningThread, &(Kern::CurrentThread()) );
 	return iFrozenThreadSemaphores.Append(sem);
 	}
 
@@ -322,6 +326,7 @@
 	TInt err = iSuspendedThreads.Append(threadId);
 	if(err == KErrNone)
 		{
+		LOG_MSG2("DTargetProcess::DoSuspendThread >Kern::ThreadSuspend() 0x%08x", aThread ); 
 		Kern::ThreadSuspend(*aThread, 1);
 		}
 	return err;
@@ -341,13 +346,13 @@
  */
 void DTargetProcess::FSWait()
 	{
-	LOG_MSG2("DTargetProcess::NotifyEvent(): number of attached agents: %d", AgentCount());
-	NThread* currentThread = &(Kern::CurrentThread().iNThread);
+	NThread* currentNThread = &(Kern::CurrentThread().iNThread);	
 	for(TInt i=0; i<iFrozenThreadSemaphores.Count(); i++)
 		{
-		if(iFrozenThreadSemaphores[i]->iOwningThread == currentThread)
+		if(iFrozenThreadSemaphores[i]->iOwningThread == currentNThread)
 			{
-			LOG_MSG3("DTargetProcess::FSWait(): > FSWait frozen sem %d, curr thread=0x%x", i, currentThread);
+			LOG_MSG4("DTargetProcess::FSWait(): > FSWait frozen sem %d, currentNThread=0x%08x, id=0x%x", 
+				i, currentNThread, Kern::CurrentThread().iId );
 			NKern::FSWait(iFrozenThreadSemaphores[i]);
 			return;
 			}
@@ -399,7 +404,8 @@
 void DTargetProcess::NotifyEvent(const TDriverEventInfo& aEventInfo)
 	{
 	// Stuff the event info into all the tracking agents event queues
-	LOG_MSG2("DTargetProcess::NotifyEvent(): number of attached agents: %d", AgentCount());
+	LOG_MSG4("DTargetProcess::NotifyEvent(): num attached agents: %d, iEventType=%d, this=0x%08x", 
+		AgentCount(), aEventInfo.iEventType, this);
 
 	for(TInt i = 0; i < AgentCount(); i++)
 		{
--- a/kernel/eka/drivers/debug/rmdebug/rm_debug_eventhandler.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/drivers/debug/rmdebug/rm_debug_eventhandler.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -44,7 +44,6 @@
 	iEventHandlers[EEventUserTrace] = &DRM_DebugChannel::HandleUserTrace;
 	iEventHandlers[EEventRemoveLibrary] = &DRM_DebugChannel::RemoveLibrary;
 	iEventHandlers[EEventAddLibrary] = &DRM_DebugChannel::AddLibrary;
-	iEventHandlers[EEventRemoveProcess] = &DRM_DebugChannel::RemoveProcess;
 	iEventHandlers[EEventStartThread] = &DRM_DebugChannel::StartThread;
 	iEventHandlers[EEventSwExc] = &DRM_DebugChannel::HandleSwException;
 	iEventHandlers[EEventHwExc] = &DRM_DebugChannel::HandleHwException;
@@ -55,7 +54,7 @@
 
 TInt DRM_DebugEventHandler::Create(DLogicalDevice* aDevice, DLogicalChannel* aChannel, DThread* aClient)
 {
-	LOG_MSG("DRM_DebugEventHandler::Create()");
+	LOG_MSG3("DRM_DebugEventHandler::Create(), aClientthread=0x%08x id=%d", aClient, aClient->iId);
 
 	TInt err;
 	err = aDevice->Open();
@@ -71,7 +70,7 @@
 	iClientThread = aClient;
 
 	// Use a semaphore to protect our data structures from concurrent access.
-	err = Kern::SemaphoreCreate(iLock, _L("RM_DebugEventHandlerLock"), 1 /* Initial count */);
+	err = Kern::SemaphoreCreate(iProtectionLock, _L("RM_DebugEventHandlerLock"), 1 /* Initial count */);
 	if (err != KErrNone)
 		return err;
 
@@ -84,8 +83,8 @@
 {
 	LOG_MSG("DRM_DebugEventHandler::~DRM_DebugEventHandler()");
 
-	if (iLock)
-		iLock->Close(NULL);
+	if (iProtectionLock)
+		iProtectionLock->Close(NULL);
 	
 	if (iDevice)
 		iDevice->Close(NULL);	
@@ -125,7 +124,17 @@
 
 TUint DRM_DebugEventHandler::HandleEvent(TKernelEvent aType, TAny* a1, TAny* a2)
 	{
-	if((!iTracking) || (aType > (TUint32)EEventLimit))
+	
+	/*
+	 * Check if we are tracking things at all OR 
+	 * this event is beyond the limit of known events OR 
+	 * this event is from the debug thread itself (don't want to debug ourselves) OR
+	 * this event has a handler (there is no point in proceeding without a handler)
+	 */
+	if( (!iTracking) || 
+			(aType > (TUint32)EEventLimit) ||
+			(iClientThread == &Kern::CurrentThread()) ||
+	    (iEventHandlers[aType] == &DRM_DebugChannel::HandleUnsupportedEvent) )
 		{
 		return ERunNext;
 		}
@@ -137,14 +146,14 @@
 	TBool ret = EFalse;
 
 	NKern::ThreadEnterCS();
-	Kern::SemaphoreWait(*iLock);
-	
+	LockDataAccess();
+
+
 	if (iChannel)
 		{
 		ret = (iChannel->*(iEventHandlers[aType]))(a1, a2);
 		}
-
-	Kern::SemaphoreSignal(*iLock);
+	ReleaseDataAccess();
 	NKern::ThreadLeaveCS();
 
 	switch(aType)
--- a/kernel/eka/drivers/debug/rmdebug/rm_debug_kerneldriver.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/drivers/debug/rmdebug/rm_debug_kerneldriver.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -1,4 +1,4 @@
-// Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 2004-2010 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"
@@ -59,41 +59,41 @@
 // DRM_DebugDriverFactory constructor
 //
 DRM_DebugDriverFactory::DRM_DebugDriverFactory()
-{
+	{
 	iVersion = TVersion(KMajorVersionNumber,KMinorVersionNumber,KBuildVersionNumber);
-}
+	}
 
 //
 // DRM_DebugDriverFactory::Create
 //
 TInt DRM_DebugDriverFactory::Create(DLogicalChannelBase*& aChannel)
-{
+	{
 	if (iOpenChannels != 0)
 		return KErrInUse; // a channel is already open
 
 	aChannel = new DRM_DebugChannel(this);
 
 	return aChannel ? KErrNone : KErrNoMemory;
-}
+	}
 
 //
 // DRM_DebugDriverFactory::Install
 //
 TInt DRM_DebugDriverFactory::Install()
-{
-    return(SetName(&KRM_DebugDriverName));
-}
+	{
+	return(SetName(&KRM_DebugDriverName));
+	}
 
 //
 // DRM_DebugDriverFactory::Install
 //
 void DRM_DebugDriverFactory::GetCaps(TDes8& aDes) const
-{
-    TCapsRM_DebugDriver b;
-    b.iVersion = TVersion(KMajorVersionNumber, KMinorVersionNumber, KBuildVersionNumber);
+	{
+	TCapsRM_DebugDriver b;
+	b.iVersion = TVersion(KMajorVersionNumber, KMinorVersionNumber, KBuildVersionNumber);
 
 	Kern::InfoCopy(aDes,(TUint8*)&b,sizeof(b));
-}
+	}
 
 /////////////////////////////////////////////////////////////////////////
 //
@@ -106,15 +106,15 @@
 //
 DRM_DebugChannel::DRM_DebugChannel(DLogicalDevice* aLogicalDevice)
 	: iExcludedROMAddressStart(ROM_LINEAR_BASE),
-      iExcludedROMAddressEnd(0),
-   	  iPageSize(0x1000),
-	  iBreakManager(0),
-	  iStepper(0),
-	  iStepLock(0),
-  	  iDfcQ(NULL),
-	  iInitialisedCodeModifier(0),
-	  iAsyncGetValueRequest(NULL)
-{
+	iExcludedROMAddressEnd(0),
+	iPageSize(0x1000),
+	iBreakManager(0),
+	iStepper(0),
+	iStepLock(0),
+	iDfcQ(NULL),
+	iInitialisedCodeModifier(0),
+	iAsyncGetValueRequest(NULL)
+	{
 	LOG_MSG("DRM_DebugChannel::DRM_DebugChannel()");
 
 	iDevice = aLogicalDevice;
@@ -122,21 +122,25 @@
 	iClientThread = &Kern::CurrentThread();
 	iClientThread->Open();
 
+	LOG_MSG3("DRM_DebugChannel::DRM_DebugChannel() clientThread = 0x%08x, id=%d", 
+	            iClientThread, iClientThread->iId );
+
+
 	iPageSize = Kern::RoundToPageSize(1);
-}
+	}
 
 //
 // DRM_DebugChannel destructor
 //
 DRM_DebugChannel::~DRM_DebugChannel()
-{
+	{
 	LOG_MSG("DRM_DebugChannel::~DRM_DebugChannel()");
 
 	if (iAsyncGetValueRequest)
-	{
+		{
 		Kern::QueueRequestComplete(iClientThread, iAsyncGetValueRequest, KErrCancel); // does nothing if request not pending
 		Kern::DestroyClientRequest(iAsyncGetValueRequest);
-	}
+		}
 
 	NKern::ThreadEnterCS();
 	Kern::SafeClose((DObject*&)iClientThread, NULL);
@@ -144,19 +148,19 @@
 
 	// Close breakpoint manager
 	if (iBreakManager)
-	{
+		{
 		NKern::ThreadEnterCS();
 		delete iBreakManager;
 		NKern::ThreadLeaveCS();
-	}
+		}
 
 	// Close stepping manager
 	if (iStepper)
-	{
+		{
 		NKern::ThreadEnterCS();
 		delete iStepper;
 		NKern::ThreadLeaveCS();
-	}
+		}
 
 	//close the debug process list
 	iDebugProcessList.Close();
@@ -165,10 +169,10 @@
 
 	//close the code modifier
 	if (iInitialisedCodeModifier)
-	{
+		{
 		DebugSupport::CloseCodeModifier();
+		}
 	}
-}
 
 void DRM_DebugChannel::DestroyDfcQ()
 	{
@@ -185,47 +189,45 @@
 // DRM_DebugChannel::DoCreate
 //
 TInt DRM_DebugChannel::DoCreate(TInt /*aUnit*/, const TDesC* anInfo, const TVersion& aVer)
-{
+	{
 	LOG_MSG("DRM_DebugChannel::DoCreate()");
 	TInt err = Kern::CreateClientDataRequest(iAsyncGetValueRequest);
 	if(err != KErrNone)
 		return err;
 
-  	if (!Kern::QueryVersionSupported(TVersion(KMajorVersionNumber, KMinorVersionNumber, KBuildVersionNumber), aVer))
+	if (!Kern::QueryVersionSupported(TVersion(KMajorVersionNumber, KMinorVersionNumber, KBuildVersionNumber), aVer))
 		return KErrNotSupported;
 
-  	// Do the security check here so that any arbitrary application doesn't make
-  	// use of Trk kernel driver.
-  	if (!DoSecurityCheck())
-  	{
+	// Do the security check here so that any arbitrary application doesn't make
+	// use of Trk kernel driver.
+	if (!DoSecurityCheck())
+		{
 		LOG_MSG("DRM_DebugChannel::DoCreate() - permission denied!");
-  		return KErrPermissionDenied;
-  	}
-
-  	if (anInfo)
-  	{
-  		// this is the end address of the user library.
-  		// this doesn't seem to be valid for EKA2.
-  		// right now we dont need this for EKA2 since we are not worried
-  		// about kernel being stopped as kernel is multithreaded.
-  		// just retaining this for future use.
+			return KErrPermissionDenied;
+		}
+
+	if (anInfo)
+		{
+		// this is the end address of the user library.
+		// this doesn't seem to be valid for EKA2.
+		// right now we dont need this for EKA2 since we are not worried
+		// about kernel being stopped as kernel is multithreaded.
+		// just retaining this for future use.
 		TBuf8<32> buf;
 		TInt err = Kern::ThreadRawRead(iClientThread, anInfo, &buf, 32);
 		if(err != KErrNone)
 			return err;
-
-		//iExcludedROMAddressEnd = *(TUint32 *)(&(buf.Ptr()[20]));
-	}
+		}
 
 	// Allocate a D_RMD_Breakpoints class as a breakpoint manager
 	NKern::ThreadEnterCS();
 	iBreakManager = new D_RMD_Breakpoints(this);
 	NKern::ThreadLeaveCS();
 	if (iBreakManager == NULL)
-	{
+		{
 		LOG_MSG("DRM_DebugChannel::DRM_DebugChannel - could not construct breakpoint manager");
 		return KErrNoMemory;
-	}
+		}
 
 	// Initialise the new breakpoint manager object
 	iBreakManager->Init();
@@ -235,10 +237,10 @@
 	iStepper = new DRMDStepping(this);
 	NKern::ThreadLeaveCS();
 	if (iStepper == NULL)
-	{
+		{
 		LOG_MSG("DRM_DebugChannel::DRM_DebugChannel - could not construct stepper manager");
 		return KErrNoMemory;
-	}
+		}
 
 	// Initialize the code modifier for managing breakpoints.
 	TUint caps; //ignored for now
@@ -246,13 +248,13 @@
 	//if code modifier initializer failed,
 	//return here, since we can't set an breakpoints
 	if(err != KErrNone)
-	{
+		{
 		return err;
-	}
+		}
 	else
-	{
+		{
 		iInitialisedCodeModifier = ETrue;
-	}
+		}
 
 	//create and set the driver's Dfc queue
 	err = CreateDfcQ();
@@ -273,15 +275,29 @@
 
 	//return KErrNone;
 	return iEventHandler->Start();
-}
-
-//
-// DRM_DebugChannel::SendMsg
-//
+	}
+
+/**
+Forward call to either synch or asynch methods while serialising all calls via lock.
+ 
+Protect access via a the event handler lock to 
+serialise all calls and protect concurrent access to data structures
+
+@param aMsg pointer to a TMessageBase object 
+
+@return error returned by called methods
+
+@see DRM_DebugEventHandler::HandleSpecificEvent where lock is also used
+@see DRM_DebugEventHandler::iProtectionLock
+
+*/
 TInt DRM_DebugChannel::SendMsg(TMessageBase* aMsg)
 	{
-	LOG_MSG("DRM_DebugChannel::SendMsg()");
-
+	DThread * currThread = &Kern::CurrentThread();
+	LOG_MSG3("DRM_DebugChannel::SendMsg() currThread = 0x%08x, iClientThread=0x%08x", currThread, iClientThread );
+
+	iEventHandler->LockDataAccess();
+	
 	TThreadMessage& m = *(TThreadMessage*)aMsg;
 	TInt id = m.iValue;
 	TInt err = KErrNone;
@@ -298,6 +314,8 @@
 		{
 		err = DLogicalChannel::SendMsg(aMsg);
 		}
+	
+	iEventHandler->ReleaseDataAccess();
 	return err;
 	}
 
@@ -330,7 +348,8 @@
 //
 TInt DRM_DebugChannel::PreAsyncGetValue(TEventInfo* aValue, TRequestStatus* aStatus)
 	{
-	LOG_MSG("DRM_DebugChannel::PreAsyncGetValue()");
+	LOG_MSG3("DRM_DebugChannel::PreAsyncGetValue() TEventInfo=0x%08x, TRequestStatus=0x%08x",
+		aValue, aStatus );
 	
 	iAsyncGetValueRequest->Reset();
 	
@@ -364,89 +383,93 @@
 // to a user-side struct defining the cancellation
 //
 void DRM_DebugChannel::DoCancel(TInt aReqNo)
-{
+	{
 	LOG_MSG("DRM_DebugChannel::DoCancel()");
 
 	TRMD_DebugCancelInfo info;
 
 	TInt err = Kern::ThreadRawRead(iClientThread,(TAny*)aReqNo,(TAny*)&info,sizeof(info));
 	if (err != KErrNone)
-	{
+		{
 		// How do we cancel something we know nothing about???
 		LOG_MSG("DRM_DebugChannel::DoCancel - bad arguments");
 		return;
-	}
+		}
 
 	// Find the process
 	DTargetProcess* pProcess = TheDProcessTracker.FindProcess(info.iProcessName);
 	if (pProcess == NULL)
-	{
+		{
 		// We are doomed. We don't know which event to cancel..
 		LOG_MSG2("Cannot determine which process is being debugged: %S", &(info.iProcessName));
 
 		return;
-	}
+		}
 
 	// Find the agent
 	DDebugAgent* debugAgent = pProcess->Agent(info.iAgentId);
 	if (debugAgent == NULL)
-	{
+		{
 		// Bad agent means there is no tracking agent
 		LOG_MSG2("Cannot locate debug agent with pid 0x%0x16lx",info.iAgentId);
 		return;
-	}
+		}
 
 	// Agent completes/pends the request as appropriate.
 	debugAgent->CancelGetEvent();
 
-}
+	}
 
 //
 // DRM_DebugChannel::DoRequest
 //
 void DRM_DebugChannel::DoRequest(TInt aReqNo, TRequestStatus* aStatus, TAny* a1, TAny* a2)
-{
-	LOG_MSG("DRM_DebugChannel::DoRequest()");
+	{
+	LOG_MSG4("DRM_DebugChannel::DoRequest(), iClientThread=0x%08x, tid=0x%08x, TRequestStatus=0x%08x", 
+		iClientThread, I64LOW(iClientThread->iId), aStatus);
 
 	switch(aReqNo)
-	{
+		{
 		case RRM_DebugDriver::ERequestGetEvent:
-		{
+			{
 			TEventMetaData eventMetaData;
 			TInt err = Kern::ThreadRawRead(iClientThread, a2, (TUint8 *)&eventMetaData, sizeof(TEventMetaData) );
 			if (err != KErrNone)
-			{
+				{
 				LOG_MSG("Error: could not read argument data from the DSS (TEventMetaData)");
 
 				// We could not read information from the user, so the a2 argument is probably wrong
 				Kern::RequestComplete(iClientThread, aStatus, KErrArgument);
 				return;
-			}
+				}
 
 			// Find the process
 			DTargetProcess* pProcess = TheDProcessTracker.FindProcess(eventMetaData.iTargetProcessName);
 			if (pProcess == NULL)
-			{
+				{
 				LOG_MSG("Cannot identify process being debugged");
 
 				// We could not locate the process, so the user asked for the wrong one.
 				Kern::RequestComplete(iClientThread, aStatus, KErrArgument);
 				return;
-			}
+				}
 
 			// Find the agent
 			DDebugAgent* debugAgent = pProcess->Agent(eventMetaData.iDebugAgentProcessId);
+			LOG_MSG5(" For agent pid=%d, DTargetProcess=0x%08x, Agent=0x%08x, iAsyncGetValueRequest0x%08x", 
+				I64LOW(eventMetaData.iDebugAgentProcessId), pProcess, debugAgent, iAsyncGetValueRequest );
+
 			if (debugAgent == NULL)
-			{
+				{
 				// Bad agent means there is no tracking agent
 				LOG_MSG2("Cannot locate debug agent with pid 0x%0x16lx",eventMetaData.iDebugAgentProcessId);
 				return;
-			}
+				}
 			// Agent completes/pends the request as appropriate.
-			debugAgent->GetEvent(iAsyncGetValueRequest, (TEventInfo*)a1, iClientThread);
+			debugAgent->GetEvent(iAsyncGetValueRequest, iClientThread);
 
 			break;
-		}
+			}
 		default:
 			{
 			// Don't know what to do, should not get here!
@@ -454,14 +477,14 @@
 
 			Kern::RequestComplete(iClientThread, aStatus, KErrNotSupported);
 			}
+		}
 	}
-}
 
 //
 // DRM_DebugChannel::DoControl
 //
 TInt DRM_DebugChannel::DoControl(TInt aFunction, TAny* a1, TAny* a2)
-{
+	{
 	LOG_MSG("DRM_DebugChannel::DoControl()");
 
 	LOG_MSG2("DoControl Function %d", aFunction);
@@ -470,121 +493,121 @@
 	DThread* threadObj = NULL;
 
 	switch(aFunction)
-	{
+		{
 		/* Security first */
 		case RRM_DebugDriver::EControlIsDebuggable:
-		{
+			{
 			err = IsDebuggable((TUint32)a1);
 			break;
-		}
+			}
 		case RRM_DebugDriver::EControlSetBreak:
-		{
+			{
 			err = SetBreak((TSetBreakInfo*)a1);
 			break;
-		}
+			}
 		case RRM_DebugDriver::EControlClearBreak:
-		{
+			{
 			err = iBreakManager->DoClearBreak((TInt32)a1);
 			break;
-		}
+			}
 		case RRM_DebugDriver::EControlModifyBreak:
-		{
+			{
 			err = iBreakManager->DoModifyBreak((TModifyBreakInfo*)a1);
 			break;
-		}
+			}
 		case RRM_DebugDriver::EControlModifyProcessBreak:
-		{
+			{
 			err = iBreakManager->DoModifyProcessBreak((TModifyProcessBreakInfo*)a1);
 			break;
-		}
+			}
 		case RRM_DebugDriver::EControlBreakInfo:
-		{
+			{
 			err = iBreakManager->DoBreakInfo((TGetBreakInfo*)a1);
 			break;
-		}
+			}
 		case RRM_DebugDriver::EControlSuspendThread:
-		{
+			{
 			threadObj = DebugUtils::OpenThreadHandle((TUint32)a1);
 			if (threadObj)
 			{
 				err = DoSuspendThread(threadObj);
 			}
 			break;
-		}
+			}
 		case RRM_DebugDriver::EControlResumeThread:
-		{
+			{
+			threadObj = DebugUtils::OpenThreadHandle((TUint32)a1);
+			if (threadObj)
+				{
+				err = DoResumeThread(threadObj);
+				}
+			break;
+			}
+		case RRM_DebugDriver::EControlStepRange:
+			{
+			threadObj = DebugUtils::OpenThreadHandle((TUint32)a1);
+			if (threadObj)
+				{
+				err = StepRange(threadObj, (TRM_DebugStepInfo*)a2);
+				}
+			break;
+			}
+		case RRM_DebugDriver::EControlReadMemory:
+			{
+			threadObj = DebugUtils::OpenThreadHandle((TUint32)a1);
+			if (threadObj)
+				{
+				err = ReadMemory(threadObj, (TRM_DebugMemoryInfo*)a2);
+				}
+			break;
+			}
+		case RRM_DebugDriver::EControlWriteMemory:
+			{
 			threadObj = DebugUtils::OpenThreadHandle((TUint32)a1);
 			if (threadObj)
-			{
-				err = DoResumeThread(threadObj);
-			}
-			break;
-		}
-		case RRM_DebugDriver::EControlStepRange:
-		{
-           threadObj = DebugUtils::OpenThreadHandle((TUint32)a1);
-           if (threadObj)
-           {
-   			err = StepRange(threadObj, (TRM_DebugStepInfo*)a2);
-           }
+				{
+				err = WriteMemory(threadObj, (TRM_DebugMemoryInfo*)a2);
+				}
 			break;
-		}
-		case RRM_DebugDriver::EControlReadMemory:
-		{
-           threadObj = DebugUtils::OpenThreadHandle((TUint32)a1);
-           if (threadObj)
-           {
-   			err = ReadMemory(threadObj, (TRM_DebugMemoryInfo*)a2);
-           }
-			break;
-		}
-		case RRM_DebugDriver::EControlWriteMemory:
-		{
-           threadObj = DebugUtils::OpenThreadHandle((TUint32)a1);
-           if (threadObj)
-           {
-   			err = WriteMemory(threadObj, (TRM_DebugMemoryInfo*)a2);
-           }
-			break;
-		}
+			}
 		case RRM_DebugDriver::EControlReadRegistersLegacy:
-		{
-           threadObj = DebugUtils::OpenThreadHandle((TUint32)a1);
-           if (threadObj)
-           {
-   			err = ReadRegistersLegacy(threadObj, (TRM_DebugRegisterInfo*)a2);
-           }
+			{
+			threadObj = DebugUtils::OpenThreadHandle((TUint32)a1);
+			if (threadObj)
+				{
+				err = ReadRegistersLegacy(threadObj, (TRM_DebugRegisterInfo*)a2);
+				}
 			break;
-		}
+			}
 		case RRM_DebugDriver::EControlWriteRegistersLegacy:
-		{
-           threadObj = DebugUtils::OpenThreadHandle((TUint32)a1);
-           if (threadObj)
-           {
-   			err = WriteRegistersLegacy(threadObj, (TRM_DebugRegisterInfo*)a2);
-           }
+			{
+			threadObj = DebugUtils::OpenThreadHandle((TUint32)a1);
+			if (threadObj)
+				{
+				err = WriteRegistersLegacy(threadObj, (TRM_DebugRegisterInfo*)a2);
+				}
 			break;
-		}
+			}
 		case RRM_DebugDriver::EControlReadRegisters:
-		{
-           threadObj = DebugUtils::OpenThreadHandle((TUint32)a1);
-           if (threadObj)
-           {
-   			err = ReadRegisters(threadObj, (TRM_DebugRegisterInformation*)a2);
-           }
+			{
+			threadObj = DebugUtils::OpenThreadHandle((TUint32)a1);
+			if (threadObj)
+				{
+				err = ReadRegisters(threadObj, (TRM_DebugRegisterInformation*)a2);
+				}
 			break;
-		}
+			}
 		case RRM_DebugDriver::EControlWriteRegisters:
-		{
-           threadObj = DebugUtils::OpenThreadHandle((TUint32)a1);
-           if (threadObj)
-           {
-   			err = WriteRegisters(threadObj, (TRM_DebugRegisterInformation*)a2);
-           }
+			{
+			threadObj = DebugUtils::OpenThreadHandle((TUint32)a1);
+			if (threadObj)
+				{
+				err = WriteRegisters(threadObj, (TRM_DebugRegisterInformation*)a2);
+				}
 			break;
-		}
+			}
 		case RRM_DebugDriver::EControlGetDebugFunctionalityBufSize:
-		{
+			{
 			LOG_MSG("RRM_DebugDriver::EControlGetDebugFunctionalityBufSize\n");
 
 			TDebugFunctionality df;
@@ -594,9 +617,9 @@
 			// Return size to user-side in a safe manner
 			err = Kern::ThreadRawWrite(iClientThread, a1, (TUint8*)&size, sizeof(TUint), iClientThread);
 			break;
-		}
+			}
 		case RRM_DebugDriver::EControlGetDebugFunctionality:
-		{
+			{
 			LOG_MSG("RRM_DebugDriver::EControlGetDebugFunctionality\n");
 
 			TDebugFunctionality df;
@@ -608,64 +631,64 @@
 			TUint8* dfbuffer = (TUint8*)Kern::AllocZ(dfsize);
 			NKern::ThreadLeaveCS();
 			if (dfbuffer==NULL)
-			{
+				{
 				LOG_MSG2("Could not allocate memory for %d bytes\n",dfsize);
 
 				// could not allocate memory
 				return KErrNoMemory;
-			}
+				}
 
 			// Temporary descriptor to hold DF data
 			TPtr8 tmpPtr(dfbuffer,0,dfsize);
 
 			// Obtain the DF data
 			if (df.GetDebugFunctionality(tmpPtr) )
-			{
+				{
 				// Return the DF data to the user-side
 				err = Kern::ThreadDesWrite(iClientThread, a1, tmpPtr, 0, KChunkShiftBy0, iClientThread);
-			}
+				}
 			else
-			{
+				{
 				// Failed.
 				err = KErrGeneral;
-			}
+				}
 
 			// Free tmp buffer
 			NKern::ThreadEnterCS();
 			Kern::Free(dfbuffer);
 			NKern::ThreadLeaveCS();
 			break;
-		}
+			}
 		case RRM_DebugDriver::EControlAttachProcess:
-		{
+			{
 			LOG_MSG("RRM_DebugDriver::EControlAttachProcess");
 
 			err = AttachProcess(a1,a2);
 			break;
-		}
+			}
 		case RRM_DebugDriver::EControlDetachProcess:
-		{
+			{
 			LOG_MSG("RRM_DebugDriver::EControlDetachProcess");
 
 			err = DetachProcess(a1,a2);
 			break;
-		}
+			}
 		case RRM_DebugDriver::EControlDetachAgent:
-		{
+			{
 			LOG_MSG("RRM_DebugDriver::EControlDetachAgent");
 
 			err = DetachAgent(a1,a2);
 			break;
-		}
+			}
 		case RRM_DebugDriver::EControlSetEventAction:
-		{
+			{
 			LOG_MSG("RRM_DebugDriver::EControlSetEventAction");
 
 			err = SetEventAction(a1,a2);
 			break;
-		}
+			}
 		case RRM_DebugDriver::EControlGetMemoryOperationMaxBlockSize:
-		{
+			{
 			LOG_MSG("RRM_DebugDriver::EControlGetMemoryOperationMaxBlockSize\n");
 
 			TUint32 maxSize = TDebugFunctionality::GetMemoryOperationMaxBlockSize();
@@ -673,95 +696,95 @@
 			// Return size to user-side in a safe manner
 			err = Kern::ThreadRawWrite(iClientThread, a1, (TUint8*)&maxSize, sizeof(TUint32), iClientThread);
 			break;
-		}
+			}
 		case RRM_DebugDriver::EControlGetList:
-		{
+			{
 			LOG_MSG("RRM_DebugDriver::EControlGetList\n");
 			err = GetList((TListInformation*)a1);
 			break;
-		}
+			}
 		case RRM_DebugDriver::EControlStep:
-		{
+			{
 			LOG_MSG("RRM_DebugDriver::EControlStep\n");
 
 			err = Step((TUint32)a1,(TUint32)a2);
 			break;
-		}
+			}
 		case RRM_DebugDriver::EControlKillProcess:
-		{
+			{
 			LOG_MSG("RRM_DebugDriver::EControlKillProcess\n");
 
 			err = KillProcess((TUint32)a1,(TUint32)a2);
 			break;
-		}
+			}
 		default:
-		{
+			{
 			err = KErrGeneral;
+			}
 		}
-	}
 
 	if (KErrNone != err)
-	{
+		{
 		LOG_MSG2("Error %d from control function", err);
-	}
-
-   if (threadObj)
-   {
-       // Close the thread handle which has been opened by DebugUtils::OpenThreadHandle
-       threadObj->Close(NULL);
-   }
+		}
+
+	if (threadObj)
+		{
+		// Close the thread handle which has been opened by DebugUtils::OpenThreadHandle
+		threadObj->Close(NULL);
+		}
 
 	return err;
-}
+	}
 
 void DRM_DebugChannel::HandleMsg(TMessageBase* aMsg)
-{
+	{
 	LOG_MSG("DRM_DebugChannel::HandleMsg()");
 
 	TThreadMessage& m = *(TThreadMessage*)aMsg;
 	TInt id = m.iValue;
 
 	if (id == (TInt)ECloseMsg)
-	{
+		{
 		if (iEventHandler)
-		{
+			{
 			iEventHandler->Stop();
 			iEventHandler->Close();
 			iEventHandler = NULL;
-		}
+			}
 		m.Complete(KErrNone, EFalse);
 		return;
-	}
+		}
 
 	if (id == KMaxTInt)
-	{
+		{
 		// DoCancel
 		DoCancel(m.Int0());
 		m.Complete(KErrNone, ETrue);
 		return;
-	}
+		}
 
 	if (id < 0)
-	{
+		{
 		// DoRequest
 		TRequestStatus* pStatus = (TRequestStatus*)m.Ptr0();
 		DoRequest(~id, pStatus, m.Ptr1(), m.Ptr2());
 		m.Complete(KErrNone, ETrue);
-	}
+		}
 	else
-	{
+		{
 		// DoControl
 		TInt err = DoControl(id, m.Ptr0(), m.Ptr1());
 		m.Complete(err, ETrue);
+		}
 	}
-}
 
 //
 // DRM_DebugChannel::RemoveProcess
 //
 TBool DRM_DebugChannel::RemoveProcess(TAny* a1, TAny* a2)
 	{
-	LOG_EVENT_MSG("DRM_DebugChannel::RemoveProcess()");
+	LOG_MSG("DRM_DebugChannel::RemoveProcess()");
 
 	DProcess *aProcess = (DProcess*)a1;
 
@@ -797,7 +820,6 @@
 			{
 			LOG_MSG2("Error in getting memory info: %d", err);
 			}
-
 		}
 
 	if (!codeAddress || !codeSize)
@@ -831,7 +853,7 @@
 // DRM_DebugChannel::StartThread
 //
 TBool DRM_DebugChannel::StartThread(TAny* a1, TAny* a2)
-{
+	{
 	LOG_EVENT_MSG("DRM_DebugChannel::StartThread()");
 
 	DThread *aThread = (DThread*)a1;
@@ -881,13 +903,13 @@
 			}
 		}
 	return EFalse;
-}
+	}
 
 //
 // DRM_DebugChannel::HandleAddProcessEvent
 //
 TBool DRM_DebugChannel::HandleAddProcessEvent(TAny* a1, TAny* a2)
-{
+	{
 	LOG_EVENT_MSG("DRM_DebugChannel::AddProcess()");
 
 	DProcess *aProcess = (DProcess*)a1;
@@ -905,7 +927,7 @@
 	info.iEventType = EEventsAddProcess;
 	info.iProcessId = aProcess->iId;
 
-    info.iCreatorThreadId  = aThread ? aThread->iId : 0;
+	info.iCreatorThreadId  = aThread ? aThread->iId : 0;
 	info.iProcessIdValid = ETrue;
 
 	// Copy TUids
@@ -945,13 +967,13 @@
 		}
 
 	return EFalse;
-}
+	}
 
 //
 // DRM_DebugChannel::HandleRemoveProcessEvent
 //
 TBool DRM_DebugChannel::HandleRemoveProcessEvent(TAny* a1, TAny* a2)
-{
+	{
 	LOG_EVENT_MSG("DRM_DebugChannel::RemoveProcess()");
 
 	DProcess *aProcess = (DProcess*)a1;
@@ -1004,13 +1026,13 @@
 		}
 
 	return EFalse;
-}
+	}
 
 //
 // DRM_DebugChannel::AddLibrary
 //
 TBool DRM_DebugChannel::AddLibrary(TAny* a1, TAny* a2)
-{
+	{
 	LOG_EVENT_MSG("DRM_DebugChannel::AddLibrary()");
 
 	DLibrary *aLibrary = (DLibrary*)a1;
@@ -1018,24 +1040,24 @@
 
 	// sanity check
 	if (!aLibrary)
-	{
+		{
 		LOG_EVENT_MSG("DRM_DebugChannel::AddLibrary called with no library specified");
 		return EFalse;
-	}
+		}
 
 	if (!aThread)
-	{
+		{
 		LOG_EVENT_MSG("DRM_DebugChannel::AddLibrary called with no thread specified");
 		return EFalse;
-	}
+		}
 
 	LOG_EVENT_MSG2(("Lib loaded: %S"), aLibrary->iName);
 
 	if (aThread)
-	{
+		{
 		// make sure this is not the debugger thread
 		if ((aThread != iClientThread) && (aThread->iOwningProcess->iId != iClientThread->iOwningProcess->iId))
-		{
+			{
 			TDriverEventInfo info;
 
 			info.iEventType = EEventsAddLibrary;
@@ -1047,10 +1069,10 @@
 			//get the code address
 			DCodeSeg* codeSeg = aLibrary->iCodeSeg;
 			if (!codeSeg)
-			{
+				{
 				LOG_EVENT_MSG2("Code segment not available for library %S", aLibrary->iName);
 				return EFalse;
-			}
+				}
 
 			// Uid3
 			info.iUids = codeSeg->iUids;
@@ -1059,10 +1081,10 @@
 			TModuleMemoryInfo memoryInfo;
 			TInt err = codeSeg->GetMemoryInfo(memoryInfo, NULL); //NULL for DProcess should be ok;
 			if (err != KErrNone)
-			{
+				{
 				LOG_EVENT_MSG2("Error in getting memory info: %d", err);
 				return EFalse;
-			}
+				}
 
 			info.iCodeAddress = memoryInfo.iCodeBase;
 			info.iDataAddress = memoryInfo.iInitialisedDataBase;
@@ -1073,11 +1095,11 @@
 			info.iArg1 = a1;
 			info.iArg2 = a2;
 			NotifyEvent(info);
+			}
+
 		}
-
+	return EFalse;
 	}
-	return EFalse;
-}
 
 //
 // DRM_DebugChannel::RemoveLibrary
@@ -1164,16 +1186,17 @@
 // DRM_DebugChannel::HandleEventKillThread
 //
 TBool DRM_DebugChannel::HandleEventKillThread(TAny* a1, TAny* a2)
-{
-	LOG_EVENT_MSG("DRM_DebugChannel::HandleEventKillThread");
+	{
+
+	LOG_MSG2("DRM_DebugChannel::HandleEventKillThread(Thread a1=0x%08x)", a1 );
 
 	DThread* currentThread = &Kern::CurrentThread();
 	if (!currentThread)
-	{
+		{
 		LOG_MSG("Error getting current thread");
 		__NK_ASSERT_DEBUG(currentThread);
 		return EFalse;
-	}
+		}
 
 	// a1 should point to the current thread, check this to make sure it does
 	__NK_ASSERT_DEBUG((DThread*)a1 == currentThread);
@@ -1187,14 +1210,14 @@
 	// 14 should probably be replaced by PC_REGISTER, for some reason PC_REGISTER had been replaced with 14 in the code
 	TInt err = ReadKernelRegisterValue(currentThread, 14, info.iCurrentPC);
 	if(err != KErrNone)
-	{
+		{
 		LOG_EVENT_MSG2("DRM_DebugChannel::HandleEventKillThread - Non-zero error code discarded: %d", err);
-	}
+		}
 
 	if (currentThread->iExitType == EExitPanic)
-	{
+		{
 		info.iPanicCategory.Copy(currentThread->iExitCategory);
-	}
+		}
 	info.iExceptionNumber = currentThread->iExitReason;
 	info.iExitType = currentThread->iExitType;
 	info.iEventType = EEventsKillThread;
@@ -1226,13 +1249,13 @@
 	NotifyEvent(info);
 
 	return ETrue;
-}
+	}
 
 //
 // DRM_DebugChannel::HandleSwException
 //
 TBool DRM_DebugChannel::HandleSwException(TAny* a1, TAny* a2)
-{
+	{
 	LOG_EVENT_MSG("DRM_DebugChannel::HandleSwException");
 	TExcType aExcType = (TExcType)(TInt)a1;
 
@@ -1240,11 +1263,11 @@
 
 	DThread* currentThread = &Kern::CurrentThread();
 	if (!currentThread)
-	{
+		{
 		LOG_MSG("Error getting current thread");
 		__NK_ASSERT_DEBUG(currentThread);
 		return EFalse;
-	}
+		}
 
 	info.iProcessId = currentThread->iOwningProcess->iId;
 	info.iProcessIdValid = ETrue;
@@ -1252,9 +1275,9 @@
 	info.iThreadIdValid = ETrue;
 	TInt err = ReadKernelRegisterValue(currentThread, PC_REGISTER, info.iCurrentPC);
 	if(err != KErrNone)
-	{
+		{
 		LOG_EVENT_MSG2("DRM_DebugChannel::HandleSwException - Non-zero error code discarded: %d", err);
-	}
+		}
 	info.iExceptionNumber = aExcType;
 	info.iEventType = EEventsSwExc;
 	info.iArg1 = a1;
@@ -1263,35 +1286,33 @@
 	NotifyEvent(info);
 
 	return EFalse;
-}
+	}
 
 //
 // DRM_DebugChannel::HandleHwException
 //
 TBool DRM_DebugChannel::HandleHwException(TAny* a1, TAny* a2)
-{
-	LOG_EVENT_MSG("DRM_DebugChannel::HandleHwException()");
+	{
 	TArmExcInfo* aExcInfo = (TArmExcInfo*)a1;
 
 	// sanity check
 	if (!aExcInfo)
-	{
+		{
 		LOG_MSG("DRM_DebugChannel::HandleHwException called with no aExcInfo");
 		__NK_ASSERT_DEBUG(aExcInfo);
 		return EFalse;
-	}
+		}
 
 	TDriverEventInfo info;
 
 	DThread* currentThread = &Kern::CurrentThread();
-	LOG_EVENT_MSG2("DRM_DebugChannel::HandleHwException current thread = 0x%x", currentThread);
 
 	if (!currentThread)
-	{
+		{
 		LOG_MSG("Error getting current thread");
 		__NK_ASSERT_DEBUG(currentThread);
 		return EFalse;
-	}
+		}
 
 	info.iProcessId = currentThread->iOwningProcess->iId;
 	info.iProcessIdValid = ETrue;
@@ -1299,8 +1320,10 @@
 	info.iThreadIdValid = ETrue;
 	info.iRmdArmExcInfo.iFaultAddress= aExcInfo->iFaultAddress;
 	info.iRmdArmExcInfo.iFaultStatus= aExcInfo->iFaultStatus;
-	LOG_EVENT_MSG3("DRM_DebugChannel::HandleHwException iFaultAddress=0x%x, iFaultStatus=0x%x",
-			aExcInfo->iFaultAddress, aExcInfo->iFaultStatus);
+
+	LOG_MSG5("DRM_DebugChannel::HandleHwException current thread = 0x%08x, CritSect count=%d,\n"
+		" iFaultAddress=0x%08x, iFaultStatus=0x%08x",
+		currentThread, currentThread->iNThread.iCsCount, aExcInfo->iFaultAddress, aExcInfo->iFaultStatus);
 
 	info.iRmdArmExcInfo.iR0= aExcInfo->iR0;
 	info.iRmdArmExcInfo.iR1= aExcInfo->iR1;
@@ -1320,18 +1343,16 @@
 	info.iRmdArmExcInfo.iR13= aExcInfo->iR13;
 	info.iRmdArmExcInfo.iR14= aExcInfo->iR14;
 	info.iRmdArmExcInfo.iR15= aExcInfo->iR15;
-	LOG_EVENT_MSG5(" R12=0x%x, R13=0x%x, R14=0x%x, R15=0x%x ",
-			aExcInfo->iR12, aExcInfo->iR13, aExcInfo->iR14, aExcInfo->iR15);
 
 	info.iRmdArmExcInfo.iCpsr= aExcInfo->iCpsr;
 	info.iRmdArmExcInfo.iR13Svc= aExcInfo->iR13Svc;
 	info.iRmdArmExcInfo.iR14Svc= aExcInfo->iR14Svc;
 	info.iRmdArmExcInfo.iSpsrSvc= aExcInfo->iSpsrSvc;
-	LOG_EVENT_MSG5(" iCpsr=0x%x, iR13Svc=0x%x, iR14Svc=0x%x, iSpsrSvc=0x%x ",
-			aExcInfo->iCpsr, aExcInfo->iR13Svc, aExcInfo->iR14Svc, aExcInfo->iSpsrSvc);
+	LOG_MSG5(" iCpsr=0x%x, iExcCode=0x%x, R14=0x%x, R15=0x%x",
+			aExcInfo->iCpsr, aExcInfo->iExcCode, aExcInfo->iR14, aExcInfo->iR15);
 
 	switch (aExcInfo->iExcCode)
-	{
+		{
 		case 0:
 			info.iExceptionNumber = EExcCodeAbort;
 			LOG_EVENT_MSG(" iExcCode == 0 => EExcCodeAbort");
@@ -1348,8 +1369,8 @@
 			// new event? Something gone wrong?
 			__NK_ASSERT_DEBUG(EFalse);
 			return EFalse;
-
-	}
+		}
+
 	info.iEventType = EEventsHwExc;
 
 	info.iArg1 = a1;
@@ -1362,22 +1383,22 @@
 
 	NotifyEvent(info);
 	return EFalse;
-}
+	}
 
 //
 // DRM_DebugChannel::HandUserTrace
 //
 TBool DRM_DebugChannel::HandleUserTrace(TAny* a1, TAny* a2)
-{
+	{
 	LOG_EVENT_MSG("DRM_DebugChannel::HandleUserTrace()");
 
 	DThread* currentThread = &Kern::CurrentThread();
 	if (!currentThread)
-	{
+		{
 		LOG_EVENT_MSG("Error getting current thread");
 		__NK_ASSERT_DEBUG(currentThread);
 		return EFalse;
-	}
+		}
 
 	TDriverEventInfo info;
 	info.iProcessId = currentThread->iOwningProcess->iId;
@@ -1402,13 +1423,13 @@
 	NotifyEvent(info);
 
 	return EFalse;
-}
+	}
 
 //
 // DRM_DebugChannel::HandleException
 //
 TBool DRM_DebugChannel::HandleInvalidOpCodeException(TDriverEventInfo& aEventInfo, DThread* aCurrentThread)
-{
+	{
 	LOG_EVENT_MSG("DRM_DebugChannel::HandleInvalidOpCodeException()");
 
 	TInt err = KErrNone;
@@ -1420,37 +1441,38 @@
 	TUint32 regValue;
 	err = ReadKernelRegisterValue(aCurrentThread, STATUS_REGISTER, regValue);
 	if(err != KErrNone)
-	{
+		{
 		LOG_EVENT_MSG2("DRM_DebugChannel::HandleInvalidOpCodeException - Non-zero error code discarded: %d", err);
-	}
+		}
+
 	if (regValue & ECpuThumb)
-	{
+		{
 		inst = KThumbBreakPoint;
 		instSize = 2;
-	}
+		}
 
 	TUint32 instruction = 0;
 	err = Kern::ThreadRawRead(aCurrentThread, (TUint32 *)aEventInfo.iRmdArmExcInfo.iR15, (TUint8 *)&instruction, instSize);
 
 	if (KErrNone != err)
-		LOG_EVENT_MSG2("Error reading instruction at currentpc: %d", err);
+		LOG_MSG2("Error reading instruction at currentpc: %d", err);
 
 	if (!memcompare((TUint8 *)&inst, instSize, (TUint8 *)&instruction, instSize))
-	{
+		{
 		TInt err = DoSuspendThread(aCurrentThread);
 		if(! ((KErrNone == err) || (KErrAlreadyExists == err)) )
 			{
-			LOG_EVENT_MSG2("DRM_DebugChannel::HandleInvalidOpCodeException() Thread with id 0x%08x could not be suspended.", aCurrentThread->iId);
+			LOG_MSG2("DRM_DebugChannel::HandleInvalidOpCodeException() Thread with id 0x%08x could not be suspended.", aCurrentThread->iId);
 			return EFalse;
 			}
 
 		// the exception was a breakpoint instruction.  see if we have a breakpoint at that address
 		TBreakEntry* breakEntry = NULL;
 		do
-		{
+			{
 			breakEntry = iBreakManager->GetNextBreak(breakEntry);
 			if (breakEntry && ((breakEntry->iThreadSpecific && breakEntry->iId == aEventInfo.iThreadId) || (!breakEntry->iThreadSpecific && breakEntry->iId == aEventInfo.iProcessId)) && breakEntry->iAddress == aEventInfo.iRmdArmExcInfo.iR15)
-			{
+				{
 				LOG_EVENT_MSG2("Breakpoint with Id %d has been hit", breakEntry->iBreakId);
 
 				TBreakEntry tempBreakEntry = *breakEntry;
@@ -1465,7 +1487,7 @@
 
 				// see if this is a temp breakpoint
 				if (iBreakManager->IsTemporaryBreak(*breakEntry))
-				{
+					{
 					// this was a temp breakpoint, so we need to clear it now
 					err = iBreakManager->DoClearBreak(breakEntry->iBreakId);
 					if (KErrNone != err)
@@ -1480,32 +1502,32 @@
 
 					// New. If we have not finished do all the steps, continue stepping and don't notify event
 					if (tempBreakEntry.iNumSteps)
-					{
+						{
 						LOG_EVENT_MSG("Continuing stepping...not telling the agent yet\n");
 						err = DoStepRange(aCurrentThread, aEventInfo.iRmdArmExcInfo.iR15, aEventInfo.iRmdArmExcInfo.iR15, ETrue, tempBreakEntry.iResumeOnceOutOfRange /*EFalse*/, tempBreakEntry.iNumSteps, ETrue);
 						if (err != KErrNone)
-						{
+							{
 							LOG_EVENT_MSG("Failed to continue stepping\n");
 
 							// what do we do? might as well stop here and tell the user
 							NotifyEvent(aEventInfo);
 
 							return ETrue;
-						}
+							}
 
 						// continue as though no event occured. No need to suspend/resume anything...
 						LOG_EVENT_MSG("Continuing to step\n");
 						return ETrue;
-					}
+						}
 
 					// Is this a case where we just want to continue?
 					if (tempBreakEntry.iResumeOnceOutOfRange)
-					{
-					LOG_EVENT_MSG("PC is out of range, continuing thread");
+						{
+						LOG_EVENT_MSG("PC is out of range, continuing thread");
 						DoResumeThread(aCurrentThread);
 
 						return ETrue;
-    					}
+						}
 					}
 
 				// if the breakpoint is thread specific, make sure it's the right thread
@@ -1517,49 +1539,49 @@
 					(!tempBreakEntry.iThreadSpecific && tempBreakEntry.iId != aEventInfo.iProcessId);
 
 				if (needToResume)
-				{
+					{
 					LOG_EVENT_MSG("breakpoint does not match threadId, calling DoResumeThread");
 					err = DoResumeThread(aCurrentThread);
 					if (KErrNone != err)
-						LOG_EVENT_MSG2("Error in DoResumeThread: %d", err);
+						LOG_MSG2("Error in DoResumeThread: %d", err);
 
 					return EFalse;
-				}
+					}
 
 				//normal user break point, just notify the event
 				break;
-			}
-		} while(breakEntry);
-	}
+				}
+			} while(breakEntry);
+		}
 
 	NotifyEvent(aEventInfo);
 
 	return (aEventInfo.iEventType == EEventsBreakPoint) || (aEventInfo.iEventType == EEventsProcessBreakPoint);
-}
+	}
 
 //
 // DRM_DebugChannel::SetBreak
 //
 TInt DRM_DebugChannel::SetBreak(TSetBreakInfo* aBreakInfo)
-{
+	{
 	LOG_MSG("DRM_DebugChannel::SetBreak()");
 
 	TInt err = KErrNone;
 
 	if (!aBreakInfo)
-	{
+		{
 		LOG_MSG("DRM_DebugChannel::SetBreak() was passed a NULL argument");
 		return KErrArgument;
-	}
+		}
 
 	//User side memory is not accessible directly
 	TSetBreakInfo info;
 	err = Kern::ThreadRawRead(iClientThread, aBreakInfo, (TUint8*)&info, sizeof(TSetBreakInfo));
 	if (err != KErrNone)
-	{
+		{
 		LOG_MSG("DRM_DebugChannel::SetBreak() was passed a bad argument");
 		return err;
-	}
+		}
 
 	DProcess* process = NULL;
 	if(info.iThreadSpecific)
@@ -1583,11 +1605,13 @@
 		{
 		process = DebugUtils::OpenProcessHandle(info.iId);
 		}
+
 	if(!process)
 		{
 		LOG_MSG2("DRM_DebugChannel::SetBreak() Process with id 0x%08x not found", process->iId);
 		return KErrNotFound;
 		}
+
 	TBool found = EFalse;
 	for(TInt i=0; i<iDebugProcessList.Count(); i++)
 		{
@@ -1596,6 +1620,7 @@
 			found = ETrue;
 			}
 		}
+
 	if(!found)
 		{
 		DCodeSeg* codeSeg = process->iCodeSeg;
@@ -1623,24 +1648,25 @@
 		return KErrArgument;
 
 	if (err == KErrNone)
-	{
+		{
 		TInt32 iBreakId;
 
 		err = iBreakManager->DoSetBreak(iBreakId, info.iId, info.iThreadSpecific, info.iAddress, info.iMode );
 
 		if (err == KErrNone)
-		{
+			{
 			err = Kern::ThreadRawWrite(iClientThread, (TUint8 *)info.iBreakId, &iBreakId, sizeof(TInt32), iClientThread);
+			}
 		}
-	}
+
 	return err;
-}
+	}
 
 //
 // DRM_DebugChannel::StepRange
 //
 TInt DRM_DebugChannel::StepRange(DThread* aThread, TRM_DebugStepInfo* aStepInfo)
-{
+	{
 	LOG_MSG("DRM_DebugChannel::StepRange()");
 
 	TInt err = KErrNone;
@@ -1663,7 +1689,7 @@
 	err = DoStepRange(aThread, info.iStartAddress, info.iStopAddress, info.iStepInto, EFalse, ETrue);
 
 	return err;
-}
+	}
 
 /**
 Read memory from a target thread and return the data to the client. If the
@@ -1680,7 +1706,7 @@
         or another of the system wide error codes
 */
 TInt DRM_DebugChannel::ReadMemory(DThread* aThread, TRM_DebugMemoryInfo* aMemoryInfo)
-{
+	{
 	LOG_MSG("DRM_DebugChannel::ReadMemory()");
 
 	TInt err = KErrNone;
@@ -1700,9 +1726,9 @@
 	TUint8 *data = (TUint8*)Kern::Alloc(info.iLength);
 	NKern::ThreadLeaveCS();
 	if (!data)
-	{
+		{
 		return KErrNoMemory;
-	}
+		}
 
 	TPtr8 dataDes(data, info.iLength);
 
@@ -1717,7 +1743,7 @@
 	NKern::ThreadLeaveCS();
 
 	return err;
-}
+	}
 
 /**
 Attempt to write memory to aThread's address space
@@ -1734,7 +1760,7 @@
 	or another of the system wide error codes
 */
 TInt DRM_DebugChannel::WriteMemory(DThread* aThread, TRM_DebugMemoryInfo* aMemoryInfo)
-{
+	{
 	LOG_MSG("DRM_DebugChannel::WriteMemory()");
 
 	TInt err = KErrNone;
@@ -1754,30 +1780,30 @@
 	TUint8 *data = (TUint8*)Kern::Alloc(info.iLength);
 	NKern::ThreadLeaveCS();
 	if (!data)
-	{
+		{
 		return KErrNoMemory;
-	}
+		}
 
 	TPtr8 dataDes(data, info.iLength);
 
 	err = Kern::ThreadDesRead(iClientThread, info.iData, dataDes, 0);
 	if (err == KErrNone)
-	{
+		{
 		err = DoWriteMemory(aThread, info.iAddress, info.iLength, dataDes);
-	}
+		}
 
 	NKern::ThreadEnterCS();
 	Kern::Free(data);
 	NKern::ThreadLeaveCS();
 
 	return err;
-}
+	}
 
 //
 // DRM_DebugChannel::ReadRegisters
 //
 TInt DRM_DebugChannel::ReadRegistersLegacy(DThread* aThread, TRM_DebugRegisterInfo* aRegisterInfo)
-{
+	{
 	LOG_MSG("DRM_DebugChannel::ReadRegistersLegacy()");
 
 	TInt err = KErrNone;
@@ -1799,24 +1825,24 @@
 	TUint8 *values = (TUint8*)Kern::Alloc(length);
 	NKern::ThreadLeaveCS();
 	if (!values)
-	{
+		{
 		return KErrNoMemory;
-	}
+		}
 
 	TPtr8 valuesDes(values, length);
 
 	err = DoReadRegisters(aThread, info.iFirstRegister, info.iLastRegister, valuesDes);
 	if (err == KErrNone)
-	{
+		{
 		err = Kern::ThreadDesWrite(iClientThread, info.iValues, valuesDes, 0, KChunkShiftBy0, iClientThread);
-	}
+		}
 
 	NKern::ThreadEnterCS();
 	Kern::Free(values);
 	NKern::ThreadLeaveCS();
 
 	return err;
-}
+	}
 
 /**
 Get listing information.
@@ -1922,6 +1948,7 @@
 		//if no error then write the buffer back
 		err = Kern::ThreadDesWrite(iClientThread, info.iBuffer, buffer, 0, KChunkShiftBy0, iClientThread);
 		}
+
 	//write back the size of the data regardless of any error
 	TInt writeErr = Kern::ThreadRawWrite(iClientThread, info.iDataSize, (TUint8*)&dataSize, sizeof(TUint32), iClientThread);
 	if(writeErr != KErrNone)
@@ -1956,7 +1983,7 @@
         KErrDied, if the thread with thread ID aThreadId is dead
 */
 TInt DRM_DebugChannel::ReadRegisters(DThread* aThread, TRM_DebugRegisterInformation* aRegisterInfo) const
-{
+	{
 	LOG_MSG("DRM_DebugChannel::ReadRegisters()");
 
 	TInt err = KErrNone;
@@ -1978,11 +2005,11 @@
 	if(err != KErrNone)
 		{
 		if(err == KErrNoMemory)
-		{
+			{
 			NKern::ThreadEnterCS();
 			Kern::Free((TAny*)ids.Ptr());
 			NKern::ThreadLeaveCS();
-		}
+			}
 		return err;
 		}
 
@@ -1992,10 +2019,12 @@
 	if(err != KErrNone)
 		{
 		if(err == KErrNoMemory)
-		{	NKern::ThreadEnterCS();
+			{
+			NKern::ThreadEnterCS();
 			Kern::Free((TAny*)values.Ptr());
 			NKern::ThreadLeaveCS();
-		}
+			}
+
 		NKern::ThreadEnterCS();
 		Kern::Free((TAny*)ids.Ptr());
 		NKern::ThreadLeaveCS();
@@ -2008,11 +2037,11 @@
 	if(err != KErrNone)
 		{
 		if(err == KErrNoMemory)
-		{
+			{
 			NKern::ThreadEnterCS();
 			Kern::Free((TAny*)flags.Ptr());
 			NKern::ThreadLeaveCS();
-		}
+			}
 		NKern::ThreadEnterCS();
 		Kern::Free((TAny*)ids.Ptr());
 		Kern::Free((TAny*)values.Ptr());
@@ -2037,13 +2066,13 @@
 	NKern::ThreadLeaveCS();
 
 	return err;
-}
+	}
 
 /**
 @deprecated use DRM_DebugChannel::WriteRegisters(DThread* aThread, TRM_DebugRegisterInformation* aRegisterInfo) instead
 */
 TInt DRM_DebugChannel::WriteRegistersLegacy(DThread* aThread, const TRM_DebugRegisterInfo* aRegisterInfo)
-{
+	{
 	LOG_MSG("DRM_DebugChannel::WriteRegistersLegacy()");
 
 	TInt err = KErrNone;
@@ -2065,24 +2094,24 @@
 	TUint8 *values = (TUint8*)Kern::Alloc(length);
 	NKern::ThreadLeaveCS();
 	if (!values)
-	{
+		{
 		return KErrNoMemory;
-	}
+		}
 
 	TPtr8 valuesDes(values, length);
 
 	err = Kern::ThreadDesRead(iClientThread, info.iValues, valuesDes, 0);
 	if (err == KErrNone)
-	{
+		{
 		err = DoWriteRegisters(aThread, info.iFirstRegister, info.iLastRegister, valuesDes);
-	}
+		}
 
 	NKern::ThreadEnterCS();
 	Kern::Free(values);
 	NKern::ThreadLeaveCS();
 
 	return err;
-}
+	}
 
 /**
 Write registers and store flags data in aRegisterInfo
@@ -2103,7 +2132,7 @@
         KErrDied, if the thread with thread ID aThreadId is dead
 */
 TInt DRM_DebugChannel::WriteRegisters(DThread* aThread, TRM_DebugRegisterInformation* aRegisterInfo) const
-{
+	{
 	LOG_MSG("DRM_DebugChannel::WriteRegisters()");
 
 	TInt err = KErrNone;
@@ -2181,7 +2210,7 @@
 	NKern::ThreadLeaveCS();
 
 	return err;
-}
+	}
 
 /**
 Suspends execution of the specified thread.
@@ -2239,6 +2268,7 @@
 				}
 			}
 		} while(breakEntry);
+
 	return TheDProcessTracker.ResumeThread(aThread);
 	}
 
@@ -2246,7 +2276,7 @@
 // DRM_DebugChannel::DoStepRange
 //
 TInt DRM_DebugChannel::DoStepRange(DThread *aThread, const TUint32 aStartAddress, const TUint32 aStopAddress, TBool aStepInto, TBool aResumeOnceOutOfRange, const TUint32 aNumSteps, TBool aUserRequest)
-{
+	{
 	LOG_MSG("DRM_DebugChannel::DoStepRange()");
 
 	if (!aThread)
@@ -2285,7 +2315,7 @@
 	LOG_MSG("DRM_DebugChannel::DoStepRange() - resuming thread\n");
 
 	return TheDProcessTracker.ResumeThread(aThread);
-}
+	}
 
 /**
 Read memory from the specified addres into the aData descriptor. If there is a
@@ -2382,7 +2412,7 @@
 	TInt err = KErrNone;
 
 	// trap exceptions in case the address is invalid
-	XTRAPD(r, XT_DEFAULT,  err = TryToWriteMemory(aThread, (TAny *)aAddress, (TAny *)aData.Ptr(), aLength));
+	XTRAPD(r, XT_DEFAULT, err = TryToWriteMemory(aThread, (TAny *)aAddress, (TAny *)aData.Ptr(), aLength));
 
 	err = (KErrNone == r) ? err : r;
 
@@ -2436,8 +2466,8 @@
 // DRM_DebugChannel::DoReadRegisters
 //
 TInt DRM_DebugChannel::DoReadRegisters(DThread *aThread, const TInt16 aFirstRegister, const TInt16 aLastRegister, TDes8 &aValues)
-{
-	LOG_MSG("DRM_DebugChannel::DoReadRegisters()");
+	{
+	LOG_EVENT_MSG("DRM_DebugChannel::DoReadRegisters()");
 
 	// make sure the parameters are valid
 	if (!aThread || (aFirstRegister < 0) || (aLastRegister >= (TInt16)(sizeof(TArmRegSet)/sizeof(TArmReg))))
@@ -2448,19 +2478,19 @@
 		return KErrArgument;
 
 	TArmRegSet regSet;
-    TUint32 unused;
+	TUint32 unused;
 
 	NKern::ThreadGetUserContext(&aThread->iNThread, &regSet, unused);
 
 	LOG_MSG2( "DRM_DebugChannel::DoReadRegistersLegacy() : unused = 0x%X\n", unused );
 
-    TArmReg *reg = &regSet.iR0;
+	TArmReg *reg = &regSet.iR0;
 
 	if (!reg)
 		return KErrGeneral;
 
-    for (TInt16 i = aFirstRegister; i <= aLastRegister; i++)
-    	aValues.Append((TUint8 *)&reg[i], sizeof(TArmReg));
+	for (TInt16 i = aFirstRegister; i <= aLastRegister; i++)
+		aValues.Append((TUint8 *)&reg[i], sizeof(TArmReg));
 
 	return KErrNone;
 }
@@ -2510,7 +2540,7 @@
         KErrGeneral if there was a problem initialising the register set
 */
 TInt DRM_DebugChannel::DoReadRegisters(DThread *aThread, const TDesC8 &aRegisterIds, TDes8 &aRegisterValues, TDes8& aRegisterFlags) const
-{
+	{
 	LOG_MSG("DRM_DebugChannel::DoReadRegisters()");
 
 	// make sure the parameters are valid
@@ -2613,13 +2643,13 @@
 			}
 		}
 	return KErrNone;
-}
+	}
 
 //
 // DRM_DebugChannel::DoWriteRegisters
 //
 TInt DRM_DebugChannel::DoWriteRegisters(DThread *aThread, const TInt16 aFirstRegister, const TInt16 aLastRegister, TDesC8 &aValues)
-{
+	{
 	LOG_MSG("DRM_DebugChannel::DoWriteRegisters()");
 
 	// make sure the parameters are valid
@@ -2643,7 +2673,7 @@
 	NKern::ThreadSetUserContext(&aThread->iNThread, &regSet);
 
 	return KErrNone;
-}
+	}
 
 /**
 Write registers and store flags indicating which registers could be read in
@@ -2662,7 +2692,7 @@
         KErrGeneral if there was a problem initialising the register set
 */
 TInt DRM_DebugChannel::DoWriteRegisters(DThread *aThread, const TDesC8 &aRegisterIds, TDesC8 &aRegisterValues, TDes8 &aRegisterFlags) const
-{
+	{
 	LOG_MSG("DRM_DebugChannel::DoWriteRegisters()");
 
 	// make sure the parameters are valid
@@ -2765,23 +2795,23 @@
 // DRM_DebugChannel::DoSecurityCheck
 //
 TBool DRM_DebugChannel::DoSecurityCheck()
-{
+	{
 	LOG_MSG("DRM_DebugChannel::DoSecurityCheck");
 	DProcess* clientProcess = iClientThread->iOwningProcess;
 	if (clientProcess)
-	{
+		{
 		SSecurityInfo secureInfo = clientProcess->iS;
 
 		LOG_MSG2("DoSecurityCheck - client secure id is 0x%08x",secureInfo.iSecureId);
 
 		// Ensure we really are communicating with the Debug Security Server
 		if (secureInfo.iSecureId == KUidDebugSecurityServer.iUid )
-		{
+			{
 			return ETrue;
+			}
 		}
+	return EFalse;
 	}
-	return EFalse;
-}
 
 /**
 Attempt to read memory from aThread's address space
@@ -2795,7 +2825,7 @@
 	or another of the system wide error codes
 */
 TInt DRM_DebugChannel::TryToReadMemory(const DThread *aThread, const TAny *aSrc, TAny *aDest, const TUint32 aLength) const
-{
+	{
 	LOG_MSG("DRM_DebugChannel::TryToReadMemory()");
 
 	// make sure the parameters are valid
@@ -2814,7 +2844,7 @@
 
 	LOG_MSG2("Using Kern::ThreadRawRead to read memory at address %x", aSrc);
 	return Kern::ThreadRawRead((DThread *)aThread, aSrc, aDest, aLength);
-}
+	}
 
 /**
 Attempt to write memory to aThread's address space
@@ -2828,7 +2858,7 @@
         error codes
 */
 TInt DRM_DebugChannel::TryToWriteMemory(const DThread *aThread, TAny *aDest, const TAny *aSrc, const TUint32 aLength)
-{
+	{
 	LOG_MSG("DRM_DebugChannel::TryToWriteMemory()");
 
 	//check that the thread is suspended before writing the memory
@@ -2840,30 +2870,30 @@
 
 	LOG_MSG2("Using Kern::ThreadRawWrite to write memory at address %x", (TUint32)aDest);
 	return Kern::ThreadRawWrite((DThread *)aThread, aDest, aSrc, aLength, iClientThread);
-}
+	}
 
 /**
 @deprecated use DRM_DebugChannel::ReadKernelRegisterValue(DThread *aThread, const TArmReg aKernelRegisterId, T4ByteRegisterValue &aValue) instead
 */
 TInt32 DRM_DebugChannel::ReadRegister(DThread *aThread, TInt aNum)
-{
+	{
 	LOG_MSG("DRM_DebugChannel::ReadRegister()");
 
 	if (!aThread || (aNum < 0) || (aNum >= (TInt16)(sizeof(TArmRegSet)/sizeof(TArmReg))))
-	{
+		{
 		LOG_MSG2("Invalid register number (%d) passed to ReadRegister", aNum);
 		return 0;
-	}
+		}
 
 	TArmRegSet regSet;
-    TUint32 unused;
+	TUint32 unused;
 
 	NKern::ThreadGetUserContext(&aThread->iNThread, &regSet, unused);
 
-    TArmReg *reg = &regSet.iR0;
+	TArmReg *reg = &regSet.iR0;
 
 	return ((TUint32 *)reg)[aNum];
-}
+	}
 
 /**
 Given a TArmReg register ID, read the value of the register. The register value
@@ -2879,7 +2909,7 @@
         or a return value from DRM_DebugChannel::ReadDebugRegisterValue()
 */
 TInt32 DRM_DebugChannel::ReadKernelRegisterValue(DThread *aThread, const TArmReg aKernelRegisterId, T4ByteRegisterValue &aValue) const
-{
+	{
 	//get register ID as a TRegisterInfo ID
 	TRegisterInfo regId;
 	TInt err = GetDebugRegisterId(aKernelRegisterId, regId);
@@ -2906,33 +2936,34 @@
         or a return value from DRM_DebugChannel::DoReadRegisters
 */
 TInt32 DRM_DebugChannel::ReadDebugRegisterValue(DThread *aThread, const TRegisterInfo aDebugRegisterId, T4ByteRegisterValue &aValue) const
-{
+	{
 	//allocate temporary buffers to store data
 	NKern::ThreadEnterCS();
 	TUint8* id = (TUint8*)Kern::Alloc(sizeof(TRegisterInfo));
 	NKern::ThreadLeaveCS();
 	if(id == NULL)
-	{
+		{
 		return KErrNoMemory;
-	}
+		}
+
 	TPtr8 idPtr(id, sizeof(TRegisterInfo));
 
 	NKern::ThreadEnterCS();
 	TUint8* value = (TUint8*)Kern::Alloc(sizeof(T4ByteRegisterValue));
 	NKern::ThreadLeaveCS();
 	if(value == NULL)
-	{
+		{
 		return KErrNoMemory;
-	}
+		}
 	TPtr8 valuePtr(value, sizeof(T4ByteRegisterValue));
 
 	NKern::ThreadEnterCS();
 	TUint8* flag = (TUint8*)Kern::Alloc(sizeof(TUint8));
 	NKern::ThreadLeaveCS();
 	if(flag == NULL)
-	{
+		{
 		return KErrNoMemory;
-	}
+		}
 	TPtr8 flagPtr(flag, sizeof(TUint8));
 
 	//store register id in buffer
@@ -2941,18 +2972,18 @@
 	//read registers
 	TInt err = DoReadRegisters(aThread, idPtr, valuePtr, flagPtr);
 	if(err == KErrNone)
-	{
+		{
 		if(*flag == EValid)
-		{
+			{
 			//register could be read so store value
 			aValue = *(T4ByteRegisterValue*)value;
-		}
+			}
 		else
-		{
+			{
 			//register couldn't be read for some reason
 			err = *flag;
+			}
 		}
-	}
 
 	//free memory
 	NKern::ThreadEnterCS();
@@ -2962,13 +2993,13 @@
 	NKern::ThreadLeaveCS();
 
 	return err;
-}
+	}
 
 //
 // DRM_DebugChannel::NotifyEvent
 //
 void DRM_DebugChannel::NotifyEvent(const TDriverEventInfo& aEventInfo)
-{
+	{
 	LOG_EVENT_MSG("DRM_DebugChannel::NotifyEvent()");
 
 	// Look for the relevant DTargetProcess
@@ -3016,7 +3047,7 @@
 		}
 
 	foundProcess->NotifyEvent(aEventInfo);
-}
+	}
 
 #ifndef __LAUNCH_AS_EXTENSION__
 DECLARE_STANDARD_LDD()
@@ -3112,23 +3143,23 @@
  * to both co-exist and exist independantly of the existing one *
  */
 DDebuggerInfo::DDebuggerInfo():
-    iObjectOffsetTable(NULL),
-    iObjectOffsetTableCount(NULL),
-    iThreadContextTable(NULL),
-    iStopModeExtension(new DStopModeExtension()),
-    iContainers(NULL),
-    iCodeSegLock(NULL),
-    iCodeSegGlobalList(NULL),
-    iScheduler(NULL),
-    iShadowPages(NULL),
-    iShadowPageCount(0),
-    iCurrentThread(NULL),
-    iEventMask(),
-    iEventHandlerBreakpoint(0),
-    iMemModelObjectOffsetTable(NULL),
-    iMemModelObjectOffsetTableCount(0)
-    {
-    }
+	iObjectOffsetTable(NULL),
+	iObjectOffsetTableCount(NULL),
+	iThreadContextTable(NULL),
+	iStopModeExtension(new DStopModeExtension()),
+	iContainers(NULL),
+	iCodeSegLock(NULL),
+	iCodeSegGlobalList(NULL),
+	iScheduler(NULL),
+	iShadowPages(NULL),
+	iShadowPageCount(0),
+	iCurrentThread(NULL),
+	iEventMask(),
+	iEventHandlerBreakpoint(0),
+	iMemModelObjectOffsetTable(NULL),
+	iMemModelObjectOffsetTableCount(0)
+	{
+	}
 
 /**
  * Installs the stop-mode debugger extension
@@ -3136,9 +3167,9 @@
  * existence in the superpage
 */
 void DStopModeExtension::Install(DStopModeExtension* aExt)
-    {
-    Kern::SuperPage().iDebuggerInfo->iStopModeExtension = aExt;
-    }
+	{
+	Kern::SuperPage().iDebuggerInfo->iStopModeExtension = aExt;
+	}
 
 #endif
 
@@ -3342,7 +3373,7 @@
 */
 TBool DRM_DebugChannel::GetFlagAtOffset(const TUint32 aFlags, const TArmReg aIndex) const
 	{
-	return ( aFlags & (1<<aIndex) ) ? ETrue : EFalse;
+	return aFlags & (1<<aIndex);
 	}
 
 /* Register the attachment of a debug agent to a process to be debugged
@@ -3475,38 +3506,38 @@
 	TUint8* buffer = (TUint8*)Kern::AllocZ(length);
 	NKern::ThreadLeaveCS();
 	if (buffer==NULL)
-	{
+		{
 		// Out of memory
 		return KErrNoMemory;
-	}
+		}
 
 	TPtr8 targetProcessName(buffer,length,length);
 
 	// Read the user-side data into targetProcessName
 	err = Kern::ThreadDesRead(iClientThread,a1,targetProcessName,0,KChunkShiftBy0);
 	if (err != KErrNone)
-	{
+		{
 		// Something bad happened so free the memory and return
 		NKern::ThreadEnterCS();
 		Kern::Free(buffer);
 		NKern::ThreadLeaveCS();
 
 		return err;
-	}
+		}
 
 	// Obtain the AgentId
 	TUint64 debugAgentId = 0;
 
 	err = Kern::ThreadRawRead(iClientThread,a2,&debugAgentId,sizeof(debugAgentId));
 	if (err != KErrNone)
-	{
+		{
 		// Something bad happened so free the memory and return
 		NKern::ThreadEnterCS();
 		Kern::Free(buffer);
 		NKern::ThreadLeaveCS();
 
 		return err;
-	}
+		}
 
 	// Remove the process from our list of tracked processes
 	err = TheDProcessTracker.DetachProcess(targetProcessName, debugAgentId);
@@ -3531,9 +3562,9 @@
 
 	TInt err = Kern::ThreadRawRead(iClientThread,a1,&debugAgentId,sizeof(debugAgentId));
 	if (err != KErrNone)
-	{
+		{
 		return err;
-	}
+		}
 
 	// Remove the process from our list of tracked processes
 	return TheDProcessTracker.DetachAgent(debugAgentId);
@@ -3578,30 +3609,30 @@
 	TUint8* buffer = (TUint8*)Kern::AllocZ(length);
 	NKern::ThreadLeaveCS();
 	if (buffer==NULL)
-	{
+		{
 		// Out of memory
 		return KErrNoMemory;
-	}
+		}
 	TPtr8 targetProcessName(buffer,length,length);
 
 	// Read the user-side data into targetProcessName
 	err = Kern::ThreadDesRead(iClientThread,a1,targetProcessName,0,KChunkShiftBy0);
 	if (err != KErrNone)
-	{
+		{
 		// Something bad happened so free the memory and return
 		NKern::ThreadEnterCS();
 		Kern::Free(buffer);
 		NKern::ThreadLeaveCS();
 
 		return err;
-	}
+		}
 
 	// Read the Event and Action from the user-side
 	TRM_DebugEventActionInfo info(0,0,0);
 
 	err = Kern::ThreadRawRead(iClientThread, a2, &info, sizeof(info));
 	if (err != KErrNone)
-	{
+		{
 		// Could not read event action data from the user-side
 
 		// Free memory used for targetProcessName
@@ -3610,12 +3641,12 @@
 		NKern::ThreadLeaveCS();
 
 		return err;
-	}
+		}
 
 	// Find the target process
 	DTargetProcess* pProcess = TheDProcessTracker.FindProcess(targetProcessName);
 	if (pProcess == NULL)
-	{
+		{
 		// Could not find this process
 
 		// Free memory used for targetProcessName
@@ -3624,14 +3655,14 @@
 		NKern::ThreadLeaveCS();
 
 		return KErrArgument;
-	}
+		}
 
 	TUint64 debugAgentId = info.iAgentId;
 
 	// Find the agent
 	DDebugAgent* debugAgent = pProcess->Agent(debugAgentId);
 	if (debugAgent == NULL)
-	{
+		{
 		// Bad agent means there is no tracking agent
 		LOG_MSG2("Cannot locate debug agent with pid 0x%0x16lx",info.iAgentId);
 
@@ -3641,7 +3672,7 @@
 		NKern::ThreadLeaveCS();
 
 		return KErrGeneral;
-	}
+		}
 
 	// Set the event action
 	debugAgent->SetEventAction((TEventType)info.iEvent,(TKernelEventAction)info.iAction);
@@ -3752,9 +3783,9 @@
 		}
 
 	if (err == KErrNone)
-	{
+		{
 		LOG_MSG2("DRM_DebugChannel::IsDebuggable(aProcessId 0x%08x) - Yes it is debuggable\n",aProcessId);
-	}
+		}
 
 	return err;
 	}
--- a/kernel/eka/drivers/display/base_e32_drivers_display.mrp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/drivers/display/base_e32_drivers_display.mrp	Fri Apr 16 16:24:37 2010 +0300
@@ -1,3 +1,18 @@
+#
+# 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 "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: 
+#
 # component name "Graphics GCE Driver"
 
 component	base_e32_drivers_display
--- a/kernel/eka/drivers/dma/dma2_pil.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/drivers/dma/dma2_pil.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -1,4 +1,4 @@
-// Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 2002-2010 Nokia Corporation and/or its subsidiary(-ies).
 // All rights reserved.
 // This component and the accompanying materials are made available
 // under the terms of "Eclipse Public License v1.0"
@@ -1186,6 +1186,14 @@
 	// Append request to queue and link new descriptor list to existing one.
 	iChannel.Wait();
 
+	TUint32 req_count = iChannel.iQueuedRequests++;
+	if (req_count == 0)
+		{
+		iChannel.Signal();
+		iChannel.QueuedRequestCountChanged();
+		iChannel.Wait();
+		}
+
 	TInt r = KErrGeneral;
 	const TBool ch_isr_cb = __e32_atomic_load_acq32(&iChannel.iIsrCbRequest);
 	if (ch_isr_cb)
@@ -1195,6 +1203,13 @@
 		// that the channel's Transfer() function is not called by both the ISR
 		// and the client thread at the same time.
 		__KTRACE_OPT(KPANIC, Kern::Printf("An ISR cb request exists - not queueing"));
+		// Undo the request count increment...
+		req_count = --iChannel.iQueuedRequests;
+		iChannel.Signal();
+		if (req_count == 0)
+			{
+			iChannel.QueuedRequestCountChanged();
+			}
 		}
 	else if (iIsrCb && !iChannel.IsQueueEmpty())
 		{
@@ -1203,10 +1218,24 @@
 		// the ISR callback doesn't get executed together with the DFC(s) of
 		// any previous request(s).
 		__KTRACE_OPT(KPANIC, Kern::Printf("Request queue not empty - not queueing"));
+		// Undo the request count increment...
+		req_count = --iChannel.iQueuedRequests;
+		iChannel.Signal();
+		if (req_count == 0)
+			{
+			iChannel.QueuedRequestCountChanged();
+			}
 		}
 	else if (iChannel.iIsrDfc & (TUint32)TDmaChannel::KCancelFlagMask)
 		{
 		__KTRACE_OPT(KPANIC, Kern::Printf("Channel requests cancelled - not queueing"));
+		// Someone is cancelling all requests - undo the request count increment...
+		req_count = --iChannel.iQueuedRequests;
+		iChannel.Signal();
+		if (req_count == 0)
+			{
+			iChannel.QueuedRequestCountChanged();
+			}
 		}
 	else
 		{
@@ -1228,8 +1257,8 @@
 			}
 		iChannel.DoQueue(const_cast<const DDmaRequest&>(*this));
 		r = KErrNone;
+		iChannel.Signal();
 		}
-	iChannel.Signal();
 
 	__DMA_INVARIANT();
 	return r;
@@ -1491,8 +1520,6 @@
 //////////////////////////////////////////////////////////////////////////////
 // TDmaChannel
 
-_LIT(KDmaChannelMutex, "DMA-Channel");
-
 TDmaChannel::TDmaChannel()
 	: iController(NULL),
 	  iDmacCaps(NULL),
@@ -1507,24 +1534,13 @@
 	  iIsrDfc(0),
 	  iReqQ(),
 	  iReqCount(0),
+	  iQueuedRequests(0),
 	  iCancelInfo(NULL),
 	  iRedoRequest(EFalse),
 	  iIsrCbRequest(EFalse)
 	{
-	const TInt r = Kern::MutexCreate(iMutex, KDmaChannelMutex, KMutexOrdDmaChannel);
-	__DMA_ASSERTA(r == KErrNone);
-
-#ifndef __WINS__
-	// On the emulator this code is called from within the codeseg mutex.
-	// The invariant tries to hold the dma channel mutex, but this is not allowed
+	__KTRACE_OPT(KDMA, Kern::Printf("TDmaChannel::TDmaChannel"));
 	__DMA_INVARIANT();
-#endif
-	}
-
-
-TDmaChannel::~TDmaChannel()
-	{
-	Kern::SafeClose((DObject*&)iMutex, NULL);
 	}
 
 
@@ -1581,6 +1597,8 @@
 	__DMA_ASSERTD(IsQueueEmpty());
 	__DMA_ASSERTD(iReqCount == 0);
 
+	__DMA_ASSERTD(iQueuedRequests == 0);
+
 	// Descriptor leak? -> bug in request code
 	__DMA_ASSERTD(iAvailDesCount == iMaxDesCount);
 
@@ -1642,7 +1660,7 @@
 
 	NKern::ThreadEnterCS();
 	Wait();
-
+	const TUint32 req_count_before = iQueuedRequests;
 	NThreadBase* const dfc_nt = iDfc.Thread();
 	// Shouldn't be NULL (i.e. an IDFC)
 	__DMA_ASSERTD(dfc_nt);
@@ -1663,6 +1681,7 @@
 		SDblQueLink* pL;
 		while ((pL = iReqQ.GetFirst()) != NULL)
 			{
+			iQueuedRequests--;
 			DDmaRequest* pR = _LOFF(pL, DDmaRequest, iLink);
 			pR->OnDeque();
 			}
@@ -1695,6 +1714,8 @@
 		iDfc.Enque();
 		}
 
+	const TUint32 req_count_after = iQueuedRequests;
+
 	Signal();
 
 	if (waiters)
@@ -1707,6 +1728,14 @@
 		}
 
  	NKern::ThreadLeaveCS();
+
+	// Only call PSL if there were requests queued when we entered AND there
+	// are now no requests left on the queue.
+	if ((req_count_before != 0) && (req_count_after == 0))
+		{
+		QueuedRequestCountChanged();
+		}
+
 	__DMA_INVARIANT();
 	}
 
@@ -1878,8 +1907,10 @@
 	TUint32 count = w & KDfcCountMask;
 	const TBool error = w & (TUint32)KErrorFlagMask;
 	TBool stop = w & (TUint32)KCancelFlagMask;
+	const TUint32 req_count_before = iQueuedRequests;
+	TUint32 req_count_after = 0;
+
 	__DMA_ASSERTD((count > 0) || stop);
-
 	__DMA_ASSERTD(!iRedoRequest); // We shouldn't be here if this is true
 
 	while (count && !stop)
@@ -1908,6 +1939,7 @@
 				{
 				pCompletedReq = pCurReq;
 				pCurReq->iLink.Deque();
+				iQueuedRequests--;
 				if (iReqQ.IsEmpty())
 					iNullPtr = &iCurHdr;
 				pCompletedReq->OnDeque();
@@ -1947,28 +1979,13 @@
 					}
 				}
 			}
-		else
+		// Allow another thread in, in case they are trying to cancel
+		if (pCompletedReq || Flash())
 			{
-			// Allow another thread in, in case they are trying to cancel
-			Flash();
+			stop = __e32_atomic_load_acq32(&iIsrDfc) & (TUint32)KCancelFlagMask;
 			}
-		stop = __e32_atomic_load_acq32(&iIsrDfc) & (TUint32)KCancelFlagMask;
 		}
 
-	// Some interrupts may be missed (double-buffer and scatter-gather
-	// controllers only) if two or more transfers complete while interrupts are
-	// disabled in the CPU. If this happens, the framework will go out of sync
-	// and leave some orphaned requests in the queue.
-	//
-	// To ensure correctness we handle this case here by checking that the request
-	// queue is empty when all transfers have completed and, if not, cleaning up
-	// and notifying the client of the completion of the orphaned requests.
-	//
-	// Note that if some interrupts are missed and the controller raises an
-	// error while transferring a subsequent fragment, the error will be reported
-	// on a fragment which was successfully completed.  There is no easy solution
-	// to this problem, but this is okay as the only possible action following a
-	// failure is to flush the whole queue.
 	if (stop)
 		{
 		// If another thread set the cancel flag, it should have
@@ -1984,73 +2001,25 @@
 		// reset the ISR count - new requests can now be processed
 		__e32_atomic_store_rel32(&iIsrDfc, 0);
 
+		req_count_after = iQueuedRequests;
 		Signal();
 
 		// release threads doing CancelAll()
 		waiters->Signal();
 		}
-	else if (!error && !iReqQ.IsEmpty() && iController->IsIdle(*this))
+	else
 		{
-#ifdef __SMP__
-		// On an SMP system we must call stop transfer, it will block until
-		// any ISRs have completed so that the system does not spuriously
-		// attempt to recover from a missed interrupt.
-		//
-		// On an SMP system it is possible for the code here to execute
-		// concurrently with the DMA ISR. It is therefore possible that at this
-		// point the previous transfer has already completed (so that IsIdle
-		// reports true), but that the ISR has not yet queued a DFC. Therefore
-		// we must wait for the ISR to complete.
-		//
-		// StopTransfer should have no other side effect, given that the
-		// channel is already idle.
-		iController->StopTransfer(*this); // should block till ISR completion
-#endif
-
-		const TBool cleanup = !iDfc.Queued();
-		if(cleanup)
-			{
-			__KTRACE_OPT(KDMA, Kern::Printf("Missed interrupt(s) - draining request queue"));
-			ResetStateMachine();
-
-			// Move orphaned requests to temporary queue so channel queue can
-			// accept new requests.
-			SDblQue q;
-			q.MoveFrom(&iReqQ);
-
-			SDblQueLink* pL;
-			while ((pL = q.GetFirst()) != NULL)
-				{
-				DDmaRequest* const pR = _LOFF(pL, DDmaRequest, iLink);
-				__KTRACE_OPT(KDMA, Kern::Printf("Removing request from queue and notifying client"));
-				pR->OnDeque();
-				// Old style callback
-				DDmaRequest::TCallback const cb = pR->iCb;
-				if (cb)
-					{
-					TAny* const arg = pR->iCbArg;
-					Signal();
-					(*cb)(DDmaRequest::EOk, arg);
-					Wait();
-					}
-				else
-					{
-					// New style callback
-					TDmaCallback const ncb = pR->iDmaCb;
-					if (ncb)
-						{
-						TAny* const arg = pR->iDmaCbArg;
-						Signal();
-						(*ncb)(EDmaCallbackRequestCompletion, EDmaResultOK, arg, NULL);
-						Wait();
-						}
-					}
-				}
-			}
+		req_count_after = iQueuedRequests;
 		Signal();
 		}
-	else
-		Signal();
+
+	// Only call PSL if there were requests queued when we entered AND there
+	// are now no requests left on the queue (after also having executed all
+	// client callbacks).
+	if ((req_count_before != 0) && (req_count_after == 0))
+		{
+		QueuedRequestCountChanged();
+		}
 
 	__DMA_INVARIANT();
 	}
@@ -2103,6 +2072,20 @@
 	}
 
 
+/** PSL may override */
+void TDmaChannel::QueuedRequestCountChanged()
+	{
+#ifdef _DEBUG
+	Wait();
+	__KTRACE_OPT(KDMA,
+				 Kern::Printf("TDmaChannel::QueuedRequestCountChanged() %d",
+							  iQueuedRequests));
+	__DMA_ASSERTA(iQueuedRequests >= 0);
+	Signal();
+#endif
+	}
+
+
 #ifdef _DEBUG
 void TDmaChannel::Invariant()
 	{
--- a/kernel/eka/drivers/dma/dmapil.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/drivers/dma/dmapil.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -1,4 +1,4 @@
-// Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 2002-2010 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"
@@ -861,35 +861,66 @@
 		// release threads doing CancelAll()
 		waiters->Signal();
 		}
-	else if (!error && !iDfc.Queued() && !iReqQ.IsEmpty() && iController->IsIdle(*this))
+#ifndef DISABLE_MISSED_IRQ_RECOVERY
+	// (iController may be NULL here if the channel was closed in the client callback.)
+	else if (!error &&
+			 iController && iController->IsIdle(*this) &&
+			 !iReqQ.IsEmpty() &&
+			 !iDfc.Queued())
 		{
-		__KTRACE_OPT(KDMA, Kern::Printf("Missed interrupt(s) - draining request queue"));
-		ResetStateMachine();
-
-		// Move orphaned requests to temporary queue so channel queue can
-		// accept new requests.
-		SDblQue q;
-		q.MoveFrom(&iReqQ);
+		// Wait for a bit. If during that time the condition goes away then it
+		// was a 'spurious missed interrupt', in which case we just do nothing.
+		TBool spurious = EFalse;
+		const TUint32 nano_secs_per_loop = 1000 * 1000;			// 1ms
+		for (TInt i = 5; i > 0; i--)
+			{
+			if (!iController->IsIdle(*this))
+				{
+				__KTRACE_OPT(KDMA, Kern::Printf("DMAC no longer idle (i = %d)", i));
+				spurious = ETrue;
+				break;
+				}
+			else if (iDfc.Queued())
+				{
+				__KTRACE_OPT(KDMA, Kern::Printf("DFC now queued (i = %d)", i));
+				spurious = ETrue;
+				break;
+				}
+			Kern::NanoWait(nano_secs_per_loop);
+			}
+		if (!spurious)
+			{
+			__KTRACE_OPT(KDMA,
+						 Kern::Printf("Missed interrupt(s) - draining request queue on ch %d",
+									  PslId()));
+			ResetStateMachine();
 
-		SDblQueLink* pL;
-		while ((pL = q.GetFirst()) != NULL)
-			{
-			iQueuedRequests--;
-			DDmaRequest* pR = _LOFF(pL, DDmaRequest, iLink);
-			__KTRACE_OPT(KDMA, Kern::Printf("Removing request from queue and notifying client"));
-			pR->OnDeque();
-			DDmaRequest::TCallback cb = pR->iCb;
-			TAny* arg = pR->iCbArg;
-			if (cb)
+			// Move orphaned requests to temporary queue so channel queue can
+			// accept new requests.
+			SDblQue q;
+			q.MoveFrom(&iReqQ);
+
+			SDblQueLink* pL;
+			while ((pL = q.GetFirst()) != NULL)
 				{
-				Signal();
-				(*cb)(DDmaRequest::EOk, arg);
-				Wait();
+				iQueuedRequests--;
+				DDmaRequest* pR = _LOFF(pL, DDmaRequest, iLink);
+				__KTRACE_OPT(KDMA, Kern::Printf("Removing request from queue and notifying client"));
+				pR->OnDeque();
+				DDmaRequest::TCallback cb = pR->iCb;
+				TAny* arg = pR->iCbArg;
+				if (cb)
+					{
+					Signal();
+					(*cb)(DDmaRequest::EOk, arg);
+					Wait();
+					}
 				}
 			}
 		req_count_after = iQueuedRequests;
 		Signal();
 		}
+#endif  // #ifndef DISABLE_MISSED_IRQ_RECOVERY
 	else
 		{
 		req_count_after = iQueuedRequests;
--- a/kernel/eka/drivers/ecomm/base_e32_drivers_ecomm.mrp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/drivers/ecomm/base_e32_drivers_ecomm.mrp	Fri Apr 16 16:24:37 2010 +0300
@@ -1,3 +1,18 @@
+#
+# 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 "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: 
+#
 # component name "Serial Port Driver"
 
 component	base_e32_drivers_ecomm
--- a/kernel/eka/drivers/ethernet/base_e32_drivers_ethernet.mrp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/drivers/ethernet/base_e32_drivers_ethernet.mrp	Fri Apr 16 16:24:37 2010 +0300
@@ -1,3 +1,18 @@
+#
+# 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 "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: 
+#
 # component name "Ethernet Driver"
 
 component	base_e32_drivers_ethernet
Binary file kernel/eka/drivers/hcr/documents/HCR Design Model.eap has changed
--- a/kernel/eka/drivers/hcr/hcr_api.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/drivers/hcr/hcr_api.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -34,6 +34,7 @@
 
 // -- FUNCTIONS ---------------------------------------------------------------
 
+
 #ifndef MAKE_DEF_FILE
 namespace HCR 
 {
@@ -373,6 +374,9 @@
 #ifndef MAKE_DEF_FILE
     HCR_FUNC("HCR::GetDataTUint8");
     
+    if(aValue == NULL || aMaxLen == 0)
+        HCR_TRACE_RETURN(KErrArgument);
+    
     TInt err = GetUValueLargeSettingTUint8(aId, ETypeBinData, aMaxLen, aValue, aLen);
     if (err != KErrNone)
         HCR_TRACE_RETURN(err);        
@@ -389,6 +393,9 @@
 #ifndef MAKE_DEF_FILE
     HCR_FUNC("HCR::GetDataTDes8");
     
+    if(aValue.MaxLength()==0)
+        HCR_TRACE_RETURN(KErrArgument);
+    
     TInt err = GetUValueLargeSettingTDes8(aId, ETypeBinData, aValue);
     if (err != KErrNone)
         HCR_TRACE_RETURN(err);  
@@ -406,6 +413,9 @@
 #ifndef MAKE_DEF_FILE
     HCR_FUNC("HCR::GetStringTUint8");
     
+    if(aValue == NULL || aMaxLen == 0)
+            HCR_TRACE_RETURN(KErrArgument);
+    
     TInt err = GetUValueLargeSettingTUint8(aId, ETypeText8, aMaxLen, aValue, aLen);
     if (err != KErrNone)
         HCR_TRACE_RETURN(err);        
@@ -422,6 +432,9 @@
 #ifndef MAKE_DEF_FILE
     HCR_FUNC("HCR::GetStringTUint8");
     
+    if(aValue.MaxLength() == 0)
+            HCR_TRACE_RETURN(KErrArgument);
+        
     TInt err = GetUValueLargeSettingTDes8(aId, ETypeText8, aValue);
     if (err != KErrNone)
         HCR_TRACE_RETURN(err);        
@@ -438,6 +451,9 @@
 #ifndef MAKE_DEF_FILE
     HCR_FUNC("HCR::GetArrayTInt32");
     
+    if(aValue == NULL || aMaxLen == 0)
+                HCR_TRACE_RETURN(KErrArgument);
+        
     TInt err = GetUValueLargeSettingArray(aId, ETypeArrayInt32, aMaxLen, (TUint32*)aValue, aLen);
     if (err != KErrNone)
         HCR_TRACE_RETURN(err);        
@@ -454,6 +470,9 @@
 #ifndef MAKE_DEF_FILE
     HCR_FUNC("HCR::GetArrayTUInt32");
     
+    if(aValue == NULL || aMaxLen == 0)
+                HCR_TRACE_RETURN(KErrArgument);
+    
     TInt err = GetUValueLargeSettingArray(aId, ETypeArrayUInt32, aMaxLen, aValue, aLen);
     if (err != KErrNone)
         HCR_TRACE_RETURN(err);        
@@ -481,6 +500,21 @@
         HCR_TRACE_RETURN(KErrArgument);
     
     TInt err = KErrNone;
+    
+    //Only UDEB, check is the user provided array aIds ordered?    
+#ifdef _DEBUG
+    for(TInt cursor = 0; cursor < aNum - 1; cursor ++)
+        {
+    //Check the element at cursor position and one above 
+    err = CompareSSettingIds(aIds[cursor], aIds[cursor+1]);
+    //if next element is less than previous one then array is not ordered.
+    //Critical error, report to user
+    if(err >= 0)
+        HCR_TRACE_RETURN(KErrArgument);
+        }
+#endif
+
+
 
     //Don't leave while the resources are not fully allocated/deallocated
     NKern::ThreadEnterCS();
--- a/kernel/eka/drivers/hcr/hcr_hai.h	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/drivers/hcr/hcr_hai.h	Fri Apr 16 16:24:37 2010 +0300
@@ -1,4 +1,4 @@
-// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 2008-2010 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"
@@ -335,7 +335,9 @@
 
 /**
 Global macro for use in setting the length attribute of a SSettingC 
-instance in the PSL compiled repository static data.
+instance in the PSL compiled repository static data. Used when the setting is
+a word sized setting and the size field is Not Applicable. Not to be used 
+for large data settings i.e. where size > 4bytes, i.e. type > 0xffff.
 
 @see HCR::MVariant
 @see HCR::SRepositoryCompiled
--- a/kernel/eka/drivers/hcr/hcr_pil.h	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/drivers/hcr/hcr_pil.h	Fri Apr 16 16:24:37 2010 +0300
@@ -38,6 +38,10 @@
 #include "hcr_hai.h"
 
 
+// -- INTERNAL/HELPER FUNCTIONS PROTOTYPE --------------------------------------
+TInt CompareSSettingIds(const HCR::TSettingId& a1, const HCR::SSettingId& a2);
+
+
 // -- CLASSES -----------------------------------------------------------------
 
 namespace HCR
--- a/kernel/eka/drivers/iic/iic_channel.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/drivers/iic/iic_channel.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -129,6 +129,9 @@
 
 void DIicBusChannelMaster::CompleteRequest(TInt aResult)
 	{
+	// Ensure the timeout timer has been cancelled
+	CancelTimeOut();
+
 	TIicBusTransaction* nextTrans=NextTrans(iCurrentTransaction);
 
 	if((aResult != KErrNone)||(nextTrans == NULL))
@@ -356,7 +359,13 @@
 
 void DIicBusChannelMaster::CancelTimeOut()
 	{
+	// Silently cancel the timer and associated DFC
+	//
+	// NTimer::Cancel returns ETrue if cancelled, EFalse otherwise - which may mean it wasn't active
+	// TDfc::Cancel returns ETrue if actually de-queued, EFalse otherwise - which may mean it wasn't queued
+	//
 	iTimeoutTimer.Cancel();
+	iSlaveTimeoutDfc->Cancel();
 	}
 
 void DIicBusChannelMaster::Complete(TInt aResult, TIicBusTransaction* aTransaction) //Completes a kernel message and receive the next one
@@ -481,7 +490,7 @@
 	r=SetNotificationTrigger(0);			// Attempt to clear notification requests
 	if((r!=KErrNone)&&(r!=KErrTimedOut))	// KErrTimedOut refers to an earlier transaction, and is for information only
 		return r;
-	iTimeoutTimer.Cancel();
+	StopTimer();
 	r=DoRequest(EPowerDown);
 	if(r == KErrNone)
 		{
@@ -888,7 +897,13 @@
 
 void DIicBusChannelSlave::StopTimer()
 	{
+	// Silently cancel the timer and associated DFC
+	//
+	// NTimer::Cancel returns ETrue if cancelled, EFalse otherwise - which may mean it wasn't active
+	// TDfc::Cancel returns ETrue if actually de-queued, EFalse otherwise - which may mean it wasn't queued
+	//
 	iTimeoutTimer.Cancel();
+	iClientTimeoutDfc->Cancel();
 	}
 
 TInt DIicBusChannelSlave::UpdateReqTrig(TInt8& aCbTrigVal, TInt& aCallbackRet)
@@ -901,14 +916,15 @@
 	if(iNotif->iTrigger & EGeneralBusError)
 		{
 		// In the event of a bus error, always cancel the timer and call the Client callback
-		nextSteps |= (EStopTimer | EInvokeCb);
+		StopTimer();
 		iTimerState = EInactive;
+		nextSteps = EInvokeCb;
 		aCallbackRet = KErrGeneral;
 		}
 	else if(iNotif->iTrigger == EAsyncCaptChan)
 		{
 		// For asynchronous channel capture, no timers are involved - just call the Client callback
-		nextSteps |= EInvokeCb;
+		nextSteps = EInvokeCb;
 		aCallbackRet = KErrCompletion;
 		}
 	else if((iNotif->iTrigger & iReqTrig) != 0)
@@ -947,7 +963,8 @@
 				{
 				// All triggers required have occurred, so transition to state EWaitForClient
 				iTimerState = EWaitForClient;
-				nextSteps |= (EStopTimer | EInvokeCb | EStartTimer);
+				StopTimer();
+				nextSteps = (EInvokeCb | EStartTimer);
 				}
 			else
 				{
@@ -986,7 +1003,7 @@
 		TInt nextSteps = UpdateReqTrig(callbackTrig, callbackRet);
 		if(nextSteps & EStopTimer)
 			{
-			iTimeoutTimer.Cancel();
+			__ASSERT_DEBUG(NULL, Kern::Fault(KIicChannelPanic,__LINE__));
 			}
 		if(nextSteps & EInvokeCb)
 			{
--- a/kernel/eka/drivers/locmedia/base_e32_drivers_locmedia.mrp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/drivers/locmedia/base_e32_drivers_locmedia.mrp	Fri Apr 16 16:24:37 2010 +0300
@@ -1,3 +1,18 @@
+#
+# 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 "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: 
+#
 # component name "Local Media Subsystem"
 
 component	base_e32_drivers_locmedia
--- a/kernel/eka/drivers/locmedia/locmedia.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/drivers/locmedia/locmedia.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -3615,15 +3615,19 @@
 void DPrimaryMediaBase::RequestCountInc()
 	{
 	__ASSERT_DEBUG(iBody, LOCM_FAULT());
-	TInt oldVal = (TInt) __e32_atomic_add_ord32(&iBody->iRequestCount, (TUint) 1);
-//Kern::Printf("RCINC: this %x cnt %d, old %d", this, iBody->iRequestCount, oldVal);
-	
-	OstTraceDefExt2( OST_TRACE_CATEGORY_RND, TRACE_DEMANDPAGING, DPRIMARYMEDIABASE_REQUESTCOUNTINC, "new count=%d; old count=%d", iBody->iRequestCount, oldVal );
-	
-	if (oldVal == 0 && iBody->iPagingDevice)
+	if (iBody->iPagingDevice)
 		{
-//Kern::Printf("RCINC: NotifyBusy()");
-		iBody->iPagingDevice->NotifyBusy();
+		NFastMutex* lock = iBody->iPagingDevice->NotificationLock();
+		NKern::FMWait(lock);
+		TInt oldVal = iBody->iRequestCount++;
+		//Kern::Printf("RCINC: this %x cnt %d, old %d", this, iBody->iRequestCount, oldVal);
+		OstTraceDefExt2( OST_TRACE_CATEGORY_RND, TRACE_DEMANDPAGING, DPRIMARYMEDIABASE_REQUESTCOUNTINC, "new count=%d; old count=%d", iBody->iRequestCount, oldVal );
+		if (oldVal == 0)
+			{
+			//Kern::Printf("RCINC: NotifyBusy()");
+			iBody->iPagingDevice->NotifyBusy();
+			}
+		NKern::FMSignal(lock);
 		}
 	}
 
@@ -3635,17 +3639,21 @@
 void DPrimaryMediaBase::RequestCountDec()
 	{
 	__ASSERT_DEBUG(iBody, LOCM_FAULT());
-	TInt oldVal = (TInt) __e32_atomic_add_ord32(&iBody->iRequestCount, (TUint) -1);
-//Kern::Printf("RCDEC: this %x cnt %d, old %d", this, iBody->iRequestCount, oldVal);
-	
-	OstTraceDefExt2( OST_TRACE_CATEGORY_RND, TRACE_DEMANDPAGING, DPRIMARYMEDIABASE_REQUESTCOUNTDEC, "new count=%d; old count=%d", iBody->iRequestCount, oldVal );
-	
-	if (oldVal == 1 && iBody->iPagingDevice)
+	if (iBody->iPagingDevice)
 		{
-//Kern::Printf("RCDEC: NotifyIdle()");
-		iBody->iPagingDevice->NotifyIdle();
+		NFastMutex* lock = iBody->iPagingDevice->NotificationLock();
+		NKern::FMWait(lock);
+		TInt oldVal = iBody->iRequestCount--;
+		//Kern::Printf("RCDEC: this %x cnt %d, old %d", this, iBody->iRequestCount, oldVal);
+		OstTraceDefExt2( OST_TRACE_CATEGORY_RND, TRACE_DEMANDPAGING, DPRIMARYMEDIABASE_REQUESTCOUNTDEC, "new count=%d; old count=%d", iBody->iRequestCount, oldVal );
+		if (oldVal == 1)
+			{
+			//Kern::Printf("RCDEC: NotifyIdle()");
+			iBody->iPagingDevice->NotifyIdle();
+			}		
+		NKern::FMSignal(lock);
+		__ASSERT_DEBUG(iBody->iRequestCount >= 0, LOCM_FAULT());
 		}
-	__ASSERT_DEBUG(iBody->iRequestCount >= 0, LOCM_FAULT());
 	}
 #endif	// __DEMAND_PAGING__
 
@@ -4947,8 +4955,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 +5022,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	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/drivers/media/base_e32_drivers_media.mrp	Fri Apr 16 16:24:37 2010 +0300
@@ -1,3 +1,18 @@
+#
+# 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 "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: 
+#
 # component name "Media Drivers"
 
 component	base_e32_drivers_media
@@ -23,8 +38,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	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/drivers/medmmc/bgahsmmcptn.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -119,7 +119,7 @@
 		}
 	else if ( PartitionIsFAT(aDrive.iPartitionType) || PartitionIsFAT32(aDrive.iPartitionType)	)
 		{		
-		Info().iDriveAtt = iPartitionAttributes[aDrive.iPartitionNumber];
+		Info().iDriveAtt |= iPartitionAttributes[aDrive.iPartitionNumber];
 		}
 
 	return KErrNone;
@@ -157,46 +157,57 @@
 	BGAHSMMCPTN_PI_STR *partitionTable = (BGAHSMMCPTN_PI_STR*)(&iIntBuf[0]);
 
 	// Verify that this is the Nokia partition table
-	if( memcompare( (TUint8*)&(partitionTable->id[0]), sizeof(BGAHSMMCPTN_PI_ID), (TUint8*)BGAHSMMCPTN_PI_ID, sizeof(BGAHSMMCPTN_PI_ID)) == 0 )
+	if( memcompare( (TUint8*)&(partitionTable->iId[0]), sizeof(BGAHSMMCPTN_PI_ID), (TUint8*)BGAHSMMCPTN_PI_ID, sizeof(BGAHSMMCPTN_PI_ID)) == 0 )
 		{
 		__KTRACE_OPT(KPBUSDRV, Kern::Printf("Nokia partition structure found"));
-		__KTRACE_OPT(KPBUSDRV, Kern::Printf("partitionTable->id..............: %s", partitionTable->id ));
-		__KTRACE_OPT(KPBUSDRV, Kern::Printf("partitionTable->sector_size.....: %d = 0x%x", partitionTable->sector_size, partitionTable->sector_size));
-		__KTRACE_OPT(KPBUSDRV, Kern::Printf("partitionTable->major_ver.......: %d", partitionTable->major_ver));
-		__KTRACE_OPT(KPBUSDRV, Kern::Printf("partitionTable->minor_ver.......: %d", partitionTable->minor_ver));
-		__KTRACE_OPT(KPBUSDRV, Kern::Printf("partitionTable->partition_amount: %d", partitionTable->partition_amount));
+		__KTRACE_OPT(KPBUSDRV, Kern::Printf("partitionTable->id..............: %s", partitionTable->iId ));
+		__KTRACE_OPT(KPBUSDRV, Kern::Printf("partitionTable->sector_size.....: %d = 0x%x", partitionTable->iSector_size, partitionTable->iSector_size));
+		__KTRACE_OPT(KPBUSDRV, Kern::Printf("partitionTable->major_ver.......: %d", partitionTable->iMajor_ver));
+		__KTRACE_OPT(KPBUSDRV, Kern::Printf("partitionTable->minor_ver.......: %d", partitionTable->iMinor_ver));
+		__KTRACE_OPT(KPBUSDRV, Kern::Printf("partitionTable->partition_amount: %d", partitionTable->iPartition_amount));
+		
 		
-		for( TUint8 index = 0; (index < partitionTable->partition_amount) && (index < BGAHSMMCPTN_LAST_DRIVE); index++ )
-			{
-			if( (partitionTable->partitions[index].size > 0) &&
-				( PartitionIsFAT(partitionTable->partitions[index].partition_id) ||
-				  PartitionIsFAT32(partitionTable->partitions[index].partition_id) ||
-				  (KPartitionTypePagedData == partitionTable->partitions[index].partition_id && !foundSwap) ) )
-				{
-				iPartitionInfo->iEntry[partitionCount].iPartitionType	  = partitionTable->partitions[index].partition_id;
-				iPartitionInfo->iEntry[partitionCount].iPartitionBaseAddr = (Int64) partitionTable->partitions[index].start_sector << KDiskSectorShift;
-				iPartitionInfo->iEntry[partitionCount].iPartitionLen	  = (Int64) partitionTable->partitions[index].size << KDiskSectorShift;
-				iPartitionAttributes[partitionCount]					  = partitionTable->partitions[index].partition_attributes;
-
-				__KTRACE_OPT(KPBUSDRV, Kern::Printf("Registering partition #%d:", partitionCount));
-				__KTRACE_OPT(KPBUSDRV, Kern::Printf("partitionCount....: %d", partitionCount));
-				__KTRACE_OPT(KPBUSDRV, Kern::Printf("startSector.......: 0x%x", partitionTable->partitions[index].start_sector ));
-				__KTRACE_OPT(KPBUSDRV, Kern::Printf("iPartitionBaseAddr: 0x%lx (sectors: %d)", iPartitionInfo->iEntry[partitionCount].iPartitionBaseAddr, (TUint32)(iPartitionInfo->iEntry[partitionCount].iPartitionBaseAddr >> KDiskSectorShift)));
-				__KTRACE_OPT(KPBUSDRV, Kern::Printf("size..............: 0x%lx", partitionTable->partitions[index].size ));
-				__KTRACE_OPT(KPBUSDRV, Kern::Printf("iPartitionLen.....: 0x%lx (sectors: %d)", iPartitionInfo->iEntry[partitionCount].iPartitionLen, iPartitionInfo->iEntry[partitionCount].iPartitionLen >> KDiskSectorShift));
-				__KTRACE_OPT(KPBUSDRV, Kern::Printf("iPartitionType....: %d", iPartitionInfo->iEntry[partitionCount].iPartitionType));
-				__KTRACE_OPT(KPBUSDRV, Kern::Printf("iPartitionAttribs.: 0x%x", iPartitionAttributes[partitionCount]));
-				__KTRACE_OPT(KPBUSDRV, Kern::Printf(" "));
-
-				if(KPartitionTypePagedData == partitionTable->partitions[index].partition_id)
-					{
-					foundSwap = ETrue;
-					}
-
-				partitionCount++;
-				}
-			}
-		}
+		TUint8 PartitionType = 0;		
+		// Check Supported Version is present
+		if (partitionTable->iMajor_ver <= BGAHSMMCPTN_PI_VER_MAJOR)
+		    {
+            for( TUint8 index = 0; (index < partitionTable->iPartition_amount) && (index < BGAHSMMCPTN_LAST_DRIVE); index++ )
+                {
+                if (partitionTable->iMinor_ver >= BGAHSMMCPTN_PART_TYPE_SUPP_VER_MINOR)
+                    PartitionType = partitionTable->iPartitions[index].iPartition_type;
+                else                    
+                    PartitionType = partitionTable->iPartitions[index].iPartition_id;
+            
+                if( (partitionTable->iPartitions[index].iSize > 0) &&
+                    ( PartitionIsFAT(PartitionType) ||
+                      PartitionIsFAT32(PartitionType) ||
+                     (KPartitionTypePagedData == PartitionType && !foundSwap) ) )
+                    {                   
+                    iPartitionInfo->iEntry[partitionCount].iPartitionType	  = PartitionType;                    
+                    iPartitionInfo->iEntry[partitionCount].iPartitionBaseAddr = (Int64) partitionTable->iPartitions[index].iStart_sector << KDiskSectorShift;
+                    iPartitionInfo->iEntry[partitionCount].iPartitionLen	  = (Int64) partitionTable->iPartitions[index].iSize << KDiskSectorShift;
+                    iPartitionAttributes[partitionCount]					  = partitionTable->iPartitions[index].iPartition_attributes;
+    
+                    __KTRACE_OPT(KPBUSDRV, Kern::Printf("Registering partition #%d:", partitionCount));
+                    __KTRACE_OPT(KPBUSDRV, Kern::Printf("partitionCount....: %d", partitionCount));
+                    __KTRACE_OPT(KPBUSDRV, Kern::Printf("startSector.......: 0x%x", partitionTable->iPartitions[index].iStart_sector ));
+                    __KTRACE_OPT(KPBUSDRV, Kern::Printf("iPartitionBaseAddr: 0x%lx (sectors: %d)", iPartitionInfo->iEntry[partitionCount].iPartitionBaseAddr, (TUint32)(iPartitionInfo->iEntry[partitionCount].iPartitionBaseAddr >> KDiskSectorShift)));
+                    __KTRACE_OPT(KPBUSDRV, Kern::Printf("size..............: 0x%lx", partitionTable->iPartitions[index].iSize ));
+                    __KTRACE_OPT(KPBUSDRV, Kern::Printf("iPartitionLen.....: 0x%lx (sectors: %d)", iPartitionInfo->iEntry[partitionCount].iPartitionLen, iPartitionInfo->iEntry[partitionCount].iPartitionLen >> KDiskSectorShift));
+                    __KTRACE_OPT(KPBUSDRV, Kern::Printf("iPartitionType....: %d", iPartitionInfo->iEntry[partitionCount].iPartitionType));
+                    __KTRACE_OPT(KPBUSDRV, Kern::Printf("iPartitionAttribs.: 0x%x", iPartitionAttributes[partitionCount]));
+                    __KTRACE_OPT(KPBUSDRV, Kern::Printf(" "));
+    
+                    if(KPartitionTypePagedData == PartitionType)
+                        {
+                        foundSwap = ETrue;
+                        }
+    
+                    partitionCount++;
+                    }
+                }
+            } 
+		} 
 
 	// Validate partition address boundaries
 	if(partitionCount == 0)
--- a/kernel/eka/drivers/medmmc/bgahsmmcptn.h	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/drivers/medmmc/bgahsmmcptn.h	Fri Apr 16 16:24:37 2010 +0300
@@ -28,32 +28,36 @@
 
 /* Partition information version */
 #define BGAHSMMCPTN_PI_VER_MAJOR	1
-#define BGAHSMMCPTN_PI_VER_MINOR	0
+#define BGAHSMMCPTN_PI_VER_MINOR	1
+
+/* Partition type field supported from version 1.1 onwards */
+#define BGAHSMMCPTN_PART_TYPE_SUPP_VER_MINOR    1
 
 #define BGAHSMMCPTN_LAST_DRIVE		7 /* MMC1_DRIVECOUNT - defined in variantmediadef.h */
 
 typedef struct
 {
-	TUint32 start_sector;			/* Partition start sector */
-	TUint32 size;					/* Partition size in sectors */
-	TUint32 attributes;				/* RO, RW attributes (bitmask) */
-	TUint8  partition_id;			/* Partition number */
-	TUint8  reserved1[3];			/* Reserved (padding for compiler alignment)*/
-	TUint32 partition_attributes;	/* Partition attributes (see e32const.h) */
-	TUint8  reserved2[8];			/* Reserved */
+	TUint32 iStart_sector;			/* Partition start sector */
+	TUint32 iSize;					/* Partition size in sectors */
+	TUint32 iAttributes;			/* RO, RW attributes (bitmask) */
+	TUint8  iPartition_id;			/* Partition number - v1.0 - partition type v1.1 - drive number*/
+	TUint8  iPartition_type;         /* Partition Type - v1.1 onwards */
+	TUint8  iReserved1[2];			/* Reserved (padding for compiler alignment)*/
+	TUint32 iPartition_attributes;	/* Partition attributes (see e32const.h) */
+	TUint8  iReserved2[8];			/* Reserved */
 /* = 28 bytes */
 } BGAHSMMCPTN_PART_STR;
 
 typedef struct
 {
-	TUint8 id[BGAHSMMCPTN_PI_ID_SIZE];	/* Partition information version */
-	TUint32 sector_size;			/* Used sector size */
-	TUint16 major_ver;				/* Major version number */
-	TUint16 minor_ver;				/* Minor version number */
-	TUint16 partition_amount;		/* The amount of partitions */
-	TUint8 reserved[42];			/* Reserved */
+	TUint8  iId[BGAHSMMCPTN_PI_ID_SIZE];	/* Partition information version */
+	TUint32 iSector_size;			/* Used sector size */
+	TUint16 iMajor_ver;				/* Major version number */
+	TUint16 iMinor_ver;				/* Minor version number */
+	TUint16 iPartition_amount;		/* The amount of partitions */
+	TUint8  iReserved[42];			/* Reserved */
 /* = 64 bytes */
-	BGAHSMMCPTN_PART_STR partitions[BGAHSMMCPTN_LAST_DRIVE];
+	BGAHSMMCPTN_PART_STR iPartitions[BGAHSMMCPTN_LAST_DRIVE];	
 } BGAHSMMCPTN_PI_STR;
 
 #define BGAHSMMCPTN_PI_STR_SIZE sizeof( BGAHSMMCPTN_PI_STR )
--- a/kernel/eka/drivers/pbus/mmc/mmccd_init.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/drivers/pbus/mmc/mmccd_init.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -296,7 +296,7 @@
 				break;
 			}
 
-		if (mi.iFlags & TMMCMachineInfo::ESupportsDMA)
+		if ((mi.iFlags & TMMCMachineInfo::ESupportsDMA) == TMMCMachineInfo::ESupportsDMA)
 			{
 			err = LocDrv::RegisterDmaDevice(pMedia,
 											KMMCardHighCapBlockSize, 
--- a/kernel/eka/drivers/pbus/mmc/sdcard/Obtaining_PSL_Software_Source_Code.txt	Tue Feb 02 01:24:03 2010 +0200
+++ /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/bmarm/sdcard3c/epbusmu.def	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,115 @@
+EXPORTS
+	__9DMMCStackiP10DMMCSocket @ 1 NONAME ; DMMCStack::DMMCStack(int, DMMCSocket *)
+	AddNewCard__12TMMCardArrayPCUcP4TRCA @ 2 NONAME ; TMMCardArray::AddNewCard(unsigned char const *, TRCA *)
+	Add__11DPBusSocketP13TPBusCallBack @ 3 NONAME ; DPBusSocket::Add(TPBusCallBack *)
+	AllocCards__12TMMCardArray @ 4 NONAME ; TMMCardArray::AllocCards(void)
+	Block__9DMMCStackP11DMMCSessionUl @ 5 NONAME ; DMMCStack::Block(DMMCSession *, unsigned long)
+	CIMReadWriteBlocksSM__9DMMCStack @ 6 NONAME ; DMMCStack::CIMReadWriteBlocksSM(void)
+	CSDField__C4TCSDRCUiT1 @ 7 NONAME ; TCSD::CSDField(unsigned int const &, unsigned int const &) const
+	CardDetect__9DMMCStackUi @ 8 NONAME ; DMMCStack::CardDetect(unsigned int)
+	Create__16DMediaChangeBase @ 9 NONAME ; DMediaChangeBase::Create(void)
+	Create__26TMMCardControllerInterface @ 10 NONAME ; TMMCardControllerInterface::Create(void)
+	DeclareCardAsGone__12TMMCardArrayUi @ 11 NONAME ; TMMCardArray::DeclareCardAsGone(unsigned int)
+	DeltaCurrentConsumption__11DPBusSocketi @ 12 NONAME ; DPBusSocket::DeltaCurrentConsumption(int)
+	DeviceSize__C4TCSD @ 13 NONAME ; TCSD::DeviceSize(void) const
+	Direction__C15TMMCCommandDesc @ 14 NONAME ; TMMCCommandDesc::Direction(void) const
+	Dispatch__16TMMCStateMachine @ 15 NONAME ; TMMCStateMachine::Dispatch(void)
+	DoCreate__12DPBusPsuBase @ 16 NONAME ; DPBusPsuBase::DoCreate(void)
+	DoCreate__7DMMCPsu @ 17 NONAME ; DMMCPsu::DoCreate(void)
+	DoTickService__12DPBusPsuBase @ 18 NONAME ; DPBusPsuBase::DoTickService(void)
+	DoorClosedService__16DMediaChangeBase @ 19 NONAME ; DMediaChangeBase::DoorClosedService(void)
+	DoorOpenService__16DMediaChangeBase @ 20 NONAME ; DMediaChangeBase::DoorOpenService(void)
+	EffectiveModes__9DMMCStackRC15TMMCStackConfig @ 21 NONAME ; DMMCStack::EffectiveModes(TMMCStackConfig const &)
+	EndInCritical__11DPBusSocket @ 22 NONAME ; DPBusSocket::EndInCritical(void)
+	Engage__11DMMCSession @ 23 NONAME ; DMMCSession::Engage(void)
+	EpocErrorCode__C11DMMCSession @ 24 NONAME ; DMMCSession::EpocErrorCode(void) const
+	EraseGroupSize__C4TCSD @ 25 NONAME ; TCSD::EraseGroupSize(void) const
+	EraseSectorSize__C4TCSD @ 26 NONAME ; TCSD::EraseSectorSize(void) const
+	ForceMediaChange__11DPBusSocket @ 27 NONAME ; DPBusSocket::ForceMediaChange(void)
+	InCritical__11DPBusSocket @ 28 NONAME ; DPBusSocket::InCritical(void)
+	Init__9DMMCStack @ 29 NONAME ; DMMCStack::Init(void)
+	IsLocked__12DPBusPsuBase @ 30 NONAME ; DPBusPsuBase::IsLocked(void)
+	IsLocked__C7TMMCard @ 31 NONAME ; TMMCard::IsLocked(void) const
+	IsMappingIncorrect__17TMMCPasswordStoreRC4TCIDRCt5TBuf81i16 @ 32 NONAME ; TMMCPasswordStore::IsMappingIncorrect(TCID const &, TBuf8<16> const &)
+	IsReady__C7TMMCard @ 33 NONAME ; TMMCard::IsReady(void) const
+	Jump__16TMMCStateMachinePFPv_Uli @ 34 NONAME ; TMMCStateMachine::Jump(unsigned long (*)(void *), int)
+	MaxReadCurrentInMilliamps__C4TCSD @ 35 NONAME ; TCSD::MaxReadCurrentInMilliamps(void) const
+	MaxTranSpeedInKilohertz__C4TCSD @ 36 NONAME ; TCSD::MaxTranSpeedInKilohertz(void) const
+	MaxWriteCurrentInMilliamps__C4TCSD @ 37 NONAME ; TCSD::MaxWriteCurrentInMilliamps(void) const
+	MediaType__C4TCSD @ 38 NONAME ; TCSD::MediaType(void) const
+	MinReadCurrentInMilliamps__C4TCSD @ 39 NONAME ; TCSD::MinReadCurrentInMilliamps(void) const
+	MinWriteCurrentInMilliamps__C4TCSD @ 40 NONAME ; TCSD::MinWriteCurrentInMilliamps(void) const
+	Panic__10DMMCSocketQ210DMMCSocket9TMMCPanic @ 41 NONAME ; DMMCSocket::Panic(DMMCSocket::TMMCPanic)
+	Panic__11DPBusSocketQ211DPBusSocket6TPanic @ 42 NONAME ; DPBusSocket::Panic(DPBusSocket::TPanic)
+	PowerDownStack__9DMMCStack @ 43 NONAME ; DMMCStack::PowerDownStack(void)
+	PowerUpSequenceComplete__11DPBusSocketi @ 44 NONAME ; DPBusSocket::PowerUpSequenceComplete(int)
+	PowerUpStack__9DMMCStack @ 45 NONAME ; DMMCStack::PowerUpStack(void)
+	PowerUp__11DPBusSocket @ 46 NONAME ; DPBusSocket::PowerUp(void)
+	Push__16TMMCStateMachinePFPv_Uli @ 47 NONAME ; TMMCStateMachine::Push(unsigned long (*)(void *), int)
+	ReadBlockLength__C4TCSD @ 48 NONAME ; TCSD::ReadBlockLength(void) const
+	ReceiveVoltageCheckResult__12DPBusPsuBasei @ 49 NONAME ; DPBusPsuBase::ReceiveVoltageCheckResult(int)
+	Remove__13TPBusCallBack @ 50 NONAME ; TPBusCallBack::Remove(void)
+	Reset__16TMMCStateMachine @ 51 NONAME ; TMMCStateMachine::Reset(void)
+	SetCard__11DMMCSessionP7TMMCard @ 52 NONAME ; DMMCSession::SetCard(TMMCard *)
+	SetSocket__13TPBusCallBacki @ 53 NONAME ; TPBusCallBack::SetSocket(int)
+	SetState__12DPBusPsuBase13TPBusPsuState @ 54 NONAME ; DPBusPsuBase::SetState(TPBusPsuState)
+	SetupCIMEraseGroup__11DMMCSessionG12TMMCArgumentUl @ 55 NONAME ; DMMCSession::SetupCIMEraseGroup(TMMCArgument, unsigned long)
+	SetupCIMEraseSector__11DMMCSessionG12TMMCArgumentUl @ 56 NONAME ; DMMCSession::SetupCIMEraseSector(TMMCArgument, unsigned long)
+	SetupCIMLockUnlock__11DMMCSessionUlPUc @ 57 NONAME ; DMMCSession::SetupCIMLockUnlock(unsigned long, unsigned char *)
+	SetupCIMReadBlock__11DMMCSessionG12TMMCArgumentUlPUc @ 58 NONAME ; DMMCSession::SetupCIMReadBlock(TMMCArgument, unsigned long, unsigned char *)
+	SetupCIMReadIO__11DMMCSessionUcUlPUc @ 59 NONAME ; DMMCSession::SetupCIMReadIO(unsigned char, unsigned long, unsigned char *)
+	SetupCIMReadMBlock__11DMMCSessionG12TMMCArgumentUlPUcUl @ 60 NONAME ; DMMCSession::SetupCIMReadMBlock(TMMCArgument, unsigned long, unsigned char *, unsigned long)
+	SetupCIMWriteBlock__11DMMCSessionG12TMMCArgumentUlPUc @ 61 NONAME ; DMMCSession::SetupCIMWriteBlock(TMMCArgument, unsigned long, unsigned char *)
+	SetupCIMWriteIO__11DMMCSessionUcUlPUc @ 62 NONAME ; DMMCSession::SetupCIMWriteIO(unsigned char, unsigned long, unsigned char *)
+	SetupCIMWriteMBlock__11DMMCSessionG12TMMCArgumentUlPUcUl @ 63 NONAME ; DMMCSession::SetupCIMWriteMBlock(TMMCArgument, unsigned long, unsigned char *, unsigned long)
+	SetupCommand__11DMMCSession15TMMCCommandEnumG12TMMCArgument @ 64 NONAME ; DMMCSession::SetupCommand(TMMCCommandEnum, TMMCArgument)
+	SetupDTCommand__11DMMCSession15TMMCCommandEnumG12TMMCArgumentUlPUcUli14TMMCCmdDirEnumUl @ 65 NONAME ; DMMCSession::SetupDTCommand(TMMCCommandEnum, TMMCArgument, unsigned long, unsigned char *, unsigned long, int, TMMCCmdDirEnum, unsigned long)
+	SetupRSCommand__11DMMCSession15TMMCCommandEnumG12TMMCArgumentUl19TMMCCommandTypeEnum20TMMCResponseTypeEnumUl @ 66 NONAME ; DMMCSession::SetupRSCommand(TMMCCommandEnum, TMMCArgument, unsigned long, TMMCCommandTypeEnum, TMMCResponseTypeEnum, unsigned long)
+	SocketFromId__11DPBusSocketi @ 67 NONAME ; DPBusSocket::SocketFromId(int)
+	Stop__9DMMCStackP7TMMCard @ 68 NONAME ; DMMCStack::Stop(TMMCard *)
+	UnBlock__9DMMCStackP11DMMCSessionUlUl @ 69 NONAME ; DMMCStack::UnBlock(DMMCSession *, unsigned long, unsigned long)
+	WriteBlockLength__C4TCSD @ 70 NONAME ; TCSD::WriteBlockLength(void) const
+	WriteProtected__9DMMCStackUi @ 71 NONAME ; DMMCStack::WriteProtected(unsigned int)
+	"_._11DMMCSession" @ 72 NONAME ; DMMCSession::~DMMCSession(void)
+	__10DMMCSocketiP17TMMCPasswordStore @ 73 NONAME ; DMMCSocket::DMMCSocket(int, TMMCPasswordStore *)
+	__11DMMCSessionRC12TMMCCallBack @ 74 NONAME ; DMMCSession::DMMCSession(TMMCCallBack const &)
+	__13TPBusCallBack @ 75 NONAME ; TPBusCallBack::TPBusCallBack(void)
+	__13TPBusCallBackPFPviPvPv_vPv @ 76 NONAME ; TPBusCallBack::TPBusCallBack(void (*)(void *, int, void *, void *), void *)
+	__13TPBusCallBackPFPvi_vPvUi @ 77 NONAME ; TPBusCallBack::TPBusCallBack(void (*)(void *, int), void *, unsigned int)
+	__15DMMCMediaChangei @ 78 NONAME ; DMMCMediaChange::DMMCMediaChange(int)
+	__16DMediaChangeBasei @ 79 NONAME ; DMediaChangeBase::DMediaChangeBase(int)
+	__7DMMCPsuii @ 80 NONAME ; DMMCPsu::DMMCPsu(int, int)
+	AcquireStackSM__9DMMCStack @ 81 NONAME ; DMMCStack::AcquireStackSM(void)
+	Create__15DMMCMediaChange @ 82 NONAME ; DMMCMediaChange::Create(void)
+	AllocSession__C9DMMCStackRC12TMMCCallBack @ 83 NONAME ; DMMCStack::AllocSession(TMMCCallBack const &) const
+	CIMReadWriteBlocksSMST__9DMMCStackPv @ 84 NONAME ; DMMCStack::CIMReadWriteBlocksSMST(void *)
+	CardRCA__11DMMCSession @ 85 NONAME ; DMMCSession::CardRCA(void)
+	FillCommandArgs__11DMMCSessionG12TMMCArgumentUlPUcUl @ 86 NONAME ; DMMCSession::FillCommandArgs(TMMCArgument, unsigned long, unsigned char *, unsigned long)
+	FillCommandDesc__11DMMCSession @ 87 NONAME ; DMMCSession::FillCommandDesc(void)
+	FillCommandDesc__11DMMCSession15TMMCCommandEnum @ 88 NONAME ; DMMCSession::FillCommandDesc(TMMCCommandEnum)
+	FillCommandDesc__11DMMCSession15TMMCCommandEnumG12TMMCArgument @ 89 NONAME ; DMMCSession::FillCommandDesc(TMMCCommandEnum, TMMCArgument)
+	GetMacro__C11DMMCSessioni @ 90 NONAME ; DMMCSession::GetMacro(int) const
+	IssueMMCCommandSMST__9DMMCStackPv @ 91 NONAME ; DMMCStack::IssueMMCCommandSMST(void *)
+	PowerDownComplete__11DPBusSocket @ 92 NONAME ; DPBusSocket::PowerDownComplete(void)
+	RequestAsyncPowerDown__11DPBusSocket @ 93 NONAME ; DPBusSocket::RequestAsyncPowerDown(void)
+	InitStackAfterUnlockSM__9DMMCStack @ 94 NONAME ; DMMCStack::InitStackAfterUnlockSM(void)
+	RegisterMediaDevices__26TMMCardControllerInterfacei @ 95 NONAME ; TMMCardControllerInterface::RegisterMediaDevices(int)
+	ModifyCardCapabilitySM__9DMMCStack @ 96 NONAME R3UNUSED ; DMMCStack::ModifyCardCapabilitySM(void)
+	Dummy1__9DMMCStack @ 97 NONAME R3UNUSED ; DMMCStack::Dummy1(void)
+	GetInterface__9DMMCStackQ29DMMCStack12TInterfaceIdRPQ29DMMCStack10MInterface @ 98 NONAME R3UNUSED ; DMMCStack::GetInterface(DMMCStack::TInterfaceId, DMMCStack::MInterface *&)
+	MachineInfo__9DMMCStackR5TDes8 @ 99 NONAME R3UNUSED ; DMMCStack::MachineInfo(TDes8 &)
+	SetBusWidth__9DMMCStackUl @ 100 NONAME R3UNUSED ; DMMCStack::SetBusWidth(unsigned long)
+	ControlIO__11DPBusSocketiPvT2 @ 101 NONAME ; DPBusSocket::ControlIO(int, void *, void *)
+	AllocCards__12TSDCardArray @ 102 NONAME R3UNUSED ; TSDCardArray::AllocCards(void)
+	AllocSession__C8DSDStackRC12TMMCCallBack @ 103 NONAME R3UNUSED ; DSDStack::AllocSession(TMMCCallBack const &) const
+	CIMReadWriteBlocksSM__8DSDStack @ 104 NONAME R3UNUSED ; DSDStack::CIMReadWriteBlocksSM(void)
+	DeclareCardAsGone__12TSDCardArrayUi @ 105 NONAME R3UNUSED ; TSDCardArray::DeclareCardAsGone(unsigned int)
+	Dummy1__8DSDStack @ 106 NONAME R3UNUSED ; DSDStack::Dummy1(void)
+	Dummy2__8DSDStack @ 107 NONAME R3UNUSED ; DSDStack::Dummy2(void)
+	Dummy3__8DSDStack @ 108 NONAME R3UNUSED ; DSDStack::Dummy3(void)
+	CardType__8DSDStackii @ 109 NONAME R3UNUSED ; DSDStack::CardType(int, int)
+	InitStackAfterUnlockSM__8DSDStack @ 110 NONAME R3UNUSED ; DSDStack::InitStackAfterUnlockSM(void)
+	Init__8DSDStack @ 111 NONAME R3UNUSED ; DSDStack::Init(void)
+	ModifyCardCapabilitySM__8DSDStack @ 112 NONAME R3UNUSED ; DSDStack::ModifyCardCapabilitySM(void)
+	AcquireStackSM__8DSDStack @ 113 NONAME R3UNUSED ; DSDStack::AcquireStackSM(void)
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kernel/eka/drivers/pbus/mmc/sdcard/bmarm/sdcard3c/sdio/epbusmu.def	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,217 @@
+EXPORTS
+	__9DMMCStackiP10DMMCSocket @ 1 NONAME ; DMMCStack::DMMCStack(int, DMMCSocket *)
+	AddNewCard__12TMMCardArrayPCUcP4TRCA @ 2 NONAME ; TMMCardArray::AddNewCard(unsigned char const *, TRCA *)
+	Add__11DPBusSocketP13TPBusCallBack @ 3 NONAME ; DPBusSocket::Add(TPBusCallBack *)
+	AllocCards__12TMMCardArray @ 4 NONAME ; TMMCardArray::AllocCards(void)
+	Block__9DMMCStackP11DMMCSessionUl @ 5 NONAME ; DMMCStack::Block(DMMCSession *, unsigned long)
+	CIMReadWriteBlocksSM__9DMMCStack @ 6 NONAME ; DMMCStack::CIMReadWriteBlocksSM(void)
+	CSDField__C4TCSDRCUiT1 @ 7 NONAME ; TCSD::CSDField(unsigned int const &, unsigned int const &) const
+	CardDetect__9DMMCStackUi @ 8 NONAME ; DMMCStack::CardDetect(unsigned int)
+	Create__16DMediaChangeBase @ 9 NONAME ; DMediaChangeBase::Create(void)
+	Create__26TMMCardControllerInterface @ 10 NONAME ; TMMCardControllerInterface::Create(void)
+	DeclareCardAsGone__12TMMCardArrayUi @ 11 NONAME ; TMMCardArray::DeclareCardAsGone(unsigned int)
+	DeltaCurrentConsumption__11DPBusSocketi @ 12 NONAME ; DPBusSocket::DeltaCurrentConsumption(int)
+	DeviceSize__C4TCSD @ 13 NONAME ; TCSD::DeviceSize(void) const
+	Direction__C15TMMCCommandDesc @ 14 NONAME ; TMMCCommandDesc::Direction(void) const
+	Dispatch__16TMMCStateMachine @ 15 NONAME ; TMMCStateMachine::Dispatch(void)
+	DoCreate__12DPBusPsuBase @ 16 NONAME ; DPBusPsuBase::DoCreate(void)
+	DoCreate__7DMMCPsu @ 17 NONAME ; DMMCPsu::DoCreate(void)
+	DoTickService__12DPBusPsuBase @ 18 NONAME ; DPBusPsuBase::DoTickService(void)
+	DoorClosedService__16DMediaChangeBase @ 19 NONAME ; DMediaChangeBase::DoorClosedService(void)
+	DoorOpenService__16DMediaChangeBase @ 20 NONAME ; DMediaChangeBase::DoorOpenService(void)
+	EffectiveModes__9DMMCStackRC15TMMCStackConfig @ 21 NONAME ; DMMCStack::EffectiveModes(TMMCStackConfig const &)
+	EndInCritical__11DPBusSocket @ 22 NONAME ; DPBusSocket::EndInCritical(void)
+	Engage__11DMMCSession @ 23 NONAME ; DMMCSession::Engage(void)
+	EpocErrorCode__C11DMMCSession @ 24 NONAME ; DMMCSession::EpocErrorCode(void) const
+	EraseGroupSize__C4TCSD @ 25 NONAME ; TCSD::EraseGroupSize(void) const
+	EraseSectorSize__C4TCSD @ 26 NONAME ; TCSD::EraseSectorSize(void) const
+	ForceMediaChange__11DPBusSocket @ 27 NONAME ; DPBusSocket::ForceMediaChange(void)
+	InCritical__11DPBusSocket @ 28 NONAME ; DPBusSocket::InCritical(void)
+	Init__9DMMCStack @ 29 NONAME ; DMMCStack::Init(void)
+	IsLocked__12DPBusPsuBase @ 30 NONAME ; DPBusPsuBase::IsLocked(void)
+	IsLocked__C7TMMCard @ 31 NONAME ; TMMCard::IsLocked(void) const
+	IsMappingIncorrect__17TMMCPasswordStoreRC4TCIDRCt5TBuf81i16 @ 32 NONAME ; TMMCPasswordStore::IsMappingIncorrect(TCID const &, TBuf8<16> const &)
+	IsReady__C7TMMCard @ 33 NONAME ; TMMCard::IsReady(void) const
+	Jump__16TMMCStateMachinePFPv_Uli @ 34 NONAME ; TMMCStateMachine::Jump(unsigned long (*)(void *), int)
+	MaxReadCurrentInMilliamps__C4TCSD @ 35 NONAME ; TCSD::MaxReadCurrentInMilliamps(void) const
+	MaxTranSpeedInKilohertz__C4TCSD @ 36 NONAME ; TCSD::MaxTranSpeedInKilohertz(void) const
+	MaxWriteCurrentInMilliamps__C4TCSD @ 37 NONAME ; TCSD::MaxWriteCurrentInMilliamps(void) const
+	MediaType__C4TCSD @ 38 NONAME ; TCSD::MediaType(void) const
+	MinReadCurrentInMilliamps__C4TCSD @ 39 NONAME ; TCSD::MinReadCurrentInMilliamps(void) const
+	MinWriteCurrentInMilliamps__C4TCSD @ 40 NONAME ; TCSD::MinWriteCurrentInMilliamps(void) const
+	Panic__10DMMCSocketQ210DMMCSocket9TMMCPanic @ 41 NONAME ; DMMCSocket::Panic(DMMCSocket::TMMCPanic)
+	Panic__11DPBusSocketQ211DPBusSocket6TPanic @ 42 NONAME ; DPBusSocket::Panic(DPBusSocket::TPanic)
+	PowerDownStack__9DMMCStack @ 43 NONAME ; DMMCStack::PowerDownStack(void)
+	PowerUpSequenceComplete__11DPBusSocketi @ 44 NONAME ; DPBusSocket::PowerUpSequenceComplete(int)
+	PowerUpStack__9DMMCStack @ 45 NONAME ; DMMCStack::PowerUpStack(void)
+	PowerUp__11DPBusSocket @ 46 NONAME ; DPBusSocket::PowerUp(void)
+	Push__16TMMCStateMachinePFPv_Uli @ 47 NONAME ; TMMCStateMachine::Push(unsigned long (*)(void *), int)
+	ReadBlockLength__C4TCSD @ 48 NONAME ; TCSD::ReadBlockLength(void) const
+	ReceiveVoltageCheckResult__12DPBusPsuBasei @ 49 NONAME ; DPBusPsuBase::ReceiveVoltageCheckResult(int)
+	Remove__13TPBusCallBack @ 50 NONAME ; TPBusCallBack::Remove(void)
+	Reset__16TMMCStateMachine @ 51 NONAME ; TMMCStateMachine::Reset(void)
+	SetCard__11DMMCSessionP7TMMCard @ 52 NONAME ; DMMCSession::SetCard(TMMCard *)
+	SetSocket__13TPBusCallBacki @ 53 NONAME ; TPBusCallBack::SetSocket(int)
+	SetState__12DPBusPsuBase13TPBusPsuState @ 54 NONAME ; DPBusPsuBase::SetState(TPBusPsuState)
+	SetupCIMEraseGroup__11DMMCSessionG12TMMCArgumentUl @ 55 NONAME ; DMMCSession::SetupCIMEraseGroup(TMMCArgument, unsigned long)
+	SetupCIMEraseSector__11DMMCSessionG12TMMCArgumentUl @ 56 NONAME ; DMMCSession::SetupCIMEraseSector(TMMCArgument, unsigned long)
+	SetupCIMLockUnlock__11DMMCSessionUlPUc @ 57 NONAME ; DMMCSession::SetupCIMLockUnlock(unsigned long, unsigned char *)
+	SetupCIMReadBlock__11DMMCSessionG12TMMCArgumentUlPUc @ 58 NONAME ; DMMCSession::SetupCIMReadBlock(TMMCArgument, unsigned long, unsigned char *)
+	SetupCIMReadIO__11DMMCSessionUcUlPUc @ 59 NONAME ; DMMCSession::SetupCIMReadIO(unsigned char, unsigned long, unsigned char *)
+	SetupCIMReadMBlock__11DMMCSessionG12TMMCArgumentUlPUcUl @ 60 NONAME ; DMMCSession::SetupCIMReadMBlock(TMMCArgument, unsigned long, unsigned char *, unsigned long)
+	SetupCIMWriteBlock__11DMMCSessionG12TMMCArgumentUlPUc @ 61 NONAME ; DMMCSession::SetupCIMWriteBlock(TMMCArgument, unsigned long, unsigned char *)
+	SetupCIMWriteIO__11DMMCSessionUcUlPUc @ 62 NONAME ; DMMCSession::SetupCIMWriteIO(unsigned char, unsigned long, unsigned char *)
+	SetupCIMWriteMBlock__11DMMCSessionG12TMMCArgumentUlPUcUl @ 63 NONAME ; DMMCSession::SetupCIMWriteMBlock(TMMCArgument, unsigned long, unsigned char *, unsigned long)
+	SetupCommand__11DMMCSession15TMMCCommandEnumG12TMMCArgument @ 64 NONAME ; DMMCSession::SetupCommand(TMMCCommandEnum, TMMCArgument)
+	SetupDTCommand__11DMMCSession15TMMCCommandEnumG12TMMCArgumentUlPUcUli14TMMCCmdDirEnumUl @ 65 NONAME ; DMMCSession::SetupDTCommand(TMMCCommandEnum, TMMCArgument, unsigned long, unsigned char *, unsigned long, int, TMMCCmdDirEnum, unsigned long)
+	SetupRSCommand__11DMMCSession15TMMCCommandEnumG12TMMCArgumentUl19TMMCCommandTypeEnum20TMMCResponseTypeEnumUl @ 66 NONAME ; DMMCSession::SetupRSCommand(TMMCCommandEnum, TMMCArgument, unsigned long, TMMCCommandTypeEnum, TMMCResponseTypeEnum, unsigned long)
+	SocketFromId__11DPBusSocketi @ 67 NONAME ; DPBusSocket::SocketFromId(int)
+	Stop__9DMMCStackP7TMMCard @ 68 NONAME ; DMMCStack::Stop(TMMCard *)
+	UnBlock__9DMMCStackP11DMMCSessionUlUl @ 69 NONAME ; DMMCStack::UnBlock(DMMCSession *, unsigned long, unsigned long)
+	WriteBlockLength__C4TCSD @ 70 NONAME ; TCSD::WriteBlockLength(void) const
+	WriteProtected__9DMMCStackUi @ 71 NONAME ; DMMCStack::WriteProtected(unsigned int)
+	"_._11DMMCSession" @ 72 NONAME ; DMMCSession::~DMMCSession(void)
+	__10DMMCSocketiP17TMMCPasswordStore @ 73 NONAME ; DMMCSocket::DMMCSocket(int, TMMCPasswordStore *)
+	__11DMMCSessionRC12TMMCCallBack @ 74 NONAME ; DMMCSession::DMMCSession(TMMCCallBack const &)
+	__13TPBusCallBack @ 75 NONAME ; TPBusCallBack::TPBusCallBack(void)
+	__13TPBusCallBackPFPviPvPv_vPv @ 76 NONAME ; TPBusCallBack::TPBusCallBack(void (*)(void *, int, void *, void *), void *)
+	__13TPBusCallBackPFPvi_vPvUi @ 77 NONAME ; TPBusCallBack::TPBusCallBack(void (*)(void *, int), void *, unsigned int)
+	__15DMMCMediaChangei @ 78 NONAME ; DMMCMediaChange::DMMCMediaChange(int)
+	__16DMediaChangeBasei @ 79 NONAME ; DMediaChangeBase::DMediaChangeBase(int)
+	__7DMMCPsuii @ 80 NONAME ; DMMCPsu::DMMCPsu(int, int)
+	AcquireStackSM__9DMMCStack @ 81 NONAME ; DMMCStack::AcquireStackSM(void)
+	Create__15DMMCMediaChange @ 82 NONAME ; DMMCMediaChange::Create(void)
+	AllocSession__C9DMMCStackRC12TMMCCallBack @ 83 NONAME ; DMMCStack::AllocSession(TMMCCallBack const &) const
+	CIMReadWriteBlocksSMST__9DMMCStackPv @ 84 NONAME ; DMMCStack::CIMReadWriteBlocksSMST(void *)
+	CardRCA__11DMMCSession @ 85 NONAME ; DMMCSession::CardRCA(void)
+	FillCommandArgs__11DMMCSessionG12TMMCArgumentUlPUcUl @ 86 NONAME ; DMMCSession::FillCommandArgs(TMMCArgument, unsigned long, unsigned char *, unsigned long)
+	FillCommandDesc__11DMMCSession @ 87 NONAME ; DMMCSession::FillCommandDesc(void)
+	FillCommandDesc__11DMMCSession15TMMCCommandEnum @ 88 NONAME ; DMMCSession::FillCommandDesc(TMMCCommandEnum)
+	FillCommandDesc__11DMMCSession15TMMCCommandEnumG12TMMCArgument @ 89 NONAME ; DMMCSession::FillCommandDesc(TMMCCommandEnum, TMMCArgument)
+	GetMacro__C11DMMCSessioni @ 90 NONAME ; DMMCSession::GetMacro(int) const
+	IssueMMCCommandSMST__9DMMCStackPv @ 91 NONAME ; DMMCStack::IssueMMCCommandSMST(void *)
+	PowerDownComplete__11DPBusSocket @ 92 NONAME ; DPBusSocket::PowerDownComplete(void)
+	RequestAsyncPowerDown__11DPBusSocket @ 93 NONAME ; DPBusSocket::RequestAsyncPowerDown(void)
+	InitStackAfterUnlockSM__9DMMCStack @ 94 NONAME ; DMMCStack::InitStackAfterUnlockSM(void)
+	RegisterMediaDevices__26TMMCardControllerInterfacei @ 95 NONAME ; TMMCardControllerInterface::RegisterMediaDevices(int)
+	ModifyCardCapabilitySM__9DMMCStack @ 96 NONAME R3UNUSED ; DMMCStack::ModifyCardCapabilitySM(void)
+	Dummy1__9DMMCStack @ 97 NONAME R3UNUSED ; DMMCStack::Dummy1(void)
+	GetInterface__9DMMCStackQ29DMMCStack12TInterfaceIdRPQ29DMMCStack10MInterface @ 98 NONAME R3UNUSED ; DMMCStack::GetInterface(DMMCStack::TInterfaceId, DMMCStack::MInterface *&)
+	MachineInfo__9DMMCStackR5TDes8 @ 99 NONAME R3UNUSED ; DMMCStack::MachineInfo(TDes8 &)
+	SetBusWidth__9DMMCStackUl @ 100 NONAME R3UNUSED ; DMMCStack::SetBusWidth(unsigned long)
+	ControlIO__11DPBusSocketiPvT2 @ 101 NONAME ; DPBusSocket::ControlIO(int, void *, void *)
+	AllocCards__12TSDCardArray @ 102 NONAME R3UNUSED ; TSDCardArray::AllocCards(void)
+	AllocSession__C8DSDStackRC12TMMCCallBack @ 103 NONAME R3UNUSED ; DSDStack::AllocSession(TMMCCallBack const &) const
+	CIMReadWriteBlocksSM__8DSDStack @ 104 NONAME R3UNUSED ; DSDStack::CIMReadWriteBlocksSM(void)
+	DeclareCardAsGone__12TSDCardArrayUi @ 105 NONAME R3UNUSED ; TSDCardArray::DeclareCardAsGone(unsigned int)
+	Dummy1__8DSDStack @ 106 NONAME R3UNUSED ; DSDStack::Dummy1(void)
+	Dummy2__8DSDStack @ 107 NONAME R3UNUSED ; DSDStack::Dummy2(void)
+	Dummy3__8DSDStack @ 108 NONAME R3UNUSED ; DSDStack::Dummy3(void)
+	CardType__8DSDStackii @ 109 NONAME R3UNUSED ; DSDStack::CardType(int, int)
+	InitStackAfterUnlockSM__8DSDStack @ 110 NONAME R3UNUSED ; DSDStack::InitStackAfterUnlockSM(void)
+	Init__8DSDStack @ 111 NONAME R3UNUSED ; DSDStack::Init(void)
+	ModifyCardCapabilitySM__8DSDStack @ 112 NONAME R3UNUSED ; DSDStack::ModifyCardCapabilitySM(void)
+	AcquireStackSM__8DSDStack @ 113 NONAME R3UNUSED ; DSDStack::AcquireStackSM(void)
+	DummyExport10__13DDummySession @ 114 NONAME R3UNUSED ; DDummySession::DummyExport10(void)
+	DummyExport11__13DDummySession @ 115 NONAME R3UNUSED ; DDummySession::DummyExport11(void)
+	DummyExport12__13DDummySession @ 116 NONAME R3UNUSED ; DDummySession::DummyExport12(void)
+	DummyExport13__13DDummySession @ 117 NONAME R3UNUSED ; DDummySession::DummyExport13(void)
+	DummyExport14__13DDummySession @ 118 NONAME R3UNUSED ; DDummySession::DummyExport14(void)
+	DummyExport15__13DDummySession @ 119 NONAME R3UNUSED ; DDummySession::DummyExport15(void)
+	DummyExport1__13DDummySession @ 120 NONAME R3UNUSED ; DDummySession::DummyExport1(void)
+	DummyExport2__13DDummySession @ 121 NONAME R3UNUSED ; DDummySession::DummyExport2(void)
+	DummyExport3__13DDummySession @ 122 NONAME R3UNUSED ; DDummySession::DummyExport3(void)
+	DummyExport4__13DDummySession @ 123 NONAME R3UNUSED ; DDummySession::DummyExport4(void)
+	DummyExport5__13DDummySession @ 124 NONAME R3UNUSED ; DDummySession::DummyExport5(void)
+	DummyExport6__13DDummySession @ 125 NONAME R3UNUSED ; DDummySession::DummyExport6(void)
+	DummyExport7__13DDummySession @ 126 NONAME R3UNUSED ; DDummySession::DummyExport7(void)
+	DummyExport8__13DDummySession @ 127 NONAME R3UNUSED ; DDummySession::DummyExport8(void)
+	DummyExport9__13DDummySession @ 128 NONAME R3UNUSED ; DDummySession::DummyExport9(void)
+	AllocCards__14TSDIOCardArray @ 129 NONAME R3UNUSED ; TSDIOCardArray::AllocCards(void)
+	AllocSession__C10DSDIOStackRC12TMMCCallBack @ 130 NONAME R3UNUSED ; DSDIOStack::AllocSession(TMMCCallBack const &) const
+	Bind__14TSDIOInterruptPFPv_vPv @ 131 NONAME R3UNUSED ; TSDIOInterrupt::Bind(void (*)(void *), void *)
+	BlockIOSession__10DSDIOStackQ210DSDIOStack22TSDIOBlockingCondition @ 132 NONAME R3UNUSED ; DSDIOStack::BlockIOSession(DSDIOStack::TSDIOBlockingCondition)
+	CIMIoModifySM__10DSDIOStack @ 133 NONAME R3UNUSED ; DSDIOStack::CIMIoModifySM(void)
+	CIMIoReadWriteDirectSM__10DSDIOStack @ 134 NONAME R3UNUSED ; DSDIOStack::CIMIoReadWriteDirectSM(void)
+	CIMIoReadWriteExtendedSM__10DSDIOStack @ 135 NONAME R3UNUSED ; DSDIOStack::CIMIoReadWriteExtendedSM(void)
+	CIMReadWriteBlocksSM__10DSDIOStack @ 136 NONAME R3UNUSED ; DSDIOStack::CIMReadWriteBlocksSM(void)
+	CapabilitiesMatch__17TSDIOFunctionCapsR17TSDIOFunctionCapsUl @ 137 NONAME R3UNUSED ; TSDIOFunctionCaps::CapabilitiesMatch(TSDIOFunctionCaps &, unsigned long)
+	CheckCIS__9TSDIOCard @ 138 NONAME R3UNUSED ; TSDIOCard::CheckCIS(void)
+	DeclareCardAsGone__14TSDIOCardArrayUi @ 139 NONAME R3UNUSED ; TSDIOCardArray::DeclareCardAsGone(unsigned int)
+	DeregisterClient__13TSDIOFunctionP5DBase @ 140 NONAME R3UNUSED ; TSDIOFunction::DeregisterClient(DBase *)
+	Disable__13TSDIOFunction @ 141 NONAME R3UNUSED ; TSDIOFunction::Disable(void)
+	Disable__14TSDIOInterrupt @ 142 NONAME R3UNUSED ; TSDIOInterrupt::Disable(void)
+	DoCreate__8DSDIOPsu @ 143 NONAME R3UNUSED ; DSDIOPsu::DoCreate(void)
+	DoTickService__8DSDIOPsu @ 144 NONAME R3UNUSED ; DSDIOPsu::DoTickService(void)
+	Dummy1__10DSDIOStack @ 145 NONAME R3UNUSED ; DSDIOStack::Dummy1(void)
+	Dummy2__10DSDIOStack @ 146 NONAME R3UNUSED ; DSDIOStack::Dummy2(void)
+	Dummy3__10DSDIOStack @ 147 NONAME R3UNUSED ; DSDIOStack::Dummy3(void)
+	Dummy4__10DSDIOStack @ 148 NONAME R3UNUSED ; DSDIOStack::Dummy4(void)
+	Enable__13TSDIOFunctioni @ 149 NONAME R3UNUSED ; TSDIOFunction::Enable(int)
+	Enable__14TSDIOInterrupt @ 150 NONAME R3UNUSED ; TSDIOInterrupt::Enable(void)
+	FillAppCommandDesc__12DSDIOSessionR15TMMCCommandDesc @ 151 NONAME R3UNUSED ; DSDIOSession::FillAppCommandDesc(TMMCCommandDesc &)
+	FillAppCommandDesc__12DSDIOSessionR15TMMCCommandDesc11TSDIOAppCmd @ 152 NONAME R3UNUSED ; DSDIOSession::FillAppCommandDesc(TMMCCommandDesc &, TSDIOAppCmd)
+	FillAppCommandDesc__12DSDIOSessionR15TMMCCommandDesc11TSDIOAppCmdG12TMMCArgument @ 153 NONAME R3UNUSED ; DSDIOSession::FillAppCommandDesc(TMMCCommandDesc &, TSDIOAppCmd, TMMCArgument)
+	FindFunction__C9TSDIOCardR17TSDIOFunctionCapsUlP13TSDIOFunction @ 154 NONAME ; TSDIOCard::FindFunction(TSDIOFunctionCaps &, unsigned long, TSDIOFunction *) const
+	FindReadCommonConfig__10TCisReaderR15TSDIOCardConfig @ 155 NONAME R3UNUSED ; TCisReader::FindReadCommonConfig(TSDIOCardConfig &)
+	FindReadFunctionConfig__10TCisReaderR17TSDIOFunctionCaps @ 156 NONAME R3UNUSED ; TCisReader::FindReadFunctionConfig(TSDIOFunctionCaps &)
+	FindReadTuple__10TCisReaderUcR5TDes8Ui @ 157 NONAME ; TCisReader::FindReadTuple(unsigned char, TDes8 &, unsigned int)
+	GetMacro__C12DSDIOSessioni @ 158 NONAME R3UNUSED ; DSDIOSession::GetMacro(int) const
+	HandleSDIOInterrupt__10DSDIOStackUi @ 159 NONAME R3UNUSED ; DSDIOStack::HandleSDIOInterrupt(unsigned int)
+	Init__10DSDIOStack @ 160 NONAME R3UNUSED ; DSDIOStack::Init(void)
+	IsLocked__8DSDIOPsu @ 161 NONAME R3UNUSED ; DSDIOPsu::IsLocked(void)
+	IsReady__13TSDIOFunctionRi @ 162 NONAME R3UNUSED ; TSDIOFunction::IsReady(int &)
+	Modify8__22DSDIORegisterInterfaceUlUcUcPUc @ 163 NONAME ; DSDIORegisterInterface::Modify8(unsigned long, unsigned char, unsigned char, unsigned char *)
+	ModifyCardCapabilitySM__10DSDIOStack @ 164 NONAME R3UNUSED ; DSDIOStack::ModifyCardCapabilitySM(void)
+	Read8__22DSDIORegisterInterfaceUlPUc @ 165 NONAME R3UNUSED ; DSDIORegisterInterface::Read8(unsigned long, unsigned char *)
+	ReadMultiple8__22DSDIORegisterInterfaceUlPUcUli @ 166 NONAME ; DSDIORegisterInterface::ReadMultiple8(unsigned long, unsigned char *, unsigned long, int)
+	ReadTuple__10TCisReaderR5TDes8 @ 167 NONAME R3UNUSED ; TCisReader::ReadTuple(TDes8 &)
+	RegisterClient__13TSDIOFunctionP5DBaseP6DMutex @ 168 NONAME R3UNUSED ; TSDIOFunction::RegisterClient(DBase *, DMutex *)
+	RegisterMediaDevices__28TSDIOCardControllerInterfacei @ 169 NONAME R3UNUSED ; TSDIOCardControllerInterface::RegisterMediaDevices(int)
+	Register__21TSDIOFunctionCallbackP10DMMCSocket @ 170 NONAME R3UNUSED ; TSDIOFunctionCallback::Register(DMMCSocket *)
+	RequestAsyncSleep__11DSDIOSocket @ 171 NONAME R3UNUSED ; DSDIOSocket::RequestAsyncSleep(void)
+	Restart__10TCisReader @ 172 NONAME R3UNUSED ; TCisReader::Restart(void)
+	SelectCis__10TCisReaderUiUiUiUc @ 173 NONAME ; TCisReader::SelectCis(unsigned int, unsigned int, unsigned int, unsigned char)
+	SetAsync__22DSDIORegisterInterfaceR12TMMCCallBack @ 174 NONAME R3UNUSED ; DSDIORegisterInterface::SetAsync(TMMCCallBack &)
+	SetPriority__13TSDIOFunction21TSDIOFunctionPriority @ 175 NONAME R3UNUSED ; TSDIOFunction::SetPriority(TSDIOFunctionPriority)
+	SetSync__22DSDIORegisterInterface @ 176 NONAME R3UNUSED ; DSDIORegisterInterface::SetSync(void)
+	SetupCIMIoModify__12DSDIOSessionUlUcUcPUc @ 177 NONAME ; DSDIOSession::SetupCIMIoModify(unsigned long, unsigned char, unsigned char, unsigned char *)
+	SetupCIMIoReadMultiple__12DSDIOSessionUlUlPUci @ 178 NONAME ; DSDIOSession::SetupCIMIoReadMultiple(unsigned long, unsigned long, unsigned char *, int)
+	SetupCIMIoRead__12DSDIOSessionUlPUc @ 179 NONAME R3UNUSED ; DSDIOSession::SetupCIMIoRead(unsigned long, unsigned char *)
+	SetupCIMIoWriteMultiple__12DSDIOSessionUlUlPUci @ 180 NONAME ; DSDIOSession::SetupCIMIoWriteMultiple(unsigned long, unsigned long, unsigned char *, int)
+	SetupCIMIoWrite__12DSDIOSessionUlUcPUc @ 181 NONAME ; DSDIOSession::SetupCIMIoWrite(unsigned long, unsigned char, unsigned char *)
+	SleepComplete__11DSDIOSocket @ 182 NONAME R3UNUSED ; DSDIOSocket::SleepComplete(void)
+	Unbind__14TSDIOInterrupt @ 183 NONAME R3UNUSED ; TSDIOInterrupt::Unbind(void)
+	UnblockIOSession__10DSDIOStackQ210DSDIOStack22TSDIOBlockingConditionUl @ 184 NONAME R3UNUSED ; DSDIOStack::UnblockIOSession(DSDIOStack::TSDIOBlockingCondition, unsigned long)
+	Write8__22DSDIORegisterInterfaceUlUcPUc @ 185 NONAME ; DSDIORegisterInterface::Write8(unsigned long, unsigned char, unsigned char *)
+	WriteMultiple8__22DSDIORegisterInterfaceUlPUcUli @ 186 NONAME ; DSDIORegisterInterface::WriteMultiple8(unsigned long, unsigned char *, unsigned long, int)
+	"_._13TSDIOFunction" @ 187 NONAME R3UNUSED ; TSDIOFunction::~TSDIOFunction(void)
+	"_._14TSDIOInterrupt" @ 188 NONAME R3UNUSED ; TSDIOInterrupt::~TSDIOInterrupt(void)
+	"_._22DSDIORegisterInterface" @ 189 NONAME R3UNUSED ; DSDIORegisterInterface::~DSDIORegisterInterface(void)
+	__10TCisReader @ 190 NONAME R3UNUSED ; TCisReader::TCisReader(void)
+	__11DSDIOSocketiP17TMMCPasswordStore @ 191 NONAME R3UNUSED ; DSDIOSocket::DSDIOSocket(int, TMMCPasswordStore *)
+	__13TSDIOFunctionP9TSDIOCardUc @ 192 NONAME R3UNUSED ; TSDIOFunction::TSDIOFunction(TSDIOCard *, unsigned char)
+	__14TSDIOInterruptP24TSDIOInterruptControllerUc @ 193 NONAME R3UNUSED ; TSDIOInterrupt::TSDIOInterrupt(TSDIOInterruptController *, unsigned char)
+	__15TSDIOCardConfig @ 194 NONAME R3UNUSED ; TSDIOCardConfig::TSDIOCardConfig(void)
+	__22DSDIORegisterInterfaceP9TSDIOCardUc @ 195 NONAME R3UNUSED ; DSDIORegisterInterface::DSDIORegisterInterface(TSDIOCard *, unsigned char)
+	__22DSDIORegisterInterfaceP9TSDIOCardUcP6DMutex @ 196 NONAME ; DSDIORegisterInterface::DSDIORegisterInterface(TSDIOCard *, unsigned char, DMutex *)
+	__8DSDIOPsuii @ 197 NONAME R3UNUSED ; DSDIOPsu::DSDIOPsu(int, int)
+	AcquireStackSM__10DSDIOStack @ 198 NONAME R3UNUSED ; DSDIOStack::AcquireStackSM(void)
+	ReadMultiple8__22DSDIORegisterInterfaceUlP6DChunkUlUli @ 199 NONAME ; DSDIORegisterInterface::ReadMultiple8(unsigned long, DChunk *, unsigned long, unsigned long, int)
+	WriteMultiple8__22DSDIORegisterInterfaceUlP6DChunkUlUli @ 200 NONAME ; DSDIORegisterInterface::WriteMultiple8(unsigned long, DChunk *, unsigned long, unsigned long, int)
+	"_._12DSDIOSession" @ 201 NONAME R3UNUSED ; DSDIOSession::~DSDIOSession(void)
+	Dummy1__12DSDIOSession @ 202  NONAME R3UNUSED ; DSDIOSession::Dummy1(void)
+	Dummy1__8DSDIOPsu @ 203  NONAME R3UNUSED ; DSDIOPsu::Dummy1(void)
+	Dummy2__12DSDIOSession @ 204  NONAME R3UNUSED ; DSDIOSession::Dummy2(void)
+	Dummy2__8DSDIOPsu @ 205  NONAME R3UNUSED ; DSDIOPsu::Dummy2(void)
+	Dummy3__12DSDIOSession @ 206  NONAME R3UNUSED ; DSDIOSession::Dummy3(void)
+	Dummy3__8DSDIOPsu @ 207  NONAME R3UNUSED ; DSDIOPsu::Dummy3(void)
+	Dummy4__12DSDIOSession @ 208  NONAME R3UNUSED ; DSDIOSession::Dummy4(void)
+	Dummy4__8DSDIOPsu @ 209  NONAME R3UNUSED ; DSDIOPsu::Dummy4(void)
+	Modify8__22DSDIORegisterInterfaceUlUcUc @ 210  NONAME ; DSDIORegisterInterface::Modify8(unsigned long, unsigned char, unsigned char)
+	ReadMultiple8__22DSDIORegisterInterfaceUlP6DChunkUlUl @ 211  NONAME ; DSDIORegisterInterface::ReadMultiple8(unsigned long, DChunk *, unsigned long, unsigned long)
+	ReadMultiple8__22DSDIORegisterInterfaceUlPUcUl @ 212  NONAME ; DSDIORegisterInterface::ReadMultiple8(unsigned long, unsigned char *, unsigned long)
+	Write8__22DSDIORegisterInterfaceUlUc @ 213  NONAME R3UNUSED ; DSDIORegisterInterface::Write8(unsigned long, unsigned char)
+	WriteMultiple8__22DSDIORegisterInterfaceUlP6DChunkUlUl @ 214  NONAME ; DSDIORegisterInterface::WriteMultiple8(unsigned long, DChunk *, unsigned long, unsigned long)
+	WriteMultiple8__22DSDIORegisterInterfaceUlPUcUl @ 215  NONAME ; DSDIORegisterInterface::WriteMultiple8(unsigned long, unsigned char *, unsigned long)
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kernel/eka/drivers/pbus/mmc/sdcard/bwins/sdcard3c/epbusmu.def	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,116 @@
+EXPORTS
+	??0DMMCMediaChange@@QAE@H@Z @ 1 NONAME ; public: __thiscall DMMCMediaChange::DMMCMediaChange(int)
+	??0DMMCPsu@@QAE@HH@Z @ 2 NONAME ; public: __thiscall DMMCPsu::DMMCPsu(int,int)
+	??0DMMCSession@@QAE@ABVTMMCCallBack@@@Z @ 3 NONAME ; public: __thiscall DMMCSession::DMMCSession(class TMMCCallBack const &)
+	??0DMMCSocket@@QAE@HPAVTMMCPasswordStore@@@Z @ 4 NONAME ; public: __thiscall DMMCSocket::DMMCSocket(int,class TMMCPasswordStore *)
+	??0DMMCStack@@QAE@HPAVDMMCSocket@@@Z @ 5 NONAME ; public: __thiscall DMMCStack::DMMCStack(int,class DMMCSocket *)
+	??0DMediaChangeBase@@QAE@H@Z @ 6 NONAME ; public: __thiscall DMediaChangeBase::DMediaChangeBase(int)
+	??0TPBusCallBack@@QAE@P6AXPAXH00@Z0@Z @ 7 NONAME ; public: __thiscall TPBusCallBack::TPBusCallBack(void (__cdecl*)(void *,int,void *,void *),void *)
+	??0TPBusCallBack@@QAE@P6AXPAXH@Z0I@Z @ 8 NONAME ; public: __thiscall TPBusCallBack::TPBusCallBack(void (__cdecl*)(void *,int),void *,unsigned int)
+	??0TPBusCallBack@@QAE@XZ @ 9 NONAME ; public: __thiscall TPBusCallBack::TPBusCallBack(void)
+	??1DMMCSession@@UAE@XZ @ 10 NONAME ; public: virtual __thiscall DMMCSession::~DMMCSession(void)
+	?AcquireStackSM@DMMCStack@@MAEKXZ @ 11 NONAME ; protected: virtual unsigned long __thiscall DMMCStack::AcquireStackSM(void)
+	?Add@DPBusSocket@@QAEXPAVTPBusCallBack@@@Z @ 12 NONAME ; public: void __thiscall DPBusSocket::Add(class TPBusCallBack *)
+	?AddNewCard@TMMCardArray@@QAEXPBEPAVTRCA@@@Z @ 13 NONAME ; public: void __thiscall TMMCardArray::AddNewCard(unsigned char const *,class TRCA *)
+	?AllocCards@TMMCardArray@@UAEHXZ @ 14 NONAME ; public: virtual int __thiscall TMMCardArray::AllocCards(void)
+	?AllocSession@DMMCStack@@UBEPAVDMMCSession@@ABVTMMCCallBack@@@Z @ 15 NONAME ; public: virtual class DMMCSession * __thiscall DMMCStack::AllocSession(class TMMCCallBack const &)const 
+	?Block@DMMCStack@@IAEXPAVDMMCSession@@K@Z @ 16 NONAME ; protected: void __thiscall DMMCStack::Block(class DMMCSession *,unsigned long)
+	?CIMReadWriteBlocksSM@DMMCStack@@MAEKXZ @ 17 NONAME ; protected: virtual unsigned long __thiscall DMMCStack::CIMReadWriteBlocksSM(void)
+	?CIMReadWriteBlocksSMST@DMMCStack@@KAKPAX@Z @ 18 NONAME ; protected: static unsigned long __cdecl DMMCStack::CIMReadWriteBlocksSMST(void *)
+	?CSDField@TCSD@@QBEIABI0@Z @ 19 NONAME ; public: unsigned int __thiscall TCSD::CSDField(unsigned int const &,unsigned int const &)const 
+	?CardDetect@DMMCStack@@MAEHI@Z @ 20 NONAME ; protected: virtual int __thiscall DMMCStack::CardDetect(unsigned int)
+	?CardRCA@DMMCSession@@QAE?AVTRCA@@XZ @ 21 NONAME ; public: class TRCA  __thiscall DMMCSession::CardRCA(void)
+	?Create@DMMCMediaChange@@UAEHXZ @ 22 NONAME ; public: virtual int __thiscall DMMCMediaChange::Create(void)
+	?Create@DMediaChangeBase@@UAEHXZ @ 23 NONAME ; public: virtual int __thiscall DMediaChangeBase::Create(void)
+	?Create@TMMCardControllerInterface@@QAEHXZ @ 24 NONAME ; public: int __thiscall TMMCardControllerInterface::Create(void)
+	?DeclareCardAsGone@TMMCardArray@@UAEXI@Z @ 25 NONAME ; public: virtual void __thiscall TMMCardArray::DeclareCardAsGone(unsigned int)
+	?DeltaCurrentConsumption@DPBusSocket@@QAEXH@Z @ 26 NONAME ; public: void __thiscall DPBusSocket::DeltaCurrentConsumption(int)
+	?DeviceSize@TCSD@@QBEIXZ @ 27 NONAME ; public: unsigned int __thiscall TCSD::DeviceSize(void)const 
+	?Direction@TMMCCommandDesc@@QBEHXZ @ 28 NONAME ; public: int __thiscall TMMCCommandDesc::Direction(void)const 
+	?Dispatch@TMMCStateMachine@@QAEKXZ @ 29 NONAME ; public: unsigned long __thiscall TMMCStateMachine::Dispatch(void)
+	?DoCreate@DMMCPsu@@UAEHXZ @ 30 NONAME ; public: virtual int __thiscall DMMCPsu::DoCreate(void)
+	?DoCreate@DPBusPsuBase@@UAEHXZ @ 31 NONAME ; public: virtual int __thiscall DPBusPsuBase::DoCreate(void)
+	?DoTickService@DPBusPsuBase@@UAEXXZ @ 32 NONAME ; public: virtual void __thiscall DPBusPsuBase::DoTickService(void)
+	?DoorClosedService@DMediaChangeBase@@QAEXXZ @ 33 NONAME ; public: void __thiscall DMediaChangeBase::DoorClosedService(void)
+	?DoorOpenService@DMediaChangeBase@@QAEXXZ @ 34 NONAME ; public: void __thiscall DMediaChangeBase::DoorOpenService(void)
+	?EffectiveModes@DMMCStack@@QAEKABVTMMCStackConfig@@@Z @ 35 NONAME ; public: unsigned long __thiscall DMMCStack::EffectiveModes(class TMMCStackConfig const &)
+	?EndInCritical@DPBusSocket@@QAEXXZ @ 36 NONAME ; public: void __thiscall DPBusSocket::EndInCritical(void)
+	?Engage@DMMCSession@@QAEHXZ @ 37 NONAME ; public: int __thiscall DMMCSession::Engage(void)
+	?EpocErrorCode@DMMCSession@@QBEHXZ @ 38 NONAME ; public: int __thiscall DMMCSession::EpocErrorCode(void)const 
+	?EraseGroupSize@TCSD@@QBEIXZ @ 39 NONAME ; public: unsigned int __thiscall TCSD::EraseGroupSize(void)const 
+	?EraseSectorSize@TCSD@@QBEIXZ @ 40 NONAME ; public: unsigned int __thiscall TCSD::EraseSectorSize(void)const 
+	?FillCommandArgs@DMMCSession@@QAEXVTMMCArgument@@KPAEK@Z @ 41 NONAME ; public: void __thiscall DMMCSession::FillCommandArgs(class TMMCArgument,unsigned long,unsigned char *,unsigned long)
+	?FillCommandDesc@DMMCSession@@QAEXW4TMMCCommandEnum@@@Z @ 42 NONAME ; public: void __thiscall DMMCSession::FillCommandDesc(enum TMMCCommandEnum)
+	?FillCommandDesc@DMMCSession@@QAEXW4TMMCCommandEnum@@VTMMCArgument@@@Z @ 43 NONAME ; public: void __thiscall DMMCSession::FillCommandDesc(enum TMMCCommandEnum,class TMMCArgument)
+	?FillCommandDesc@DMMCSession@@QAEXXZ @ 44 NONAME ; public: void __thiscall DMMCSession::FillCommandDesc(void)
+	?ForceMediaChange@DPBusSocket@@QAEXXZ @ 45 NONAME ; public: void __thiscall DPBusSocket::ForceMediaChange(void)
+	?GetMacro@DMMCSession@@MBEP6AKPAX@ZH@Z @ 46 NONAME ; protected: virtual unsigned long (__cdecl*__thiscall DMMCSession::GetMacro(int)const )(void *)
+	?InCritical@DPBusSocket@@QAEHXZ @ 47 NONAME ; public: int __thiscall DPBusSocket::InCritical(void)
+	?Init@DMMCStack@@UAEHXZ @ 48 NONAME ; public: virtual int __thiscall DMMCStack::Init(void)
+	?IsLocked@DPBusPsuBase@@UAEHXZ @ 49 NONAME ; public: virtual int __thiscall DPBusPsuBase::IsLocked(void)
+	?IsLocked@TMMCard@@QBEHXZ @ 50 NONAME ; public: int __thiscall TMMCard::IsLocked(void)const 
+	?IsMappingIncorrect@TMMCPasswordStore@@QAEHABVTCID@@ABV?$TBuf8@$0BA@@@@Z @ 51 NONAME ; public: int __thiscall TMMCPasswordStore::IsMappingIncorrect(class TCID const &,class TBuf8<16> const &)
+	?IsReady@TMMCard@@QBEHXZ @ 52 NONAME ; public: int __thiscall TMMCard::IsReady(void)const 
+	?IssueMMCCommandSMST@DMMCStack@@KAKPAX@Z @ 53 NONAME ; protected: static unsigned long __cdecl DMMCStack::IssueMMCCommandSMST(void *)
+	?Jump@TMMCStateMachine@@QAEKP6AKPAX@ZH@Z @ 54 NONAME ; public: unsigned long __thiscall TMMCStateMachine::Jump(unsigned long (__cdecl*)(void *),int)
+	?MaxReadCurrentInMilliamps@TCSD@@QBEIXZ @ 55 NONAME ; public: unsigned int __thiscall TCSD::MaxReadCurrentInMilliamps(void)const 
+	?MaxTranSpeedInKilohertz@TCSD@@QBEIXZ @ 56 NONAME ; public: unsigned int __thiscall TCSD::MaxTranSpeedInKilohertz(void)const 
+	?MaxWriteCurrentInMilliamps@TCSD@@QBEIXZ @ 57 NONAME ; public: unsigned int __thiscall TCSD::MaxWriteCurrentInMilliamps(void)const 
+	?MediaType@TCSD@@QBE?AW4TMMCMediaTypeEnum@@XZ @ 58 NONAME ; public: enum TMMCMediaTypeEnum  __thiscall TCSD::MediaType(void)const 
+	?MinReadCurrentInMilliamps@TCSD@@QBEIXZ @ 59 NONAME ; public: unsigned int __thiscall TCSD::MinReadCurrentInMilliamps(void)const 
+	?MinWriteCurrentInMilliamps@TCSD@@QBEIXZ @ 60 NONAME ; public: unsigned int __thiscall TCSD::MinWriteCurrentInMilliamps(void)const 
+	?Panic@DMMCSocket@@SAXW4TMMCPanic@1@@Z @ 61 NONAME ; public: static void __cdecl DMMCSocket::Panic(enum DMMCSocket::TMMCPanic)
+	?Panic@DPBusSocket@@SAXW4TPanic@1@@Z @ 62 NONAME ; public: static void __cdecl DPBusSocket::Panic(enum DPBusSocket::TPanic)
+	?PowerDownComplete@DPBusSocket@@QAEXXZ @ 63 NONAME ; public: void __thiscall DPBusSocket::PowerDownComplete(void)
+	?PowerDownStack@DMMCStack@@QAEXXZ @ 64 NONAME ; public: void __thiscall DMMCStack::PowerDownStack(void)
+	?PowerUp@DPBusSocket@@QAEHXZ @ 65 NONAME ; public: int __thiscall DPBusSocket::PowerUp(void)
+	?PowerUpSequenceComplete@DPBusSocket@@QAEXH@Z @ 66 NONAME ; public: void __thiscall DPBusSocket::PowerUpSequenceComplete(int)
+	?PowerUpStack@DMMCStack@@QAEXXZ @ 67 NONAME ; public: void __thiscall DMMCStack::PowerUpStack(void)
+	?Push@TMMCStateMachine@@QAEKP6AKPAX@ZH@Z @ 68 NONAME ; public: unsigned long __thiscall TMMCStateMachine::Push(unsigned long (__cdecl*)(void *),int)
+	?ReadBlockLength@TCSD@@QBEIXZ @ 69 NONAME ; public: unsigned int __thiscall TCSD::ReadBlockLength(void)const 
+	?ReceiveVoltageCheckResult@DPBusPsuBase@@UAEXH@Z @ 70 NONAME ; public: virtual void __thiscall DPBusPsuBase::ReceiveVoltageCheckResult(int)
+	?Remove@TPBusCallBack@@QAEXXZ @ 71 NONAME ; public: void __thiscall TPBusCallBack::Remove(void)
+	?RequestAsyncPowerDown@DPBusSocket@@QAEXXZ @ 72 NONAME ; public: void __thiscall DPBusSocket::RequestAsyncPowerDown(void)
+	?Reset@TMMCStateMachine@@QAEXXZ @ 73 NONAME ; public: void __thiscall TMMCStateMachine::Reset(void)
+	?SetCard@DMMCSession@@QAEXPAVTMMCard@@@Z @ 74 NONAME ; public: void __thiscall DMMCSession::SetCard(class TMMCard *)
+	?SetSocket@TPBusCallBack@@QAEXH@Z @ 75 NONAME ; public: void __thiscall TPBusCallBack::SetSocket(int)
+	?SetState@DPBusPsuBase@@QAEHW4TPBusPsuState@@@Z @ 76 NONAME ; public: int __thiscall DPBusPsuBase::SetState(enum TPBusPsuState)
+	?SetupCIMEraseGroup@DMMCSession@@QAEXVTMMCArgument@@K@Z @ 77 NONAME ; public: void __thiscall DMMCSession::SetupCIMEraseGroup(class TMMCArgument,unsigned long)
+	?SetupCIMEraseSector@DMMCSession@@QAEXVTMMCArgument@@K@Z @ 78 NONAME ; public: void __thiscall DMMCSession::SetupCIMEraseSector(class TMMCArgument,unsigned long)
+	?SetupCIMLockUnlock@DMMCSession@@QAEXKPAE@Z @ 79 NONAME ; public: void __thiscall DMMCSession::SetupCIMLockUnlock(unsigned long,unsigned char *)
+	?SetupCIMReadBlock@DMMCSession@@QAEXVTMMCArgument@@KPAE@Z @ 80 NONAME ; public: void __thiscall DMMCSession::SetupCIMReadBlock(class TMMCArgument,unsigned long,unsigned char *)
+	?SetupCIMReadIO@DMMCSession@@QAEXEKPAE@Z @ 81 NONAME ; public: void __thiscall DMMCSession::SetupCIMReadIO(unsigned char,unsigned long,unsigned char *)
+	?SetupCIMReadMBlock@DMMCSession@@QAEXVTMMCArgument@@KPAEK@Z @ 82 NONAME ; public: void __thiscall DMMCSession::SetupCIMReadMBlock(class TMMCArgument,unsigned long,unsigned char *,unsigned long)
+	?SetupCIMWriteBlock@DMMCSession@@QAEXVTMMCArgument@@KPAE@Z @ 83 NONAME ; public: void __thiscall DMMCSession::SetupCIMWriteBlock(class TMMCArgument,unsigned long,unsigned char *)
+	?SetupCIMWriteIO@DMMCSession@@QAEXEKPAE@Z @ 84 NONAME ; public: void __thiscall DMMCSession::SetupCIMWriteIO(unsigned char,unsigned long,unsigned char *)
+	?SetupCIMWriteMBlock@DMMCSession@@QAEXVTMMCArgument@@KPAEK@Z @ 85 NONAME ; public: void __thiscall DMMCSession::SetupCIMWriteMBlock(class TMMCArgument,unsigned long,unsigned char *,unsigned long)
+	?SetupCommand@DMMCSession@@QAEXW4TMMCCommandEnum@@VTMMCArgument@@@Z @ 86 NONAME ; public: void __thiscall DMMCSession::SetupCommand(enum TMMCCommandEnum,class TMMCArgument)
+	?SetupDTCommand@DMMCSession@@QAEXW4TMMCCommandEnum@@VTMMCArgument@@KPAEKHW4TMMCCmdDirEnum@@K@Z @ 87 NONAME ; public: void __thiscall DMMCSession::SetupDTCommand(enum TMMCCommandEnum,class TMMCArgument,unsigned long,unsigned char *,unsigned long,int,enum TMMCCmdDirEnum,unsigned long)
+	?SetupRSCommand@DMMCSession@@QAEXW4TMMCCommandEnum@@VTMMCArgument@@KW4TMMCCommandTypeEnum@@W4TMMCResponseTypeEnum@@K@Z @ 88 NONAME ; public: void __thiscall DMMCSession::SetupRSCommand(enum TMMCCommandEnum,class TMMCArgument,unsigned long,enum TMMCCommandTypeEnum,enum TMMCResponseTypeEnum,unsigned long)
+	?SocketFromId@DPBusSocket@@SAPAV1@H@Z @ 89 NONAME ; public: static class DPBusSocket * __cdecl DPBusSocket::SocketFromId(int)
+	?Stop@DMMCStack@@QAEHPAVTMMCard@@@Z @ 90 NONAME ; public: int __thiscall DMMCStack::Stop(class TMMCard *)
+	?UnBlock@DMMCStack@@IAEXPAVDMMCSession@@KK@Z @ 91 NONAME ; protected: void __thiscall DMMCStack::UnBlock(class DMMCSession *,unsigned long,unsigned long)
+	?WriteBlockLength@TCSD@@QBEIXZ @ 92 NONAME ; public: unsigned int __thiscall TCSD::WriteBlockLength(void)const 
+	?WriteProtected@DMMCStack@@MAEHI@Z @ 93 NONAME ; protected: virtual int __thiscall DMMCStack::WriteProtected(unsigned int)
+	?InitStackAfterUnlockSM@DMMCStack@@MAEKXZ @ 94 NONAME ; protected: virtual unsigned long __thiscall DMMCStack::InitStackAfterUnlockSM(void)
+	?RegisterMediaDevices@TMMCardControllerInterface@@MAEHH@Z @ 95 NONAME ; protected: virtual int __thiscall TMMCardControllerInterface::RegisterMediaDevices(int)
+	?ModifyCardCapabilitySM@DMMCStack@@MAEKXZ @ 96 NONAME ; unsigned long DMMCStack::ModifyCardCapabilitySM(void)
+	?Dummy1@DMMCStack@@EAEXXZ @ 97 NONAME ; void DMMCStack::Dummy1(void)
+	?GetInterface@DMMCStack@@MAEXW4TInterfaceId@1@AAPAVMInterface@1@@Z @ 98 NONAME ; protected: virtual void __thiscall DMMCStack::GetInterface(enum DMMCStack::TInterfaceId,class DMMCStack::MInterface * &)
+	?MachineInfo@DMMCStack@@UAEXAAVTDes8@@@Z @ 99 NONAME ; public: virtual void __thiscall DMMCStack::MachineInfo(class TDes8 &)
+	?SetBusWidth@DMMCStack@@MAEXK@Z @ 100 NONAME ; protected: virtual void __thiscall DMMCStack::SetBusWidth(unsigned long)
+	?ControlIO@DPBusSocket@@UAEHHPAX0@Z @ 101 NONAME ; public: virtual int __thiscall DPBusSocket::ControlIO(int,void *,void *)
+	?AcquireStackSM@DSDStack@@UAEKXZ @ 102 NONAME ; public: virtual unsigned long __thiscall DSDStack::AcquireStackSM(void)
+	?AllocCards@TSDCardArray@@UAEHXZ @ 103 NONAME ; public: virtual int __thiscall TSDCardArray::AllocCards(void)
+	?AllocSession@DSDStack@@UBEPAVDMMCSession@@ABVTMMCCallBack@@@Z @ 104 NONAME ; public: virtual class DMMCSession * __thiscall DSDStack::AllocSession(class TMMCCallBack const &)const 
+	?CIMReadWriteBlocksSM@DSDStack@@UAEKXZ @ 105 NONAME ; public: virtual unsigned long __thiscall DSDStack::CIMReadWriteBlocksSM(void)
+	?DeclareCardAsGone@TSDCardArray@@UAEXI@Z @ 106 NONAME ; public: virtual void __thiscall TSDCardArray::DeclareCardAsGone(unsigned int)
+	?Dummy1@DSDStack@@EAEXXZ @ 107 NONAME ; private: virtual void __thiscall DSDStack::Dummy1(void)
+	?Dummy2@DSDStack@@EAEXXZ @ 108 NONAME ; private: virtual void __thiscall DSDStack::Dummy2(void)
+	?Dummy3@DSDStack@@EAEXXZ @ 109 NONAME ; private: virtual void __thiscall DSDStack::Dummy3(void)
+	?CardType@DSDStack@@UAE?AW4TSDCardType@1@HH@Z @ 110 NONAME ; public: virtual enum DSDStack::TSDCardType __thiscall DSDStack::CardType(int,int)
+	?Init@DSDStack@@UAEHXZ @ 111 NONAME ; public: virtual int __thiscall DSDStack::Init(void)
+	?InitStackAfterUnlockSM@DSDStack@@MAEKXZ @ 112 NONAME ; protected: virtual unsigned long __thiscall DSDStack::InitStackAfterUnlockSM(void)
+	?ModifyCardCapabilitySM@DSDStack@@MAEKXZ @ 113 NONAME ; protected: virtual unsigned long __thiscall DSDStack::ModifyCardCapabilitySM(void)
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kernel/eka/drivers/pbus/mmc/sdcard/bwins/sdcard3c/sdio/epbusmu.def	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,217 @@
+EXPORTS
+	??0DMMCMediaChange@@QAE@H@Z @ 1 NONAME ; public: __thiscall DMMCMediaChange::DMMCMediaChange(int)
+	??0DMMCPsu@@QAE@HH@Z @ 2 NONAME ; public: __thiscall DMMCPsu::DMMCPsu(int,int)
+	??0DMMCSession@@QAE@ABVTMMCCallBack@@@Z @ 3 NONAME ; public: __thiscall DMMCSession::DMMCSession(class TMMCCallBack const &)
+	??0DMMCSocket@@QAE@HPAVTMMCPasswordStore@@@Z @ 4 NONAME ; public: __thiscall DMMCSocket::DMMCSocket(int,class TMMCPasswordStore *)
+	??0DMMCStack@@QAE@HPAVDMMCSocket@@@Z @ 5 NONAME ; public: __thiscall DMMCStack::DMMCStack(int,class DMMCSocket *)
+	??0DMediaChangeBase@@QAE@H@Z @ 6 NONAME ; public: __thiscall DMediaChangeBase::DMediaChangeBase(int)
+	??0TPBusCallBack@@QAE@P6AXPAXH00@Z0@Z @ 7 NONAME ; public: __thiscall TPBusCallBack::TPBusCallBack(void (__cdecl*)(void *,int,void *,void *),void *)
+	??0TPBusCallBack@@QAE@P6AXPAXH@Z0I@Z @ 8 NONAME ; public: __thiscall TPBusCallBack::TPBusCallBack(void (__cdecl*)(void *,int),void *,unsigned int)
+	??0TPBusCallBack@@QAE@XZ @ 9 NONAME ; public: __thiscall TPBusCallBack::TPBusCallBack(void)
+	??1DMMCSession@@UAE@XZ @ 10 NONAME ; public: virtual __thiscall DMMCSession::~DMMCSession(void)
+	?AcquireStackSM@DMMCStack@@MAEKXZ @ 11 NONAME ; protected: virtual unsigned long __thiscall DMMCStack::AcquireStackSM(void)
+	?Add@DPBusSocket@@QAEXPAVTPBusCallBack@@@Z @ 12 NONAME ; public: void __thiscall DPBusSocket::Add(class TPBusCallBack *)
+	?AddNewCard@TMMCardArray@@QAEXPBEPAVTRCA@@@Z @ 13 NONAME ; public: void __thiscall TMMCardArray::AddNewCard(unsigned char const *,class TRCA *)
+	?AllocCards@TMMCardArray@@UAEHXZ @ 14 NONAME ; public: virtual int __thiscall TMMCardArray::AllocCards(void)
+	?AllocSession@DMMCStack@@UBEPAVDMMCSession@@ABVTMMCCallBack@@@Z @ 15 NONAME ; public: virtual class DMMCSession * __thiscall DMMCStack::AllocSession(class TMMCCallBack const &)const 
+	?Block@DMMCStack@@IAEXPAVDMMCSession@@K@Z @ 16 NONAME ; protected: void __thiscall DMMCStack::Block(class DMMCSession *,unsigned long)
+	?CIMReadWriteBlocksSM@DMMCStack@@MAEKXZ @ 17 NONAME ; protected: virtual unsigned long __thiscall DMMCStack::CIMReadWriteBlocksSM(void)
+	?CIMReadWriteBlocksSMST@DMMCStack@@KAKPAX@Z @ 18 NONAME ; protected: static unsigned long __cdecl DMMCStack::CIMReadWriteBlocksSMST(void *)
+	?CSDField@TCSD@@QBEIABI0@Z @ 19 NONAME ; public: unsigned int __thiscall TCSD::CSDField(unsigned int const &,unsigned int const &)const 
+	?CardDetect@DMMCStack@@MAEHI@Z @ 20 NONAME ; protected: virtual int __thiscall DMMCStack::CardDetect(unsigned int)
+	?CardRCA@DMMCSession@@QAE?AVTRCA@@XZ @ 21 NONAME ; public: class TRCA  __thiscall DMMCSession::CardRCA(void)
+	?Create@DMMCMediaChange@@UAEHXZ @ 22 NONAME ; public: virtual int __thiscall DMMCMediaChange::Create(void)
+	?Create@DMediaChangeBase@@UAEHXZ @ 23 NONAME ; public: virtual int __thiscall DMediaChangeBase::Create(void)
+	?Create@TMMCardControllerInterface@@QAEHXZ @ 24 NONAME ; public: int __thiscall TMMCardControllerInterface::Create(void)
+	?DeclareCardAsGone@TMMCardArray@@UAEXI@Z @ 25 NONAME ; public: virtual void __thiscall TMMCardArray::DeclareCardAsGone(unsigned int)
+	?DeltaCurrentConsumption@DPBusSocket@@QAEXH@Z @ 26 NONAME ; public: void __thiscall DPBusSocket::DeltaCurrentConsumption(int)
+	?DeviceSize@TCSD@@QBEIXZ @ 27 NONAME ; public: unsigned int __thiscall TCSD::DeviceSize(void)const 
+	?Direction@TMMCCommandDesc@@QBEHXZ @ 28 NONAME ; public: int __thiscall TMMCCommandDesc::Direction(void)const 
+	?Dispatch@TMMCStateMachine@@QAEKXZ @ 29 NONAME ; public: unsigned long __thiscall TMMCStateMachine::Dispatch(void)
+	?DoCreate@DMMCPsu@@UAEHXZ @ 30 NONAME ; public: virtual int __thiscall DMMCPsu::DoCreate(void)
+	?DoCreate@DPBusPsuBase@@UAEHXZ @ 31 NONAME ; public: virtual int __thiscall DPBusPsuBase::DoCreate(void)
+	?DoTickService@DPBusPsuBase@@UAEXXZ @ 32 NONAME ; public: virtual void __thiscall DPBusPsuBase::DoTickService(void)
+	?DoorClosedService@DMediaChangeBase@@QAEXXZ @ 33 NONAME ; public: void __thiscall DMediaChangeBase::DoorClosedService(void)
+	?DoorOpenService@DMediaChangeBase@@QAEXXZ @ 34 NONAME ; public: void __thiscall DMediaChangeBase::DoorOpenService(void)
+	?EffectiveModes@DMMCStack@@QAEKABVTMMCStackConfig@@@Z @ 35 NONAME ; public: unsigned long __thiscall DMMCStack::EffectiveModes(class TMMCStackConfig const &)
+	?EndInCritical@DPBusSocket@@QAEXXZ @ 36 NONAME ; public: void __thiscall DPBusSocket::EndInCritical(void)
+	?Engage@DMMCSession@@QAEHXZ @ 37 NONAME ; public: int __thiscall DMMCSession::Engage(void)
+	?EpocErrorCode@DMMCSession@@QBEHXZ @ 38 NONAME ; public: int __thiscall DMMCSession::EpocErrorCode(void)const 
+	?EraseGroupSize@TCSD@@QBEIXZ @ 39 NONAME ; public: unsigned int __thiscall TCSD::EraseGroupSize(void)const 
+	?EraseSectorSize@TCSD@@QBEIXZ @ 40 NONAME ; public: unsigned int __thiscall TCSD::EraseSectorSize(void)const 
+	?FillCommandArgs@DMMCSession@@QAEXVTMMCArgument@@KPAEK@Z @ 41 NONAME ; public: void __thiscall DMMCSession::FillCommandArgs(class TMMCArgument,unsigned long,unsigned char *,unsigned long)
+	?FillCommandDesc@DMMCSession@@QAEXW4TMMCCommandEnum@@@Z @ 42 NONAME ; public: void __thiscall DMMCSession::FillCommandDesc(enum TMMCCommandEnum)
+	?FillCommandDesc@DMMCSession@@QAEXW4TMMCCommandEnum@@VTMMCArgument@@@Z @ 43 NONAME ; public: void __thiscall DMMCSession::FillCommandDesc(enum TMMCCommandEnum,class TMMCArgument)
+	?FillCommandDesc@DMMCSession@@QAEXXZ @ 44 NONAME ; public: void __thiscall DMMCSession::FillCommandDesc(void)
+	?ForceMediaChange@DPBusSocket@@QAEXXZ @ 45 NONAME ; public: void __thiscall DPBusSocket::ForceMediaChange(void)
+	?GetMacro@DMMCSession@@MBEP6AKPAX@ZH@Z @ 46 NONAME ; protected: virtual unsigned long (__cdecl*__thiscall DMMCSession::GetMacro(int)const )(void *)
+	?InCritical@DPBusSocket@@QAEHXZ @ 47 NONAME ; public: int __thiscall DPBusSocket::InCritical(void)
+	?Init@DMMCStack@@UAEHXZ @ 48 NONAME ; public: virtual int __thiscall DMMCStack::Init(void)
+	?IsLocked@DPBusPsuBase@@UAEHXZ @ 49 NONAME ; public: virtual int __thiscall DPBusPsuBase::IsLocked(void)
+	?IsLocked@TMMCard@@QBEHXZ @ 50 NONAME ; public: int __thiscall TMMCard::IsLocked(void)const 
+	?IsMappingIncorrect@TMMCPasswordStore@@QAEHABVTCID@@ABV?$TBuf8@$0BA@@@@Z @ 51 NONAME ; public: int __thiscall TMMCPasswordStore::IsMappingIncorrect(class TCID const &,class TBuf8<16> const &)
+	?IsReady@TMMCard@@QBEHXZ @ 52 NONAME ; public: int __thiscall TMMCard::IsReady(void)const 
+	?IssueMMCCommandSMST@DMMCStack@@KAKPAX@Z @ 53 NONAME ; protected: static unsigned long __cdecl DMMCStack::IssueMMCCommandSMST(void *)
+	?Jump@TMMCStateMachine@@QAEKP6AKPAX@ZH@Z @ 54 NONAME ; public: unsigned long __thiscall TMMCStateMachine::Jump(unsigned long (__cdecl*)(void *),int)
+	?MaxReadCurrentInMilliamps@TCSD@@QBEIXZ @ 55 NONAME ; public: unsigned int __thiscall TCSD::MaxReadCurrentInMilliamps(void)const 
+	?MaxTranSpeedInKilohertz@TCSD@@QBEIXZ @ 56 NONAME ; public: unsigned int __thiscall TCSD::MaxTranSpeedInKilohertz(void)const 
+	?MaxWriteCurrentInMilliamps@TCSD@@QBEIXZ @ 57 NONAME ; public: unsigned int __thiscall TCSD::MaxWriteCurrentInMilliamps(void)const 
+	?MediaType@TCSD@@QBE?AW4TMMCMediaTypeEnum@@XZ @ 58 NONAME ; public: enum TMMCMediaTypeEnum  __thiscall TCSD::MediaType(void)const 
+	?MinReadCurrentInMilliamps@TCSD@@QBEIXZ @ 59 NONAME ; public: unsigned int __thiscall TCSD::MinReadCurrentInMilliamps(void)const 
+	?MinWriteCurrentInMilliamps@TCSD@@QBEIXZ @ 60 NONAME ; public: unsigned int __thiscall TCSD::MinWriteCurrentInMilliamps(void)const 
+	?Panic@DMMCSocket@@SAXW4TMMCPanic@1@@Z @ 61 NONAME ; public: static void __cdecl DMMCSocket::Panic(enum DMMCSocket::TMMCPanic)
+	?Panic@DPBusSocket@@SAXW4TPanic@1@@Z @ 62 NONAME ; public: static void __cdecl DPBusSocket::Panic(enum DPBusSocket::TPanic)
+	?PowerDownComplete@DPBusSocket@@QAEXXZ @ 63 NONAME ; public: void __thiscall DPBusSocket::PowerDownComplete(void)
+	?PowerDownStack@DMMCStack@@QAEXXZ @ 64 NONAME ; public: void __thiscall DMMCStack::PowerDownStack(void)
+	?PowerUp@DPBusSocket@@QAEHXZ @ 65 NONAME ; public: int __thiscall DPBusSocket::PowerUp(void)
+	?PowerUpSequenceComplete@DPBusSocket@@QAEXH@Z @ 66 NONAME ; public: void __thiscall DPBusSocket::PowerUpSequenceComplete(int)
+	?PowerUpStack@DMMCStack@@QAEXXZ @ 67 NONAME ; public: void __thiscall DMMCStack::PowerUpStack(void)
+	?Push@TMMCStateMachine@@QAEKP6AKPAX@ZH@Z @ 68 NONAME ; public: unsigned long __thiscall TMMCStateMachine::Push(unsigned long (__cdecl*)(void *),int)
+	?ReadBlockLength@TCSD@@QBEIXZ @ 69 NONAME ; public: unsigned int __thiscall TCSD::ReadBlockLength(void)const 
+	?ReceiveVoltageCheckResult@DPBusPsuBase@@UAEXH@Z @ 70 NONAME ; public: virtual void __thiscall DPBusPsuBase::ReceiveVoltageCheckResult(int)
+	?Remove@TPBusCallBack@@QAEXXZ @ 71 NONAME ; public: void __thiscall TPBusCallBack::Remove(void)
+	?RequestAsyncPowerDown@DPBusSocket@@QAEXXZ @ 72 NONAME ; public: void __thiscall DPBusSocket::RequestAsyncPowerDown(void)
+	?Reset@TMMCStateMachine@@QAEXXZ @ 73 NONAME ; public: void __thiscall TMMCStateMachine::Reset(void)
+	?SetCard@DMMCSession@@QAEXPAVTMMCard@@@Z @ 74 NONAME ; public: void __thiscall DMMCSession::SetCard(class TMMCard *)
+	?SetSocket@TPBusCallBack@@QAEXH@Z @ 75 NONAME ; public: void __thiscall TPBusCallBack::SetSocket(int)
+	?SetState@DPBusPsuBase@@QAEHW4TPBusPsuState@@@Z @ 76 NONAME ; public: int __thiscall DPBusPsuBase::SetState(enum TPBusPsuState)
+	?SetupCIMEraseGroup@DMMCSession@@QAEXVTMMCArgument@@K@Z @ 77 NONAME ; public: void __thiscall DMMCSession::SetupCIMEraseGroup(class TMMCArgument,unsigned long)
+	?SetupCIMEraseSector@DMMCSession@@QAEXVTMMCArgument@@K@Z @ 78 NONAME ; public: void __thiscall DMMCSession::SetupCIMEraseSector(class TMMCArgument,unsigned long)
+	?SetupCIMLockUnlock@DMMCSession@@QAEXKPAE@Z @ 79 NONAME ; public: void __thiscall DMMCSession::SetupCIMLockUnlock(unsigned long,unsigned char *)
+	?SetupCIMReadBlock@DMMCSession@@QAEXVTMMCArgument@@KPAE@Z @ 80 NONAME ; public: void __thiscall DMMCSession::SetupCIMReadBlock(class TMMCArgument,unsigned long,unsigned char *)
+	?SetupCIMReadIO@DMMCSession@@QAEXEKPAE@Z @ 81 NONAME ; public: void __thiscall DMMCSession::SetupCIMReadIO(unsigned char,unsigned long,unsigned char *)
+	?SetupCIMReadMBlock@DMMCSession@@QAEXVTMMCArgument@@KPAEK@Z @ 82 NONAME ; public: void __thiscall DMMCSession::SetupCIMReadMBlock(class TMMCArgument,unsigned long,unsigned char *,unsigned long)
+	?SetupCIMWriteBlock@DMMCSession@@QAEXVTMMCArgument@@KPAE@Z @ 83 NONAME ; public: void __thiscall DMMCSession::SetupCIMWriteBlock(class TMMCArgument,unsigned long,unsigned char *)
+	?SetupCIMWriteIO@DMMCSession@@QAEXEKPAE@Z @ 84 NONAME ; public: void __thiscall DMMCSession::SetupCIMWriteIO(unsigned char,unsigned long,unsigned char *)
+	?SetupCIMWriteMBlock@DMMCSession@@QAEXVTMMCArgument@@KPAEK@Z @ 85 NONAME ; public: void __thiscall DMMCSession::SetupCIMWriteMBlock(class TMMCArgument,unsigned long,unsigned char *,unsigned long)
+	?SetupCommand@DMMCSession@@QAEXW4TMMCCommandEnum@@VTMMCArgument@@@Z @ 86 NONAME ; public: void __thiscall DMMCSession::SetupCommand(enum TMMCCommandEnum,class TMMCArgument)
+	?SetupDTCommand@DMMCSession@@QAEXW4TMMCCommandEnum@@VTMMCArgument@@KPAEKHW4TMMCCmdDirEnum@@K@Z @ 87 NONAME ; public: void __thiscall DMMCSession::SetupDTCommand(enum TMMCCommandEnum,class TMMCArgument,unsigned long,unsigned char *,unsigned long,int,enum TMMCCmdDirEnum,unsigned long)
+	?SetupRSCommand@DMMCSession@@QAEXW4TMMCCommandEnum@@VTMMCArgument@@KW4TMMCCommandTypeEnum@@W4TMMCResponseTypeEnum@@K@Z @ 88 NONAME ; public: void __thiscall DMMCSession::SetupRSCommand(enum TMMCCommandEnum,class TMMCArgument,unsigned long,enum TMMCCommandTypeEnum,enum TMMCResponseTypeEnum,unsigned long)
+	?SocketFromId@DPBusSocket@@SAPAV1@H@Z @ 89 NONAME ; public: static class DPBusSocket * __cdecl DPBusSocket::SocketFromId(int)
+	?Stop@DMMCStack@@QAEHPAVTMMCard@@@Z @ 90 NONAME ; public: int __thiscall DMMCStack::Stop(class TMMCard *)
+	?UnBlock@DMMCStack@@IAEXPAVDMMCSession@@KK@Z @ 91 NONAME ; protected: void __thiscall DMMCStack::UnBlock(class DMMCSession *,unsigned long,unsigned long)
+	?WriteBlockLength@TCSD@@QBEIXZ @ 92 NONAME ; public: unsigned int __thiscall TCSD::WriteBlockLength(void)const 
+	?WriteProtected@DMMCStack@@MAEHI@Z @ 93 NONAME ; protected: virtual int __thiscall DMMCStack::WriteProtected(unsigned int)
+	?InitStackAfterUnlockSM@DMMCStack@@MAEKXZ @ 94 NONAME ; protected: virtual unsigned long __thiscall DMMCStack::InitStackAfterUnlockSM(void)
+	?RegisterMediaDevices@TMMCardControllerInterface@@MAEHH@Z @ 95 NONAME ; protected: virtual int __thiscall TMMCardControllerInterface::RegisterMediaDevices(int)
+	?ModifyCardCapabilitySM@DMMCStack@@MAEKXZ @ 96 NONAME ; unsigned long DMMCStack::ModifyCardCapabilitySM(void)
+	?Dummy1@DMMCStack@@EAEXXZ @ 97 NONAME ; void DMMCStack::Dummy1(void)
+	?GetInterface@DMMCStack@@MAEXW4TInterfaceId@1@AAPAVMInterface@1@@Z @ 98 NONAME ; protected: virtual void __thiscall DMMCStack::GetInterface(enum DMMCStack::TInterfaceId,class DMMCStack::MInterface * &)
+	?MachineInfo@DMMCStack@@UAEXAAVTDes8@@@Z @ 99 NONAME ; public: virtual void __thiscall DMMCStack::MachineInfo(class TDes8 &)
+	?SetBusWidth@DMMCStack@@MAEXK@Z @ 100 NONAME ; protected: virtual void __thiscall DMMCStack::SetBusWidth(unsigned long)
+	?ControlIO@DPBusSocket@@UAEHHPAX0@Z @ 101 NONAME ; public: virtual int __thiscall DPBusSocket::ControlIO(int,void *,void *)
+	?AcquireStackSM@DSDStack@@UAEKXZ @ 102 NONAME ; public: virtual unsigned long __thiscall DSDStack::AcquireStackSM(void)
+	?AllocCards@TSDCardArray@@UAEHXZ @ 103 NONAME ; public: virtual int __thiscall TSDCardArray::AllocCards(void)
+	?AllocSession@DSDStack@@UBEPAVDMMCSession@@ABVTMMCCallBack@@@Z @ 104 NONAME ; public: virtual class DMMCSession * __thiscall DSDStack::AllocSession(class TMMCCallBack const &)const 
+	?CIMReadWriteBlocksSM@DSDStack@@UAEKXZ @ 105 NONAME ; public: virtual unsigned long __thiscall DSDStack::CIMReadWriteBlocksSM(void)
+	?DeclareCardAsGone@TSDCardArray@@UAEXI@Z @ 106 NONAME ; public: virtual void __thiscall TSDCardArray::DeclareCardAsGone(unsigned int)
+	?Dummy1@DSDStack@@EAEXXZ @ 107 NONAME ; private: virtual void __thiscall DSDStack::Dummy1(void)
+	?Dummy2@DSDStack@@EAEXXZ @ 108 NONAME ; private: virtual void __thiscall DSDStack::Dummy2(void)
+	?Dummy3@DSDStack@@EAEXXZ @ 109 NONAME ; private: virtual void __thiscall DSDStack::Dummy3(void)
+	?CardType@DSDStack@@UAE?AW4TSDCardType@1@HH@Z @ 110 NONAME ; public: virtual enum DSDStack::TSDCardType __thiscall DSDStack::CardType(int,int)
+	?Init@DSDStack@@UAEHXZ @ 111 NONAME ; public: virtual int __thiscall DSDStack::Init(void)
+	?InitStackAfterUnlockSM@DSDStack@@MAEKXZ @ 112 NONAME ; protected: virtual unsigned long __thiscall DSDStack::InitStackAfterUnlockSM(void)
+	?ModifyCardCapabilitySM@DSDStack@@MAEKXZ @ 113 NONAME ; protected: virtual unsigned long __thiscall DSDStack::ModifyCardCapabilitySM(void)
+	?DummyExport10@DDummySession@@AAEXXZ @ 114 NONAME ; private: void __thiscall DDummySession::DummyExport10(void)
+	?DummyExport11@DDummySession@@AAEXXZ @ 115 NONAME ; private: void __thiscall DDummySession::DummyExport11(void)
+	?DummyExport12@DDummySession@@AAEXXZ @ 116 NONAME ; private: void __thiscall DDummySession::DummyExport12(void)
+	?DummyExport13@DDummySession@@AAEXXZ @ 117 NONAME ; private: void __thiscall DDummySession::DummyExport13(void)
+	?DummyExport14@DDummySession@@AAEXXZ @ 118 NONAME ; private: void __thiscall DDummySession::DummyExport14(void)
+	?DummyExport15@DDummySession@@AAEXXZ @ 119 NONAME ; private: void __thiscall DDummySession::DummyExport15(void)
+	?DummyExport1@DDummySession@@AAEXXZ @ 120 NONAME ; private: void __thiscall DDummySession::DummyExport1(void)
+	?DummyExport2@DDummySession@@AAEXXZ @ 121 NONAME ; private: void __thiscall DDummySession::DummyExport2(void)
+	?DummyExport3@DDummySession@@AAEXXZ @ 122 NONAME ; private: void __thiscall DDummySession::DummyExport3(void)
+	?DummyExport4@DDummySession@@AAEXXZ @ 123 NONAME ; private: void __thiscall DDummySession::DummyExport4(void)
+	?DummyExport5@DDummySession@@AAEXXZ @ 124 NONAME ; private: void __thiscall DDummySession::DummyExport5(void)
+	?DummyExport6@DDummySession@@AAEXXZ @ 125 NONAME ; private: void __thiscall DDummySession::DummyExport6(void)
+	?DummyExport7@DDummySession@@AAEXXZ @ 126 NONAME ; private: void __thiscall DDummySession::DummyExport7(void)
+	?DummyExport8@DDummySession@@AAEXXZ @ 127 NONAME ; private: void __thiscall DDummySession::DummyExport8(void)
+	?DummyExport9@DDummySession@@AAEXXZ @ 128 NONAME ; private: void __thiscall DDummySession::DummyExport9(void)
+	??0DSDIOPsu@@QAE@HH@Z @ 129 NONAME ; public: __thiscall DSDIOPsu::DSDIOPsu(int,int)
+	??0DSDIORegisterInterface@@QAE@PAVTSDIOCard@@E@Z @ 130 NONAME ; public: __thiscall DSDIORegisterInterface::DSDIORegisterInterface(class TSDIOCard *,unsigned char)
+	??0DSDIORegisterInterface@@QAE@PAVTSDIOCard@@EPAVDMutex@@@Z @ 131 NONAME ; public: __thiscall DSDIORegisterInterface::DSDIORegisterInterface(class TSDIOCard *,unsigned char,class DMutex *)
+	??0DSDIOSocket@@QAE@HPAVTMMCPasswordStore@@@Z @ 132 NONAME ; public: __thiscall DSDIOSocket::DSDIOSocket(int,class TMMCPasswordStore *)
+	??0TCisReader@@QAE@XZ @ 133 NONAME ; public: __thiscall TCisReader::TCisReader(void)
+	??0TSDIOCardConfig@@QAE@XZ @ 134 NONAME ; public: __thiscall TSDIOCardConfig::TSDIOCardConfig(void)
+	??0TSDIOFunction@@QAE@PAVTSDIOCard@@E@Z @ 135 NONAME ; public: __thiscall TSDIOFunction::TSDIOFunction(class TSDIOCard *,unsigned char)
+	??0TSDIOInterrupt@@QAE@PAVTSDIOInterruptController@@E@Z @ 136 NONAME ; public: __thiscall TSDIOInterrupt::TSDIOInterrupt(class TSDIOInterruptController *,unsigned char)
+	??1DSDIORegisterInterface@@UAE@XZ @ 137 NONAME ; public: virtual __thiscall DSDIORegisterInterface::~DSDIORegisterInterface(void)
+	??1TSDIOFunction@@QAE@XZ @ 138 NONAME ; public: __thiscall TSDIOFunction::~TSDIOFunction(void)
+	??1TSDIOInterrupt@@QAE@XZ @ 139 NONAME ; public: __thiscall TSDIOInterrupt::~TSDIOInterrupt(void)
+	?AcquireStackSM@DSDIOStack@@MAEKXZ @ 140 NONAME ; protected: virtual unsigned long __thiscall DSDIOStack::AcquireStackSM(void)
+	?AllocCards@TSDIOCardArray@@UAEHXZ @ 141 NONAME ; public: virtual int __thiscall TSDIOCardArray::AllocCards(void)
+	?AllocSession@DSDIOStack@@UBEPAVDMMCSession@@ABVTMMCCallBack@@@Z @ 142 NONAME ; public: virtual class DMMCSession * __thiscall DSDIOStack::AllocSession(class TMMCCallBack const &)const 
+	?Bind@TSDIOInterrupt@@QAEHP6AXPAX@Z0@Z @ 143 NONAME ; public: int __thiscall TSDIOInterrupt::Bind(void (__cdecl*)(void *),void *)
+	?BlockIOSession@DSDIOStack@@IAEXW4TSDIOBlockingCondition@1@@Z @ 144 NONAME ; protected: void __thiscall DSDIOStack::BlockIOSession(enum DSDIOStack::TSDIOBlockingCondition)
+	?CIMIoModifySM@DSDIOStack@@IAEKXZ @ 145 NONAME ; protected: unsigned long __thiscall DSDIOStack::CIMIoModifySM(void)
+	?CIMIoReadWriteDirectSM@DSDIOStack@@IAEKXZ @ 146 NONAME ; protected: unsigned long __thiscall DSDIOStack::CIMIoReadWriteDirectSM(void)
+	?CIMIoReadWriteExtendedSM@DSDIOStack@@IAEKXZ @ 147 NONAME ; protected: unsigned long __thiscall DSDIOStack::CIMIoReadWriteExtendedSM(void)
+	?CIMReadWriteBlocksSM@DSDIOStack@@MAEKXZ @ 148 NONAME ; protected: virtual unsigned long __thiscall DSDIOStack::CIMReadWriteBlocksSM(void)
+	?CapabilitiesMatch@TSDIOFunctionCaps@@QAEHAAV1@K@Z @ 149 NONAME ; public: int __thiscall TSDIOFunctionCaps::CapabilitiesMatch(class TSDIOFunctionCaps &,unsigned long)
+	?CheckCIS@TSDIOCard@@QAEHXZ @ 150 NONAME ; public: int __thiscall TSDIOCard::CheckCIS(void)
+	?DeclareCardAsGone@TSDIOCardArray@@UAEXI@Z @ 151 NONAME ; public: virtual void __thiscall TSDIOCardArray::DeclareCardAsGone(unsigned int)
+	?DeregisterClient@TSDIOFunction@@QAEHPAVDBase@@@Z @ 152 NONAME ; public: int __thiscall TSDIOFunction::DeregisterClient(class DBase *)
+	?Disable@TSDIOFunction@@QAEHXZ @ 153 NONAME ; public: int __thiscall TSDIOFunction::Disable(void)
+	?Disable@TSDIOInterrupt@@QAEHXZ @ 154 NONAME ; public: int __thiscall TSDIOInterrupt::Disable(void)
+	?DoCreate@DSDIOPsu@@UAEHXZ @ 155 NONAME ; public: virtual int __thiscall DSDIOPsu::DoCreate(void)
+	?DoTickService@DSDIOPsu@@UAEXXZ @ 156 NONAME ; public: virtual void __thiscall DSDIOPsu::DoTickService(void)
+	?Dummy1@DSDIOStack@@EAEXXZ @ 157 NONAME ; private: virtual void __thiscall DSDIOStack::Dummy1(void)
+	?Dummy2@DSDIOStack@@EAEXXZ @ 158 NONAME ; private: virtual void __thiscall DSDIOStack::Dummy2(void)
+	?Dummy3@DSDIOStack@@EAEXXZ @ 159 NONAME ; private: virtual void __thiscall DSDIOStack::Dummy3(void)
+	?Dummy4@DSDIOStack@@EAEXXZ @ 160 NONAME ; private: virtual void __thiscall DSDIOStack::Dummy4(void)
+	?Enable@TSDIOFunction@@QAEHH@Z @ 161 NONAME ; public: int __thiscall TSDIOFunction::Enable(int)
+	?Enable@TSDIOInterrupt@@QAEHXZ @ 162 NONAME ; public: int __thiscall TSDIOInterrupt::Enable(void)
+	?FillAppCommandDesc@DSDIOSession@@CAXAAVTMMCCommandDesc@@@Z @ 163 NONAME ; private: static void __cdecl DSDIOSession::FillAppCommandDesc(class TMMCCommandDesc &)
+	?FillAppCommandDesc@DSDIOSession@@SAXAAVTMMCCommandDesc@@W4TSDIOAppCmd@@@Z @ 164 NONAME ; public: static void __cdecl DSDIOSession::FillAppCommandDesc(class TMMCCommandDesc &,enum TSDIOAppCmd)
+	?FillAppCommandDesc@DSDIOSession@@SAXAAVTMMCCommandDesc@@W4TSDIOAppCmd@@VTMMCArgument@@@Z @ 165 NONAME ; public: static void __cdecl DSDIOSession::FillAppCommandDesc(class TMMCCommandDesc &,enum TSDIOAppCmd,class TMMCArgument)
+	?FindFunction@TSDIOCard@@QBEPAVTSDIOFunction@@AAVTSDIOFunctionCaps@@KPAV2@@Z @ 166 NONAME ; public: class TSDIOFunction * __thiscall TSDIOCard::FindFunction(class TSDIOFunctionCaps &,unsigned long,class TSDIOFunction *)const 
+	?FindReadCommonConfig@TCisReader@@QAEHAAVTSDIOCardConfig@@@Z @ 167 NONAME ; public: int __thiscall TCisReader::FindReadCommonConfig(class TSDIOCardConfig &)
+	?FindReadFunctionConfig@TCisReader@@QAEHAAVTSDIOFunctionCaps@@@Z @ 168 NONAME ; public: int __thiscall TCisReader::FindReadFunctionConfig(class TSDIOFunctionCaps &)
+	?FindReadTuple@TCisReader@@QAEHEAAVTDes8@@I@Z @ 169 NONAME ; public: int __thiscall TCisReader::FindReadTuple(unsigned char,class TDes8 &,unsigned int)
+	?GetMacro@DSDIOSession@@MBEP6AKPAX@ZH@Z @ 170 NONAME ; protected: virtual unsigned long (__cdecl*__thiscall DSDIOSession::GetMacro(int)const )(void *)
+	?HandleSDIOInterrupt@DSDIOStack@@IAEXI@Z @ 171 NONAME ; protected: void __thiscall DSDIOStack::HandleSDIOInterrupt(unsigned int)
+	?Init@DSDIOStack@@UAEHXZ @ 172 NONAME ; public: virtual int __thiscall DSDIOStack::Init(void)
+	?IsLocked@DSDIOPsu@@UAEHXZ @ 173 NONAME ; public: virtual int __thiscall DSDIOPsu::IsLocked(void)
+	?IsReady@TSDIOFunction@@QAEHAAH@Z @ 174 NONAME ; public: int __thiscall TSDIOFunction::IsReady(int &)
+	?Modify8@DSDIORegisterInterface@@QAEHKEEPAE@Z @ 175 NONAME ; public: int __thiscall DSDIORegisterInterface::Modify8(unsigned long,unsigned char,unsigned char,unsigned char *)
+	?ModifyCardCapabilitySM@DSDIOStack@@MAEKXZ @ 176 NONAME ; protected: virtual unsigned long __thiscall DSDIOStack::ModifyCardCapabilitySM(void)
+	?Read8@DSDIORegisterInterface@@QAEHKPAE@Z @ 177 NONAME ; public: int __thiscall DSDIORegisterInterface::Read8(unsigned long,unsigned char *)
+	?ReadMultiple8@DSDIORegisterInterface@@QAEHKPAEKH@Z @ 178 NONAME ; public: int __thiscall DSDIORegisterInterface::ReadMultiple8(unsigned long,unsigned char *,unsigned long,int)
+	?ReadTuple@TCisReader@@QAEHAAVTDes8@@@Z @ 179 NONAME ; public: int __thiscall TCisReader::ReadTuple(class TDes8 &)
+	?Register@TSDIOFunctionCallback@@QAEXPAVDMMCSocket@@@Z @ 180 NONAME ; public: void __thiscall TSDIOFunctionCallback::Register(class DMMCSocket *)
+	?RegisterClient@TSDIOFunction@@QAEHPAVDBase@@PAVDMutex@@@Z @ 181 NONAME ; public: int __thiscall TSDIOFunction::RegisterClient(class DBase *,class DMutex *)
+	?RegisterMediaDevices@TSDIOCardControllerInterface@@MAEHH@Z @ 182 NONAME ; protected: virtual int __thiscall TSDIOCardControllerInterface::RegisterMediaDevices(int)
+	?RequestAsyncSleep@DSDIOSocket@@QAEXXZ @ 183 NONAME ; public: void __thiscall DSDIOSocket::RequestAsyncSleep(void)
+	?Restart@TCisReader@@QAEHXZ @ 184 NONAME ; public: int __thiscall TCisReader::Restart(void)
+	?SelectCis@TCisReader@@QAEHIIIE@Z @ 185 NONAME ; public: int __thiscall TCisReader::SelectCis(unsigned int,unsigned int,unsigned int,unsigned char)
+	?SetAsync@DSDIORegisterInterface@@QAEHAAVTMMCCallBack@@@Z @ 186 NONAME ; public: int __thiscall DSDIORegisterInterface::SetAsync(class TMMCCallBack &)
+	?SetPriority@TSDIOFunction@@QAEHW4TSDIOFunctionPriority@@@Z @ 187 NONAME ; public: int __thiscall TSDIOFunction::SetPriority(enum TSDIOFunctionPriority)
+	?SetSync@DSDIORegisterInterface@@QAEHXZ @ 188 NONAME ; public: int __thiscall DSDIORegisterInterface::SetSync(void)
+	?SetupCIMIoModify@DSDIOSession@@QAEXKEEPAE@Z @ 189 NONAME ; public: void __thiscall DSDIOSession::SetupCIMIoModify(unsigned long,unsigned char,unsigned char,unsigned char *)
+	?SetupCIMIoRead@DSDIOSession@@QAEXKPAE@Z @ 190 NONAME ; public: void __thiscall DSDIOSession::SetupCIMIoRead(unsigned long,unsigned char *)
+	?SetupCIMIoReadMultiple@DSDIOSession@@QAEXKKPAEH@Z @ 191 NONAME ; public: void __thiscall DSDIOSession::SetupCIMIoReadMultiple(unsigned long,unsigned long,unsigned char *,int)
+	?SetupCIMIoWrite@DSDIOSession@@QAEXKEPAE@Z @ 192 NONAME ; public: void __thiscall DSDIOSession::SetupCIMIoWrite(unsigned long,unsigned char,unsigned char *)
+	?SetupCIMIoWriteMultiple@DSDIOSession@@QAEXKKPAEH@Z @ 193 NONAME ; public: void __thiscall DSDIOSession::SetupCIMIoWriteMultiple(unsigned long,unsigned long,unsigned char *,int)
+	?SleepComplete@DSDIOSocket@@QAEXXZ @ 194 NONAME ; public: void __thiscall DSDIOSocket::SleepComplete(void)
+	?Unbind@TSDIOInterrupt@@QAEHXZ @ 195 NONAME ; public: int __thiscall TSDIOInterrupt::Unbind(void)
+	?UnblockIOSession@DSDIOStack@@IAEPAVDSDIOSession@@W4TSDIOBlockingCondition@1@K@Z @ 196  NONAME ; class DSDIOSession * DSDIOStack::UnblockIOSession(enum DSDIOStack::TSDIOBlockingCondition, unsigned long)
+	?Write8@DSDIORegisterInterface@@QAEHKEPAE@Z @ 197 NONAME ; public: int __thiscall DSDIORegisterInterface::Write8(unsigned long,unsigned char,unsigned char *)
+	?WriteMultiple8@DSDIORegisterInterface@@QAEHKPAEKH@Z @ 198 NONAME ; public: int __thiscall DSDIORegisterInterface::WriteMultiple8(unsigned long,unsigned char *,unsigned long,int)
+?ReadMultiple8@DSDIORegisterInterface@@QAEHKPAVDChunk@@KKH@Z @ 199  NONAME ; int DSDIORegisterInterface::ReadMultiple8(unsigned long, class DChunk *, unsigned long, unsigned long, int)
+	?WriteMultiple8@DSDIORegisterInterface@@QAEHKPAEK@Z @ 200  NONAME ; int DSDIORegisterInterface::WriteMultiple8(unsigned long, unsigned char *, unsigned long)
+	?Dummy4@DSDIOPsu@@EAEXXZ @ 201  NONAME ; void DSDIOPsu::Dummy4(void)
+	?WriteMultiple8@DSDIORegisterInterface@@QAEHKPAVDChunk@@KKH@Z @ 202  NONAME ; int DSDIORegisterInterface::WriteMultiple8(unsigned long, class DChunk *, unsigned long, unsigned long, int)
+	?Dummy1@DSDIOPsu@@EAEXXZ @ 203  NONAME ; void DSDIOPsu::Dummy1(void)
+	?MachineInfo@DMMCStack@@UAEXAAVTDes8@@@Z @ 204  NONAME ; void DMMCStack::MachineInfo(class TDes8 &)
+	?WriteMultiple8@DSDIORegisterInterface@@QAEHKPAVDChunk@@KK@Z @ 205  NONAME ; int DSDIORegisterInterface::WriteMultiple8(unsigned long, class DChunk *, unsigned long, unsigned long)
+	?Write8@DSDIORegisterInterface@@QAEHKE@Z @ 206  NONAME ; int DSDIORegisterInterface::Write8(unsigned long, unsigned char)
+	?Dummy2@DSDIOPsu@@EAEXXZ @ 207  NONAME ; void DSDIOPsu::Dummy2(void)
+	??1DSDIOSession@@UAE@XZ @ 208  NONAME ; DSDIOSession::~DSDIOSession(void)
+	?Modify8@DSDIORegisterInterface@@QAEHKEE@Z @ 209  NONAME ; int DSDIORegisterInterface::Modify8(unsigned long, unsigned char, unsigned char)
+	?Dummy4@DSDIOSession@@EAEXXZ @ 210  NONAME ; void DSDIOSession::Dummy4(void)
+	?Dummy3@DSDIOSession@@EAEXXZ @ 211  NONAME ; void DSDIOSession::Dummy3(void)
+	?Dummy3@DSDIOPsu@@EAEXXZ @ 212  NONAME ; void DSDIOPsu::Dummy3(void)
+	?ReadMultiple8@DSDIORegisterInterface@@QAEHKPAEK@Z @ 213  NONAME ; int DSDIORegisterInterface::ReadMultiple8(unsigned long, unsigned char *, unsigned long)
+	?Dummy2@DSDIOSession@@EAEXXZ @ 214  NONAME ; void DSDIOSession::Dummy2(void)
+	?ReadMultiple8@DSDIORegisterInterface@@QAEHKPAVDChunk@@KK@Z @ 215  NONAME ; int DSDIORegisterInterface::ReadMultiple8(unsigned long, class DChunk *, unsigned long, unsigned long)
+	?Dummy1@DSDIOSession@@EAEXXZ @ 216  NONAME ; void DSDIOSession::Dummy1(void)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kernel/eka/drivers/pbus/mmc/sdcard/bx86/sdcard3c/epbusmu.def	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,115 @@
+EXPORTS
+	??0DMMCMediaChange@@QAE@H@Z @ 1 NONAME ; public: __thiscall DMMCMediaChange::DMMCMediaChange(int)
+	??0DMMCPsu@@QAE@HH@Z @ 2 NONAME ; public: __thiscall DMMCPsu::DMMCPsu(int,int)
+	??0DMMCSession@@QAE@ABVTMMCCallBack@@@Z @ 3 NONAME ; public: __thiscall DMMCSession::DMMCSession(class TMMCCallBack const &)
+	??0DMMCSocket@@QAE@HPAVTMMCPasswordStore@@@Z @ 4 NONAME ; public: __thiscall DMMCSocket::DMMCSocket(int,class TMMCPasswordStore *)
+	??0DMMCStack@@QAE@HPAVDMMCSocket@@@Z @ 5 NONAME ; public: __thiscall DMMCStack::DMMCStack(int,class DMMCSocket *)
+	??0DMediaChangeBase@@QAE@H@Z @ 6 NONAME ; public: __thiscall DMediaChangeBase::DMediaChangeBase(int)
+	??0TPBusCallBack@@QAE@P6AXPAXH00@Z0@Z @ 7 NONAME ; public: __thiscall TPBusCallBack::TPBusCallBack(void (__cdecl*)(void *,int,void *,void *),void *)
+	??0TPBusCallBack@@QAE@P6AXPAXH@Z0I@Z @ 8 NONAME ; public: __thiscall TPBusCallBack::TPBusCallBack(void (__cdecl*)(void *,int),void *,unsigned int)
+	??0TPBusCallBack@@QAE@XZ @ 9 NONAME ; public: __thiscall TPBusCallBack::TPBusCallBack(void)
+	??1DMMCSession@@UAE@XZ @ 10 NONAME ; public: virtual __thiscall DMMCSession::~DMMCSession(void)
+	?AcquireStackSM@DMMCStack@@MAEKXZ @ 11 NONAME ; protected: virtual unsigned long __thiscall DMMCStack::AcquireStackSM(void)
+	?Add@DPBusSocket@@QAEXPAVTPBusCallBack@@@Z @ 12 NONAME ; public: void __thiscall DPBusSocket::Add(class TPBusCallBack *)
+	?AddNewCard@TMMCardArray@@QAEXPBEPAVTRCA@@@Z @ 13 NONAME ; public: void __thiscall TMMCardArray::AddNewCard(unsigned char const *,class TRCA *)
+	?AllocCards@TMMCardArray@@UAEHXZ @ 14 NONAME ; public: virtual int __thiscall TMMCardArray::AllocCards(void)
+	?Block@DMMCStack@@IAEXPAVDMMCSession@@K@Z @ 15 NONAME ; protected: void __thiscall DMMCStack::Block(class DMMCSession *,unsigned long)
+	?CIMReadWriteBlocksSM@DMMCStack@@MAEKXZ @ 16 NONAME ; protected: virtual unsigned long __thiscall DMMCStack::CIMReadWriteBlocksSM(void)
+	?CSDField@TCSD@@QBEIABI0@Z @ 17 NONAME ; public: unsigned int __thiscall TCSD::CSDField(unsigned int const &,unsigned int const &)const 
+	?CardDetect@DMMCStack@@MAEHI@Z @ 18 NONAME ; protected: virtual int __thiscall DMMCStack::CardDetect(unsigned int)
+	?Create@DMediaChangeBase@@UAEHXZ @ 19 NONAME ; public: virtual int __thiscall DMediaChangeBase::Create(void)
+	?Create@TMMCardControllerInterface@@QAEHXZ @ 20 NONAME ; public: int __thiscall TMMCardControllerInterface::Create(void)
+	?DeclareCardAsGone@TMMCardArray@@UAEXI@Z @ 21 NONAME ; public: virtual void __thiscall TMMCardArray::DeclareCardAsGone(unsigned int)
+	?DeltaCurrentConsumption@DPBusSocket@@QAEXH@Z @ 22 NONAME ; public: void __thiscall DPBusSocket::DeltaCurrentConsumption(int)
+	?DeviceSize@TCSD@@QBEIXZ @ 23 NONAME ; public: unsigned int __thiscall TCSD::DeviceSize(void)const 
+	?Direction@TMMCCommandDesc@@QBEHXZ @ 24 NONAME ; public: int __thiscall TMMCCommandDesc::Direction(void)const 
+	?Dispatch@TMMCStateMachine@@QAEKXZ @ 25 NONAME ; public: unsigned long __thiscall TMMCStateMachine::Dispatch(void)
+	?DoCreate@DMMCPsu@@UAEHXZ @ 26 NONAME ; public: virtual int __thiscall DMMCPsu::DoCreate(void)
+	?DoCreate@DPBusPsuBase@@UAEHXZ @ 27 NONAME ; public: virtual int __thiscall DPBusPsuBase::DoCreate(void)
+	?DoTickService@DPBusPsuBase@@UAEXXZ @ 28 NONAME ; public: virtual void __thiscall DPBusPsuBase::DoTickService(void)
+	?DoorClosedService@DMediaChangeBase@@QAEXXZ @ 29 NONAME ; public: void __thiscall DMediaChangeBase::DoorClosedService(void)
+	?DoorOpenService@DMediaChangeBase@@QAEXXZ @ 30 NONAME ; public: void __thiscall DMediaChangeBase::DoorOpenService(void)
+	?EffectiveModes@DMMCStack@@QAEKABVTMMCStackConfig@@@Z @ 31 NONAME ; public: unsigned long __thiscall DMMCStack::EffectiveModes(class TMMCStackConfig const &)
+	?EndInCritical@DPBusSocket@@QAEXXZ @ 32 NONAME ; public: void __thiscall DPBusSocket::EndInCritical(void)
+	?Engage@DMMCSession@@QAEHXZ @ 33 NONAME ; public: int __thiscall DMMCSession::Engage(void)
+	?EpocErrorCode@DMMCSession@@QBEHXZ @ 34 NONAME ; public: int __thiscall DMMCSession::EpocErrorCode(void)const 
+	?EraseGroupSize@TCSD@@QBEIXZ @ 35 NONAME ; public: unsigned int __thiscall TCSD::EraseGroupSize(void)const 
+	?EraseSectorSize@TCSD@@QBEIXZ @ 36 NONAME ; public: unsigned int __thiscall TCSD::EraseSectorSize(void)const 
+	?ForceMediaChange@DPBusSocket@@QAEXXZ @ 37 NONAME ; public: void __thiscall DPBusSocket::ForceMediaChange(void)
+	?InCritical@DPBusSocket@@QAEHXZ @ 38 NONAME ; public: int __thiscall DPBusSocket::InCritical(void)
+	?Init@DMMCStack@@UAEHXZ @ 39 NONAME ; public: virtual int __thiscall DMMCStack::Init(void)
+	?IsLocked@DPBusPsuBase@@UAEHXZ @ 40 NONAME ; public: virtual int __thiscall DPBusPsuBase::IsLocked(void)
+	?IsLocked@TMMCard@@QBEHXZ @ 41 NONAME ; public: int __thiscall TMMCard::IsLocked(void)const 
+	?IsMappingIncorrect@TMMCPasswordStore@@QAEHABVTCID@@ABV?$TBuf8@$0BA@@@@Z @ 42 NONAME ; public: int __thiscall TMMCPasswordStore::IsMappingIncorrect(class TCID const &,class TBuf8<16> const &)
+	?IsReady@TMMCard@@QBEHXZ @ 43 NONAME ; public: int __thiscall TMMCard::IsReady(void)const 
+	?Jump@TMMCStateMachine@@QAEKP6AKPAX@ZH@Z @ 44 NONAME ; public: unsigned long __thiscall TMMCStateMachine::Jump(unsigned long (__cdecl*)(void *),int)
+	?MaxReadCurrentInMilliamps@TCSD@@QBEIXZ @ 45 NONAME ; public: unsigned int __thiscall TCSD::MaxReadCurrentInMilliamps(void)const 
+	?MaxTranSpeedInKilohertz@TCSD@@QBEIXZ @ 46 NONAME ; public: unsigned int __thiscall TCSD::MaxTranSpeedInKilohertz(void)const 
+	?MaxWriteCurrentInMilliamps@TCSD@@QBEIXZ @ 47 NONAME ; public: unsigned int __thiscall TCSD::MaxWriteCurrentInMilliamps(void)const 
+	?MediaType@TCSD@@QBE?AW4TMMCMediaTypeEnum@@XZ @ 48 NONAME ; public: enum TMMCMediaTypeEnum  __thiscall TCSD::MediaType(void)const 
+	?MinReadCurrentInMilliamps@TCSD@@QBEIXZ @ 49 NONAME ; public: unsigned int __thiscall TCSD::MinReadCurrentInMilliamps(void)const 
+	?MinWriteCurrentInMilliamps@TCSD@@QBEIXZ @ 50 NONAME ; public: unsigned int __thiscall TCSD::MinWriteCurrentInMilliamps(void)const 
+	?Panic@DMMCSocket@@SAXW4TMMCPanic@1@@Z @ 51 NONAME ; public: static void __cdecl DMMCSocket::Panic(enum DMMCSocket::TMMCPanic)
+	?Panic@DPBusSocket@@SAXW4TPanic@1@@Z @ 52 NONAME ; public: static void __cdecl DPBusSocket::Panic(enum DPBusSocket::TPanic)
+	?PowerDownStack@DMMCStack@@QAEXXZ @ 53 NONAME ; public: void __thiscall DMMCStack::PowerDownStack(void)
+	?PowerUp@DPBusSocket@@QAEHXZ @ 54 NONAME ; public: int __thiscall DPBusSocket::PowerUp(void)
+	?PowerUpSequenceComplete@DPBusSocket@@QAEXH@Z @ 55 NONAME ; public: void __thiscall DPBusSocket::PowerUpSequenceComplete(int)
+	?PowerUpStack@DMMCStack@@QAEXXZ @ 56 NONAME ; public: void __thiscall DMMCStack::PowerUpStack(void)
+	?Push@TMMCStateMachine@@QAEKP6AKPAX@ZH@Z @ 57 NONAME ; public: unsigned long __thiscall TMMCStateMachine::Push(unsigned long (__cdecl*)(void *),int)
+	?ReadBlockLength@TCSD@@QBEIXZ @ 58 NONAME ; public: unsigned int __thiscall TCSD::ReadBlockLength(void)const 
+	?ReceiveVoltageCheckResult@DPBusPsuBase@@UAEXH@Z @ 59 NONAME ; public: virtual void __thiscall DPBusPsuBase::ReceiveVoltageCheckResult(int)
+	?Remove@TPBusCallBack@@QAEXXZ @ 60 NONAME ; public: void __thiscall TPBusCallBack::Remove(void)
+	?Reset@TMMCStateMachine@@QAEXXZ @ 61 NONAME ; public: void __thiscall TMMCStateMachine::Reset(void)
+	?SetCard@DMMCSession@@QAEXPAVTMMCard@@@Z @ 62 NONAME ; public: void __thiscall DMMCSession::SetCard(class TMMCard *)
+	?SetSocket@TPBusCallBack@@QAEXH@Z @ 63 NONAME ; public: void __thiscall TPBusCallBack::SetSocket(int)
+	?SetState@DPBusPsuBase@@QAEHW4TPBusPsuState@@@Z @ 64 NONAME ; public: int __thiscall DPBusPsuBase::SetState(enum TPBusPsuState)
+	?SetupCIMEraseGroup@DMMCSession@@QAEXVTMMCArgument@@K@Z @ 65 NONAME ; public: void __thiscall DMMCSession::SetupCIMEraseGroup(class TMMCArgument,unsigned long)
+	?SetupCIMEraseSector@DMMCSession@@QAEXVTMMCArgument@@K@Z @ 66 NONAME ; public: void __thiscall DMMCSession::SetupCIMEraseSector(class TMMCArgument,unsigned long)
+	?SetupCIMLockUnlock@DMMCSession@@QAEXKPAE@Z @ 67 NONAME ; public: void __thiscall DMMCSession::SetupCIMLockUnlock(unsigned long,unsigned char *)
+	?SetupCIMReadBlock@DMMCSession@@QAEXVTMMCArgument@@KPAE@Z @ 68 NONAME ; public: void __thiscall DMMCSession::SetupCIMReadBlock(class TMMCArgument,unsigned long,unsigned char *)
+	?SetupCIMReadIO@DMMCSession@@QAEXEKPAE@Z @ 69 NONAME ; public: void __thiscall DMMCSession::SetupCIMReadIO(unsigned char,unsigned long,unsigned char *)
+	?SetupCIMReadMBlock@DMMCSession@@QAEXVTMMCArgument@@KPAEK@Z @ 70 NONAME ; public: void __thiscall DMMCSession::SetupCIMReadMBlock(class TMMCArgument,unsigned long,unsigned char *,unsigned long)
+	?SetupCIMWriteBlock@DMMCSession@@QAEXVTMMCArgument@@KPAE@Z @ 71 NONAME ; public: void __thiscall DMMCSession::SetupCIMWriteBlock(class TMMCArgument,unsigned long,unsigned char *)
+	?SetupCIMWriteIO@DMMCSession@@QAEXEKPAE@Z @ 72 NONAME ; public: void __thiscall DMMCSession::SetupCIMWriteIO(unsigned char,unsigned long,unsigned char *)
+	?SetupCIMWriteMBlock@DMMCSession@@QAEXVTMMCArgument@@KPAEK@Z @ 73 NONAME ; public: void __thiscall DMMCSession::SetupCIMWriteMBlock(class TMMCArgument,unsigned long,unsigned char *,unsigned long)
+	?SetupCommand@DMMCSession@@QAEXW4TMMCCommandEnum@@VTMMCArgument@@@Z @ 74 NONAME ; public: void __thiscall DMMCSession::SetupCommand(enum TMMCCommandEnum,class TMMCArgument)
+	?SetupDTCommand@DMMCSession@@QAEXW4TMMCCommandEnum@@VTMMCArgument@@KPAEKHW4TMMCCmdDirEnum@@K@Z @ 75 NONAME ; public: void __thiscall DMMCSession::SetupDTCommand(enum TMMCCommandEnum,class TMMCArgument,unsigned long,unsigned char *,unsigned long,int,enum TMMCCmdDirEnum,unsigned long)
+	?SetupRSCommand@DMMCSession@@QAEXW4TMMCCommandEnum@@VTMMCArgument@@KW4TMMCCommandTypeEnum@@W4TMMCResponseTypeEnum@@K@Z @ 76 NONAME ; public: void __thiscall DMMCSession::SetupRSCommand(enum TMMCCommandEnum,class TMMCArgument,unsigned long,enum TMMCCommandTypeEnum,enum TMMCResponseTypeEnum,unsigned long)
+	?SocketFromId@DPBusSocket@@SAPAV1@H@Z @ 77 NONAME ; public: static class DPBusSocket * __cdecl DPBusSocket::SocketFromId(int)
+	?Stop@DMMCStack@@QAEHPAVTMMCard@@@Z @ 78 NONAME ; public: int __thiscall DMMCStack::Stop(class TMMCard *)
+	?UnBlock@DMMCStack@@IAEXPAVDMMCSession@@KK@Z @ 79 NONAME ; protected: void __thiscall DMMCStack::UnBlock(class DMMCSession *,unsigned long,unsigned long)
+	?WriteBlockLength@TCSD@@QBEIXZ @ 80 NONAME ; public: unsigned int __thiscall TCSD::WriteBlockLength(void)const 
+	?WriteProtected@DMMCStack@@MAEHI@Z @ 81 NONAME ; protected: virtual int __thiscall DMMCStack::WriteProtected(unsigned int)
+	?Create@DMMCMediaChange@@UAEHXZ @ 82 NONAME ; public: virtual int __thiscall DMMCMediaChange::Create(void)
+	?AllocSession@DMMCStack@@UBEPAVDMMCSession@@ABVTMMCCallBack@@@Z @ 83 NONAME ; public: virtual class DMMCSession * __thiscall DMMCStack::AllocSession(class TMMCCallBack const &)const 
+	?CIMReadWriteBlocksSMST@DMMCStack@@KAKPAX@Z @ 84 NONAME ; protected: static unsigned long __cdecl DMMCStack::CIMReadWriteBlocksSMST(void *)
+	?CardRCA@DMMCSession@@QAE?AVTRCA@@XZ @ 85 NONAME ; public: class TRCA  __thiscall DMMCSession::CardRCA(void)
+	?FillCommandArgs@DMMCSession@@QAEXVTMMCArgument@@KPAEK@Z @ 86 NONAME ; public: void __thiscall DMMCSession::FillCommandArgs(class TMMCArgument,unsigned long,unsigned char *,unsigned long)
+	?FillCommandDesc@DMMCSession@@QAEXW4TMMCCommandEnum@@@Z @ 87 NONAME ; public: void __thiscall DMMCSession::FillCommandDesc(enum TMMCCommandEnum)
+	?FillCommandDesc@DMMCSession@@QAEXW4TMMCCommandEnum@@VTMMCArgument@@@Z @ 88 NONAME ; public: void __thiscall DMMCSession::FillCommandDesc(enum TMMCCommandEnum,class TMMCArgument)
+	?FillCommandDesc@DMMCSession@@QAEXXZ @ 89 NONAME ; public: void __thiscall DMMCSession::FillCommandDesc(void)
+	?GetMacro@DMMCSession@@MBEP6AKPAX@ZH@Z @ 90 NONAME ; protected: virtual unsigned long (__cdecl*__thiscall DMMCSession::GetMacro(int)const )(void *)
+	?IssueMMCCommandSMST@DMMCStack@@KAKPAX@Z @ 91 NONAME ; protected: static unsigned long __cdecl DMMCStack::IssueMMCCommandSMST(void *)
+	?InitStackAfterUnlockSM@DMMCStack@@MAEKXZ @ 92 NONAME ; protected: virtual unsigned long __thiscall DMMCStack::InitStackAfterUnlockSM(void)
+	?PowerDownComplete@DPBusSocket@@QAEXXZ @ 93 NONAME ; public: void __thiscall DPBusSocket::PowerDownComplete(void)
+	?RegisterMediaDevices@TMMCardControllerInterface@@MAEHH@Z @ 94 NONAME ; protected: virtual int __thiscall TMMCardControllerInterface::RegisterMediaDevices(int)
+	?RequestAsyncPowerDown@DPBusSocket@@QAEXXZ @ 95 NONAME ; public: void __thiscall DPBusSocket::RequestAsyncPowerDown(void)
+	?ControlIO@DPBusSocket@@UAEHHPAX0@Z @ 96 NONAME ; public: virtual int __thiscall DPBusSocket::ControlIO(int,void *,void *)
+	?Dummy1@DMMCStack@@EAEXXZ @ 97 NONAME ; private: virtual void __thiscall DMMCStack::Dummy1(void)
+	?GetInterface@DMMCStack@@MAEXW4TInterfaceId@1@AAPAVMInterface@1@@Z @ 98 NONAME ; protected: virtual void __thiscall DMMCStack::GetInterface(enum DMMCStack::TInterfaceId,class DMMCStack::MInterface * &)
+	?MachineInfo@DMMCStack@@UAEXAAVTDes8@@@Z @ 99 NONAME ; public: virtual void __thiscall DMMCStack::MachineInfo(class TDes8 &)
+	?SetBusWidth@DMMCStack@@MAEXK@Z @ 100 NONAME ; protected: virtual void __thiscall DMMCStack::SetBusWidth(unsigned long)
+	?ModifyCardCapabilitySM@DMMCStack@@MAEKXZ @ 101 NONAME ; protected: virtual unsigned long __thiscall DMMCStack::ModifyCardCapabilitySM(void)
+	?AcquireStackSM@DSDStack@@UAEKXZ @ 102 NONAME ; public: virtual unsigned long __thiscall DSDStack::AcquireStackSM(void)
+	?AllocCards@TSDCardArray@@UAEHXZ @ 103 NONAME ; public: virtual int __thiscall TSDCardArray::AllocCards(void)
+	?AllocSession@DSDStack@@UBEPAVDMMCSession@@ABVTMMCCallBack@@@Z @ 104 NONAME ; public: virtual class DMMCSession * __thiscall DSDStack::AllocSession(class TMMCCallBack const &)const 
+	?CIMReadWriteBlocksSM@DSDStack@@UAEKXZ @ 105 NONAME ; public: virtual unsigned long __thiscall DSDStack::CIMReadWriteBlocksSM(void)
+	?DeclareCardAsGone@TSDCardArray@@UAEXI@Z @ 106 NONAME ; public: virtual void __thiscall TSDCardArray::DeclareCardAsGone(unsigned int)
+	?Dummy1@DSDStack@@EAEXXZ @ 107 NONAME ; private: virtual void __thiscall DSDStack::Dummy1(void)
+	?Dummy2@DSDStack@@EAEXXZ @ 108 NONAME ; private: virtual void __thiscall DSDStack::Dummy2(void)
+	?Dummy3@DSDStack@@EAEXXZ @ 109 NONAME ; private: virtual void __thiscall DSDStack::Dummy3(void)
+	?CardType@DSDStack@@UAE?AW4TSDCardType@1@HH@Z @ 110 NONAME ; public: virtual enum DSDStack::TSDCardType __thiscall DSDStack::CardType(int,int)
+	?Init@DSDStack@@UAEHXZ @ 111 NONAME ; public: virtual int __thiscall DSDStack::Init(void)
+	?InitStackAfterUnlockSM@DSDStack@@MAEKXZ @ 112 NONAME ; protected: virtual unsigned long __thiscall DSDStack::InitStackAfterUnlockSM(void)
+	?ModifyCardCapabilitySM@DSDStack@@MAEKXZ @ 113 NONAME ; protected: virtual unsigned long __thiscall DSDStack::ModifyCardCapabilitySM(void)
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kernel/eka/drivers/pbus/mmc/sdcard/bx86/sdcard3c/sdio/epbusmu.def	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,219 @@
+EXPORTS
+	??0DMMCMediaChange@@QAE@H@Z @ 1 NONAME ; public: __thiscall DMMCMediaChange::DMMCMediaChange(int)
+	??0DMMCPsu@@QAE@HH@Z @ 2 NONAME ; public: __thiscall DMMCPsu::DMMCPsu(int,int)
+	??0DMMCSession@@QAE@ABVTMMCCallBack@@@Z @ 3 NONAME ; public: __thiscall DMMCSession::DMMCSession(class TMMCCallBack const &)
+	??0DMMCSocket@@QAE@HPAVTMMCPasswordStore@@@Z @ 4 NONAME ; public: __thiscall DMMCSocket::DMMCSocket(int,class TMMCPasswordStore *)
+	??0DMMCStack@@QAE@HPAVDMMCSocket@@@Z @ 5 NONAME ; public: __thiscall DMMCStack::DMMCStack(int,class DMMCSocket *)
+	??0DMediaChangeBase@@QAE@H@Z @ 6 NONAME ; public: __thiscall DMediaChangeBase::DMediaChangeBase(int)
+	??0TPBusCallBack@@QAE@P6AXPAXH00@Z0@Z @ 7 NONAME ; public: __thiscall TPBusCallBack::TPBusCallBack(void (__cdecl*)(void *,int,void *,void *),void *)
+	??0TPBusCallBack@@QAE@P6AXPAXH@Z0I@Z @ 8 NONAME ; public: __thiscall TPBusCallBack::TPBusCallBack(void (__cdecl*)(void *,int),void *,unsigned int)
+	??0TPBusCallBack@@QAE@XZ @ 9 NONAME ; public: __thiscall TPBusCallBack::TPBusCallBack(void)
+	??1DMMCSession@@UAE@XZ @ 10 NONAME ; public: virtual __thiscall DMMCSession::~DMMCSession(void)
+	?AcquireStackSM@DMMCStack@@MAEKXZ @ 11 NONAME ; protected: virtual unsigned long __thiscall DMMCStack::AcquireStackSM(void)
+	?Add@DPBusSocket@@QAEXPAVTPBusCallBack@@@Z @ 12 NONAME ; public: void __thiscall DPBusSocket::Add(class TPBusCallBack *)
+	?AddNewCard@TMMCardArray@@QAEXPBEPAVTRCA@@@Z @ 13 NONAME ; public: void __thiscall TMMCardArray::AddNewCard(unsigned char const *,class TRCA *)
+	?AllocCards@TMMCardArray@@UAEHXZ @ 14 NONAME ; public: virtual int __thiscall TMMCardArray::AllocCards(void)
+	?Block@DMMCStack@@IAEXPAVDMMCSession@@K@Z @ 15 NONAME ; protected: void __thiscall DMMCStack::Block(class DMMCSession *,unsigned long)
+	?CIMReadWriteBlocksSM@DMMCStack@@MAEKXZ @ 16 NONAME ; protected: virtual unsigned long __thiscall DMMCStack::CIMReadWriteBlocksSM(void)
+	?CSDField@TCSD@@QBEIABI0@Z @ 17 NONAME ; public: unsigned int __thiscall TCSD::CSDField(unsigned int const &,unsigned int const &)const 
+	?CardDetect@DMMCStack@@MAEHI@Z @ 18 NONAME ; protected: virtual int __thiscall DMMCStack::CardDetect(unsigned int)
+	?Create@DMediaChangeBase@@UAEHXZ @ 19 NONAME ; public: virtual int __thiscall DMediaChangeBase::Create(void)
+	?Create@TMMCardControllerInterface@@QAEHXZ @ 20 NONAME ; public: int __thiscall TMMCardControllerInterface::Create(void)
+	?DeclareCardAsGone@TMMCardArray@@UAEXI@Z @ 21 NONAME ; public: virtual void __thiscall TMMCardArray::DeclareCardAsGone(unsigned int)
+	?DeltaCurrentConsumption@DPBusSocket@@QAEXH@Z @ 22 NONAME ; public: void __thiscall DPBusSocket::DeltaCurrentConsumption(int)
+	?DeviceSize@TCSD@@QBEIXZ @ 23 NONAME ; public: unsigned int __thiscall TCSD::DeviceSize(void)const 
+	?Direction@TMMCCommandDesc@@QBEHXZ @ 24 NONAME ; public: int __thiscall TMMCCommandDesc::Direction(void)const 
+	?Dispatch@TMMCStateMachine@@QAEKXZ @ 25 NONAME ; public: unsigned long __thiscall TMMCStateMachine::Dispatch(void)
+	?DoCreate@DMMCPsu@@UAEHXZ @ 26 NONAME ; public: virtual int __thiscall DMMCPsu::DoCreate(void)
+	?DoCreate@DPBusPsuBase@@UAEHXZ @ 27 NONAME ; public: virtual int __thiscall DPBusPsuBase::DoCreate(void)
+	?DoTickService@DPBusPsuBase@@UAEXXZ @ 28 NONAME ; public: virtual void __thiscall DPBusPsuBase::DoTickService(void)
+	?DoorClosedService@DMediaChangeBase@@QAEXXZ @ 29 NONAME ; public: void __thiscall DMediaChangeBase::DoorClosedService(void)
+	?DoorOpenService@DMediaChangeBase@@QAEXXZ @ 30 NONAME ; public: void __thiscall DMediaChangeBase::DoorOpenService(void)
+	?EffectiveModes@DMMCStack@@QAEKABVTMMCStackConfig@@@Z @ 31 NONAME ; public: unsigned long __thiscall DMMCStack::EffectiveModes(class TMMCStackConfig const &)
+	?EndInCritical@DPBusSocket@@QAEXXZ @ 32 NONAME ; public: void __thiscall DPBusSocket::EndInCritical(void)
+	?Engage@DMMCSession@@QAEHXZ @ 33 NONAME ; public: int __thiscall DMMCSession::Engage(void)
+	?EpocErrorCode@DMMCSession@@QBEHXZ @ 34 NONAME ; public: int __thiscall DMMCSession::EpocErrorCode(void)const 
+	?EraseGroupSize@TCSD@@QBEIXZ @ 35 NONAME ; public: unsigned int __thiscall TCSD::EraseGroupSize(void)const 
+	?EraseSectorSize@TCSD@@QBEIXZ @ 36 NONAME ; public: unsigned int __thiscall TCSD::EraseSectorSize(void)const 
+	?ForceMediaChange@DPBusSocket@@QAEXXZ @ 37 NONAME ; public: void __thiscall DPBusSocket::ForceMediaChange(void)
+	?InCritical@DPBusSocket@@QAEHXZ @ 38 NONAME ; public: int __thiscall DPBusSocket::InCritical(void)
+	?Init@DMMCStack@@UAEHXZ @ 39 NONAME ; public: virtual int __thiscall DMMCStack::Init(void)
+	?IsLocked@DPBusPsuBase@@UAEHXZ @ 40 NONAME ; public: virtual int __thiscall DPBusPsuBase::IsLocked(void)
+	?IsLocked@TMMCard@@QBEHXZ @ 41 NONAME ; public: int __thiscall TMMCard::IsLocked(void)const 
+	?IsMappingIncorrect@TMMCPasswordStore@@QAEHABVTCID@@ABV?$TBuf8@$0BA@@@@Z @ 42 NONAME ; public: int __thiscall TMMCPasswordStore::IsMappingIncorrect(class TCID const &,class TBuf8<16> const &)
+	?IsReady@TMMCard@@QBEHXZ @ 43 NONAME ; public: int __thiscall TMMCard::IsReady(void)const 
+	?Jump@TMMCStateMachine@@QAEKP6AKPAX@ZH@Z @ 44 NONAME ; public: unsigned long __thiscall TMMCStateMachine::Jump(unsigned long (__cdecl*)(void *),int)
+	?MaxReadCurrentInMilliamps@TCSD@@QBEIXZ @ 45 NONAME ; public: unsigned int __thiscall TCSD::MaxReadCurrentInMilliamps(void)const 
+	?MaxTranSpeedInKilohertz@TCSD@@QBEIXZ @ 46 NONAME ; public: unsigned int __thiscall TCSD::MaxTranSpeedInKilohertz(void)const 
+	?MaxWriteCurrentInMilliamps@TCSD@@QBEIXZ @ 47 NONAME ; public: unsigned int __thiscall TCSD::MaxWriteCurrentInMilliamps(void)const 
+	?MediaType@TCSD@@QBE?AW4TMMCMediaTypeEnum@@XZ @ 48 NONAME ; public: enum TMMCMediaTypeEnum  __thiscall TCSD::MediaType(void)const 
+	?MinReadCurrentInMilliamps@TCSD@@QBEIXZ @ 49 NONAME ; public: unsigned int __thiscall TCSD::MinReadCurrentInMilliamps(void)const 
+	?MinWriteCurrentInMilliamps@TCSD@@QBEIXZ @ 50 NONAME ; public: unsigned int __thiscall TCSD::MinWriteCurrentInMilliamps(void)const 
+	?Panic@DMMCSocket@@SAXW4TMMCPanic@1@@Z @ 51 NONAME ; public: static void __cdecl DMMCSocket::Panic(enum DMMCSocket::TMMCPanic)
+	?Panic@DPBusSocket@@SAXW4TPanic@1@@Z @ 52 NONAME ; public: static void __cdecl DPBusSocket::Panic(enum DPBusSocket::TPanic)
+	?PowerDownStack@DMMCStack@@QAEXXZ @ 53 NONAME ; public: void __thiscall DMMCStack::PowerDownStack(void)
+	?PowerUp@DPBusSocket@@QAEHXZ @ 54 NONAME ; public: int __thiscall DPBusSocket::PowerUp(void)
+	?PowerUpSequenceComplete@DPBusSocket@@QAEXH@Z @ 55 NONAME ; public: void __thiscall DPBusSocket::PowerUpSequenceComplete(int)
+	?PowerUpStack@DMMCStack@@QAEXXZ @ 56 NONAME ; public: void __thiscall DMMCStack::PowerUpStack(void)
+	?Push@TMMCStateMachine@@QAEKP6AKPAX@ZH@Z @ 57 NONAME ; public: unsigned long __thiscall TMMCStateMachine::Push(unsigned long (__cdecl*)(void *),int)
+	?ReadBlockLength@TCSD@@QBEIXZ @ 58 NONAME ; public: unsigned int __thiscall TCSD::ReadBlockLength(void)const 
+	?ReceiveVoltageCheckResult@DPBusPsuBase@@UAEXH@Z @ 59 NONAME ; public: virtual void __thiscall DPBusPsuBase::ReceiveVoltageCheckResult(int)
+	?Remove@TPBusCallBack@@QAEXXZ @ 60 NONAME ; public: void __thiscall TPBusCallBack::Remove(void)
+	?Reset@TMMCStateMachine@@QAEXXZ @ 61 NONAME ; public: void __thiscall TMMCStateMachine::Reset(void)
+	?SetCard@DMMCSession@@QAEXPAVTMMCard@@@Z @ 62 NONAME ; public: void __thiscall DMMCSession::SetCard(class TMMCard *)
+	?SetSocket@TPBusCallBack@@QAEXH@Z @ 63 NONAME ; public: void __thiscall TPBusCallBack::SetSocket(int)
+	?SetState@DPBusPsuBase@@QAEHW4TPBusPsuState@@@Z @ 64 NONAME ; public: int __thiscall DPBusPsuBase::SetState(enum TPBusPsuState)
+	?SetupCIMEraseGroup@DMMCSession@@QAEXVTMMCArgument@@K@Z @ 65 NONAME ; public: void __thiscall DMMCSession::SetupCIMEraseGroup(class TMMCArgument,unsigned long)
+	?SetupCIMEraseSector@DMMCSession@@QAEXVTMMCArgument@@K@Z @ 66 NONAME ; public: void __thiscall DMMCSession::SetupCIMEraseSector(class TMMCArgument,unsigned long)
+	?SetupCIMLockUnlock@DMMCSession@@QAEXKPAE@Z @ 67 NONAME ; public: void __thiscall DMMCSession::SetupCIMLockUnlock(unsigned long,unsigned char *)
+	?SetupCIMReadBlock@DMMCSession@@QAEXVTMMCArgument@@KPAE@Z @ 68 NONAME ; public: void __thiscall DMMCSession::SetupCIMReadBlock(class TMMCArgument,unsigned long,unsigned char *)
+	?SetupCIMReadIO@DMMCSession@@QAEXEKPAE@Z @ 69 NONAME ; public: void __thiscall DMMCSession::SetupCIMReadIO(unsigned char,unsigned long,unsigned char *)
+	?SetupCIMReadMBlock@DMMCSession@@QAEXVTMMCArgument@@KPAEK@Z @ 70 NONAME ; public: void __thiscall DMMCSession::SetupCIMReadMBlock(class TMMCArgument,unsigned long,unsigned char *,unsigned long)
+	?SetupCIMWriteBlock@DMMCSession@@QAEXVTMMCArgument@@KPAE@Z @ 71 NONAME ; public: void __thiscall DMMCSession::SetupCIMWriteBlock(class TMMCArgument,unsigned long,unsigned char *)
+	?SetupCIMWriteIO@DMMCSession@@QAEXEKPAE@Z @ 72 NONAME ; public: void __thiscall DMMCSession::SetupCIMWriteIO(unsigned char,unsigned long,unsigned char *)
+	?SetupCIMWriteMBlock@DMMCSession@@QAEXVTMMCArgument@@KPAEK@Z @ 73 NONAME ; public: void __thiscall DMMCSession::SetupCIMWriteMBlock(class TMMCArgument,unsigned long,unsigned char *,unsigned long)
+	?SetupCommand@DMMCSession@@QAEXW4TMMCCommandEnum@@VTMMCArgument@@@Z @ 74 NONAME ; public: void __thiscall DMMCSession::SetupCommand(enum TMMCCommandEnum,class TMMCArgument)
+	?SetupDTCommand@DMMCSession@@QAEXW4TMMCCommandEnum@@VTMMCArgument@@KPAEKHW4TMMCCmdDirEnum@@K@Z @ 75 NONAME ; public: void __thiscall DMMCSession::SetupDTCommand(enum TMMCCommandEnum,class TMMCArgument,unsigned long,unsigned char *,unsigned long,int,enum TMMCCmdDirEnum,unsigned long)
+	?SetupRSCommand@DMMCSession@@QAEXW4TMMCCommandEnum@@VTMMCArgument@@KW4TMMCCommandTypeEnum@@W4TMMCResponseTypeEnum@@K@Z @ 76 NONAME ; public: void __thiscall DMMCSession::SetupRSCommand(enum TMMCCommandEnum,class TMMCArgument,unsigned long,enum TMMCCommandTypeEnum,enum TMMCResponseTypeEnum,unsigned long)
+	?SocketFromId@DPBusSocket@@SAPAV1@H@Z @ 77 NONAME ; public: static class DPBusSocket * __cdecl DPBusSocket::SocketFromId(int)
+	?Stop@DMMCStack@@QAEHPAVTMMCard@@@Z @ 78 NONAME ; public: int __thiscall DMMCStack::Stop(class TMMCard *)
+	?UnBlock@DMMCStack@@IAEXPAVDMMCSession@@KK@Z @ 79 NONAME ; protected: void __thiscall DMMCStack::UnBlock(class DMMCSession *,unsigned long,unsigned long)
+	?WriteBlockLength@TCSD@@QBEIXZ @ 80 NONAME ; public: unsigned int __thiscall TCSD::WriteBlockLength(void)const 
+	?WriteProtected@DMMCStack@@MAEHI@Z @ 81 NONAME ; protected: virtual int __thiscall DMMCStack::WriteProtected(unsigned int)
+	?Create@DMMCMediaChange@@UAEHXZ @ 82 NONAME ; public: virtual int __thiscall DMMCMediaChange::Create(void)
+	?AllocSession@DMMCStack@@UBEPAVDMMCSession@@ABVTMMCCallBack@@@Z @ 83 NONAME ; public: virtual class DMMCSession * __thiscall DMMCStack::AllocSession(class TMMCCallBack const &)const 
+	?CIMReadWriteBlocksSMST@DMMCStack@@KAKPAX@Z @ 84 NONAME ; protected: static unsigned long __cdecl DMMCStack::CIMReadWriteBlocksSMST(void *)
+	?CardRCA@DMMCSession@@QAE?AVTRCA@@XZ @ 85 NONAME ; public: class TRCA  __thiscall DMMCSession::CardRCA(void)
+	?FillCommandArgs@DMMCSession@@QAEXVTMMCArgument@@KPAEK@Z @ 86 NONAME ; public: void __thiscall DMMCSession::FillCommandArgs(class TMMCArgument,unsigned long,unsigned char *,unsigned long)
+	?FillCommandDesc@DMMCSession@@QAEXW4TMMCCommandEnum@@@Z @ 87 NONAME ; public: void __thiscall DMMCSession::FillCommandDesc(enum TMMCCommandEnum)
+	?FillCommandDesc@DMMCSession@@QAEXW4TMMCCommandEnum@@VTMMCArgument@@@Z @ 88 NONAME ; public: void __thiscall DMMCSession::FillCommandDesc(enum TMMCCommandEnum,class TMMCArgument)
+	?FillCommandDesc@DMMCSession@@QAEXXZ @ 89 NONAME ; public: void __thiscall DMMCSession::FillCommandDesc(void)
+	?GetMacro@DMMCSession@@MBEP6AKPAX@ZH@Z @ 90 NONAME ; protected: virtual unsigned long (__cdecl*__thiscall DMMCSession::GetMacro(int)const )(void *)
+	?IssueMMCCommandSMST@DMMCStack@@KAKPAX@Z @ 91 NONAME ; protected: static unsigned long __cdecl DMMCStack::IssueMMCCommandSMST(void *)
+	?InitStackAfterUnlockSM@DMMCStack@@MAEKXZ @ 92 NONAME ; protected: virtual unsigned long __thiscall DMMCStack::InitStackAfterUnlockSM(void)
+	?PowerDownComplete@DPBusSocket@@QAEXXZ @ 93 NONAME ; public: void __thiscall DPBusSocket::PowerDownComplete(void)
+	?RegisterMediaDevices@TMMCardControllerInterface@@MAEHH@Z @ 94 NONAME ; protected: virtual int __thiscall TMMCardControllerInterface::RegisterMediaDevices(int)
+	?RequestAsyncPowerDown@DPBusSocket@@QAEXXZ @ 95 NONAME ; public: void __thiscall DPBusSocket::RequestAsyncPowerDown(void)
+	?ControlIO@DPBusSocket@@UAEHHPAX0@Z @ 96 NONAME ; public: virtual int __thiscall DPBusSocket::ControlIO(int,void *,void *)
+	?Dummy1@DMMCStack@@EAEXXZ @ 97 NONAME ; private: virtual void __thiscall DMMCStack::Dummy1(void)
+	?GetInterface@DMMCStack@@MAEXW4TInterfaceId@1@AAPAVMInterface@1@@Z @ 98 NONAME ; protected: virtual void __thiscall DMMCStack::GetInterface(enum DMMCStack::TInterfaceId,class DMMCStack::MInterface * &)
+	?MachineInfo@DMMCStack@@UAEXAAVTDes8@@@Z @ 99 NONAME ; public: virtual void __thiscall DMMCStack::MachineInfo(class TDes8 &)
+	?SetBusWidth@DMMCStack@@MAEXK@Z @ 100 NONAME ; protected: virtual void __thiscall DMMCStack::SetBusWidth(unsigned long)
+	?ModifyCardCapabilitySM@DMMCStack@@MAEKXZ @ 101 NONAME ; protected: virtual unsigned long __thiscall DMMCStack::ModifyCardCapabilitySM(void)
+	?AcquireStackSM@DSDStack@@UAEKXZ @ 102 NONAME ; public: virtual unsigned long __thiscall DSDStack::AcquireStackSM(void)
+	?AllocCards@TSDCardArray@@UAEHXZ @ 103 NONAME ; public: virtual int __thiscall TSDCardArray::AllocCards(void)
+	?AllocSession@DSDStack@@UBEPAVDMMCSession@@ABVTMMCCallBack@@@Z @ 104 NONAME ; public: virtual class DMMCSession * __thiscall DSDStack::AllocSession(class TMMCCallBack const &)const 
+	?CIMReadWriteBlocksSM@DSDStack@@UAEKXZ @ 105 NONAME ; public: virtual unsigned long __thiscall DSDStack::CIMReadWriteBlocksSM(void)
+	?DeclareCardAsGone@TSDCardArray@@UAEXI@Z @ 106 NONAME ; public: virtual void __thiscall TSDCardArray::DeclareCardAsGone(unsigned int)
+	?Dummy1@DSDStack@@EAEXXZ @ 107 NONAME ; private: virtual void __thiscall DSDStack::Dummy1(void)
+	?Dummy2@DSDStack@@EAEXXZ @ 108 NONAME ; private: virtual void __thiscall DSDStack::Dummy2(void)
+	?Dummy3@DSDStack@@EAEXXZ @ 109 NONAME ; private: virtual void __thiscall DSDStack::Dummy3(void)
+	?CardType@DSDStack@@UAE?AW4TSDCardType@1@HH@Z @ 110 NONAME ; public: virtual enum DSDStack::TSDCardType __thiscall DSDStack::CardType(int,int)
+	?Init@DSDStack@@UAEHXZ @ 111 NONAME ; public: virtual int __thiscall DSDStack::Init(void)
+	?InitStackAfterUnlockSM@DSDStack@@MAEKXZ @ 112 NONAME ; protected: virtual unsigned long __thiscall DSDStack::InitStackAfterUnlockSM(void)
+	?ModifyCardCapabilitySM@DSDStack@@MAEKXZ @ 113 NONAME ; protected: virtual unsigned long __thiscall DSDStack::ModifyCardCapabilitySM(void)
+	?DummyExport10@DDummySession@@AAEXXZ @ 114 NONAME ; private: void __thiscall DDummySession::DummyExport10(void)
+	?DummyExport11@DDummySession@@AAEXXZ @ 115 NONAME ; private: void __thiscall DDummySession::DummyExport11(void)
+	?DummyExport12@DDummySession@@AAEXXZ @ 116 NONAME ; private: void __thiscall DDummySession::DummyExport12(void)
+	?DummyExport13@DDummySession@@AAEXXZ @ 117 NONAME ; private: void __thiscall DDummySession::DummyExport13(void)
+	?DummyExport14@DDummySession@@AAEXXZ @ 118 NONAME ; private: void __thiscall DDummySession::DummyExport14(void)
+	?DummyExport15@DDummySession@@AAEXXZ @ 119 NONAME ; private: void __thiscall DDummySession::DummyExport15(void)
+	?DummyExport1@DDummySession@@AAEXXZ @ 120 NONAME ; private: void __thiscall DDummySession::DummyExport1(void)
+	?DummyExport2@DDummySession@@AAEXXZ @ 121 NONAME ; private: void __thiscall DDummySession::DummyExport2(void)
+	?DummyExport3@DDummySession@@AAEXXZ @ 122 NONAME ; private: void __thiscall DDummySession::DummyExport3(void)
+	?DummyExport4@DDummySession@@AAEXXZ @ 123 NONAME ; private: void __thiscall DDummySession::DummyExport4(void)
+	?DummyExport5@DDummySession@@AAEXXZ @ 124 NONAME ; private: void __thiscall DDummySession::DummyExport5(void)
+	?DummyExport6@DDummySession@@AAEXXZ @ 125 NONAME ; private: void __thiscall DDummySession::DummyExport6(void)
+	?DummyExport7@DDummySession@@AAEXXZ @ 126 NONAME ; private: void __thiscall DDummySession::DummyExport7(void)
+	?DummyExport8@DDummySession@@AAEXXZ @ 127 NONAME ; private: void __thiscall DDummySession::DummyExport8(void)
+	?DummyExport9@DDummySession@@AAEXXZ @ 128 NONAME ; private: void __thiscall DDummySession::DummyExport9(void)
+	??0DSDIOPsu@@QAE@HH@Z @ 129 NONAME ; public: __thiscall DSDIOPsu::DSDIOPsu(int,int)
+	??0DSDIORegisterInterface@@QAE@PAVTSDIOCard@@E@Z @ 130 NONAME ; public: __thiscall DSDIORegisterInterface::DSDIORegisterInterface(class TSDIOCard *,unsigned char)
+	??0DSDIORegisterInterface@@QAE@PAVTSDIOCard@@EPAVDMutex@@@Z @ 131 NONAME ; public: __thiscall DSDIORegisterInterface::DSDIORegisterInterface(class TSDIOCard *,unsigned char,class DMutex *)
+	??0DSDIOSocket@@QAE@HPAVTMMCPasswordStore@@@Z @ 132 NONAME ; public: __thiscall DSDIOSocket::DSDIOSocket(int,class TMMCPasswordStore *)
+	??0TCisReader@@QAE@XZ @ 133 NONAME ; public: __thiscall TCisReader::TCisReader(void)
+	??0TSDIOCardConfig@@QAE@XZ @ 134 NONAME ; public: __thiscall TSDIOCardConfig::TSDIOCardConfig(void)
+	??0TSDIOFunction@@QAE@PAVTSDIOCard@@E@Z @ 135 NONAME ; public: __thiscall TSDIOFunction::TSDIOFunction(class TSDIOCard *,unsigned char)
+	??0TSDIOInterrupt@@QAE@PAVTSDIOInterruptController@@E@Z @ 136 NONAME ; public: __thiscall TSDIOInterrupt::TSDIOInterrupt(class TSDIOInterruptController *,unsigned char)
+	??1DSDIORegisterInterface@@UAE@XZ @ 137 NONAME ; public: virtual __thiscall DSDIORegisterInterface::~DSDIORegisterInterface(void)
+	??1TSDIOFunction@@QAE@XZ @ 138 NONAME ; public: __thiscall TSDIOFunction::~TSDIOFunction(void)
+	??1TSDIOInterrupt@@QAE@XZ @ 139 NONAME ; public: __thiscall TSDIOInterrupt::~TSDIOInterrupt(void)
+	?AcquireStackSM@DSDIOStack@@MAEKXZ @ 140 NONAME ; protected: virtual unsigned long __thiscall DSDIOStack::AcquireStackSM(void)
+	?AllocCards@TSDIOCardArray@@UAEHXZ @ 141 NONAME ; public: virtual int __thiscall TSDIOCardArray::AllocCards(void)
+	?AllocSession@DSDIOStack@@UBEPAVDMMCSession@@ABVTMMCCallBack@@@Z @ 142 NONAME ; public: virtual class DMMCSession * __thiscall DSDIOStack::AllocSession(class TMMCCallBack const &)const 
+	?Bind@TSDIOInterrupt@@QAEHP6AXPAX@Z0@Z @ 143 NONAME ; public: int __thiscall TSDIOInterrupt::Bind(void (__cdecl*)(void *),void *)
+	?BlockIOSession@DSDIOStack@@IAEXW4TSDIOBlockingCondition@1@@Z @ 144 NONAME ; protected: void __thiscall DSDIOStack::BlockIOSession(enum DSDIOStack::TSDIOBlockingCondition)
+	?CIMIoModifySM@DSDIOStack@@IAEKXZ @ 145 NONAME ; protected: unsigned long __thiscall DSDIOStack::CIMIoModifySM(void)
+	?CIMIoReadWriteDirectSM@DSDIOStack@@IAEKXZ @ 146 NONAME ; protected: unsigned long __thiscall DSDIOStack::CIMIoReadWriteDirectSM(void)
+	?CIMIoReadWriteExtendedSM@DSDIOStack@@IAEKXZ @ 147 NONAME ; protected: unsigned long __thiscall DSDIOStack::CIMIoReadWriteExtendedSM(void)
+	?CIMReadWriteBlocksSM@DSDIOStack@@MAEKXZ @ 148 NONAME ; protected: virtual unsigned long __thiscall DSDIOStack::CIMReadWriteBlocksSM(void)
+	?CapabilitiesMatch@TSDIOFunctionCaps@@QAEHAAV1@K@Z @ 149 NONAME ; public: int __thiscall TSDIOFunctionCaps::CapabilitiesMatch(class TSDIOFunctionCaps &,unsigned long)
+	?CheckCIS@TSDIOCard@@QAEHXZ @ 150 NONAME ; public: int __thiscall TSDIOCard::CheckCIS(void)
+	?DeclareCardAsGone@TSDIOCardArray@@UAEXI@Z @ 151 NONAME ; public: virtual void __thiscall TSDIOCardArray::DeclareCardAsGone(unsigned int)
+	?DeregisterClient@TSDIOFunction@@QAEHPAVDBase@@@Z @ 152 NONAME ; public: int __thiscall TSDIOFunction::DeregisterClient(class DBase *)
+	?Disable@TSDIOFunction@@QAEHXZ @ 153 NONAME ; public: int __thiscall TSDIOFunction::Disable(void)
+	?Disable@TSDIOInterrupt@@QAEHXZ @ 154 NONAME ; public: int __thiscall TSDIOInterrupt::Disable(void)
+	?DoCreate@DSDIOPsu@@UAEHXZ @ 155 NONAME ; public: virtual int __thiscall DSDIOPsu::DoCreate(void)
+	?DoTickService@DSDIOPsu@@UAEXXZ @ 156 NONAME ; public: virtual void __thiscall DSDIOPsu::DoTickService(void)
+	?Dummy1@DSDIOStack@@EAEXXZ @ 157 NONAME ; private: virtual void __thiscall DSDIOStack::Dummy1(void)
+	?Dummy2@DSDIOStack@@EAEXXZ @ 158 NONAME ; private: virtual void __thiscall DSDIOStack::Dummy2(void)
+	?Dummy3@DSDIOStack@@EAEXXZ @ 159 NONAME ; private: virtual void __thiscall DSDIOStack::Dummy3(void)
+	?Dummy4@DSDIOStack@@EAEXXZ @ 160 NONAME ; private: virtual void __thiscall DSDIOStack::Dummy4(void)
+	?Enable@TSDIOFunction@@QAEHH@Z @ 161 NONAME ; public: int __thiscall TSDIOFunction::Enable(int)
+	?Enable@TSDIOInterrupt@@QAEHXZ @ 162 NONAME ; public: int __thiscall TSDIOInterrupt::Enable(void)
+	?FillAppCommandDesc@DSDIOSession@@CAXAAVTMMCCommandDesc@@@Z @ 163 NONAME ; private: static void __cdecl DSDIOSession::FillAppCommandDesc(class TMMCCommandDesc &)
+	?FillAppCommandDesc@DSDIOSession@@SAXAAVTMMCCommandDesc@@W4TSDIOAppCmd@@@Z @ 164 NONAME ; public: static void __cdecl DSDIOSession::FillAppCommandDesc(class TMMCCommandDesc &,enum TSDIOAppCmd)
+	?FillAppCommandDesc@DSDIOSession@@SAXAAVTMMCCommandDesc@@W4TSDIOAppCmd@@VTMMCArgument@@@Z @ 165 NONAME ; public: static void __cdecl DSDIOSession::FillAppCommandDesc(class TMMCCommandDesc &,enum TSDIOAppCmd,class TMMCArgument)
+	?FindFunction@TSDIOCard@@QBEPAVTSDIOFunction@@AAVTSDIOFunctionCaps@@KPAV2@@Z @ 166 NONAME ; public: class TSDIOFunction * __thiscall TSDIOCard::FindFunction(class TSDIOFunctionCaps &,unsigned long,class TSDIOFunction *)const 
+	?FindReadCommonConfig@TCisReader@@QAEHAAVTSDIOCardConfig@@@Z @ 167 NONAME ; public: int __thiscall TCisReader::FindReadCommonConfig(class TSDIOCardConfig &)
+	?FindReadFunctionConfig@TCisReader@@QAEHAAVTSDIOFunctionCaps@@@Z @ 168 NONAME ; public: int __thiscall TCisReader::FindReadFunctionConfig(class TSDIOFunctionCaps &)
+	?FindReadTuple@TCisReader@@QAEHEAAVTDes8@@I@Z @ 169 NONAME ; public: int __thiscall TCisReader::FindReadTuple(unsigned char,class TDes8 &,unsigned int)
+	?GetMacro@DSDIOSession@@MBEP6AKPAX@ZH@Z @ 170 NONAME ; protected: virtual unsigned long (__cdecl*__thiscall DSDIOSession::GetMacro(int)const )(void *)
+	?HandleSDIOInterrupt@DSDIOStack@@IAEXI@Z @ 171 NONAME ; protected: void __thiscall DSDIOStack::HandleSDIOInterrupt(unsigned int)
+	?Init@DSDIOStack@@UAEHXZ @ 172 NONAME ; public: virtual int __thiscall DSDIOStack::Init(void)
+	?IsLocked@DSDIOPsu@@UAEHXZ @ 173 NONAME ; public: virtual int __thiscall DSDIOPsu::IsLocked(void)
+	?IsReady@TSDIOFunction@@QAEHAAH@Z @ 174 NONAME ; public: int __thiscall TSDIOFunction::IsReady(int &)
+	?Modify8@DSDIORegisterInterface@@QAEHKEEPAE@Z @ 175 NONAME ; public: int __thiscall DSDIORegisterInterface::Modify8(unsigned long,unsigned char,unsigned char,unsigned char *)
+	?ModifyCardCapabilitySM@DSDIOStack@@MAEKXZ @ 176 NONAME ; protected: virtual unsigned long __thiscall DSDIOStack::ModifyCardCapabilitySM(void)
+	?Read8@DSDIORegisterInterface@@QAEHKPAE@Z @ 177 NONAME ; public: int __thiscall DSDIORegisterInterface::Read8(unsigned long,unsigned char *)
+	?ReadMultiple8@DSDIORegisterInterface@@QAEHKPAEKH@Z @ 178 NONAME ; public: int __thiscall DSDIORegisterInterface::ReadMultiple8(unsigned long,unsigned char *,unsigned long,int)
+	?ReadTuple@TCisReader@@QAEHAAVTDes8@@@Z @ 179 NONAME ; public: int __thiscall TCisReader::ReadTuple(class TDes8 &)
+	?Register@TSDIOFunctionCallback@@QAEXPAVDMMCSocket@@@Z @ 180 NONAME ; public: void __thiscall TSDIOFunctionCallback::Register(class DMMCSocket *)
+	?RegisterClient@TSDIOFunction@@QAEHPAVDBase@@PAVDMutex@@@Z @ 181 NONAME ; public: int __thiscall TSDIOFunction::RegisterClient(class DBase *,class DMutex *)
+	?RegisterMediaDevices@TSDIOCardControllerInterface@@MAEHH@Z @ 182 NONAME ; protected: virtual int __thiscall TSDIOCardControllerInterface::RegisterMediaDevices(int)
+	?RequestAsyncSleep@DSDIOSocket@@QAEXXZ @ 183 NONAME ; public: void __thiscall DSDIOSocket::RequestAsyncSleep(void)
+	?Restart@TCisReader@@QAEHXZ @ 184 NONAME ; public: int __thiscall TCisReader::Restart(void)
+	?SelectCis@TCisReader@@QAEHIIIE@Z @ 185 NONAME ; public: int __thiscall TCisReader::SelectCis(unsigned int,unsigned int,unsigned int,unsigned char)
+	?SetAsync@DSDIORegisterInterface@@QAEHAAVTMMCCallBack@@@Z @ 186 NONAME ; public: int __thiscall DSDIORegisterInterface::SetAsync(class TMMCCallBack &)
+	?SetPriority@TSDIOFunction@@QAEHW4TSDIOFunctionPriority@@@Z @ 187 NONAME ; public: int __thiscall TSDIOFunction::SetPriority(enum TSDIOFunctionPriority)
+	?SetSync@DSDIORegisterInterface@@QAEHXZ @ 188 NONAME ; public: int __thiscall DSDIORegisterInterface::SetSync(void)
+	?SetupCIMIoModify@DSDIOSession@@QAEXKEEPAE@Z @ 189 NONAME ; public: void __thiscall DSDIOSession::SetupCIMIoModify(unsigned long,unsigned char,unsigned char,unsigned char *)
+	?SetupCIMIoRead@DSDIOSession@@QAEXKPAE@Z @ 190 NONAME ; public: void __thiscall DSDIOSession::SetupCIMIoRead(unsigned long,unsigned char *)
+	?SetupCIMIoReadMultiple@DSDIOSession@@QAEXKKPAEH@Z @ 191 NONAME ; public: void __thiscall DSDIOSession::SetupCIMIoReadMultiple(unsigned long,unsigned long,unsigned char *,int)
+	?SetupCIMIoWrite@DSDIOSession@@QAEXKEPAE@Z @ 192 NONAME ; public: void __thiscall DSDIOSession::SetupCIMIoWrite(unsigned long,unsigned char,unsigned char *)
+	?SetupCIMIoWriteMultiple@DSDIOSession@@QAEXKKPAEH@Z @ 193 NONAME ; public: void __thiscall DSDIOSession::SetupCIMIoWriteMultiple(unsigned long,unsigned long,unsigned char *,int)
+	?SleepComplete@DSDIOSocket@@QAEXXZ @ 194 NONAME ; public: void __thiscall DSDIOSocket::SleepComplete(void)
+	?Unbind@TSDIOInterrupt@@QAEHXZ @ 195 NONAME ; public: int __thiscall TSDIOInterrupt::Unbind(void)
+	?UnblockIOSession@DSDIOStack@@IAEPAVDSDIOSession@@W4TSDIOBlockingCondition@1@K@Z @ 196  NONAME ; protected: class DSDIOSession * __thiscall DSDIOStack::UnblockIOSession(enum DSDIOStack::TSDIOBlockingCondition,unsigned long)
+	?Write8@DSDIORegisterInterface@@QAEHKEPAE@Z @ 197 NONAME ; public: int __thiscall DSDIORegisterInterface::Write8(unsigned long,unsigned char,unsigned char *)
+	?WriteMultiple8@DSDIORegisterInterface@@QAEHKPAEKH@Z @ 198 NONAME ; public: int __thiscall DSDIORegisterInterface::WriteMultiple8(unsigned long,unsigned char *,unsigned long,int)
+	??1DSDIOSession@@UAE@XZ @ 199  NONAME ; public: virtual __thiscall DSDIOSession::~DSDIOSession(void)
+	?Dummy1@DSDIOPsu@@EAEXXZ @ 200  NONAME ; private: virtual void __thiscall DSDIOPsu::Dummy1(void)
+	?Dummy1@DSDIOSession@@EAEXXZ @ 201  NONAME ; private: virtual void __thiscall DSDIOSession::Dummy1(void)
+	?Dummy2@DSDIOPsu@@EAEXXZ @ 202  NONAME ; private: virtual void __thiscall DSDIOPsu::Dummy2(void)
+	?Dummy2@DSDIOSession@@EAEXXZ @ 203  NONAME ; private: virtual void __thiscall DSDIOSession::Dummy2(void)
+	?Dummy3@DSDIOPsu@@EAEXXZ @ 204  NONAME ; private: virtual void __thiscall DSDIOPsu::Dummy3(void)
+	?Dummy3@DSDIOSession@@EAEXXZ @ 205  NONAME ; private: virtual void __thiscall DSDIOSession::Dummy3(void)
+	?Dummy4@DSDIOPsu@@EAEXXZ @ 206  NONAME ; private: virtual void __thiscall DSDIOPsu::Dummy4(void)
+	?Dummy4@DSDIOSession@@EAEXXZ @ 207  NONAME ; private: virtual void __thiscall DSDIOSession::Dummy4(void)
+	?MachineInfo@DMMCStack@@UAEXAAVTDes8@@@Z @ 208  NONAME ; public: virtual void __thiscall DMMCStack::MachineInfo(class TDes8 &)
+	?Modify8@DSDIORegisterInterface@@QAEHKEE@Z @ 209  NONAME ; public: int __thiscall DSDIORegisterInterface::Modify8(unsigned long,unsigned char,unsigned char)
+	?ReadMultiple8@DSDIORegisterInterface@@QAEHKPAEK@Z @ 210  NONAME ; public: int __thiscall DSDIORegisterInterface::ReadMultiple8(unsigned long,unsigned char *,unsigned long)
+	?ReadMultiple8@DSDIORegisterInterface@@QAEHKPAVDChunk@@KK@Z @ 211  NONAME ; public: int __thiscall DSDIORegisterInterface::ReadMultiple8(unsigned long,class DChunk *,unsigned long,unsigned long)
+	?ReadMultiple8@DSDIORegisterInterface@@QAEHKPAVDChunk@@KKH@Z @ 212  NONAME ; public: int __thiscall DSDIORegisterInterface::ReadMultiple8(unsigned long,class DChunk *,unsigned long,unsigned long,int)
+	?Write8@DSDIORegisterInterface@@QAEHKE@Z @ 213  NONAME ; public: int __thiscall DSDIORegisterInterface::Write8(unsigned long,unsigned char)
+	?WriteMultiple8@DSDIORegisterInterface@@QAEHKPAEK@Z @ 214  NONAME ; public: int __thiscall DSDIORegisterInterface::WriteMultiple8(unsigned long,unsigned char *,unsigned long)
+	?WriteMultiple8@DSDIORegisterInterface@@QAEHKPAVDChunk@@KK@Z @ 215  NONAME ; public: int __thiscall DSDIORegisterInterface::WriteMultiple8(unsigned long,class DChunk *,unsigned long,unsigned long)
+	?WriteMultiple8@DSDIORegisterInterface@@QAEHKPAVDChunk@@KKH@Z @ 216  NONAME ; public: int __thiscall DSDIORegisterInterface::WriteMultiple8(unsigned long,class DChunk *,unsigned long,unsigned long,int)
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kernel/eka/drivers/pbus/mmc/sdcard/eabi/sdcard3c/epbusmu.def	Fri Apr 16 16:24:37 2010 +0300
@@ -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	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/drivers/pbus/mmc/sdcard/eabi/sdcard3c/sdio/epbusmu.def	Fri Apr 16 16:24:37 2010 +0300
@@ -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	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/drivers/pbus/mmc/sdcard/sdcard3c/sdcard.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -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	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/drivers/pbus/mmc/sdcard/sdcard3c/sdio/sdiostack.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -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	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/drivers/pbus/mmc/session.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -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	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/drivers/pbus/mmc/stack.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -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	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/drivers/pbus/pbusmedia.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -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	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/drivers/pbus/spbus.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -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
@@ -1111,6 +1111,9 @@
 	OstTraceFunctionEntry1( DPBUSSOCKET_DOORCLOSEEVENT_ENTRY, this );
 	__KTRACE_OPT(KPBUS1,Kern::Printf(">DPBusSocket(%d)::DoorCloseEvent state %d",iSocketNumber,iState));
 	OstTraceExt2(TRACE_INTERNALS, DPBUSSOCKET_DOORCLOSEEVENT , "iSocketNumber=%d; iState=%d",iSocketNumber,iState);
+	
+	if (iPostponedEvents & EMediaChange)
+		iPostponedEvents &= ~EMediaChange;
 
 	// NB If there are multiple doors then the bus may already be powererd up, 
 	// so it's not possible to determine the bus state.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kernel/eka/drivers/power/smppower/idlehelper.cia	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,308 @@
+/*
+* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "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:  
+* os\kernelhwsrv\kernel\eka\drivers\power\smpidlehelper.cpp
+* Impelentation of helper classes required to implement CPU idle
+* functionality in a SMP BSP.
+*
+*/
+
+
+/**
+ @file
+ @prototype
+*/
+
+
+
+#ifdef __SMP__
+
+
+#include <smppower/idlehelper.h>
+
+
+#ifndef DISABLE_TRACE
+
+extern "C" void btrace_printfn(const TAny *aPtr,const TInt regNum)
+    {
+    PMBTRACE4(KPrintReg,regNum,aPtr);
+    }
+
+extern "C" void btrace_printfnId(const TAny *aPtr,const TInt regNum, TUint aId)
+    {
+    PMBTRACE8(KPrintReg,0xffu,regNum,aPtr);
+    }
+
+#define PRINTREG(Rn)                 \
+        asm("stmfd sp!,{r0-r12,lr}"); \
+        asm("mov r0,r"#Rn); \
+        asm("mov r1,#"#Rn); \
+        asm("bl btrace_printfn"); \
+        asm("ldmfd sp!,{r0-r12,lr}"); 
+
+#define PRINTREGID(Rn,n)               \
+        asm("stmfd sp!,{r0-r12,lr}"); \
+        asm("mov r0,r"#Rn); \
+        asm("mov r1,#"#Rn); \
+        asm("mov r2,#"#n); \
+        asm("bl btrace_printfnId"); \
+        asm("ldmfd sp!,{r0-r12,lr}"); 
+
+
+#else
+#define PRINTREG(Rn)
+#define PRINTREGID(Rn,n)
+#endif
+
+
+/**
+   Atomically does the following:
+     sets the current cpu idle mask bit to indicate current core wants to idle
+     if all enaged cores have set their bit the flag KGlobalIdleFlag is also 
+     orred into the idle mask to indicate all cores are going down. In this case
+     the function returned true. False otherwise
+
+   aCMask- Bit mask with only current CPU bit set
+   Normal Usage:use in idle handler before waiting for all cores down IPI
+   
+   @pre 
+ */		
+	
+__NAKED__ TBool TIdleSupport::SetLocalAndCheckSetGlobalIdle(TUint32 /*aCpuMask*/)
+    {
+	asm("ldr    r1,__iAllEngagedCpusMask");                           //r1 = address of iAllEngagedCpusMask
+	asm("ldr	r2, [r1]");                                           //r2 = iAllEngagedCpusMask
+    asm("add    r1,r1,#4");                                           //r1 = address of iIdlingCpus 
+    __DATA_MEMORY_BARRIER_Z__(r12);   
+    asm("1: ");
+	LDREX(3,1);                                                       // r3 = iIdlingCpus
+    asm("orr    r3,r0,r3");                                           // orr in mask for this CPU
+    asm("cmp    r3,r2");                                              // compare to iAllEngagedCpusMask
+    asm("orreq  r3,r3,#%a0" : : "i" (TIdleSupport::KGlobalIdleFlag)); // if equal orr in KGlobalIdleFlag
+    STREX(12,3,1);
+    asm("cmp    r12, #0 ");                                              // 
+	asm("bne    1b ");                                                   // write didn't succeed try again
+    __DATA_MEMORY_BARRIER__(r12);
+    asm("and    r0,r3,#%a0" : : "i" (TIdleSupport::KGlobalIdleFlag));
+	__JUMP(,lr);
+    asm("__iAllEngagedCpusMask:");
+    asm(".word %a0" : : "i" ((TInt)&TIdleSupport::iAllEngagedCpusMask));//
+    }
+
+/** 
+
+Wait for all CPUs to reach the sync point. A CPU will only exit this function when all other CPUs
+have reached it. 
+
+Works like this:
+
+cpuMask = 1 << NKern::CurrentCpu()
+BEGIN_ATOMIC
+    stage = iStageAndCPUWaitingMask >> 16
+    waitingCpus = iStageAndCPUWaitingMask&iAllCpusMask
+    oldstage = stage;
+    if (waitingCpus == iAllCpusMask) // we synched already and this is new 
+             waitingCpus = 0;
+     waitingCpus |= cpuMask
+     if (waitingCpus == iAllCpusMask) stage++
+     iStageAndCPUWaitingMask = (stage << 16) | waitingCpus
+END_ATOMIC
+FOREVER 
+   if (oldstage!=stage) return
+   stage = iStageAndCPUWaitingMask >> 16 // reread stage
+END_FOREVER   
+
+*/
+__NAKED__ void TSyncPoint::DoSW(TUint32 /*aCpuMask*/)
+    {
+    asm("stmfd sp!, {r4-r5,lr} ");	
+    asm("add r0,r0,#%a0" : : "i"  _FOFF(TSyncPointBase, iStageAndCPUWaitingMask)); // skip vt
+    asm("ldr r4,[r0,#4]"); 
+    asm("ldr r4,[r4]")
+   __DATA_MEMORY_BARRIER_Z__(r12);          // 
+    asm("1: ");
+	LDREX(2,0);                             // r2 =  iStageAndCPUWaitingMask, r4 = iAllEnagedCpusMask
+    asm("mov r5,r2,lsr #16");               // r5 has old staging value
+    asm("and r2,r2,r4");                    // r2 has currently waiting cpus
+    asm("cmp r2,r4");                       // if r2 == r4 then we previously have had all cpus synched 
+    asm("moveq r2,#0");                     // reset 
+    asm("orr r2, r2, r1");                  // orr mask for this CPU 
+    asm("mov r3,r5");                       // r3 will have new stage
+    asm("cmp r2,r4");                       // if r2 == r4 then all cpus have set
+    asm("addeq r3,r3,#1");                  // increment new stage count
+    asm("orr r2,r2,r3, lsl #16");          
+	STREX(12,2,0);                           // try to atomically iStageAndCPUWaitingMask
+	asm("cmp r12, #0 ");
+	asm("bne 1b ");                         // write didn't succeed try again
+    __DATA_MEMORY_BARRIER__(r12);          // ensure that's written
+#ifdef SYNCPOINT_WFE	
+	asm("ands r2,r2,r4");
+    asm("cmp r2,r4");                       // if r2 == r4 then all cpus have set      			
+	ARM_SEVcc(CC_EQ);
+#endif		
+    asm("2: ");
+    asm("cmp r3,r5");                       // all (old stage does not equal new stage)
+    asm("ldmfdne sp!, {r4-r5,pc}");         // yup return
+#ifdef SYNCPOINT_WFE		
+	__DATA_MEMORY_BARRIER__(r12);        
+	ARM_WFE;
+#endif	
+    asm("ldr r2,[r0]");                     // otherwise re read iWaitingCpusMask into r5
+    __DATA_MEMORY_BARRIER__(r12);           // ensure read is observed
+    asm("mov r3,r2,lsr #16");               // re-read new stage
+    asm("b 2b");                            // loop back
+    }
+
+/** 
+
+Wait for all CPUs to reach the sync point. A CPU will only exit this function when all other CPUs
+have reached it or if another CPU has called the Break function. An attempt to wait on a broken
+syncpoint will return immediately.
+
+Works like this:
+
+cpuMask = 1 << NKern::CurrentCpu()
+BEGIN_ATOMIC
+     waitingCpus = iStageAndCPUWaitingMask&iAllEnagedCpusMask
+     if (iStageAndCPUWaitingMask & 0x80000000) // sync point is broken
+        END_ATOMIC and return
+
+     waitingCpus |= cpuMask
+     if (waitingCpus == iAllEnagedCpusMask) waitingCpus |= 0x80000000
+     iStageAndCPUWaitingMask = waitingCpus
+END_ATOMIC
+FOREVER 
+     if (iStageAndCPUWaitingMask&0x80000000) break
+END_FOREVER   
+
+*/
+__NAKED__ void TBreakableSyncPoint::DoSW(TUint32 /*aCpuMask*/)
+    {
+    asm("stmfd sp!, {r4,lr} ");	
+    asm("add r0,r0,#%a0" : : "i"  _FOFF(TSyncPointBase, iStageAndCPUWaitingMask)); // skip vt
+    asm("ldr r4,[r0,#4]");
+    asm("ldr r4,[r4]")
+    __DATA_MEMORY_BARRIER_Z__(r12);          // 
+    asm("1: ");
+	LDREX(2,0);                             // r2 =  iStageAndCPUWaitingMask, r4 = iAllEnagedCpusMask
+    asm("ands r3,r2,#0x80000000");          // 
+    asm("bne 3f");                          // sync point broken so return
+    asm("and r2,r2,r4");                    // r2 has currently waiting cpus
+    asm("orr r2, r2, r1");                  // orr mask for this CPU 
+    asm("cmp r2,r4");                       // if r2 == r4 then all cpus have set
+    asm("orreq r2,r2,#0x80000000");         // set MSB
+	STREX(12,2,0);                          // try to atomically iStageAndCPUWaitingMask
+	asm("cmp r12, #0 ");
+	asm("bne 1b ");                         // write didn't succeed try again		
+    __DATA_MEMORY_BARRIER__(r12);           // ensure that's written
+#ifdef SYNCPOINT_WFE	
+	asm("ands r3,r2,#0x80000000");          // MSB set?
+	ARM_SEVcc(CC_NE);
+#endif		
+    asm("2: ");
+    asm("ands r3,r2,#0x80000000");          // MSB set?	
+    asm("ldmfdne sp!, {r4,pc}");            // yup return
+#ifdef SYNCPOINT_WFE		
+	__DATA_MEMORY_BARRIER__(r12);
+	ARM_WFE;
+#endif	
+    asm("ldr r2,[r0]");                     // otherwise re read iWaitingCpusMask into r5
+    //__DATA_MEMORY_BARRIER_Z__(r12);        // ensure read is observed
+    asm("b 2b");                            // loop back
+    asm("3:");
+    CLREX;
+#ifdef SYNCPOINT_WFE	 
+    __DATA_MEMORY_BARRIER__(r12);           // ensure that's written
+	ARM_SEV;
+#endif	
+    asm("ldmfd sp!, {r4,pc}");            // yup return
+    }
+	
+	
+#ifdef PROPER_WFI
+__NAKED__ void TIdleSupport::DoWFI()
+    {
+    __DATA_SYNC_BARRIER_Z__(r12);  // generally good idea to a barrier before WFI            
+    ARM_WFI;
+	__JUMP(,lr);
+    }
+#else
+void TIdleSupport::DoWFI()
+    {
+    TInt c=NKern::CurrentCpu();
+    FOREVER
+        {
+        TInt isr = Pending();
+        if (isr!=1023) 
+            {
+            BTRACE0(KIsrPendingCat,isr&0xff);
+            break;
+            }
+        }
+    }
+#endif
+
+__NAKED__ void TIdleSupport::DoIdleIPI(TUint32 /*aMask*/) 
+    {
+	//r0 = cpu mask
+    asm("ldr    r2,__EnagedCpusMask");  // only IPI enaged cores r2 has enaged core mask addr
+    asm("ldr    r2,[r2]");   
+    asm("and    r0,r0,r2");            // and out retired cores
+    asm("ldr	r1,__KGICAddr");//r1 = address off iGlobalIntDistAddress
+    asm("ldr	r1, [r1]");//r1 = address of Hw GIC interrupt dispatcher base			
+    __DATA_SYNC_BARRIER_Z__(r12);			// need DSB before sending any IPI
+    asm("movs	r0, r0, lsl #16 ");		// CPU mask into bits 16-23 - any bits set in aMask?
+    asm("orrne	r0, r0, #%a0" : : "i" ((TInt) IDLE_WAKEUP_IPI_VECTOR));
+    asm("strne	r0, [r1, #%a0]" : : "i" _FOFF(GicDistributor, iSoftIrq));	// trigger IPIs if any
+    __JUMP(,lr);
+    asm("__KGICAddr:");
+    asm(".word %a0" : : "i" ((TInt)&TIdleSupport::iGlobalIntDistAddress));
+    asm("__EnagedCpusMask:");
+    asm(".word %a0" : : "i" ((TInt)&TIdleSupport::iAllEngagedCpusMask));
+    }
+
+#ifdef _DEBUG
+__NAKED__  TInt TIdleSupport::DoClearIdleIPI()
+#else
+__NAKED__  void TIdleSupport::ClearIdleIPI()
+#endif
+    {
+    __DATA_SYNC_BARRIER_Z__(r12);			// DSB    
+    asm("ldr    r1,__KCPUIFAddr");//r1 = address of iBaseIntIfAddress
+    asm("ldr	r1, [r1]");//r1 = address of Hw GIC CPU interrupt interface base address
+    asm("ldr    r0,[r1, #%a0]" : : "i" _FOFF(GicCpuIfc, iAck));
+    // asm("mov    r0,#%a0" : : "i" ((TInt) IDLE_WAKEUP_IPI_VECTOR)); // has to be!
+    asm("str    r0, [r1, #%a0]" : : "i" _FOFF(GicCpuIfc, iEoi));
+	__JUMP(,lr);
+    asm("__KCPUIFAddr:");
+    asm(".word %a0" : : "i" ((TInt)&TIdleSupport::iBaseIntIfAddress));// CPU interrupt interface base address
+    }
+
+#ifndef _DEBUG
+TInt TIdleSupport::DoClearIdleIPI()
+    {
+    return 0;
+    }
+#endif
+
+__NAKED__  TInt TIdleSupport::IntPending()  
+    {
+	asm("ldr    r1,__KCPUIFAddr");//r1 = address of iBaseIntIfAddress
+	asm("ldr	r1, [r1]");//r1 = address of Hw GIC CPU interrupt interface base address
+	asm("ldr    r0, [r1, #%a0]" : : "i" _FOFF(GicCpuIfc, iHighestPending));    
+	__JUMP(,lr);
+    }	
+
+
+#endif // ifdef __SMP__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kernel/eka/drivers/power/smppower/idlehelper.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,304 @@
+/*
+* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "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:  
+* os\kernelhwsrv\kernel\eka\drivers\power\smppower\idlehelper.cpp
+* Impelentation of helper classes required to implement CPU idle
+* functionality in a SMP BSP.
+*
+*/
+
+
+/**
+ @file
+ @prototype
+*/
+
+#include <kernel/arm/arm.h>
+#include <smppower/idlehelper.h>
+
+#ifdef __SMP__
+//-/-/-/-/-/-/-/-/-/ class TIdleSupport/-/-/-/-/-/-/-/-/-/
+
+TUint TIdleSupport::iGlobalIntDistAddress=0;
+TUint TIdleSupport::iBaseIntIfAddress=0;
+volatile TUint32* TIdleSupport::iTimerCount=0;
+volatile TUint32 TIdleSupport::iIdlingCpus=0;
+volatile TUint32 TIdleSupport::iAllEngagedCpusMask=0;
+volatile TUint32 TIdleSupport::iRousingCpus=0;
+volatile TUint32 TIdleSupport::iExitRequired=EFalse;
+
+/**
+   Setup interrupt access for static library  by setting up
+   interrupt distributor and CPU interrupt interface addresses
+   aGlobalIntDistAddress = interrupt distributor base address
+   aBaseIntIfAddress = CPU interrupt base address
+   aTimerCount = optional pointer to hw timer counter reg from bsp (only used for btrace)   
+   @pre 
+ */
+ 
+void TIdleSupport::SetupIdleSupport(TUint32 aGlobalIntDistAddress, TUint32 aBaseIntIfAddress, TUint32* aTimerCount)
+	{
+	iGlobalIntDistAddress=aGlobalIntDistAddress;
+	iBaseIntIfAddress=aBaseIntIfAddress;
+	iTimerCount=aTimerCount; /*NULL by default*/
+    iAllEngagedCpusMask=AllCpusMask();
+	}
+/**
+   Returns the current HW timer count reg value by default
+   Only used for btrace. If this is not set NKern::FastCounter is
+   returned.
+*/	
+	
+TUint32 TIdleSupport::GetTimerCount()
+	{
+    if(iTimerCount)
+        return *iTimerCount;
+    else
+        return NKern::FastCounter();
+	}
+
+/**
+   Returns TRUE if any interrupt is pending,FALSE otherwise 
+*/	
+
+TBool TIdleSupport::IsIntPending()
+	{
+	return (IntPending()!=KNoInterruptsPending);
+	}
+		
+/**
+   Set the piroity of the Idle IPI to be the highest
+   @pre 
+*/		
+	
+void TIdleSupport::SetIdleIPIToHighestPriority()
+	{	
+    // Set Idle IPI to highest priority
+    NKern::ThreadEnterCS();
+    TInt frz = NKern::FreezeCpu();
+    __PM_IDLE_ASSERT_ALWAYS(!frz);
+    TInt orig_cpu = NKern::CurrentCpu();
+    TInt ncpu = NKern::NumberOfCpus();
+    TInt cpu = orig_cpu;
+    TUint32 orig_affinity = 0;
+    do	
+        {
+        TUint32 affinity = NKern::ThreadSetCpuAffinity(NKern::CurrentThread(), (TUint32)cpu);
+        if (cpu == orig_cpu)
+            {
+            orig_affinity = affinity;
+            NKern::EndFreezeCpu(frz);
+            }
+        TInt cpu_now = NKern::CurrentCpu();
+        __PM_IDLE_ASSERT_ALWAYS(cpu_now == cpu);
+          
+        // here we can set the priority of the IPI vector for each CPU in turn
+        GicDistributor* theGIC = (GicDistributor*) TIdleSupport::iGlobalIntDistAddress;
+        TUint8* priorities = (TUint8*) &(theGIC->iPriority);
+        priorities[IDLE_WAKEUP_IPI_VECTOR]=0x0;
+        __e32_io_completion_barrier();
+        if (++cpu == ncpu)
+            cpu = 0;
+        } while (cpu != orig_cpu);
+    NKern::ThreadSetCpuAffinity(NKern::CurrentThread(), orig_affinity);
+    NKern::ThreadLeaveCS(); 
+	}
+
+
+/**
+   Atomically clears the current cpu idle mask bit to indicate current core has woken 
+   up from an interrupt or IPI.   
+   return TRUE only if all other cores are in idle and we were woken from an IPI from the last 
+   core going idle (otherwisw FALSE). 
+   aCpuMask- Bit mask with only current CPU bit set
+   Normal usage:use in idle handler after waking from all cores down IPI    
+      
+   @pre 
+ */	
+TBool TIdleSupport::ClearLocalAndCheckGlobalIdle(TUint32 aCpuMask)
+    {
+    return (__e32_atomic_and_ord32(&iIdlingCpus,~aCpuMask) & KGlobalIdleFlag);
+    }
+
+
+/**
+	Atomically sets the cpu bit rousing mask only to indicate current CPU has woken. 
+	return TRUE only if this is first CPU awake.(otherwise FALSE).
+	aCMask- Bit mask with only current CPU bit set	
+	Normal usage: use in idle handler just after core is woken
+	
+   @pre  */		
+	
+	
+TBool TIdleSupport::FirstCoreAwake(TUint32 aCMask)
+	{
+	//TInt c = NKern::CurrentCpu();
+    //TUint32 cMask = (1<<c);//only current cpu mask is set 
+	return (!__e32_atomic_ior_acq32(&iRousingCpus,aCMask));	
+	}
+
+/**
+   Sets the exit required flag in TIdleSupport. Exit required is
+   normaly required be set if an interrupt is pending on a Core
+   aBreakSyncPoint- TBreakableSyncPoint* that all cores were waiting on
+   before interrupt occured. Normal usage: after interrupt pending check	
+      
+   @pre */
+   
+void TIdleSupport::SetExitRequired(TBreakableSyncPoint* aBreakSyncPoint)	
+	{
+	iExitRequired=ETrue;
+	if(aBreakSyncPoint)
+		aBreakSyncPoint->Break();
+	}
+	
+/**
+   Sets the exit required flag in TIdleSupport. Exit required is
+   normaly required be set if an interrupt is pending on a Core
+   aBreakSyncPoint- TBreakableSyncPoint that all cores were waiting on
+   before interrupt occured.  
+      
+   @pre */	
+
+TBool TIdleSupport::GetExitRequired()
+	{
+	return iExitRequired;
+	}
+	
+/**
+   Resets all the control flags/syncpoints. This is normally done by the 
+   last core when all cores are confirmed to be idle.
+   
+      
+   @pre */		
+	
+void TIdleSupport::ResetLogic()	
+	{
+    iIdlingCpus = 0;         // clear idle CPUs
+    iRousingCpus = 0;         // clear rousing CPUs
+    iExitRequired = EFalse; 
+	}
+
+
+/**
+   mark a core as retired
+
+   @pre called by idle handler
+*/	
+void TIdleSupport::MarkCoreRetired(TUint32 aCpuMask)
+    {
+    __e32_atomic_and_rlx32(&iAllEngagedCpusMask,~aCpuMask);
+    PMBTRACE4(KRetireCore,KRetireMarkCoreRetired,aCpuMask);
+    }
+
+/**
+   mark a core as enaged
+   @pre called outside idle handler
+ */	
+void TIdleSupport::MarkCoreEngaged(TUint32 aCpuMask)
+    {
+    __e32_atomic_ior_rlx32(&iAllEngagedCpusMask,aCpuMask);
+    PMBTRACE4(KEngageCore,KEngageMarkCoreEngaged,aCpuMask);
+    }
+
+/**
+   Returns the current cpu idling bit mask
+   @pre */	
+
+TUint32 TIdleSupport::GetCpusIdleMask()
+	{
+	return iIdlingCpus;
+	}
+
+/**
+   Returns address of enaged cpus mask, needed for synch point construction
+
+   */	
+
+volatile TUint32* TIdleSupport::EngagedCpusMaskAddr()
+    { 
+    return &iAllEngagedCpusMask; 
+    }
+
+/**
+   Returns address of enaged cpus mask, needed for synch point construction
+
+   */	
+
+TUint32 TIdleSupport::AllCpusMask()
+    { 
+    return ((0x1<<NKern::NumberOfCpus())-1); 
+    }
+
+/**
+   clears IPI and asserts so in 
+   @pre */	
+#ifdef _DEBUG
+void TIdleSupport::ClearIdleIPI()
+    {
+    __PM_IDLE_ASSERT_ALWAYS((DoClearIdleIPI()&0x1ff)==IDLE_WAKEUP_IPI_VECTOR);
+    }
+#endif
+
+
+//-/-/-/-/-/-/-/-/-/ class TSyncPointBase /-/-/-/-/-/-/-/-/-/
+TSyncPointBase::TSyncPointBase()
+    :iStageAndCPUWaitingMask(0),
+     iAllEnagedCpusMask(TIdleSupport::EngagedCpusMaskAddr())
+    {
+    }
+
+
+#ifdef _DEBUG
+void TSyncPointBase::SignalAndWait(TUint32 aStage)
+    {	
+    PMBTRACE8(KSyncPoint,KSignalAndWaitEntry,aStage,*iAllEnagedCpusMask);    
+#else
+void TSyncPointBase::SignalAndWait()
+    {
+#endif	
+    TInt c = NKern::CurrentCpu();
+    DoSW(1<<c);
+#ifdef _DEBUG
+	PMBTRACE0(KSyncPoint,KSignalAndWaiteXit);	
+#endif
+    }
+
+
+/**
+   Resets a syncpoint. 
+   No barriers are used in function so add them if required. For breakable synchpoints this must be called before sync point can be used, 
+   for normal syncpoints this must be called whenever a CPU gets enaged
+   @pre Should be called from one CPU. 
+ */
+void TSyncPointBase::Reset()
+    {
+    // Could assert it is already broken // not using atomics because this must be called from only one cpu before
+    // and be synchronised
+    iStageAndCPUWaitingMask = 0;
+    }
+
+
+//-/-/-/-/-/-/-/-/-/ class TBreakableSyncPoint /-/-/-/-/-/-/-/-/-/
+
+/**
+   Breaks the sync point until it is reset again. Any attempt to wait on the point will return inmediatelly until the point is reset
+ */
+void TBreakableSyncPoint::Break()
+    {
+    __e32_atomic_ior_ord32(&iStageAndCPUWaitingMask,0x80000000);
+    }
+
+
+#endif //__SMP__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kernel/eka/drivers/power/smppower/idlehelper_lib.mmp	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,40 @@
+// Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "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:
+// e32\drivers\power\smppower\smpidlehelper_lib.mmp
+// Helper library required to implement CPU idle
+// functionality in a SMP BSP.
+//
+
+
+#define NO_EKERN_LIB
+#include "../../kernel/kern_ext.mmh"
+
+target				idlehelper.lib
+targettype			klib
+
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN
+
+sourcepath       ../../power/smppower
+source           idlehelper.cpp idlehelper.cia
+
+start wins
+win32_headers
+end
+
+capability		all
+
+vendorid 0x70000001
+
+SMPSAFE
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kernel/eka/drivers/power/smppower/sample_idlehandler/smpidlehandler.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,305 @@
+/*
+* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "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:  
+* os\kernelhwsrv\kernel\eka\drivers\power\smppower\sample_idlehandler\smpidlehandler.cpp
+* implements a basic smp idle handler generic layer that can be derived from 
+* to create platform specific SMP idle handlers
+*
+*/
+
+
+/**
+ @file
+ @prototype
+*/
+#ifndef __WINS__
+#include <kernel/arm/arm.h>
+#endif
+#include "smpidlehandler.h"
+
+#ifdef __SMP__
+
+//-/-/-/-/-/-/-/-/-/ class DDSMPIdleHandler /-/-/-/-/-/-/-/-/-/
+
+DSMPIdleHandler* gTheIdleHandler = NULL;
+
+DSMPIdleHandler::DSMPIdleHandler ()
+    :iAllCpusMask(TIdleSupport::AllCpusMask()),
+     iStartAfterExtInitDfc(StartAfterExtIntDfcFn,this,Kern::SvMsgQue(),0),
+     iInitialised(EFalse)
+      {
+      // singleton class
+      __PM_IDLE_ASSERT_DEBUG(!gTheIdleHandler);
+      gTheIdleHandler = this;
+      }
+
+
+/**
+   To be called after construction in a thread context with interrupts enabled. Power extension entry point ideal
+   @pre thread context ints enable no kernel locks or fast mutexes
+   @param aGlobalIntDistAddress GIC address
+   @param aBaseIntIfAddress GIC CPU interface address
+ */
+void DSMPIdleHandler::Initialise(TUint32 aGlobalIntDistAddress, TUint32 aBaseIntIfAddress)
+    {
+	TIdleSupport::SetupIdleSupport(aGlobalIntDistAddress,aBaseIntIfAddress);
+    //Set Idle IPI to highest priority
+	TIdleSupport::SetIdleIPIToHighestPriority();
+    Arm::SetIdleHandler((TCpuIdleHandlerFn)DSMPIdleHandler::IdleHandler, this);
+    iStartAfterExtInitDfc.Enque();
+    }
+
+
+/**
+   Must be called when cores are enaged or retired
+   @pre calling code must be outside idle handler, or in DoEnterIdle call
+*/
+void DSMPIdleHandler::ResetSyncPoints()
+    {
+    iIdleSync.Reset();
+    iStage2.Reset();
+    }
+
+
+/**
+   Called by idle handler inmediatelly after idle entry. Can be used for things such as checking 
+   if a core is going to be retired. Can return EFalse to force the idle handler to return 
+   at that point
+   @param aCpuMask mask of current cpu
+   @param aStage passed from kernel indicated things such core retiring or postamble
+   @param aU points to some per-CPU uncached memory used for handshaking in 
+       during power up/power down of a core for support of core retiring. This 
+       memory is provided by baseport to the kernel via the VIB
+
+   @return EFalse if the cpu should exit idle, ETrue otherwise
+ */
+TBool DSMPIdleHandler::DoEnterIdle(TInt aCpuMask, TInt aStage,  volatile TAny* aU)
+    {
+    return ETrue;
+    }
+
+ /**
+    Called by idle handler all cpus to enter idle once all have entered idle but
+    before NTimeQ::IdleTime is called to check time to next timer expiry. Can be used 
+    for things such as idle timer pre-idle processing. In such cases only the last CPU
+    should do the idle timer processing
+    @param aCpuMask mask of current cpu
+    @param aLastCPu indicates if this is last CPU.
+ */
+void DSMPIdleHandler::CpusHaveEnteredIdle(TInt aCpuMask, TInt aLastCpu)
+    {
+    }
+
+
+/**
+   Called after wakeup can be used for status restoring
+   a sync point is placed after the call to this function
+   This can be a good place to do idle tick restoration
+   @param TInt aCpuMask indicates calling CPU
+   @param aLastCPu indicates if this is last CPU.
+   @see EnterLowPowerMode
+*/
+void DSMPIdleHandler::PostWakeup(TInt aCpuMask, TBool aLastCpu)
+    {
+    }
+
+/**
+   Called at exit of idle handler not synchronised in any way
+   @param aExitPoint point at which you might exit the idle handler
+   @param TInt aCpuMask indicates calling CPU
+   @param aLastCPu indicates if this is last CPU.
+*/
+void DSMPIdleHandler::DoExitIdle(TIdleExit aExitPoint, TInt aCpuMask, TBool aLastCpu)
+    {
+    }
+
+/**
+   IdleHandler just calls DoIdle
+*/
+void DSMPIdleHandler::IdleHandler(TAny* /*aPtr*/, TInt aStage, volatile TAny* aU)
+    {
+    gTheIdleHandler->DoIdle(aStage,aU);
+    }
+
+/**
+   Idle handling per se
+*/
+void DSMPIdleHandler::DoIdle(TInt aStage, volatile TAny* aU)
+    {
+    // wait after all extensions have initialsed before running
+    if (!iInitialised) return;
+    
+    TInt c = NKern::CurrentCpu();
+	TUint32 cMask = (1<<c);
+	TUint32 allButC = (~cMask) & iAllCpusMask;
+
+    if (!DoEnterIdle(cMask,aStage,aU)) return;
+
+	if (TIdleSupport::SetLocalAndCheckSetGlobalIdle(cMask)) // check if last down
+		{
+        //LastCpuIdle:                               
+        PMBTRACE4(KIdleEntry,KIdleEntryLastCpu,TIdleSupport::GetCpusIdleMask());
+        // we have now managed to lock the system into all cpus waiting, by setting MSB we are now informing any leaving CPUs 
+        // that we intend to take the system down
+        // other CPUs with an STI so they can proceed with power down
+        // when we get there, all other CPUs can be in of the following states:
+        // 1. In the DoWFI of the section above (allButC!=_....) 
+        // 2. They could have already got past the DoWFI due to another interrupt waking them up
+        TIdleSupport::DoIdleIPI(allButC);          // wake all sleeping CPUs   
+        PMBTRACE0(KSendIPI,0);
+        SYNCPOINT(iIdleSync,0);  // After this point all should be awake and then other will clear the pending IPI 
+        CpusHaveEnteredIdle(cMask,ETrue);
+        iStage2.Reset();
+        TIdleSupport::ResetLogic(); // 
+        SYNCPOINT(iIdleSync,1);  // sync on IPI clearing
+
+        // here do we have
+        // a/ Interrupt pending?
+        // b/ Timer coming up soon? 
+        // if (a or b) just allow all idle handlers to return
+        TInt nextTimer = NTimerQ::IdleTime();
+        TBool exitNow = !GetLowPowerMode(nextTimer,iLowPowerMode);
+        
+        PMBTRACE8(KMisc,2,nextTimer,iLowPowerMode);
+        
+        if (TIdleSupport::IsIntPending() || exitNow)
+            {
+            // clear idling cpus this will cause all cpus to exit idle handler
+            TIdleSupport::SetExitRequired(&iStage2);		
+            }
+        
+        SYNCPOINT(iStage2,2);
+        if(TIdleSupport::GetExitRequired())            
+            {
+            DoExitIdle(EExitBeforeLPM,cMask,ETrue);
+            PMBTRACE4(KIdleeXit,KIdleeXitLastCpu1,TIdleSupport::GetCpusIdleMask());
+            return;
+            }
+        
+        // We enter LPM here!!!
+        TBool exitRouseRequired = EnterLowPowerMode(iLowPowerMode,cMask,ETrue);
+
+        TBool firstToWake = EFalse;
+
+        if (exitRouseRequired)
+            {
+            firstToWake = TIdleSupport::FirstCoreAwake(cMask);
+            if (firstToWake)
+                {
+                // we are probaly first to rouse so wake the others
+                PMBTRACE0(KMisc,0x50);
+                TIdleSupport::DoIdleIPI (allButC);
+                }
+            }
+
+        PostWakeup(cMask,ETrue);
+        PMBTRACE4(KMisc,3,exitRouseRequired);
+        SYNCPOINT(iIdleSync,3);  
+        if (exitRouseRequired)
+            {
+            if (!firstToWake)
+                {
+                TIdleSupport::ClearIdleIPI();
+                PMBTRACE0(KMisc,0x51);
+                }
+            }
+        DoExitIdle(EExitAfterLPM,cMask,ETrue);    
+        PMBTRACE4(KMisc,0x52,TIdleSupport::IntPending()&0x1ff);
+        PMBTRACE4(KIdleeXit,KIdleeXitLastCpu0,TIdleSupport::GetCpusIdleMask());
+        }
+	else
+        {
+        //NormalIdle:                               
+        PMBTRACE4(KIdleEntry,KIdleEntryNormalCpu,TIdleSupport::GetCpusIdleMask());	
+        TIdleSupport::DoWFI();	// CPU in WFI
+        // here we could have woken up because of the Idle IPI or because of another interrupt
+        if (!TIdleSupport::ClearLocalAndCheckGlobalIdle(cMask)) 
+            {
+            // not all other cores are idling we were woken up by some interrupt so exit
+            DoExitIdle(EExitOtherCPUsNotIdle,cMask,EFalse);
+            PMBTRACE4(KIdleeXit,KIdleeXitNormalCpu0,TIdleSupport::GetCpusIdleMask());
+            return;
+            }
+
+        // we are all idling
+        SYNCPOINT(iIdleSync,0x10);
+        // clear IdleIPI, we could actually have another interrupt pending but 
+        // we ignore this for now as it is checked later
+        
+        TIdleSupport::ClearIdleIPI(); 
+        PMBTRACE0(KClearIPI,0x10);
+        CpusHaveEnteredIdle(cMask,EFalse);
+        SYNCPOINT(iIdleSync,0x11);
+
+        if (TIdleSupport::IsIntPending())
+				{
+                // clear idling cpus this will cause all cpus to exit idle handler
+                TIdleSupport::SetExitRequired(&iStage2);				           
+				}
+
+        SYNCPOINT(iStage2,0x12);			
+        if (TIdleSupport::GetExitRequired())
+            {
+            DoExitIdle(EExitBeforeLPM,cMask,EFalse);
+            PMBTRACE4(KIdleeXit,KIdleeXitNormalCpu1,TIdleSupport::GetCpusIdleMask());
+            return;
+            }
+
+        // We enter LPM here!!!
+        TBool exitRouseRequired = EnterLowPowerMode(iLowPowerMode,cMask,EFalse);
+
+        TBool firstToWake = EFalse;
+        
+        if (exitRouseRequired)
+            {
+            firstToWake = TIdleSupport::FirstCoreAwake(cMask);
+            if (firstToWake)
+                {
+                // we are probaly first to rouse so wake the others
+                PMBTRACE0(KMisc,0x50);
+                TIdleSupport::DoIdleIPI (allButC);
+                }
+            }
+
+        PostWakeup(cMask,EFalse);
+        PMBTRACE4(KMisc,3,exitRouseRequired);
+        SYNCPOINT(iIdleSync,0x13);  
+        if (exitRouseRequired)
+            {
+            if (!firstToWake)
+                {
+                TIdleSupport::ClearIdleIPI();
+                PMBTRACE0(KMisc,0x51);
+                }
+            }
+        
+        DoExitIdle(EExitAfterLPM,cMask,EFalse);    
+        PMBTRACE4(KMisc,0x52,TIdleSupport::IntPending()&0x1ff);
+        PMBTRACE4(KIdleeXit,KIdleeXitNormalCpu0,TIdleSupport::GetCpusIdleMask());
+        }
+    }
+
+
+/**
+   Dfc queued on init to delay idle handler entry until after all
+   extensions have initialised
+*/
+void DSMPIdleHandler::StartAfterExtIntDfcFn(TAny* aPtr)
+    {
+    DSMPIdleHandler* pD = (DSMPIdleHandler*) aPtr;
+    pD->iInitialised = ETrue;
+    }
+
+
+#endif //__SMP__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kernel/eka/drivers/power/smppower/sample_idlehandler/smpidlehandler_lib.mmp	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,35 @@
+// Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "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\drivers\power\smppower\sample_idlehandler\smpidlehandler_lib.mmp
+// Helper library required to implement CPU idle
+// functionality in a SMP BSP.
+//
+
+
+#define NO_EKERN_LIB
+#include "../../kernel/kern_ext.mmh"
+
+target				sample_smpidlehandler.lib
+targettype			klib
+
+userinclude      ../../../../include/drivers/smppower/sample_idlehandler
+sourcepath       .
+source 		 smpidlehandler.cpp
+
+capability		all
+
+vendorid 0x70000001
+
+SMPSAFE
+
--- a/kernel/eka/drivers/soundsc/base_e32_drivers_sound.mrp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/drivers/soundsc/base_e32_drivers_sound.mrp	Fri Apr 16 16:24:37 2010 +0300
@@ -1,3 +1,18 @@
+#
+# 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 "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: 
+#
 # component name "Audio Driver"
 
 component	base_e32_drivers_sound
--- a/kernel/eka/drivers/trace/base_e32_drivers_trace.mrp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/drivers/trace/base_e32_drivers_trace.mrp	Fri Apr 16 16:24:37 2010 +0300
@@ -1,3 +1,18 @@
+#
+# 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 "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: 
+#
 # component name "Kernel Trace Tool"
 
 component	base_e32_drivers_trace
--- a/kernel/eka/drivers/usbc/base_e32_drivers_usbcli.mrp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/drivers/usbc/base_e32_drivers_usbcli.mrp	Fri Apr 16 16:24:37 2010 +0300
@@ -1,3 +1,18 @@
+#
+# 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 "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: 
+#
 # component name "USB Client Driver"
 
 component	base_e32_drivers_usbcli
--- a/kernel/eka/drivers/usbc/d_usbc.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/drivers/usbc/d_usbc.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -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);
@@ -1959,7 +1959,12 @@
             // Parcel out the memory between endpoints
             TUint8* newAddr = reinterpret_cast<TUint8*>(chunk->LinearAddress());
             __KTRACE_OPT(KUSB, Kern::Printf("SetupInterfaceMemory alloc new chunk=0x%x, size=%d", newAddr,bufSizes[chunkInd]));
-            chunkChanged = (newAddr != oldAddr);
+            // The check is important to avoid chunkChanged to be corrupted.
+            // This code change is to fix the problem that one chunk is used by multiple interfaces.
+            if(!chunkChanged)
+            	{
+            	chunkChanged = (newAddr != oldAddr);
+            	}            
             aHwChunks[chunkInd] = chunk;
             }
         chunkInd++;
--- a/kernel/eka/drivers/usbcc/chapter9.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/drivers/usbcc/chapter9.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -306,7 +306,7 @@
 	else
 		{
 		// Type mask != KUsbRequestType_TypeStd => class- or vendor-specific request
-		iEp0ReceivedNonStdRequest = ETrue;
+        iEp0ReceivedNonStdRequest = ETrue;
 		const DBase* client = NULL;
 		switch (packet.iRequestType & KUsbRequestType_DestMask)
 			{ // Recipient
@@ -314,6 +314,11 @@
 			client = iEp0DeviceControl;
 			break;
 		case KUsbRequestType_DestIfc:
+		    //Add this mutex to protect the interface set data structure
+		    if (NKern::CurrentContext() == EThread)
+		        {
+		        NKern::FMWait(&iMutex);
+		        }
 			if (iTrackDeviceState && iDeviceState < EUsbcDeviceStateConfigured)
 				{
 				__KTRACE_OPT(KPANIC, Kern::Printf("  Error: Invalid device state"));
@@ -322,7 +327,10 @@
 				{
 				const TUsbcInterfaceSet* const ifcset_ptr =
 					InterfaceNumber2InterfacePointer(packet.iIndex);
-				if (ifcset_ptr)
+				//In some rare case, ifcset_ptr is not NULL but the ifcset_ptr->iInterfaces.Count() is 0,
+				//so panic will happen when excute the following line. so I add the conditon
+				//0 != ifcset_ptr->iInterfaces.Count() here.
+				if (ifcset_ptr && 0 != ifcset_ptr->iInterfaces.Count())
 					{
 					if (ifcset_ptr->CurrentInterface()->iNoEp0Requests)
 						{
@@ -339,8 +347,17 @@
 													  packet.iIndex));
 					}
 				}
+	        if (NKern::CurrentContext() == EThread)
+	            {
+                NKern::FMSignal(&iMutex);
+	            }
 			break;
 		case KUsbRequestType_DestEp:
+		    //Add this mutex to protect the interface set data structure
+	        if (NKern::CurrentContext() == EThread)
+	            {
+                NKern::FMWait(&iMutex);
+	            }
 			if (iTrackDeviceState && iDeviceState < EUsbcDeviceStateConfigured)
 				{
 				__KTRACE_OPT(KPANIC, Kern::Printf("  Error: Invalid device state"));
@@ -364,6 +381,10 @@
 					client = ifcset_ptr->iClientId;
 					}
 				}
+            if (NKern::CurrentContext() == EThread)
+                {
+                NKern::FMSignal(&iMutex);
+                }
 			break;
 		default:
 			__KTRACE_OPT(KPANIC, Kern::Printf("  Error: Other or Unknown recipient"));
@@ -1231,7 +1252,17 @@
 	if (aIfcSet->CurrentInterface() != 0)
 		{
 		__KTRACE_OPT(KUSB, Kern::Printf("  Resetting alternate interface setting to 0"));
+		//Add this mutex to protect the interface set data structure
+		if (NKern::CurrentContext() == EThread)
+		    {
+            NKern::FMWait(&iMutex);
+		    }
+        
 		aIfcSet->iCurrentInterface = 0;
+	    if (NKern::CurrentContext() == EThread)
+	        {
+            NKern::FMSignal(&iMutex);
+	        }		
 		}
 	return;
 	}
--- a/kernel/eka/drivers/usbcc/ps_usbc.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/drivers/usbcc/ps_usbc.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -180,11 +180,13 @@
 		}
 	DeActivateHardwareController();					 // turn off UDC altogether
 	iStackIsActive = EFalse;
+	// Notify registered clients on the user side about a USB device state
+	// change event and a transition to the "Undefined" state.
+	// Note: the state should be changed to "Undefined" before calling RunClientCallbacks(), 
+	//       otherwise the "Undefined" state will probably be lost.
+	NextDeviceState(EUsbcDeviceStateUndefined);
 	// Complete all pending requests, returning KErrDisconnected
 	RunClientCallbacks();
-	// Notify registered clients on the user side about a USB device state
-	// change event and a transition to the "Undefined" state.
-	NextDeviceState(EUsbcDeviceStateUndefined);
 	}
 
 
@@ -672,14 +674,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 +745,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 +763,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 +772,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 +811,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 +829,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 +838,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 +1058,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 +1645,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 +1663,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 +1672,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 +2883,7 @@
 	  iOtgCallbacks(_FOFF(TUsbcOtgFeatureCallback, iLink)),
 	  iReconnectTimer(ReconnectTimerCallback, this),
 	  iCableStatusTimer(CableStatusTimerCallback, this),
+      iUsbLock(TSpinLock::EOrderGenericIrqLow3),	  
 	  iPowerUpDfc(PowerUpDfc, this, 3),
 	  iPowerDownDfc(PowerDownDfc, this, 3),
 	  iStandby(EFalse),
@@ -3711,7 +3714,17 @@
 		__KTRACE_OPT(KPANIC, Kern::Printf("  Error: interface not found in array"));
 		return;
 		}
+	//Add this mutex to protect the interface set data structure
+	if (NKern::CurrentContext() == EThread)
+	    {
+        NKern::FMWait(&iMutex);
+	    }
+	
 	iConfigs[0]->iInterfaceSets.Remove(idx);
+	if (NKern::CurrentContext() == EThread)
+	    {
+        NKern::FMSignal(&iMutex);	
+	    }
 	delete ifcset_ptr;
 	}
 
@@ -3730,15 +3743,25 @@
 		__KTRACE_OPT(KPANIC, Kern::Printf("  Error: invalid interface setting: %d", aIfc));
 		return;
 		}
+	//Add this mutex to protect the interface set data structure
+	if (NKern::CurrentContext() == EThread)
+	    {
+        NKern::FMWait(&iMutex);
+	    }	
 	TUsbcInterface* const ifc_ptr = ifcset_ptr->iInterfaces[aIfc];
 	// Always first remove, then delete (see ~TUsbcLogicalEndpoint() for the reason why)
 	ifcset_ptr->iInterfaces.Remove(aIfc);
-	delete ifc_ptr;
+
 	if (aIfc == ifcset_ptr->iCurrentInterface)
 		{
 		__KTRACE_OPT(KUSB, Kern::Printf(" > Warning: deleting current interface setting"));
 		ifcset_ptr->iCurrentInterface = 0;
 		}
+	if (NKern::CurrentContext() == EThread)
+	    {
+        NKern::FMSignal(&iMutex);
+	    }	
+	delete ifc_ptr;
 	}
 
 
@@ -3765,7 +3788,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 +3801,7 @@
 				iEp0ReadRequestCallbacks.Remove(*p);
 				}
 			}
-		NKern::RestoreInterrupts(irq);
+        __SPIN_UNLOCK_IRQRESTORE(iUsbLock, irq);
 		return;
 		}
 	// Other endpoints
@@ -3798,7 +3821,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 +3832,7 @@
 			iEp0ReadRequestCallbacks.Remove(*p);
 			}
 		}
-	NKern::RestoreInterrupts(irq);
+    __SPIN_UNLOCK_IRQRESTORE(iUsbLock, irq);
 	// Other endpoints
 	for (TInt i = 1; i < KUsbcEpArraySize; i++)
 		{
@@ -4278,7 +4301,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	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/drivers/usbcsc/d_usbcsc.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -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	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/eabi/econs.def	Fri Apr 16 16:24:37 2010 +0300
@@ -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	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/eabi/ekernsmp.def	Fri Apr 16 16:24:37 2010 +0300
@@ -1175,4 +1175,16 @@
 	_ZN4Kern19UnmapAndUnpinMemoryEP16TKernelMapObject @ 1174 NONAME
 	_ZN4Kern21CreateKernelMapObjectERP16TKernelMapObjectj @ 1175 NONAME
 	_ZN4Kern22DestroyKernelMapObjectERP16TKernelMapObject @ 1176 NONAME
+	_ZN9Interrupt16AddTimingEntropyEv @ 1177 NONAME
+	_ZN4Kern10RandomSaltEmj @ 1178 NONAME
+	_ZN4Kern10RandomSaltEyj @ 1179 NONAME
+	_ZN4Kern10RandomSaltEPKhjj @ 1180 NONAME
+	_ZN4Kern12SecureRandomER5TDes8 @ 1181 NONAME
+	_ZN13DPagingDevice16NotificationLockEv @ 1182 NONAME
+	_ZN13KernCoreStats5StatsEPv @ 1183 NONAME
+	_ZN13KernCoreStats6EngageEi @ 1184 NONAME
+	_ZN13KernCoreStats6RetireEii @ 1185 NONAME
+	_ZN13KernCoreStats9ConfigureEj @ 1186 NONAME
+	_ZN5NKern21SetNumberOfActiveCpusEi @ 1187 NONAME
+	_ZN3Arm14SetIdleHandlerEPFvPvmPVvES0_ @ 1188 NONAME
 
--- a/kernel/eka/eabi/ekernu.def	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/eabi/ekernu.def	Fri Apr 16 16:24:37 2010 +0300
@@ -1166,4 +1166,17 @@
 	_ZN4Kern19UnmapAndUnpinMemoryEP16TKernelMapObject @ 1165 NONAME
 	_ZN4Kern21CreateKernelMapObjectERP16TKernelMapObjectj @ 1166 NONAME
 	_ZN4Kern22DestroyKernelMapObjectERP16TKernelMapObject @ 1167 NONAME
+	_ZN9Interrupt16AddTimingEntropyEv @ 1168 NONAME
+	_ZN4Kern10RandomSaltEmj @ 1169 NONAME
+	_ZN4Kern10RandomSaltEyj @ 1170 NONAME
+	_ZN4Kern10RandomSaltEPKhjj @ 1171 NONAME
+	_ZN4Kern12SecureRandomER5TDes8 @ 1172 NONAME
+	_ZN13DPagingDevice16NotificationLockEv @ 1173 NONAME
+	_ZN13KernCoreStats5StatsEPv @ 1174 NONAME
+	_ZN13KernCoreStats6EngageEi @ 1175 NONAME
+	_ZN13KernCoreStats6RetireEii @ 1176 NONAME
+	_ZN13KernCoreStats9ConfigureEj @ 1177 NONAME
+	_ZN13KernCoreStats9EnterIdleEv @ 1178 NONAME
+	_ZN13KernCoreStats9LeaveIdleEj @ 1179 NONAME
+	_ZN3Arm14SetIdleHandlerEPFvPvmES0_ @ 1180 NONAME
 
--- a/kernel/eka/eabi/euseru.def	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/eabi/euseru.def	Fri Apr 16 16:24:37 2010 +0300
@@ -2501,4 +2501,33 @@
 	_ZN15TExtendedLocale10LoadLocaleERK7TDesC16S2_S2_ @ 2500 NONAME
 	_ZN15TExtendedLocale16LoadLocaleAspectERK7TDesC16 @ 2501 NONAME
 	_ZN16TChunkCreateInfo11SetReadOnlyEv @ 2502 NONAME
+	_ZN4Math7RandomLER5TDes8 @ 2503 NONAME
+	_ZN4Math6RandomER5TDes8 @ 2504 NONAME
+	_ZN4Math7RandomLEv @ 2505 NONAME
+	_ZN6TDes1610LowerCase2Ev @ 2506 NONAME
+	_ZN6TDes1610UpperCase2Ev @ 2507 NONAME
+	_ZN6TDes1611AppendFill2E5TChari @ 2508 NONAME
+	_ZN6TDes1611Capitalize2Ev @ 2509 NONAME
+	_ZN6TDes1614AppendJustify2EPKti6TAlign5TChar @ 2510 NONAME
+	_ZN6TDes1614AppendJustify2EPKtii6TAlign5TChar @ 2511 NONAME
+	_ZN6TDes1614AppendJustify2ERK7TDesC16i6TAlign5TChar @ 2512 NONAME
+	_ZN6TDes1614AppendJustify2ERK7TDesC16ii6TAlign5TChar @ 2513 NONAME
+	_ZN6TDes165Fill2E5TChar @ 2514 NONAME
+	_ZN6TDes165Fill2E5TChari @ 2515 NONAME
+	_ZN6TDes165Fold2Ev @ 2516 NONAME
+	_ZN6TDes166CopyC2ERK7TDesC16 @ 2517 NONAME
+	_ZN6TDes166CopyF2ERK7TDesC16 @ 2518 NONAME
+	_ZN6TDes167Append2E5TChar @ 2519 NONAME
+	_ZN6TDes167CopyCP2ERK7TDesC16 @ 2520 NONAME
+	_ZN6TDes167CopyLC2ERK7TDesC16 @ 2521 NONAME
+	_ZN6TDes167CopyUC2ERK7TDesC16 @ 2522 NONAME
+	_ZN6TDes168Collate2Ev @ 2523 NONAME
+	_ZN6TDes168Justify2ERK7TDesC16i6TAlign5TChar @ 2524 NONAME
+	_ZNK7TDesC1614LocateReverse2E5TChar @ 2525 NONAME
+	_ZNK7TDesC1615LocateReverseF2E5TChar @ 2526 NONAME
+	_ZNK7TDesC1620FindCorruptSurrogateEv @ 2527 NONAME
+	_ZNK7TDesC166Match2ERKS_ @ 2528 NONAME
+	_ZNK7TDesC167Locate2E5TChar @ 2529 NONAME
+	_ZNK7TDesC168LocateF2E5TChar @ 2530 NONAME
+	_ZN6RTimer12AgainHighResER14TRequestStatus27TTimeIntervalMicroSeconds32 @ 2531 NONAME ; RTimer::AgainHighRes(TRequestStatus&, TTimeIntervalMicroSeconds32)
 
--- a/kernel/eka/euser/base_e32_euser.mrp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/euser/base_e32_euser.mrp	Fri Apr 16 16:24:37 2010 +0300
@@ -1,3 +1,18 @@
+#
+# 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 "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: 
+#
 # component name "User Library"
 
 component	base_e32_euser
--- a/kernel/eka/euser/unicode/Compare.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/euser/unicode/Compare.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -813,7 +813,7 @@
         // Because this function is using TUTF32Iterator, which means the
         // original author want to support surrogate. Take it as a defect and
         // fix it, while do not define a new LocateMatchStringFoldedSurrogate().
-        if (IsSurrogate(*csSection))
+        if (TChar::IsSurrogate(*csSection))
         	++csSection;
 		}
 	// this should never happen!
--- a/kernel/eka/euser/unicode/collate.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/euser/unicode/collate.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -26,44 +26,6 @@
 // 16 instead of 8, in case all supplementary characters
 static const TInt KKeyedStringBufferSize = 16;
 
-
-inline TText16 GetHighSurrogate(TUint aChar)
-/**
-Retrieve the high surrogate of a supplementary character.
-
-@param aChar The 32-bit code point value of a Unicode character.
-
-@return High surrogate of aChar, if aChar is a supplementary character; 
-        aChar itself, if aChar is not a supplementary character.
-*/
-	{
-	return STATIC_CAST(TText16, 0xD7C0 + (aChar >> 10));
-	}
-
-inline TText16 GetLowSurrogate(TUint aChar)
-/**
-Retrieve the low surrogate of a supplementary character.
-
-@param aChar The 32-bit code point value of a Unicode character.
-
-@return Low surrogate of aChar, if aChar is a supplementary character; 
-        zero, if aChar is not a supplementary character.
-*/
-	{
-	return STATIC_CAST(TText16, 0xDC00 | (aChar & 0x3FF));
-	}
-
-inline TUint JoinSurrogate(TText16 aHighSurrogate, TText16 aLowSurrogate)
-/**
-Combine a high surrogate and a low surrogate into a supplementary character.
-
-@return The 32-bit code point value of the generated Unicode supplementary
-        character.
-*/
-	{
-	return ((aHighSurrogate - 0xD7F7) << 10) + aLowSurrogate;
-	}
-
 // Creates a one or two collation keys sequence corresponding to the input character.
 // Returns the number of keys output.
 static TInt CreateDefaultCollationKeySequence(TInt aChar, TCollationKey* aBuffer)
@@ -100,22 +62,22 @@
 			break;
 			}
 		TInt c = *p >> 16;
-		if (IsHighSurrogate( (TText16)c ))
+		if (TChar::IsHighSurrogate( (TText16)c ))
 			{
-			if ((p < end) && (IsLowSurrogate( (TText16)((*(p+1))>>16) )))
+			if ((p < end) && (TChar::IsLowSurrogate( (TText16)((*(p+1))>>16) )))
 				{
 				currentCharLength = 2;
-				c = JoinSurrogate( (TText16)(*p>>16), (TText16)((*(p+1))>>16) );
+				c = TChar::JoinSurrogate( (TText16)(*p>>16), (TText16)((*(p+1))>>16) );
 				}
 			}
-		else if (IsLowSurrogate( (TText16)c ))
+		else if (TChar::IsLowSurrogate( (TText16)c ))
 			{
-			if ((p > start) && (IsHighSurrogate( (TText16)((*(p-1))>>16) )))
+			if ((p > start) && (TChar::IsHighSurrogate( (TText16)((*(p-1))>>16) )))
 				{
 				p--;
 				pivot = pivot - 1;
 				currentCharLength = 2;
-				c = JoinSurrogate( (TText16)(*p>>16), (TText16)((*(p+1))>>16) );
+				c = TChar::JoinSurrogate( (TText16)(*p>>16), (TText16)((*(p+1))>>16) );
 				}
 			}
 		else
@@ -658,8 +620,8 @@
 			}
 		else 
 			{
-			text[textLen++] = GetHighSurrogate(cur_char);
-			text[textLen++] = GetLowSurrogate(cur_char);
+			text[textLen++] = TChar::GetHighSurrogate(cur_char);
+			text[textLen++] = TChar::GetLowSurrogate(cur_char);
 			}
 		TBool possible_prefix = ETrue;
 		for(TInt i = 1; (i < KKeyedStringBufferSize) && possible_prefix; i++)
@@ -676,8 +638,8 @@
 				}
 			else
 				{
-				text[textLen++] = GetHighSurrogate(c);
-				text[textLen++] = GetLowSurrogate(c);
+				text[textLen++] = TChar::GetHighSurrogate(c);
+				text[textLen++] = TChar::GetLowSurrogate(c);
 				}
 			TInt cur_index = -1;
             ::GetStringKey(aTable, text, textLen, cur_index, possible_prefix);
--- a/kernel/eka/euser/unicode/perl/Unicode, Inc License Agreement - Data Files and Software.txt	Tue Feb 02 01:24:03 2010 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,21 +0,0 @@
-                          EXHIBIT 1
-UNICODE, INC. LICENSE AGREEMENT - DATA FILES AND SOFTWARE
-
-Unicode Data Files include all data files under the directories http://www.unicode.org/Public/, http://www.unicode.org/reports/, and http://www.unicode.org/cldr/data/ . Unicode Software includes any source code published in the Unicode Standard or under the directories http://www.unicode.org/Public/, http://www.unicode.org/reports/, and http://www.unicode.org/cldr/data/.
-
-NOTICE TO USER: Carefully read the following legal agreement. BY DOWNLOADING, INSTALLING, COPYING OR OTHERWISE USING UNICODE INC.'S DATA FILES ("DATA FILES"), AND/OR SOFTWARE ("SOFTWARE"), YOU UNEQUIVOCALLY ACCEPT, AND AGREE TO BE BOUND BY, ALL OF THE TERMS AND CONDITIONS OF THIS AGREEMENT. IF YOU DO NOT AGREE, DO NOT DOWNLOAD, INSTALL, COPY, DISTRIBUTE OR USE THE DATA FILES OR SOFTWARE.
-
-COPYRIGHT AND PERMISSION NOTICE
-
-Copyright © 1991-2009 Unicode, Inc. All rights reserved. Distributed under the Terms of Use in http://www.unicode.org/copyright.html.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of the Unicode data files and any associated documentation (the "Data Files") or Unicode software and any associated documentation (the "Software") to deal in the Data Files or Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, and/or sell copies of the Data Files or Software, and to permit persons to whom the Data Files or Software are furnished to do so, provided that (a) the above copyright notice(s) and this permission notice appear with all copies of the Data Files or Software, (b) both the above copyright notice(s) and this permission notice appear in associated documentation, and (c) there is clear notice in each modified Data File or in the Software as well as in the documentation associated with the Data File(s) or Software that the data or software has been modified.
-
-THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THE DATA FILES OR SOFTWARE.
-
-Except as contained in this notice, the name of a copyright holder shall not be used in advertising or otherwise to promote the sale, use or other dealings in these Data Files or Software without prior written authorization of the copyright holder.
-
-
---------------------------------------------------------------------------------
-
-Unicode and the Unicode logo are trademarks of Unicode, Inc., and may be registered in some jurisdictions. All other trademarks and registered trademarks mentioned herein are the property of their respective owners.
--- a/kernel/eka/euser/us_exec.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/euser/us_exec.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -5332,6 +5332,45 @@
 
 
 
+/**
+Requests an event at a specified time after the last expiry of the this
+timer object, to a resolution of 1ms. If the last usage of this timer object
+was not via either this function or RTimer::HighRes(), this call behaves the
+same as RTimer::HighRes().
+The "HighRes timer" counter stops during power-down (the same as "after timer"). 
+
+@param aStatus    On completion, contains the status of the request.
+                  This is KErrNone if the timer completed normally at the
+                  requested time, otherwise another of the
+                  system-wide error codes. In particular KErrArgument indicates
+				  that the requested expiry time has already passed.
+
+@param aInterval  The time interval, in microseconds, after which an event
+                  is to occur, measured from the last expiry time (or intended
+				  expiry time in the case where the timer was cancelled) of this
+				  timer object.
+				  Note that the interval is allowed to be negative. To see why
+				  this might be useful consider the following sequence of timer
+				  operations:
+					1. Timer expires at time T
+					2. AgainHighRes(1000000) - timer is queued for T + 1 sec
+					3. Cancel() - timer is not queued but last scheduled expiry
+									is still at T + 1 second
+					4. AgainHighRes(-500000)
+					5. Timer expires at time T + 0.5 second
+
+@panic KERN-EXEC 15, if this function is called while a request for a timer
+       event is still outstanding.
+*/
+EXPORT_C void RTimer::AgainHighRes(TRequestStatus &aStatus,TTimeIntervalMicroSeconds32 aInterval)
+	{
+	aStatus=KRequestPending;
+	Exec::TimerAgainHighRes(iHandle,aStatus,aInterval.Int());
+	}
+
+
+
+
 EXPORT_C void RTimer::At(TRequestStatus &aStatus,const TTime &aTime)
 //
 // Request an absolute timer.
@@ -6358,7 +6397,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 +6413,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/euser/us_test.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/euser/us_test.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -549,6 +549,14 @@
 		User::AfterHighRes(period);
 		}
 	User::WaitForRequest(s);
+
+	// There is a potential race condition, if the calling thread runs on a different CPU
+	// than the Supervisor thread, which can result in this thread being signaled
+	// before the RHandleBase gets fully closed (see DChangeNotifier::Complete()).
+	// For that reason, wait until Supervisor thread gets to idle, which is the indication
+	// that Complete() function has returned (DThread::Close() was called releasing memory),
+	// in the case that Kernel heap was checked just after current method returns.
+	UserSvr::HalFunction(EHalGroupKernel, EKernelHalSupervisorBarrier, (TAny*)timeout, NULL);
 	return r;
 	}
 
--- a/kernel/eka/ewsrv/base_e32_ewsrv.mrp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/ewsrv/base_e32_ewsrv.mrp	Fri Apr 16 16:24:37 2010 +0300
@@ -1,3 +1,18 @@
+#
+# 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 "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: 
+#
 # component name "Text Window Server"
 
 component	base_e32_ewsrv
--- a/kernel/eka/ewsrv/co_utl.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/ewsrv/co_utl.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -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/ky_tran.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/ewsrv/ky_tran.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -526,6 +526,7 @@
 	SConvKeyData returnVal;
 	returnVal.keyCode=EKeyNull;
 	returnVal.modifiers=0;
+	returnVal.filler = 0;
 
 	for (TUint i=0; i<iConvTable.numNodes; i++)
         {
--- a/kernel/eka/ewsrv/ws_win.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/ewsrv/ws_win.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -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	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/generic.inf	Fri Apr 16 16:24:37 2010 +0300
@@ -22,9 +22,9 @@
 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/cpudefs.h	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/include/cpudefs.h	Fri Apr 16 16:24:37 2010 +0300
@@ -605,8 +605,10 @@
 
 // Causes undefined instruction exception on both ARM and THUMB
 #define __ASM_CRASH()					asm(".word 0xe7ffdeff ")
-#if defined(__GNUC__)
+#if defined(__GNUC__)  
 #define	__crash()						asm(".word 0xe7ffdeff " : : : "memory")
+#elif defined(__GCCXML__)
+#define __crash()						(*((TInt *) 0x0) = 0xd1e)
 #elif defined(__ARMCC__)
 // RVCT doesn't let us inline an undefined instruction
 // use a CDP to CP15 instead - doesn't work on THUMB but never mind
@@ -638,8 +640,10 @@
 #define	EXC_TRAP_CTX_SZ		10		// ebx, esp, ebp, esi, edi, ds, es, fs, gs, eip
 
 // Causes exception
-#if defined(__VC32__) || defined(__CW32__)
-#define	__crash()						do { _asm int 0ffh } while(0)
+#if defined(__VC32__)
+#define	__crash()						do { _asm int 255 } while(0)
+#elif defined(__CW32__)
+#define	__crash()						do { *(volatile TInt*)0 = 0; } while(0)
 #else
 #define	__crash()						asm("int 0xff " : : : "memory")
 #endif
--- a/kernel/eka/include/drivers/dma_hai.h	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/include/drivers/dma_hai.h	Fri Apr 16 16:24:37 2010 +0300
@@ -1,4 +1,4 @@
-// Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 2002-2010 Nokia Corporation and/or its subsidiary(-ies).
 // All rights reserved.
 // This component and the accompanying materials are made available
 // under the terms of "Eclipse Public License v1.0"
@@ -863,6 +863,32 @@
 
 //////////////////////////////////////////////////////////////////////////////
 
+// Trace macros intended for use by the DMA PSL
+#define DMA_PRINTF(MSG) __KTRACE_OPT(KDMA, Kern::Printf((MSG)))
+#define DMA_PRINTF1(MSG, ARG1) __KTRACE_OPT(KDMA, Kern::Printf((MSG), (ARG1)))
+#define DMA_PRINTF2(MSG, ARG1, ARG2) __KTRACE_OPT(KDMA, Kern::Printf((MSG), (ARG1), (ARG2)))
+
+#define DMA_PSL_MESG "DMA PSL: "
+
+// General PSL tracing
+#define DMA_PSL_TRACE(MSG) DMA_PRINTF(DMA_PSL_MESG MSG)
+#define DMA_PSL_TRACE1(MSG, ARG1) DMA_PRINTF1(DMA_PSL_MESG MSG, (ARG1))
+#define DMA_PSL_TRACE2(MSG, ARG1, ARG2) DMA_PRINTF2(DMA_PSL_MESG MSG, (ARG1), (ARG2))
+
+
+#define DMA_PSL_CHAN_MESG DMA_PSL_MESG "ChanId %d: "
+#define DMA_PSL_CHAN_ARGS(CHAN) ((CHAN).PslId())
+
+// For channel specific tracing (where CHAN is a TDmaChannel)
+#define DMA_PSL_CHAN_TRACE_STATIC(CHAN, MSG) DMA_PRINTF1(DMA_PSL_CHAN_MESG MSG, DMA_PSL_CHAN_ARGS(CHAN))
+#define DMA_PSL_CHAN_TRACE_STATIC1(CHAN, MSG, ARG1) DMA_PRINTF2(DMA_PSL_CHAN_MESG MSG, DMA_PSL_CHAN_ARGS(CHAN), (ARG1))
+
+// For channel specific tracing, for use within methods of TDmaChannel derived
+// class
+#define DMA_PSL_CHAN_TRACE(MSG) DMA_PSL_CHAN_TRACE_STATIC(*this, MSG)
+#define DMA_PSL_CHAN_TRACE1(MSG, ARG1) DMA_PSL_CHAN_TRACE_STATIC1(*this, MSG, (ARG1))
+
+
 
 #include <drivers/dma_hai.inl>
 
--- a/kernel/eka/include/drivers/dma_v1.h	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/include/drivers/dma_v1.h	Fri Apr 16 16:24:37 2010 +0300
@@ -1,4 +1,4 @@
-// Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 2002-2010 Nokia Corporation and/or its subsidiary(-ies).
 // All rights reserved.
 // This component and the accompanying materials are made available
 // under the terms of "Eclipse Public License v1.0""
@@ -398,6 +398,32 @@
 // PIL-PSL INTERFACE
 //////////////////////////////////////////////////////////////////////////////
 
+// Trace macros intended for use by the DMA PSL
+#define DMA_PRINTF(MSG) __KTRACE_OPT(KDMA, Kern::Printf((MSG)))
+#define DMA_PRINTF1(MSG, ARG1) __KTRACE_OPT(KDMA, Kern::Printf((MSG), (ARG1)))
+#define DMA_PRINTF2(MSG, ARG1, ARG2) __KTRACE_OPT(KDMA, Kern::Printf((MSG), (ARG1), (ARG2)))
+
+#define DMA_PSL_MESG "DMA PSL: "
+
+// General PSL tracing
+#define DMA_PSL_TRACE(MSG) DMA_PRINTF(DMA_PSL_MESG MSG)
+#define DMA_PSL_TRACE1(MSG, ARG1) DMA_PRINTF1(DMA_PSL_MESG MSG, (ARG1))
+#define DMA_PSL_TRACE2(MSG, ARG1, ARG2) DMA_PRINTF2(DMA_PSL_MESG MSG, (ARG1), (ARG2))
+
+
+#define DMA_PSL_CHAN_MESG DMA_PSL_MESG "ChanId %d: "
+#define DMA_PSL_CHAN_ARGS(CHAN) ((CHAN).PslId())
+
+// For channel specific tracing (where CHAN is a TDmaChannel)
+#define DMA_PSL_CHAN_TRACE_STATIC(CHAN, MSG) DMA_PRINTF1(DMA_PSL_CHAN_MESG MSG, DMA_PSL_CHAN_ARGS(CHAN))
+#define DMA_PSL_CHAN_TRACE_STATIC1(CHAN, MSG, ARG1) DMA_PRINTF2(DMA_PSL_CHAN_MESG MSG, DMA_PSL_CHAN_ARGS(CHAN), (ARG1))
+
+// For channel specific tracing, for use within methods of TDmaChannel derived
+// class
+#define DMA_PSL_CHAN_TRACE(MSG) DMA_PSL_CHAN_TRACE_STATIC(*this, MSG)
+#define DMA_PSL_CHAN_TRACE1(MSG, ARG1) DMA_PSL_CHAN_TRACE_STATIC1(*this, MSG, (ARG1))
+
+
 /**
 Generic DMA descriptor used if the DMAC does not have support for hardware
 descriptor.
--- a/kernel/eka/include/drivers/dma_v2.h	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/include/drivers/dma_v2.h	Fri Apr 16 16:24:37 2010 +0300
@@ -1,4 +1,4 @@
-// Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 2002-2010 Nokia Corporation and/or its subsidiary(-ies).
 // All rights reserved.
 // This component and the accompanying materials are made available
 // under the terms of "Eclipse Public License v1.0""
@@ -1036,14 +1036,39 @@
 	virtual void DoDfc(const DDmaRequest& aCurReq, SDmaDesHdr*& aSrcCompletedHdr,
 					   SDmaDesHdr*& aDstCompletedHdr);
 
-	virtual ~TDmaChannel();
+	/** This function allows the Platform Specific Layer (PSL) to control the
+		power management of the channel or its controller by overriding the
+		PIL's default implementation (which does nothing) and making
+		appropriate use of the Power Resource Manager (PRM).
+
+		The function gets called by the PIL whenever the channel's queued
+		requests count has changed in a significant way, either before the
+		channel's Transfer() method is invoked for a request on a previously
+		empty request queue, or immediately after the request count has become
+		zero because of request cancellation or completion.
+
+		Depending on the current value of iQueuedRequests, the PSL may power
+		down or power up the channel. Note that iQueuedRequests gets accessed
+		and changed by different threads, so the PSL needs to take the usual
+		precautions when evaluating the variable's value.
+
+		None of the internal DMA framework mutexes is being held by the PIL
+		when calling this function.
+
+		@see iQueuedRequests
+	*/
+	virtual void QueuedRequestCountChanged();
+
+#if defined(__CPU_ARM) && !defined(__EABI__)
+	inline virtual ~TDmaChannel() {}	// kill really annoying warning
+#endif
 
 private:
 	static void Dfc(TAny*);
 	void DoDfc();
 	inline void Wait();
 	inline void Signal();
-	inline void Flash();
+	inline TBool Flash();
 	void ResetStateMachine();
 
 protected:
@@ -1052,7 +1077,7 @@
 	TUint32 iPslId;			 // unique identifier provided by PSL
 	TBool iDynChannel;		 // this is a dynamically allocated channel
 	TUint iPriority;		 // hardware priority of this channel
-	DMutex* iMutex;			 // for data accessed in both client & DFC context
+	NFastMutex iLock;		 // for data accessed in both client & DFC context
 	SDmaDesHdr* iCurHdr;	 // fragment being transferred or NULL
 	SDmaDesHdr** iNullPtr;	 // Pointer to NULL pointer following last fragment
 	TDfc iDfc;				  // transfer completion/failure DFC
@@ -1064,6 +1089,7 @@
 	enum {KDfcCountMask = 0x3FFFFFFF};	   // bits 0-29 - number of queued DFCs
 	SDblQue iReqQ;				 // being/about to be transferred request queue
 	TInt iReqCount;				 // number of requests attached to this channel
+	TInt iQueuedRequests; // number of requests currently queued on this channel
 private:
 	TDmaCancelInfo* iCancelInfo; // ...
 	TBool iRedoRequest;			 // client ISR callback wants a redo of request
--- a/kernel/eka/include/drivers/dma_v2.inl	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/include/drivers/dma_v2.inl	Fri Apr 16 16:24:37 2010 +0300
@@ -1,4 +1,4 @@
-// Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 2002-2010 Nokia Corporation and/or its subsidiary(-ies).
 // All rights reserved.
 // This component and the accompanying materials are made available
 // under the terms of "Eclipse Public License v1.0""
@@ -26,20 +26,28 @@
 
 inline void TDmaChannel::Wait()
 	{
-	NKern::ThreadEnterCS();
-	Kern::MutexWait(*iMutex);
+	__KTRACE_OPT(KDMA, Kern::Printf("TDmaChannel::Wait thread %O channel - %d",
+									&Kern::CurrentThread(), iPslId));
+	NKern::FMWait(&iLock);
+	__KTRACE_OPT(KDMA, Kern::Printf("TDmaChannel::Wait thread %O channel - %d Acq",
+									&Kern::CurrentThread(), iPslId));
 	}
 
 inline void TDmaChannel::Signal()
 	{
-	Kern::MutexSignal(*iMutex);
-	NKern::ThreadLeaveCS();
+	__KTRACE_OPT(KDMA, Kern::Printf("TDmaChannel::Signal thread %O channel - %d",
+									&Kern::CurrentThread(), iPslId));
+	NKern::FMSignal(&iLock);
 	}
 
-inline void TDmaChannel::Flash()
+inline TBool TDmaChannel::Flash()
 	{
-	Kern::MutexSignal(*iMutex);
-	Kern::MutexWait(*iMutex);
+	__KTRACE_OPT(KDMA, Kern::Printf("TDmaChannel::Flash thread %O channel - %d",
+									&Kern::CurrentThread(), iPslId));
+	const TBool r = NKern::FMFlash(&iLock);
+	__KTRACE_OPT(KDMA, Kern::Printf("TDmaChannel::Flash thread %O channel - %d Acq (%d)",
+									&Kern::CurrentThread(), iPslId, r));
+	return r;
 	}
 
 inline TBool TDmaChannel::IsOpened() const
--- a/kernel/eka/include/drivers/gpio.h	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/include/drivers/gpio.h	Fri Apr 16 16:24:37 2010 +0300
@@ -108,6 +108,38 @@
 		EEdgeBoth
 		};
 
+	/**
+	 Enumeration TGpioBaseId defines the highest 16 bits of 32 bit GPIO Id 
+	 to identify the GPIO hardware block:
+     - EInternalId    - The SOC GPIO hardware block (and any extender that is 
+                        covered by the vendor supplied implementation) supports
+	                    pin ids from 0-65535
+	 - EExtender0-15  - Up to 16 3rd party extenders (each supporting up
+	                                to 65536 pins) can be used.
+	 */
+	enum TGpioBaseId
+	    {
+	    EInternalId = 0x00000000,
+	    EExtender0  = 0x00010000,        
+	    EExtender1  = 0x00020000,
+	    EExtender2  = 0x00040000,
+	    EExtender3  = 0x00080000,
+	    EExtender4  = 0x00100000,
+	    EExtender5  = 0x00200000,
+	    EExtender6  = 0x00400000,
+	    EExtender7  = 0x00800000,
+	    EExtender8  = 0x01000000,
+	    EExtender9  = 0x02000000,
+	    EExtender10 = 0x04000000,
+	    EExtender11 = 0x08000000,
+	    EExtender12 = 0x10000000,
+	    EExtender13 = 0x20000000,
+	    EExtender14 = 0x40000000,
+	    EExtender15 = 0x80000000
+	    };
+
+
+	
     /**
     Sets the pin mode.
     
@@ -458,7 +490,6 @@
             KErrArgument, if aId is invalid.
             KErrNotSupported, if reading the state asynchronously is not supported.
 
-	This API should be used with off-chip GPIO modules only;
 	The result of the read operation and the state of the input pin will be passed as an argument to the callback function;
     */
 	IMPORT_C static TInt GetInputState(TInt aId, TGpioCallback* aCb);
@@ -474,7 +505,7 @@
 			KErrArgument, if aId is invalid;
             KErrNotSupported, if setting its state asynchronously is not supported.
 
-    This API should be used with off-chip GPIO modules only;
+
 	The result of the set operation will be passed as an argument to the callback function;
     */
 	IMPORT_C static TInt SetOutputState(TInt aId, TGpioState aState, TGpioCallback* aCb);
--- a/kernel/eka/include/drivers/iic_channel.h	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/include/drivers/iic_channel.h	Fri Apr 16 16:24:37 2010 +0300
@@ -40,15 +40,17 @@
 const static TInt KChannelDuplexMask	= 0x01<<KChannelDuplexShift;
 const static TInt16 KTransCountMsBit = (TInt16)((TUint16)0x8000);
 
-const static TInt8 KMaxWaitTime = 0x21; // Maximum allowable time in milliseconds for a Slave channel to wait for a response
+const static TInt8 KMaxWaitTime = 0x7E; // Maximum allowable time in milliseconds for a Slave channel to wait for a response
 										// (from Master or Client). This constant is used to limit run-time selected values
 										// for timeouts. The value stated here is semi-arbitrary.
 
 #ifdef IIC_SIMULATED_PSL
 // In a real system, the following timeout values are likely to be excessive. However, they are available
 // for use in the test framework, to account for the processing overhead.
-const TInt KSlaveDefMWaitTime = 32;
-const TInt KSlaveDefCWaitTime = 16;
+// In particular, for the simulated master timeout tests.
+const TInt KSlaveDefMWaitTime = 125;
+const TInt KSlaveDefCWaitTime = 124;
+
 #else
 const TInt KSlaveDefMWaitTime = 1;	// Default wait time for Master timeout. PSL can use SetMasterWaitTime to override.
 const TInt KSlaveDefCWaitTime = 1;	// Default wait time for Client timeout. PSL can use SetClientWaitTime to override.
@@ -120,7 +122,6 @@
 	inline void DumpChannel();
 #endif
 protected:
-	NTimer iTimeoutTimer;	// timeout timer
 	TInt8 iChannelNumber;	// this is the Key for ordering channels in the array
 	TUint8 iFlags;			// combination of TChannelType, TChannelDuplex and TBusType
 	TInt8 iSpare1;
@@ -289,6 +290,8 @@
 
 	Function to cancel the timer to check the Slave responsiveness.
 
+	Call either in a thread or an IDFC context. Do not call from an ISR.
+
 	*/
 	void CancelTimeOut();
 
@@ -499,6 +502,8 @@
 
 	TDfc* iSlaveTimeoutDfc;
 
+	NTimer iTimeoutTimer;	// timeout timer
+
 	TInt16 iTransCount; // Count of pending transactions
 	TInt8 iChannelReady;
 	TInt8 iSpare1;
@@ -652,8 +657,13 @@
 	virtual TInt Spare1(TInt aVal, TAny* aPtr1, TAny* aPtr2);
 
 	// Interface to TIicBusSlaveCallback
-	// channel-specific function to process data received/transmitted (called from NotifyClient or DFC queued from it)
-	// Must fill in the aCb object's iReturn, iRxWords and/or iTxWords using the appropriate funtions
+	//
+	// ProcessData is a channel-specific function to be provided by the PSL. Its purpose is to process
+	// data received/transmitted (called from NotifyClient or DFC queued from it). It Must fill in the
+	// aCb object's iReturn, iRxWords and/or iTxWords using the appropriate functions
+	//
+	// The functions UpdateReqTrig, StartTimerByState and StopTimer are for use by the PIL, only.
+	//
 	/**
 	@publishedPartner
 	@prototype 9.6
@@ -845,6 +855,7 @@
 	TInt16 iSpare3;
 
 	TSpinLock iSpinLock;
+	NTimer iTimeoutTimer;	// timeout timer
 	TAny* iReserved1;
 	TAny* iReserved2;
 
--- a/kernel/eka/include/drivers/iic_transaction.h	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/include/drivers/iic_transaction.h	Fri Apr 16 16:24:37 2010 +0300
@@ -192,7 +192,7 @@
 // 27:23 - Reserved
 // 22:20 - Bus type
 // 19:15 - Channel number
-// 14:10 - Transaction speed
+// 14:10 - Transaction speed	// For use with SET_TRANS_SPEED, GET_TRANS_SPEED - Deprecated
 //  9:0  - Slave address
 #define HS_MASTER_ADDR_SHIFT 29
 #define HS_MASTER_ADDR_MASK 0x7
@@ -202,8 +202,8 @@
 #define BUS_TYPE_MASK 0x7
 #define CHANNEL_NO_SHIFT 15
 #define CHANNEL_NO_MASK 0x1F
-#define TRANS_SPEED_SHIFT 10
-#define TRANS_SPEED_MASK 0x1F
+#define TRANS_SPEED_SHIFT 10	// For use with SET_TRANS_SPEED, GET_TRANS_SPEED - Deprecated
+#define TRANS_SPEED_MASK 0x1F	// For use with SET_TRANS_SPEED, GET_TRANS_SPEED - Deprecated
 #define SLAVE_ADDR_SHIFT 0
 #define SLAVE_ADDR_MASK 0x3FF
 
@@ -262,13 +262,13 @@
 #define SET_CHAN_NUM(aBusId,aChanNum) SET_CONF_FIELD(aBusId,aChanNum,CHANNEL_NO_MASK,CHANNEL_NO_SHIFT)
 /**
 @publishedPartner
-@prototype 9.6
+@deprecated
 Macro to set the Transaction speed of a Bus realisation configuration
 */
 #define SET_TRANS_SPEED(aBusId,aTransSpeed) SET_CONF_FIELD(aBusId,aTransSpeed,TRANS_SPEED_MASK,TRANS_SPEED_SHIFT)
 /**
 @publishedPartner
-@prototype 9.6
+@deprecated
 Macro to get the Transaction speed of a Bus realisation configuration
 */
 #define GET_TRANS_SPEED(aBusId) GET_CONF_FIELD(aBusId,TRANS_SPEED_MASK,TRANS_SPEED_SHIFT)
--- a/kernel/eka/include/drivers/rm_debug_eventhandler.h	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/include/drivers/rm_debug_eventhandler.h	Fri Apr 16 16:24:37 2010 +0300
@@ -1,4 +1,4 @@
-// Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 2004-2010 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"
@@ -27,14 +27,24 @@
 		TInt Start();
 		TInt Stop();
 		
+		inline void DRM_DebugEventHandler::LockDataAccess()
+		    {
+		    Kern::SemaphoreWait(*iProtectionLock);
+		    }
+
+		inline void DRM_DebugEventHandler::ReleaseDataAccess()
+		    {
+		    Kern::SemaphoreSignal(*iProtectionLock);
+		    }
+		
 	private:
 		static TUint EventHandler(TKernelEvent aEvent, TAny* a1, TAny* a2, TAny* aThis);
 		TUint HandleEvent(TKernelEvent aType, TAny* a1, TAny* a2);
 		TBool HandleSpecificEvent(TKernelEvent aType, TAny* a1, TAny* a2);
 		
 	private:
-		/** Lock serialising calls to event handler */
-		DSemaphore* iLock;
+		/** Used to serialise access data structures */
+		DSemaphore* iProtectionLock;
 
 		TBool iTracking;
 
--- a/kernel/eka/include/drivers/sdcard.h	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/include/drivers/sdcard.h	Fri Apr 16 16:24:37 2010 +0300
@@ -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];
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kernel/eka/include/drivers/smppower/idlehelper.h	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,210 @@
+/*
+* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "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:  
+* os\kernelhwsrv\kernel\eka\include\drivers\smpidlehelper.h
+* Helper classes required to implement CPU idle
+* functionality in a SMP BSP.
+*
+*/
+
+
+/**
+ @file
+ @prototype
+*/
+
+#ifndef __SMP_IDLE_HELPER_H__
+#define __SMP_IDLE_HELPER_H__
+
+#define __PM_IDLE_ASSERT_ALWAYS(aCond) \
+	__ASSERT_ALWAYS( (aCond), \
+		( \
+			Kern::Printf("Assertion '" #aCond "' failed;\nFile: '" __FILE__ "' Line: %d\n", __LINE__), \
+			Kern::Fault("TIdleSupport", 1) \
+		) )
+
+#define __PM_IDLE_ASSERT_DEBUG(aCond) \
+	__ASSERT_DEBUG( (aCond), \
+		( \
+			Kern::Printf("Assertion '" #aCond "' failed;\nFile: '" __FILE__ "' Line: %d\n", __LINE__), \
+			Kern::Fault("TIdleSupport", 1) \
+		) )
+
+
+
+#ifdef __SMP__
+
+#include <kernel/kpower.h>
+#include <e32btrace.h>
+#include <arm_gic.h>
+#include <kernel.h>
+#include <nk_priv.h>
+#include <nk_plat.h>
+
+
+const TUint32 KNoInterruptsPending = 1023;
+
+
+// Temp place holder for TRACE Categories
+const TInt KIsrPendingCat = 128;
+const TInt KPrintReg = 129;
+const TInt KIdleEntry = 130;
+const TUint8 KIdleEntryNormalCpu = 0x10;
+const TUint8 KIdleEntryLastCpu = 0;
+const TInt KIdleeXit = 131;
+const TUint8 KIdleeXitLastCpu0 = 0x1;
+const TUint8 KIdleeXitLastCpu1 = 0x1;
+const TUint8 KIdleeXitNormalCpu0 = 0x10;
+const TUint8 KIdleeXitNormalCpu1 = 0x11;
+const TInt KSyncPoint = 132;
+const TUint8 KSignalAndWaitFnEntry = 0x10;
+const TUint8 KSignalAndWaitFneXit = 0x11;
+const TUint8 KSignalAndWaitEntry = 0x0;
+const TUint8 KSignalAndWaiteXit = 0x1;
+const TInt KClearIPI = 133;
+const TInt KSendIPI = 134;
+const TInt KMisc=135;
+const TInt KIdleTickSupression=136;
+const TUint8 KCyclesInTickCyclesFullTick = 0x0;
+const TUint8 KNextInterrupt = 0x1;
+const TUint8 KTimeSleptTimeNextInt = 0x2;
+const TUint8 KTIcksSlept = 0x3;
+const TInt  KRetireCore=137;
+const TUint8 KRetireCoreEntry = 0x1;
+const TUint8 KRetireCoreeXit = 0x2;
+const TUint8 KRetireMarkCoreRetired = 0x3;
+const TInt  KEngageCore=138;
+const TUint8 KEngageMarkCoreEngaged = 0x3;
+const TInt KNTICK = 139;
+
+// End of Trace categories
+
+//#define DISABLE_TRACE
+#if defined(_DEBUG) && !defined(DISABLE_TRACE)
+
+#define PMBTRACE0(c,s) BTrace0((c),(s))
+#define PMBTRACE4(c,s,a1) BTrace4((c),(s),(a1))
+#define PMBTRACE8(c,s,a1,a2) BTrace8((c),(s),(a1),(a2))
+
+#else
+
+#define PMBTRACE0(c,s)
+#define PMBTRACE4(c,s,a1) 
+#define PMBTRACE8(c,s,a1,a2) 
+
+#endif
+
+//This will be defined in kernel header file nk_plat.h in the future
+#ifndef IDLE_WAKEUP_IPI_VECTOR
+#define IDLE_WAKEUP_IPI_VECTOR 0x07
+#endif
+
+
+#ifdef _DEBUG
+
+#define SYNCPOINT(obj,stage) (obj).SignalAndWait(stage) 
+
+#else
+
+#define SYNCPOINT(obj,stage) (obj).SignalAndWait()
+
+#endif//_DEBUG
+
+#define PROPER_WFI		//if defined uses ARM_WFI state otherwise a wait in loop
+#define SYNCPOINT_WFE 	//Sync Points use WFE and SEV
+
+//Base class for all sync points
+class TSyncPointBase
+    {
+public:
+    TSyncPointBase();
+#ifdef _DEBUG
+    void SignalAndWait(TUint32 aStage);
+#else
+    void SignalAndWait();
+#endif
+    void Reset();
+protected:
+    virtual void DoSW(TUint32 aCpuMask) = 0;
+public:
+    volatile TUint32 iStageAndCPUWaitingMask;    // upper 16 are the stage and lower 16 are cpus waiting mask
+    volatile TUint32* iAllEnagedCpusMask;
+   };
+
+    
+// Auto reseting sync point. Can not be broken. 
+class TSyncPoint : public TSyncPointBase
+    {
+private:
+    void DoSW(TUint32 aCpuMask);
+    };
+
+// Very similar to normal breakpoint except that:
+// 1. It does not autoreset between calls, therefore a call to Reset is required between
+//    syncs.
+// 2. It can be broken. That is a call to Break will result in any cpu currently waiting on the point
+//    to be freed inmediatelly, and attempt to start to wait on the point to return inmediatelly. This
+//    condition remains until reset is called once more
+class TBreakableSyncPoint : public TSyncPointBase
+    {
+public:
+    void Break();
+private:
+    void DoSW(TUint32 aCpuMask);
+};
+
+//Helper class for idle handler support to be used in smp bsp
+class TIdleSupport
+	{
+public:
+	static void SetupIdleSupport(TUint32 aGlobalIntDistAddress, TUint32 aBaseIntIfAddress, TUint32* aTimerCount=0);//setup GIC gid and cif base addresses
+	static void SetIdleIPIToHighestPriority();//sets idle IPI priority to be the highest
+	static void DoIdleIPI(TUint32);
+	static void ClearIdleIPI();
+	static void DoWFI();//puts current CPU in wait for interrupt state
+	static TBool IsIntPending();
+	static TInt	IntPending();
+	static TUint32 GetTimerCount();//HW timer can be used for tracing
+	//Atomic checks used to synchronise cores going idle
+	static TBool ClearLocalAndCheckGlobalIdle(TUint32);
+	static TBool SetLocalAndCheckSetGlobalIdle(TUint32);
+	static TBool FirstCoreAwake(TUint32);
+    // Retiring Cores
+    static void MarkCoreRetired(TUint32);
+    static void MarkCoreEngaged(TUint32);
+	//Exit methods for sync points
+	static void SetExitRequired(TBreakableSyncPoint* aBreakSyncPoint=0);
+	static TBool GetExitRequired();	
+	static void  ResetLogic();//Reset helper class flags
+	static TUint32 GetCpusIdleMask();//gets bit mask containing idling CPU's
+    static volatile TUint32* EngagedCpusMaskAddr();
+    static TUint32 AllCpusMask();
+private:
+    static TInt DoClearIdleIPI();
+private:
+    static const TUint32 KGlobalIdleFlag = 0x8000000;
+	static volatile TUint32 iAllEngagedCpusMask;
+	static volatile TUint32 iIdlingCpus;//contains CPU's idle handler waiting to go idle
+    static volatile TUint32 iRousingCpus;////contains CPU's waking up
+	static volatile TUint32 iExitRequired;
+	static TUint iGlobalIntDistAddress;//base address of gloabl interrupt dispatcher
+	static TUint iBaseIntIfAddress;//base address of CPu interrupt interface
+	static volatile TUint32* iTimerCount;//timer count register provided by bsp for tracing	
+	};
+
+
+#endif //__SMP__
+
+#endif //__SMP_IDLE_HELPER_H__
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kernel/eka/include/drivers/smppower/sample_idlehandler/smpidlehandler.h	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,145 @@
+/*
+* Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "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:  
+* os/kernelhwsrv/kernel/eka/include/drivers/smppower/sample_idlehandler/smpidlehandler.h
+* Example of a generic idle handler layer
+*
+*/
+
+
+
+#ifndef __SMPIDLEHANDLER_H__
+#define __SMPIDLEHANDLER_H__
+
+#include <smppower/idlehelper.h>
+
+#ifdef __SMP__
+
+//Helper class provides a generic idle handler that can derived from. However own idle handler can be used if the version 
+//provided here is not appropriate
+class DSMPIdleHandler
+    {
+public:
+    // points at which a cpu might exit the idle handler
+    enum TIdleExit
+        {
+        EExitOtherCPUsNotIdle,
+        EExitBeforeLPM,
+        EExitAfterLPM
+        };
+    
+
+    DSMPIdleHandler();
+    /*
+      called to init and bind the idle handler. After this call idle will be directed to idle handler
+      @pre thread context, no locks no fast mutexes, interrupt on
+    */
+    void Initialise(TUint32 aGlobalIntDistAddress, TUint32 aBaseIntIfAddress);
+    /**
+       Must be called when cores are enaged or retired
+       @pre calling code must be outside idle handler, or in DoEnterIdle call
+    */
+    void ResetSyncPoints();
+
+protected:
+    /**
+       Called by idle handler inmediatelly after idle entry. Can be used for things 
+       such as checking if a core is going to be retired and retiring
+       @param aCpuMask mask of current cpu
+       @param aStage passed from kernel indicated things such core retiring 
+       or postamble
+       @param aU points to some per-CPU uncached memory used for handshaking in 
+       during power up/power down of a core for support of core retiring. This 
+       memory is provided by baseport to the kernel via the VIB
+
+       @return EFalse if the idle handler needs to be exited, ETrue to progress
+       further into idle
+       @see TIdleSupport::MarkCoreRetired
+    */
+    virtual TBool DoEnterIdle(TInt aCpuMask, TInt aStage, volatile TAny* aU);
+    /**
+       Called by idle handler all cpus to enter idle once all have entered idle but
+       before NTimeQ::IdleTime is called to check time to next timer expiry. Can be used 
+       for things such as idle timer pre-idle processing. In such cases only the last CPU
+       should do the idle timer processing
+       @param aCpuMask mask of current cpu
+       @param aLastCPu indicates if this is last CPU.
+    */
+    virtual void CpusHaveEnteredIdle(TInt aCpuMask, TInt aLastCpu);
+    /**
+       This function gets called by the last CPU to go into idle once the system is locked 
+       with all CPUs going idle.
+       In this function the baseport would fill an opaque integer which determines what low 
+       power mode the platform can go to.
+       This mode is usually determined by the idle time available, entry and wake latencies 
+       of low power modes, and states 
+       additionally the function returns EFalse if a there is no point proceeding with idle
+       (say next tick is very close for example)
+       of other resources in the system
+       @param aIdleTime time until next timer is due as obtained from NTimerQ::IdleTime
+       @param aLowPowerMode low powe mode to go into, up to baseport on meaning of this 
+       @return EFalse to force exit from idle handler if there is no point proceeding with idle
+       @see NTimerQ::IdleTIme
+     */
+    virtual TBool GetLowPowerMode(TInt aIdleTime, TInt &aLowPowerMode) = 0;
+    /**
+       This function actually enters the low power mode. It should do any state saving and perform
+       idle tick suppression. If rousing of other CPUs is required after wake then this function should
+       return true. 
+       
+       @param aMode the low power mode obtained from GetLowPowerMode
+       @param TInt aCpuMask indicates calling CPU
+       @param aLastCpu true if the calling CPU was the last to enter the idle thread
+       @return True if rousing of other cores is required after wakeup
+     */
+    virtual TBool EnterLowPowerMode(TInt aMode, TInt aCpuMask, TBool aLastCpu) = 0;
+    /**
+       Called after wakeup can be used for status restoring
+       a sync point is placed after the call to this function
+       This can be a good place to do idle tick restoration
+       @param TInt aCpuMask indicates calling CPU
+       @param aLastCPu indicates if this is last CPU.
+       @see EnterLowPowerMode
+    */
+    virtual void PostWakeup(TInt aCpuMask, TBool aLastCpu);
+    /**
+       Called at exit of idle handler not synchronised in any way
+       @param aExitPoint point at which you might exit the idle handler
+       @param TInt aCpuMask indicates calling CPU
+       @param aLastCPu indicates if this is last CPU.
+    */
+    virtual void DoExitIdle(TIdleExit aExitPoint, TInt aCpuMask, TBool aLastCpu);
+
+private:
+    static void IdleHandler(TAny* aPtr, TInt aStage, volatile TAny* aU);
+    void DoIdle(TInt aStage, volatile TAny* aU);
+    static void StartAfterExtIntDfcFn(TAny*);
+
+private:
+ 	const TUint32 iAllCpusMask; 
+	TSyncPoint iIdleSync;
+	TBreakableSyncPoint iStage2;
+	volatile TUint32 iIdlingCpus;
+	volatile TUint32 iExitRequired;
+	TInt iLowPowerMode;
+    TDfc iStartAfterExtInitDfc;
+    TBool iInitialised;
+    };
+    
+
+
+#endif // __SMP__
+
+
+#endif //__SMPIDLEHANDLER_H__
--- a/kernel/eka/include/drivers/usbcshared.h	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/include/drivers/usbcshared.h	Fri Apr 16 16:24:37 2010 +0300
@@ -1598,6 +1598,8 @@
 	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
+	NFastMutex iMutex;										// To pretect interface set with NFastMutex
 
 protected:
 	TDfc iPowerUpDfc;										// queued by power handler upon power-up
--- a/kernel/eka/include/drivers/usbcshared.inl	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/include/drivers/usbcshared.inl	Fri Apr 16 16:24:37 2010 +0300
@@ -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/e32atomics.h	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/include/e32atomics.h	Fri Apr 16 16:24:37 2010 +0300
@@ -26,6 +26,93 @@
 /**	@file e32atomics.h
 	@publishedAll
 	@prototype
+
+	General purpose atomic operations and utility functions
+	All functions in this header are available on both user and kernel side.
+
+Atomic operations:
+	__e32_atomic_xxx_yyy8() should be used for 8 bit atomic variables
+	__e32_atomic_xxx_yyy16() should be used for 16 bit atomic variables
+	__e32_atomic_xxx_yyy32() should be used for 32 bit atomic variables
+	__e32_atomic_xxx_yyy64() should be used for 64 bit atomic variables
+	__e32_atomic_xxx_yyy_ptr() should be used for atomic updates to pointers
+
+	xxx specifies the operation performed
+		load	read memory atomically
+		store	write memory atomically
+		swp		write to a memory location and return the original value of the
+				memory location
+		add		add a value to a memory location and return the original value
+				of the memory location
+		and		bitwise AND a value with a memory location and return the
+				original value of the memory location
+		ior		bitwise OR a value with a memory location and return the
+				original value of the memory location
+		xor		bitwise XOR a value with a memory location and return the
+				original value of the memory location
+		axo		atomic { orig_v = *p; *p = (orig_v & u) ^ v; } return orig_v;
+		cas		if the value of a memory location matches a specified expected
+				value, write a specified new value and return TRUE, otherwise
+				update the expected value with the actual value seen and return
+				FALSE.
+		tau		if the value of a memory location is >= a specified threshold,
+				considered as an unsigned integer, add a specified value to it
+				otherwise add a different specified	value to it; return the
+				original value of the memory location
+		tas		if the value of a memory location is >= a specified threshold,
+				considered as a signed integer, add a specified value to it
+				otherwise add a different specified	value to it; return the
+				original value of the memory location
+				
+	yyy specifies the memory ordering:
+		rlx = relaxed memory ordering
+				there is no guarantee on the order in which the atomic operation
+				is observed relative to preceding or following memory accesses
+		acq = acquire semantics
+				the atomic operation is guaranteed to be observed before any
+				following memory accesses
+		rel = release semantics
+				the atomic operation is guaranteed to be observed after any
+				preceding memory accesses
+		ord = fully ordered
+				the atomic operation is guaranteed to be observed after any
+				preceding memory accesses and before any following memory
+				accesses
+
+	Note that these operations should only be used on normal memory regions
+	since they are implemented in terms of LDREX/STREX and so multiple reads
+	can occur before the operation completes. Also __e32_atomic_load_yyy64()
+	can't be used on read-only memory regions since it uses LDREXD/STREXD to
+	guarantee atomicity.
+	Atomic operations may only be used on naturally aligned memory (i.e. *16()
+	operations on an even address, *32() operations on an address which is a
+	multiple of 4 and *64() operations on an address which is a multiple of 8).
+	This applies even if you have (unwisely) decided to turn off alignment
+	checking.
+
+Barrier operations:
+	Two barrier functions are provided:
+	__e32_memory_barrier() - this ensures all preceding explicit memory accesses
+				are observed before any following explicit memory accesses.
+				Equates to the ARM DMB instruction.
+	__e32_io_completion_barrier() - this ensures all preceding explicit memory
+				accesses complete before any following instructions execute.
+				For example, it ensures that writes to I/O devices have actually
+				occurred before execution continues.
+				Equates to the ARM DSB instruction.
+
+Utility functions:
+	__e32_find_ms1_32	Return bit position of most significant 1 in a 32 bit
+						argument, or -1 if the argument is zero.
+	__e32_find_ls1_32	Return bit position of least significant 1 in a 32 bit
+						argument, or -1 if the argument is zero.
+	__e32_bit_count_32	Return the count of bits set to 1 in a 32 bit argument.
+	__e32_find_ms1_64	Return bit position of most significant 1 in a 64 bit
+						argument, or -1 if the argument is zero.
+	__e32_find_ls1_64	Return bit position of least significant 1 in a 64 bit
+						argument, or -1 if the argument is zero.
+	__e32_bit_count_64	Return the count of bits set to 1 in a 64 bit argument.
+
 */
 
 
--- a/kernel/eka/include/e32btrace.h	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/include/e32btrace.h	Fri Apr 16 16:24:37 2010 +0300
@@ -59,11 +59,11 @@
 					typically will contain the same values as would be returned by
 					User::FastCounter() or NKern::FastCounter().
 					This value is only present if the ETimestampPresent flag is set.
--#	Timestamp2.		Additional timestamp information. E.g. the most significant
+-#	Timestamp2. 	Additional timestamp information. E.g. the most significant
 					half of a 64bit timestamp value. Note, it is valid for a Timestamp2 value
 					to be present even if the previous Timestamp is absent.
 					This value is only present if the ETimestamp2Present flag is set.
--#	Context ID.		This value indicates the context in which the trace was generated.
+-#	Context ID. 	This value indicates the context in which the trace was generated.
 					The meaning of the id is dependent on the contents of the two
 					least significant bits:
 					-	00	indicates the value is the address of the NThread object for
@@ -207,7 +207,7 @@
 		/**
 		Header2 is present in the trace record.
 		*/
-		EHeader2Present		= 1<<0,
+		EHeader2Present 	= 1<<0,
 
 		/**
 		A timestamp value is present in the trace record.
@@ -308,7 +308,7 @@
 		/**
 		Indicates that this trace is the first part of a multipart trace.
 		*/
-		EMultipartFirst			= 1,
+		EMultipartFirst 		= 1,
 
 		/**
 		Indicates that this trace is a middle part of a multipart trace.
@@ -379,28 +379,27 @@
 		*/
 		ECpuUsage = 4,
 
-        /**
-        Category used for profiling device drivers, kernel extensions etc.
-        Used by PERF_LOG macro.
-        @prototype 9.3
-        */
-        EKernPerfLog = 5,
-
-        /**
+		/**
+		Category used for profiling device drivers, kernel extensions etc.
+		Used by PERF_LOG macro.
+		@prototype 9.3
+		*/
+		EKernPerfLog = 5,
+
+		/**
 		Trace generated when client-server activity takes place such as server creation,
 		session management, message handling, etc.
-
 		If #Prime is called with this category, traces will be generated for all
 		servers currently running and their sessions.
-        */
-        EClientServer = 6,
-
-        /**
+		*/
+		EClientServer = 6,
+
+		/**
 		Trace generated on thread request completion.
-        */
-        ERequests = 7,
-
-        /**
+		*/
+		ERequests = 7,
+
+		/**
 		Trace generated when chunks are created and destroyed, and when memory
 		is committed and decommitted to and from chunks.
 
@@ -408,10 +407,10 @@
 		chunks currently extant.
 
 		@see TChunks
-        */
-        EChunks = 8,
-
-        /**
+		*/
+		EChunks = 8,
+
+		/**
 		Trace generated when code segments are created and destroyed, mapped
 		into out of processes, and when memory is committed and decommitted to
 		and from them.
@@ -420,8 +419,8 @@
 		code segments currently extant.
 
 		@see TCodeSegs
-        */
-        ECodeSegs = 9,
+		*/
+		ECodeSegs = 9,
 
 		/**
 		Trace generated by Demand Paging.
@@ -442,7 +441,7 @@
 
 		@see enum TThreadPriority
 		@internalTechnology
-        @prototype 9.3
+		@prototype 9.3
 		*/
 		EThreadPriority = 11,
 
@@ -512,17 +511,17 @@
 		EProfiling = 18,
 
 		/**
-        Trace generated by Power Resource Manager.
-        @prototype 9.5
-        */
-        EResourceManager = 19,
-
-
-        /**
-        Trace generated by Power Resource Manager User-Side API.
-        @prototype 9.5
-        */
-        EResourceManagerUs = 20,
+		Trace generated by Power Resource Manager.
+		@prototype 9.5
+		*/
+		EResourceManager = 19,
+
+
+		/**
+		Trace generated by Power Resource Manager User-Side API.
+		@prototype 9.5
+		*/
+		EResourceManagerUs = 20,
 
 		/**
 		Trace generated by Raw Event subsystem APIs
@@ -536,13 +535,13 @@
 		of standard logging (conditional Kern::Printf() calls) is sufficiently
 		time-consuming that the required device timings mandated by the core
 		USB standards cannot be achieved
-        @prototype 9.5
+		@prototype 9.5
 		*/
 		EUsb = 22,
 
 		/**
 		Trace generated by Symbian OS kernel synchronization objects.
-        @prototype 9.5
+		@prototype 9.5
 		*/
 		ESymbianKernelSync = 23,
 
@@ -552,10 +551,22 @@
 		EFlexibleMemModel = 24,
 
 		/**
-        Trace generated by IIC bus.
-        @prototype 9.6
-        */
-        EIic = 25,
+		Trace generated by IIC bus.
+		@prototype 9.6
+		*/
+		EIic = 25,
+
+		/**
+		Trace generated by load balancing or higher-level scheduling
+		@prototype 9.6
+		*/
+		EHSched = 26,
+
+		/**
+		Trace generated by the nanokernel
+		@prototype 9.6
+		*/
+		ENKern = 27,
 
 		/**
 		First category value in the range reserved for platform specific use;
@@ -768,10 +779,10 @@
 		ENewThreadContext
 		};
 
-    /**
+	/**
 	@internalTechnology
-    @prototype 9.3
-    */
+	@prototype 9.3
+	*/
 	enum TClientServer
 		{
 		/**
@@ -845,7 +856,7 @@
 		Trace data format:
 		- 4 bytes containing the message handle.
 		- 4 bytes containing the completion reason, or object handle, value.
-		    (The object handle value is that which is delivered to the sender of the
+			(The object handle value is that which is delivered to the sender of the
 			message, not that supplied by the server actually completing the request.)
 
 		The context id (NThread*) in this trace is that of the thread which completed the message.
@@ -854,10 +865,10 @@
 		};
 
 
-    /**
+	/**
 	@internalTechnology
-    @prototype 9.3
-    */
+	@prototype 9.3
+	*/
 	enum TRequests
 		{
 		/**
@@ -1426,10 +1437,10 @@
 		EPagingPageTableAlloc,
 		};
 
-    /**
+	/**
 	Enumeration of sub-category values for trace category EResourceManager.
 	@see EResourceManager
-    @prototype 9.5
+	@prototype 9.5
 	*/
 	enum TResourceManager
 		{
@@ -1710,10 +1721,10 @@
 		*/
 		EDeRegisterResourceDependency
 		};
-    /**
+	/**
 	Enumeration of sub-category values for trace category EResourceManagerUs.
 	@see EResourceManagerUs
-    @prototype 9.5
+	@prototype 9.5
 	*/
 	enum TResourceManagerUs
 		{
@@ -1850,7 +1861,7 @@
 	Enumeration of sub-category values for trace category EThreadPriority.
 	@see EThreadPriority
 	@internalTechnology
-    @prototype 9.3
+	@prototype 9.3
 	*/
 	enum TThreadPriority
 		{
@@ -2489,7 +2500,7 @@
 
 		/**
 		Event generated when DRamAllocator::ZoneAllocRamPages has successfully
-		allocated all the requested RAM pages.  If DRamAllocator::ZoneAllocRamPages
+		allocated all the requested RAM pages.	If DRamAllocator::ZoneAllocRamPages
 		couldn't allocate all the requested pages then this event is not generated.
 
 		Trace data format:
@@ -2589,7 +2600,7 @@
 		/**
 		CPU sample from non-Symbian thread.
 
-  		Trace data format:
+		Trace data format:
 		- no extra bytes are sent
 		*/
 		ECpuNonSymbianThreadSample
@@ -2634,7 +2645,7 @@
 		--4 bytes containining the Z co-ordinate
 		--4 bytes containining the PointerNumber
 
-  		if there are  7*4 byte data
+		if there are  7*4 byte data
 		- 4 bytes containing the event type
 		--4 bytes containining the X co-ordinate
 		--4 bytes containining the Y co-ordinate
@@ -2880,7 +2891,7 @@
 		// The following traces associate memory model objects with the kernel objects that use them
 
 		/**
-	    A memory object is being used for the contents of a chunk.
+		A memory object is being used for the contents of a chunk.
 
 		Trace data format:
 		- 4 bytes containing the memory object id (a DMemoryObject*).
@@ -2889,7 +2900,7 @@
 		EMemoryObjectIsChunk,
 
 		/**
-	    A memory object is being used for the contents of a code segment.
+		A memory object is being used for the contents of a code segment.
 
 		Trace data format:
 		- 4 bytes containing the memory object id (a DMemoryObject*).
@@ -2898,7 +2909,7 @@
 		EMemoryObjectIsCodeSeg,
 
 		/**
-	    A memory object is being used for process static data.
+		A memory object is being used for process static data.
 
 		Trace data format:
 		- 4 bytes containing the memory object id (a DMemoryObject*).
@@ -2907,7 +2918,7 @@
 		EMemoryObjectIsProcessStaticData,
 
 		/**
-	    A memory object is being used for DLL static data.
+		A memory object is being used for DLL static data.
 
 		Trace data format:
 		- 4 bytes containing the memory object id (a DMemoryObject*).
@@ -2917,7 +2928,7 @@
 		EMemoryObjectIsDllStaticData,
 
 		/**
-	    A memory object is being used for a thread's supervisor stack.
+		A memory object is being used for a thread's supervisor stack.
 
 		Trace data format:
 		- 4 bytes containing the memory object id (a DMemoryObject*).
@@ -2926,7 +2937,7 @@
 		EMemoryObjectIsSupervisorStack,
 
 		/**
-	    A memory object is being used for a thread's user stack.
+		A memory object is being used for a thread's user stack.
 
 		Trace data format:
 		- 4 bytes containing the memory object id (a DMemoryObject*).
@@ -2945,10 +2956,10 @@
 		EAddressSpaceId
 		};
 
-    /**
+	/**
 	Enumeration of sub-category values for trace category EIic.
 	@see EIic
-    @prototype 9.6
+	@prototype 9.6
 	*/
 	enum TIic
 		{
@@ -3444,6 +3455,22 @@
 		};
 
 	/**
+	Enumeration of sub-category values for trace category EHSched.
+	@see EHSched
+	@prototype 9.6
+	*/
+	enum THSched
+		{
+		/**
+		Trace output when a thread has been processed by the load balancer
+		Trace data format:
+		- 4 bytes containing pointer to thread
+		- 4 bytes containing flags indicating result of balancing
+		*/
+		ELbDone = 0,
+		};
+
+	/**
 	Calculate the address of the next trace record.
 	@param aCurrentRecord A pointer to a trace record.
 	@return The address of the trace record which follows aCurrentRecord.
@@ -3472,9 +3499,9 @@
 	trace as specified in aHeader.
 
 	@param aHeader	The 4 bytes for the trace header.
-	@param aHeader2	The second header word.
+	@param aHeader2 The second header word.
 					(If EHeader2Present is set in the header flags.)
-	@param aContext	The context id.
+	@param aContext The context id.
 					(If EContextIdPresent is set in the header flags.)
 	@param a1		The first four bytes of trace data.
 					(Only if the header size indicates that this is present.)
@@ -3490,7 +3517,7 @@
 	@param aPc		The Program Counter value.
 					(If EPcPresent is set in the header flags.)
 
-	@return			True, if the trace handler is enabled and outputting trace.
+	@return 		True, if the trace handler is enabled and outputting trace.
 					False otherwise.
 
 	Here is an example implementation of a trace handler:
@@ -3606,7 +3633,7 @@
 	/**
 	Set the secondary trace filter to include only the specified UIDs.
 
-	@param aUids    Pointer to array of UIDs.
+	@param aUids	Pointer to array of UIDs.
 	@param aNumUids Number of UID values pointer to by \a aUid.
 
 	@return KErrNone on success.
@@ -3643,7 +3670,7 @@
 	/**
 	Get the contents of the secondary trace filter.
 
-	@param[out] aUids   Pointer to array of UIDs contained in the secondary filter.
+	@param[out] aUids	Pointer to array of UIDs contained in the secondary filter.
 						Ownership of this array is passed to the caller of this
 						function, which is then responsible for deleting it.
 						If filter is empty, \a aUid equals zero.
@@ -3656,7 +3683,7 @@
 
 
 	@pre Call in a thread context.
-    @pre Calling thread must be in a critical section.
+	@pre Calling thread must be in a critical section.
 
 	@publishedPartner
 	@released
@@ -3808,7 +3835,7 @@
 	@param aCategory  A category value from enum BTrace::TCategory.
 					  Only the 8 least significant bits in this value are used;
 					  other bits are ignored.
-	@param aUid       A UID to filter on.
+	@param aUid 	  A UID to filter on.
 
 	@return True if a trace with this specification would be passed by the filters.
 			False if a trace with this specification would be dropped by the filters.
@@ -3903,9 +3930,9 @@
 	*/
 	struct SExecExtension
 		{
-		TUint32	iA2;
-		TUint32	iA3;
-		TUint32	iPc;
+		TUint32 iA2;
+		TUint32 iA3;
+		TUint32 iPc;
 		};
 
 	/**
@@ -3974,7 +4001,7 @@
 /**
 @internalComponent
 */
-#define BTRACE_HEADER(aSize,aCategory,aSubCategory)			\
+#define BTRACE_HEADER(aSize,aCategory,aSubCategory) 		\
 	(((aSize)<<BTrace::ESizeIndex*8)							\
 	+((aCategory)<<BTrace::ECategoryIndex*8)					\
 	+((aSubCategory)<<BTrace::ESubCategoryIndex*8))
@@ -4402,7 +4429,7 @@
 @publishedPartner
 @released
 */
-#define BTraceContextPc4(aCategory,aSubCategory,a1)	\
+#define BTraceContextPc4(aCategory,aSubCategory,a1) \
 	((BTrace::TBTrace2)BTrace::OutX) \
 		(BTRACE_HEADER_CP(8,(aCategory),(aSubCategory)),(TUint32)(a1))
 
@@ -4505,7 +4532,7 @@
 @param aCategory	A value from enum BTrace::TCategory,
 @param aSubCategory Sub-category value between 0 and 255.
 					The meaning of this is dependent on the Category.
-@param aUid			The 32bit quantity which forms the data of this trace record.
+@param aUid 		The 32bit quantity which forms the data of this trace record.
 
 @return True if trace is enabled for aCategory and aUid, false otherwise.
 @publishedPartner
@@ -4525,7 +4552,7 @@
 @param aCategory	A value from enum BTrace::TCategory,
 @param aSubCategory Sub-category value between 0 and 255.
 					The meaning of this is dependent on the Category.
-@param aUid			The first 32bit quantity which forms the data of this trace record.
+@param aUid 		The first 32bit quantity which forms the data of this trace record.
 @param a1			The second 32bit quantity which forms the data of this trace record.
 
 @return True if trace is enabled for aCategory and aUid, false otherwise.
@@ -4546,7 +4573,7 @@
 @param aCategory	A value from enum BTrace::TCategory,
 @param aSubCategory Sub-category value between 0 and 255.
 					The meaning of this is dependent on the Category.
-@param aUid			The first 32bit quantity which forms the data of this trace record.
+@param aUid 		The first 32bit quantity which forms the data of this trace record.
 @param a1			The second 32bit quantity which forms the data of this trace record.
 @param a2			The third 32bit quantity which forms the data of this trace record.
 
@@ -4566,7 +4593,7 @@
 @param aCategory	A value from enum BTrace::TCategory,
 @param aSubCategory Sub-category value between 0 and 255.
 					The meaning of this is dependent on the Category.
-@param aUid			The first 32bit quantity which forms the data of this trace record.
+@param aUid 		The first 32bit quantity which forms the data of this trace record.
 @param a1			The second 32bit quantity which forms the data of this trace record.
 @param aData		Address of addition data to add to trace.
 					Must be word aligned, i.e. a multiple of 4.
@@ -4593,7 +4620,7 @@
 @param aCategory	A value from enum BTrace::TCategory,
 @param aSubCategory Sub-category value between 0 and 255.
 					The meaning of this is dependent on the Category.
-@param aUid			The first 32bit quantity which forms the data of this trace record.
+@param aUid 		The first 32bit quantity which forms the data of this trace record.
 @param aData		Address of addition data to add to trace.
 					Must be word aligned, i.e. a multiple of 4.
 @param aDataSize	Number of bytes of additional data.
@@ -4618,7 +4645,7 @@
 @param aCategory	A value from enum BTrace::TCategory,
 @param aSubCategory Sub-category value between 0 and 255.
 					The meaning of this is dependent on the Category.
-@param aUid			The 32bit quantity which forms the data of this trace record.
+@param aUid 		The 32bit quantity which forms the data of this trace record.
 
 @return True if trace is enabled for aCategory and aUid, false otherwise.
 @publishedPartner
@@ -4638,7 +4665,7 @@
 @param aCategory	A value from enum BTrace::TCategory,
 @param aSubCategory Sub-category value between 0 and 255.
 					The meaning of this is dependent on the Category.
-@param aUid			The first 32bit quantity which forms the data of this trace record.
+@param aUid 		The first 32bit quantity which forms the data of this trace record.
 @param a1			The second 32bit quantity which forms the data of this trace record.
 
 @return True if trace is enabled for aCategory and aUid, false otherwise.
@@ -4659,7 +4686,7 @@
 @param aCategory	A value from enum BTrace::TCategory,
 @param aSubCategory Sub-category value between 0 and 255.
 					The meaning of this is dependent on the Category.
-@param aUid			The first 32bit quantity which forms the data of this trace record.
+@param aUid 		The first 32bit quantity which forms the data of this trace record.
 @param a1			The second 32bit quantity which forms the data of this trace record.
 @param a2			The third 32bit quantity which forms the data of this trace record.
 
@@ -4679,7 +4706,7 @@
 @param aCategory	A value from enum BTrace::TCategory,
 @param aSubCategory Sub-category value between 0 and 255.
 					The meaning of this is dependent on the Category.
-@param aUid			The first 32bit quantity which forms the data of this trace record.
+@param aUid 		The first 32bit quantity which forms the data of this trace record.
 @param a1			The second 32bit quantity which forms the data of this trace record.
 @param aData		Address of addition data to add to trace.
 					Must be word aligned, i.e. a multiple of 4.
@@ -4706,7 +4733,7 @@
 @param aCategory	A value from enum BTrace::TCategory,
 @param aSubCategory Sub-category value between 0 and 255.
 					The meaning of this is dependent on the Category.
-@param aUid			The first 32bit quantity which forms the data of this trace record.
+@param aUid 		The first 32bit quantity which forms the data of this trace record.
 @param aData		Address of addition data to add to trace.
 					Must be word aligned, i.e. a multiple of 4.
 @param aDataSize	Number of bytes of additional data.
@@ -4731,7 +4758,7 @@
 @param aCategory	A value from enum BTrace::TCategory,
 @param aSubCategory Sub-category value between 0 and 255.
 					The meaning of this is dependent on the Category.
-@param aUid			The 32bit quantity which forms the data of this trace record.
+@param aUid 		The 32bit quantity which forms the data of this trace record.
 
 @return True if trace is enabled for aCategory and aUid, false otherwise.
 @publishedPartner
@@ -4751,7 +4778,7 @@
 @param aCategory	A value from enum BTrace::TCategory,
 @param aSubCategory Sub-category value between 0 and 255.
 					The meaning of this is dependent on the Category.
-@param aUid			The first 32bit quantity which forms the data of this trace record.
+@param aUid 		The first 32bit quantity which forms the data of this trace record.
 @param a1			The second 32bit quantity which forms the data of this trace record.
 
 @return True if trace is enabled for aCategory and aUid, false otherwise.
@@ -4772,7 +4799,7 @@
 @param aCategory	A value from enum BTrace::TCategory,
 @param aSubCategory Sub-category value between 0 and 255.
 					The meaning of this is dependent on the Category.
-@param aUid			The first 32bit quantity which forms the data of this trace record.
+@param aUid 		The first 32bit quantity which forms the data of this trace record.
 @param a1			The second 32bit quantity which forms the data of this trace record.
 @param a2			The third 32bit quantity which forms the data of this trace record.
 
@@ -4792,7 +4819,7 @@
 @param aCategory	A value from enum BTrace::TCategory,
 @param aSubCategory Sub-category value between 0 and 255.
 					The meaning of this is dependent on the Category.
-@param aUid			The first 32bit quantity which forms the data of this trace record.
+@param aUid 		The first 32bit quantity which forms the data of this trace record.
 @param a1			The second 32bit quantity which forms the data of this trace record.
 @param aData		Address of addition data to add to trace.
 					Must be word aligned, i.e. a multiple of 4.
@@ -4819,7 +4846,7 @@
 @param aCategory	A value from enum BTrace::TCategory,
 @param aSubCategory Sub-category value between 0 and 255.
 					The meaning of this is dependent on the Category.
-@param aUid			The first 32bit quantity which forms the data of this trace record.
+@param aUid 		The first 32bit quantity which forms the data of this trace record.
 @param aData		Address of addition data to add to trace.
 					Must be word aligned, i.e. a multiple of 4.
 @param aDataSize	Number of bytes of additional data.
@@ -4846,7 +4873,7 @@
 @param aCategory	A value from enum BTrace::TCategory,
 @param aSubCategory Sub-category value between 0 and 255.
 					The meaning of this is dependent on the Category.
-@param aUid			The 32bit quantity which forms the data of this trace record.
+@param aUid 		The 32bit quantity which forms the data of this trace record.
 
 @return True if trace is enabled for aCategory and aUid, false otherwise.
 @publishedPartner
@@ -4867,7 +4894,7 @@
 @param aCategory	A value from enum BTrace::TCategory,
 @param aSubCategory Sub-category value between 0 and 255.
 					The meaning of this is dependent on the Category.
-@param aUid			The first 32bit quantity which forms the data of this trace record.
+@param aUid 		The first 32bit quantity which forms the data of this trace record.
 @param a1			The second 32bit quantity which forms the data of this trace record.
 
 @return True if trace is enabled for aCategory and aUid, false otherwise.
@@ -4889,7 +4916,7 @@
 @param aCategory	A value from enum BTrace::TCategory,
 @param aSubCategory Sub-category value between 0 and 255.
 					The meaning of this is dependent on the Category.
-@param aUid			The first 32bit quantity which forms the data of this trace record.
+@param aUid 		The first 32bit quantity which forms the data of this trace record.
 @param a1			The second 32bit quantity which forms the data of this trace record.
 @param a2			The third 32bit quantity which forms the data of this trace record.
 
@@ -4910,7 +4937,7 @@
 @param aCategory	A value from enum BTrace::TCategory,
 @param aSubCategory Sub-category value between 0 and 255.
 					The meaning of this is dependent on the Category.
-@param aUid			The first 32bit quantity which forms the data of this trace record.
+@param aUid 		The first 32bit quantity which forms the data of this trace record.
 @param a1			The second 32bit quantity which forms the data of this trace record.
 @param aData		Address of addition data to add to trace.
 					Must be word aligned, i.e. a multiple of 4.
@@ -4938,7 +4965,7 @@
 @param aCategory	A value from enum BTrace::TCategory,
 @param aSubCategory Sub-category value between 0 and 255.
 					The meaning of this is dependent on the Category.
-@param aUid			The first 32bit quantity which forms the data of this trace record.
+@param aUid 		The first 32bit quantity which forms the data of this trace record.
 @param aData		Address of addition data to add to trace.
 					Must be word aligned, i.e. a multiple of 4.
 @param aDataSize	Number of bytes of additional data.
--- a/kernel/eka/include/e32cmn.h	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/include/e32cmn.h	Fri Apr 16 16:24:37 2010 +0300
@@ -1102,6 +1102,15 @@
 	IMPORT_C TCjkWidth GetCjkWidth() const;
 	IMPORT_C static TBool Compose(TUint& aResult,const TDesC16& aSource);
 	IMPORT_C TBool Decompose(TPtrC16& aResult) const;
+	
+	// surrogate specific ones
+	inline static TBool IsSupplementary(TUint aChar);
+	inline static TBool IsSurrogate(TText16 aInt16);
+	inline static TBool IsHighSurrogate(TText16 aInt16);
+	inline static TBool IsLowSurrogate(TText16 aInt16);
+	inline static TUint JoinSurrogate(TText16 aHighSurrogate, TText16 aLowSurrogate);
+	inline static TText16 GetHighSurrogate(TUint aChar);
+	inline static TText16 GetLowSurrogate(TUint aChar);
 
 protected:
 	inline void SetChar(TUint aChar);
@@ -3877,12 +3886,12 @@
 @param i4 The fourth TUint8
 @internalComponent
 */
-#define FOUR_TUINT8(i1,i2,i3,i4) \
-	(TUint32)(				\
-		(TUint8)i1 		 | 	\
-		(TUint8)i2 << 8  | 	\
-		(TUint8)i3 << 16 | 	\
-		(TUint8)i4 << 24	\
+#define FOUR_TUINT8(i1,i2,i3,i4)		  \
+	(									  \
+		(TUint32)((i1) & 0xFF)			| \
+		(TUint32)((i2) & 0xFF) << 8		| \
+		(TUint32)((i3) & 0xFF) << 16	| \
+		(TUint32)((i4) & 0xFF) << 24	  \
 	)
 
 
--- a/kernel/eka/include/e32des16.h	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/include/e32des16.h	Fri Apr 16 16:24:37 2010 +0300
@@ -132,6 +132,15 @@
 	IMPORT_C HBufC16 *Alloc() const;
 	IMPORT_C HBufC16 *AllocL() const;
 	IMPORT_C HBufC16 *AllocLC() const;
+
+	// surrogate-aware ones
+	IMPORT_C TInt FindCorruptSurrogate() const;
+	IMPORT_C TInt Locate2(TChar aChar) const;
+	IMPORT_C TInt LocateF2(TChar aChar) const;
+	IMPORT_C TInt LocateReverse2(TChar aChar) const;
+	IMPORT_C TInt LocateReverseF2(TChar aChar) const;
+	IMPORT_C TInt Match2(const TDesC16 &aDes) const;
+
 protected:
 	inline TDesC16() {}
 	inline TDesC16(TInt aType,TInt aLength);
@@ -335,6 +344,28 @@
 	IMPORT_C void AppendFormat(TRefByValue<const TDesC16> aFmt,...);
 	IMPORT_C void AppendFormatList(const TDesC16 &aFmt,VA_LIST aList,TDes16Overflow *aOverflowHandler=NULL);
 	IMPORT_C TPtr8 Collapse();
+	
+	// surrogate-aware ones
+	IMPORT_C void Append2(TChar aChar);
+	IMPORT_C void Fill2(TChar aChar);
+	IMPORT_C void Fill2(TChar aChar, TInt aLength);
+	IMPORT_C void AppendFill2(TChar aChar, TInt aLength);
+	IMPORT_C void Justify2(const TDesC16 &aDes, TInt aWidth, TAlign anAlignment, TChar aFill);
+	IMPORT_C void AppendJustify2(const TDesC16 &aDes, TInt aWidth, TAlign anAlignment, TChar aFill);
+	IMPORT_C void AppendJustify2(const TDesC16 &aDes, TInt aLength, TInt aWidth, TAlign anAlignment, TChar aFill);
+	IMPORT_C void AppendJustify2(const TUint16 *aString, TInt aWidth, TAlign anAlignment, TChar aFill);
+	IMPORT_C void AppendJustify2(const TUint16 *aString, TInt aLength, TInt aWidth, TAlign anAlignment, TChar aFill);
+	IMPORT_C void Fold2();
+	IMPORT_C void Collate2();
+	IMPORT_C void LowerCase2();
+	IMPORT_C void UpperCase2();
+	IMPORT_C void Capitalize2();
+	IMPORT_C void CopyF2(const TDesC16 &aDes);
+	IMPORT_C void CopyC2(const TDesC16 &aDes);
+	IMPORT_C void CopyLC2(const TDesC16 &aDes);
+	IMPORT_C void CopyUC2(const TDesC16 &aDes);
+	IMPORT_C void CopyCP2(const TDesC16 &aDes);
+	
 protected:
 	inline TDes16() {}
 	inline TDes16(TInt aType,TInt aLength,TInt aMaxLength);
--- a/kernel/eka/include/e32kpan.h	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/include/e32kpan.h	Fri Apr 16 16:24:37 2010 +0300
@@ -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	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/include/e32math.h	Fri Apr 16 16:24:37 2010 +0300
@@ -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/e32std.h	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/include/e32std.h	Fri Apr 16 16:24:37 2010 +0300
@@ -3143,6 +3143,7 @@
 	IMPORT_C void Lock(TRequestStatus& aStatus,TTimerLockSpec aLock);
 	IMPORT_C void Inactivity(TRequestStatus& aStatus, TTimeIntervalSeconds aSeconds);
 	IMPORT_C void HighRes(TRequestStatus& aStatus,TTimeIntervalMicroSeconds32 anInterval);
+	IMPORT_C void AgainHighRes(TRequestStatus& aStatus,TTimeIntervalMicroSeconds32 anInterval);
 	};
 
 
--- a/kernel/eka/include/e32std.inl	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/include/e32std.inl	Fri Apr 16 16:24:37 2010 +0300
@@ -259,6 +259,102 @@
 @return True, if the character is 0; false, otherwise.
 */
 	{return(iChar==0);}
+
+
+
+
+inline TBool TChar::IsSupplementary(TUint aChar)
+/**
+@param aChar The 32-bit code point value of a Unicode character.
+
+@return True, if aChar is supplementary character; false, otherwise.
+*/
+	{
+	return (aChar > 0xFFFF);
+	}
+
+
+
+
+inline TBool TChar::IsSurrogate(TText16 aInt16)
+/**
+@return True, if aText16 is high surrogate or low surrogate; false, otherwise.
+*/
+	{
+	return (aInt16 & 0xF800) == 0xD800;
+	}
+
+
+
+
+inline TBool TChar::IsHighSurrogate(TText16 aInt16)
+/**
+@return True, if aText16 is high surrogate; false, otherwise.
+*/
+	{
+	return (aInt16 & 0xFC00) == 0xD800;
+	}
+
+
+
+
+inline TBool TChar::IsLowSurrogate(TText16 aInt16)
+/**
+@return True, if aText16 is low surrogate; false, otherwise.
+*/
+	{
+	return (aInt16 & 0xFC00) == 0xDC00;
+	}
+
+
+
+
+inline TUint TChar::JoinSurrogate(TText16 aHighSurrogate, TText16 aLowSurrogate)
+/**
+Combine a high surrogate and a low surrogate into a supplementary character.
+
+@return The 32-bit code point value of the generated Unicode supplementary
+        character.
+*/
+	{
+	return ((aHighSurrogate - 0xD7F7) << 10) + aLowSurrogate;
+	}
+
+
+
+
+inline TText16 TChar::GetHighSurrogate(TUint aChar)
+/**
+Retrieve the high surrogate of a supplementary character.
+
+@param aChar The 32-bit code point value of a Unicode character.
+
+@return High surrogate of aChar, if aChar is a supplementary character; 
+        aChar itself, if aChar is not a supplementary character.
+
+@see TChar::GetLowSurrogate
+*/
+	{
+	return STATIC_CAST(TText16, 0xD7C0 + (aChar >> 10));
+	}
+
+
+
+
+inline TText16 TChar::GetLowSurrogate(TUint aChar)
+/**
+Retrieve the low surrogate of a supplementary character.
+
+@param aChar The 32-bit code point value of a Unicode character.
+
+@return Low surrogate of aChar, if aChar is a supplementary character; 
+        zero, if aChar is not a supplementary character.
+
+@see TChar::GetHighSurrogate
+*/
+	{
+	return STATIC_CAST(TText16, 0xDC00 | (aChar & 0x3FF));
+	}
 #endif // _UNICODE
 
 
--- a/kernel/eka/include/e32twin.h	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/include/e32twin.h	Fri Apr 16 16:24:37 2010 +0300
@@ -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	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/include/e32ver.h	Fri Apr 16 16:24:37 2010 +0300
@@ -28,7 +28,7 @@
 
 const TInt KE32MajorVersionNumber=2;
 const TInt KE32MinorVersionNumber=0;
-const TInt KE32BuildVersionNumber=2066;
+const TInt KE32BuildVersionNumber=3040;
 
 const TInt KMachineConfigurationMajorVersionNumber=1;
 const TInt KMachineConfigurationMinorVersionNumber=0;
--- a/kernel/eka/include/kernel/arm/arm.h	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/include/kernel/arm/arm.h	Fri Apr 16 16:24:37 2010 +0300
@@ -228,6 +228,12 @@
 	@publishedPartner
 	@released
 	*/
+	IMPORT_C static void SetIdleHandler(TCpuIdleHandlerFn aHandler, TAny* aPtr);
+
+	/**
+	@publishedPartner
+	@released
+	*/
 	IMPORT_C static TInt DebugOutJTAG(TUint aChar);
 
 	/**
--- a/kernel/eka/include/kernel/arm/assp.h	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/include/kernel/arm/assp.h	Fri Apr 16 16:24:37 2010 +0300
@@ -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	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/include/kernel/arm/bootdefs.h	Fri Apr 16 16:24:37 2010 +0300
@@ -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	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/include/kernel/cache_maintenance.h	Fri Apr 16 16:24:37 2010 +0300
@@ -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__
@@ -364,6 +375,12 @@
 const TUint ARML2C_CleanByWay = 0x7bc;
 const TUint ARML2C_InvalidateByWay = 0x77c;
 const TUint ARML2C_CleanInvalidateByWay = 0x7fc;
+#if defined (__ARM_PL310_CACHE__)
+    const TUint ARML2C_WayShift = 28;
+#else
+    const TUint ARML2C_WayShift = 29;
+#endif
+    const TUint ARML2C_IndexShift = 5;
 
 /*
  * A set of static utility functions for external cache memory.
--- a/kernel/eka/include/kernel/cache_maintenance.inl	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/include/kernel/cache_maintenance.inl	Fri Apr 16 16:24:37 2010 +0300
@@ -71,7 +71,7 @@
 	#endif	// else (__CPU_SUPPORTS_PAGE_TABLE_WALK_TO_L1_CACHE) || !(__CPU_PAGE_TABLES_FULLY_CACHED)
 #if defined (__FLUSH_PT_INTO_RAM__)
 	//See SinglePteUpdated for details.
-	ExternalCache::Clean(aAddr, aSize);
+	ExternalCache::Clean(aPte, aSize);
 #endif // (__FLUSH_PT_INTO_RAM__)
 	}
 
@@ -106,7 +106,7 @@
 	// tables separately (e.g. another processor using the same page tables out
 	// of main memory), and is not necessary on standard platforms.
 	// Either __ARM_L210_CACHE__ or __ARM_L220_CACHE__ must also be defined
-	ExternalCache::Clean(aAddr, 4);
+	ExternalCache::Clean(aPte, 4);
 #endif
 	}
 
--- a/kernel/eka/include/kernel/kern_priv.h	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/include/kernel/kern_priv.h	Fri Apr 16 16:24:37 2010 +0300
@@ -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;
 
@@ -543,6 +546,7 @@
 	TInt After(TInt aInterval, TTickCallBack aFunction, TRequestStatus& aStatus);
 	TInt At(const TTimeK& aTime, TSecondCallBack aFunction, TRequestStatus& aStatus);
 	TInt AfterHighRes(TInt aInterval, NTimerFn aFunction, TRequestStatus& aStatus);
+	TInt AgainHighRes(TInt aInterval, NTimerFn aFunction, TRequestStatus& aStatus);
 	TInt Inactivity(TInt aSeconds, TInactivityCallBack aFunction, TRequestStatus& aStatus);
 	void Cancel(DThread* aThread);
 	void Abort(DThread* aThread, TInt aTypeMask);
@@ -585,6 +589,7 @@
 	TInt At(TRequestStatus& aStatus, const TTimeK& aTime);
 	TInt Lock(TRequestStatus& aStatus, TTimerLockSpec aLock);
 	void HighRes(TRequestStatus& aStatus, TInt aInterval);
+	void AgainHighRes(TRequestStatus& aStatus, TInt aInterval);
 	TInt Inactivity(TRequestStatus& aStatus, TInt aSeconds);
 	void Abort(TBool aAbortAbsolute);
 	virtual TInt RequestUserHandle(DThread* aThread, TOwnerType aType);
@@ -2482,6 +2487,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 +2570,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 +2766,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	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/include/kernel/kern_test.h	Fri Apr 16 16:24:37 2010 +0300
@@ -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	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/include/kernel/kernboot.h	Fri Apr 16 16:24:37 2010 +0300
@@ -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*/
 	};
 
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kernel/eka/include/kernel/kerncorestats.h	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,127 @@
+// Copyright (c) 1994-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "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:
+// e32\include\kernel\KernCoreStats.h
+// 
+// 
+// WARNING: This file contains some APIs which are internal and are subject
+//          to change without notice. Such APIs should therefore not be used
+//          outside the Kernel and Hardware Services package.
+//
+
+/** @file
+@internalComponent
+@prototype
+*/
+
+#ifndef __KERNCORESTATS_H__
+#define __KERNCORESTATS_H__
+
+#include <kernel/kernel.h>
+
+// Kernel side stats (also used when obtaining stats from Kernel)
+const TInt KStatsCoreNumTimesInIdle		 = 0x0001;
+const TInt KStatsCoreTotalTimeInIdle		 = 0x0002;
+const TInt KStatsTimeCrossIdleAndActive		 = 0x0004;
+const TInt KStatsReadyStateChanges		 = 0x0008;
+const TInt KStatsNumTimeSliceExpire		 = 0x0010;
+const TInt KStatsNumEvents			 = 0x0020;
+
+extern "C" {
+extern  TUint KernCoreStats_EnterIdle(TUint aCore);
+extern  void KernCoreStats_LeaveIdle(TInt aCookie,TUint aCore);
+}
+
+class KernCoreStats
+	{
+
+public:
+
+IMPORT_C static TInt Stats(TAny* aBuffer);
+IMPORT_C static TInt Configure(TUint aStatSelection);
+
+IMPORT_C static TInt Retire(TInt aRetired, TInt aInfoMask=0);
+IMPORT_C static TInt Engage(TInt aEngage);
+
+#ifndef __WINS__
+#ifndef __SMP__
+
+IMPORT_C static TUint EnterIdle();
+IMPORT_C static void LeaveIdle(TUint aCookie);
+
+#endif
+#endif
+
+	static void AddEvent();
+
+	enum {KStatDisabled = 1};  // Thas value is used in place of an structure offset, to indicate the stat is'nt enabled.
+
+private:
+	TInt StatsCopy(TAny* aBuffer);
+	void Construct(TUint aBitField);
+
+	void DoEnterIdle(TUint aCore);
+	void DoLeaveIdle(TUint aCore);
+
+private:
+
+	static KernCoreStats* StatsData;
+	static TSpinLock Lock;	// We use a spinlock here becouse we cant use a FastMutex - as there is
+       				// a good chance a FastMutex will be held when the core goes
+	
+	inline TUint32* Value32(TAny* aBuffer, TUint16 aOffset);
+	inline TUint64* Value64(TAny* aBuffer, TUint16 aOffset);
+private:
+
+
+	// Here stored geometry information about data to be collected internally.
+
+	TUint64* iTotalTimeIdle;	// Pointer to Array of Time spent Idle, per core.
+	TUint64* iLastTimeCore;
+	TUint64* iTimesCIA;		//Pointer to Array of Time spent in permutions of idle.
+	TUint* iNumberIdles;	//Pointer of Array of number of times idle, per core. 
+	TUint iNumEvents;
+	TUint *iLastAddReadyCount;
+	TUint *iLastSubReadyCount;
+	TUint *iLastSlicesCount;
+
+
+	// The stored gemetry of where the colected data will be copied too, in offsets
+	TUint16 iOffsTotalTimeIdle;
+	TUint16 iOffsTimesCIA;
+
+	TUint16 iOffsNumberIdles;
+	TUint16 iOffsNumEvents;
+
+	TUint16 iOffsReadyStateAdd;
+	TUint16 iOffsReadyStateRemove;
+
+	TUint16 iOffsNumTimeSliceExpire;
+	// Idle Tracking Data
+	TUint8 iCoresIdle;
+	TUint8 iPad; // Not used.
+
+	TUint iCoreMask;			// indicates which cores are idle
+	TUint64 iLastTime;			// used for TimesCIA
+friend TUint KernCoreStats_EnterIdle(TUint aCore);
+friend void KernCoreStats_LeaveIdle(TInt aCookie,TUint aCore);
+	};
+
+inline TUint32* KernCoreStats::Value32(TAny* aBuffer, TUint16 aOffset)
+{ return (TUint32*) ((TUint8*) aBuffer + aOffset); };
+
+inline TUint64* KernCoreStats::Value64(TAny* aBuffer, TUint16 aOffset)
+{ return (TUint64*) ((TUint8*) aBuffer + aOffset); };
+
+
+#endif // __KERNCORESTATS_H__
--- a/kernel/eka/include/kernel/kernel.h	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/include/kernel/kernel.h	Fri Apr 16 16:24:37 2010 +0300
@@ -250,13 +250,15 @@
 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 */
 #if defined(__MEMMODEL_FLEXIBLE__)
 const TUint8 KMutexOrdSyncPhysMem		= 0x03; /**< @internalComponent */
+const TUint8 KMutexOrdPageOut			= 0x02; /**< @internalComponent */
 #endif
-const TUint8 KMutexOrdPageOut			= 0x02; /**< @internalComponent */
 const TUint8 KMutexOrdResourceManager	= 0x01; /**< @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);
@@ -2776,9 +2782,10 @@
 	/** The type of device this represents. */
 	enum TType
 		{
-		ERom  = 1<<0,	/**< Paged ROM device type. */
-		ECode = 1<<1,	/**< Code paging device type. */
-		EData = 1<<2	/**< Data paging device type. */
+		ERom  = 1<<0,			/**< Paged ROM device type. */
+		ECode = 1<<1,			/**< Code paging device type. */
+		EData = 1<<2,			/**< Data paging device type. */
+		EMediaExtension = 1<<3	/**< Media extension device type. */
 		};
 
 	enum TSpecialDrives
@@ -2832,6 +2839,12 @@
 	inline virtual TInt DeleteNotify(TThreadMessage* aReq,TUint aOffset,TUint aSize);
 
 	/**
+	Return the lock that should be used to synchronise calculation of the idle/busy state and
+	subsequent calls to #NotifyIdle and #NotifyBusy.
+	*/
+	IMPORT_C NFastMutex* NotificationLock();
+	
+	/**
 	Called by the paging device to notify the kernel that the device has just become idle and is not
 	currently processing any requests.
 
--- a/kernel/eka/include/kernel/kpower.h	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/include/kernel/kpower.h	Fri Apr 16 16:24:37 2010 +0300
@@ -15,7 +15,7 @@
 // Public header for power management
 // 
 // WARNING: This file contains some APIs which are internal and are subject
-//          to change without notice. Such APIs should therefore not be used
+//          to change without noticed. Such APIs should therefore not be used
 //          outside the Kernel and Hardware Services package.
 //
 
@@ -27,7 +27,7 @@
 #include <kernel/kernel.h>
 
 /**
-@internalTechnology
+@internalComponent
 */
 #define __PM_ASSERT(aCond) \
 	__ASSERT_DEBUG( (aCond), \
@@ -37,7 +37,7 @@
 		) )
 
 /**
-@internalTechnology
+@internalComponent
 */
 #define __PM_PANIC(aMsg) \
 	(\
@@ -159,7 +159,7 @@
 
 #ifndef __X86__
 /**
-@internalTechnology
+@internalComponent
 @prototype 9.5
 */
 class TPowerController
@@ -172,7 +172,7 @@
 #endif
 
 /**
-@internalTechnology
+@internalComponent
 */
 class DBatteryMonitor
 	{
@@ -185,7 +185,7 @@
 	};
 
 /**
-@internalTechnology
+@internalComponent
 */
 class DPowerHal : public DBase
 	{
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kernel/eka/include/kernel/securerng.h	Fri Apr 16 16:24:37 2010 +0300
@@ -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	Fri Apr 16 16:24:37 2010 +0300
@@ -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	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/include/kernel/x86/assp.h	Fri Apr 16 16:24:37 2010 +0300
@@ -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/memmodel/epoc/flexible/memmodel.h	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/include/memmodel/epoc/flexible/memmodel.h	Fri Apr 16 16:24:37 2010 +0300
@@ -30,8 +30,8 @@
 
 #ifdef __SMP__
 // SubScheduler fields for each processor
-#define	i_AliasLinAddr			iExtras[0]
-#define	i_AliasPdePtr			iExtras[1]
+#define	i_AliasLinAddr			iSubSchedScratch[0]
+#define	i_AliasPdePtr			iSubSchedScratch[1]
 #endif
 
 /********************************************
--- a/kernel/eka/include/memmodel/epoc/multiple/memmodel.h	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/include/memmodel/epoc/multiple/memmodel.h	Fri Apr 16 16:24:37 2010 +0300
@@ -24,8 +24,8 @@
 
 #ifdef __SMP__
 // SubScheduler fields for each processor
-#define	i_AliasLinAddr			iExtras[0]
-#define	i_AliasPdePtr			iExtras[1]
+#define	i_AliasLinAddr			iSubSchedScratch[0]
+#define	i_AliasPdePtr			iSubSchedScratch[1]
 #endif
 
 /********************************************
@@ -45,6 +45,19 @@
  * RAM Defrag Page Table Moving Support
  ********************************************/
 
+#ifdef __SMP__
+/**
+@internalComponent
+*/
+#define AliasRemapOld					((TPhysAddr&)TheScheduler.iSchedScratch[1])
+
+/**
+@internalComponent
+*/
+#define AliasRemapNew					((TPhysAddr&)TheScheduler.iSchedScratch[2])
+
+#else
+
 /**
 @internalComponent
 */
@@ -54,6 +67,7 @@
 @internalComponent
 */
 #define AliasRemapNew					((TPhysAddr&)TheScheduler.iExtras[2])
+#endif
 
 /********************************************
  * Thread Control Block
--- a/kernel/eka/include/nkern/nk_cpu.h	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/include/nkern/nk_cpu.h	Fri Apr 16 16:24:37 2010 +0300
@@ -669,6 +669,18 @@
 
 #define	__chill()
 
+#ifdef 	__CPU_ARM_HAS_WFE_SEV
+
+extern "C" void __arm_wfe();
+extern "C" void __arm_sev();
+
+#define	__snooze()	__arm_wfe()
+#define	__holler()	__arm_sev()
+#else
+#define	__snooze()
+#define	__holler()
+#endif
+
 #if defined(__SMP__) && !defined(__CPU_ARM_HAS_LDREX_STREX_V6K)
 #error SMP not allowed without v6K
 #endif
@@ -696,6 +708,9 @@
 #error Unknown x86 compiler
 #endif
 
+#define	__snooze()	__chill()
+#define	__holler()
+
 #if defined(__cplusplus)
 extern "C" {
 #endif
--- a/kernel/eka/include/nkern/nk_priv.h	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/include/nkern/nk_priv.h	Fri Apr 16 16:24:37 2010 +0300
@@ -349,6 +349,10 @@
 	// Delayed threads
 	SDblQue iDelayedQ;
 	TDfc iDelayDfc;
+	// KernCoreStats
+	TUint iMadeReadyCounter;	// Number of times threads' where made ready.
+	TUint iMadeUnReadyCounter;	// Number of times threads' where made unready.
+	TUint iTimeSliceExpireCounter;	// Number of times threads' time slice expire, resulting in round robin.
 	};
 
 GLREF_D TScheduler TheScheduler;
@@ -528,23 +532,25 @@
 /**
 @internalComponent
 */
-#define MASK_NO_FAST_MUTEX 0x1
-#define MASK_CRITICAL 0x2
-#define MASK_NO_CRITICAL 0x4
-#define MASK_KERNEL_LOCKED 0x8
-#define MASK_KERNEL_UNLOCKED 0x10
-#define MASK_KERNEL_LOCKED_ONCE 0x20
-#define MASK_INTERRUPTS_ENABLED 0x40
-#define MASK_INTERRUPTS_DISABLED 0x80
-#define MASK_SYSTEM_LOCKED 0x100
-#define MASK_NOT_ISR 0x400
-#define MASK_NOT_IDFC 0x800 
-#define MASK_NOT_THREAD 0x1000
-#define MASK_NO_CRITICAL_IF_USER 0x2000
+#define	MASK_NO_FAST_MUTEX			0x1
+#define	MASK_CRITICAL				0x2
+#define	MASK_NO_CRITICAL			0x4
+#define	MASK_KERNEL_LOCKED			0x8
+#define	MASK_KERNEL_UNLOCKED		0x10
+#define	MASK_KERNEL_LOCKED_ONCE		0x20
+#define	MASK_INTERRUPTS_ENABLED		0x40
+#define	MASK_INTERRUPTS_DISABLED	0x80
+#define	MASK_SYSTEM_LOCKED			0x100
+#define	MASK_NOT_ISR				0x400
+#define	MASK_NOT_IDFC				0x800 
+#define	MASK_NOT_THREAD				0x1000
+#define	MASK_NO_CRITICAL_IF_USER	0x2000
+#define	MASK_ALWAYS_FAIL			0x4000
+#define	MASK_NO_RESCHED				0x8000
+#define MASK_NO_KILL_OR_SUSPEND	0x10000
+
 #define MASK_THREAD_STANDARD ( MASK_NO_FAST_MUTEX | MASK_KERNEL_UNLOCKED | MASK_INTERRUPTS_ENABLED | MASK_NOT_ISR | MASK_NOT_IDFC )
 #define MASK_THREAD_CRITICAL ( MASK_THREAD_STANDARD | MASK_CRITICAL )
-#define MASK_ALWAYS_FAIL 0x4000
-#define	MASK_NO_RESCHED 0x8000
 
 #if defined(__STANDALONE_NANOKERNEL__) || (!defined (__KERNEL_APIS_CONTEXT_CHECKS_WARNING__)&&!defined (__KERNEL_APIS_CONTEXT_CHECKS_FAULT__))
 #define CHECK_PRECONDITIONS(mask,function)
--- a/kernel/eka/include/nkern/nk_trace.h	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/include/nkern/nk_trace.h	Fri Apr 16 16:24:37 2010 +0300
@@ -360,6 +360,11 @@
 */
 #define KPIPE	58 //0x04000000, index 1
 
+/**
+@internalComponent
+*/
+#define KSCHED3	48 //0x00010000, index 1
+
 // RESERVED: Trace bits 192 - 255 are reserved for licensee partners
 
 
@@ -574,7 +579,7 @@
 @publishedPartner
 @released 9.4
 */
-#if defined(__MEMMODEL_MOVING__) || defined (__MEMMODEL_MULTIPLE__)
+#if !defined(__MEMMODEL_DIRECT__) && !defined (__MEMMODEL_EMUL_SINGLE_HOST_PROCESS__)
 #define BTRACE_RAM_ALLOCATOR
 #endif
 
@@ -620,7 +625,9 @@
 
 This BTrace category is only supported on the flexible memory model.
 */
+#ifdef __MEMMODEL_FLEXIBLE__
 #define BTRACE_FLEXIBLE_MEM_MODEL
+#endif
 
 /**
 If defined, code for BTrace category BTrace::EIic is compiled into the
--- a/kernel/eka/include/nkern/nkern.h	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/include/nkern/nkern.h	Fri Apr 16 16:24:37 2010 +0300
@@ -36,7 +36,7 @@
 /** @internalComponent */
 IMPORT_C void NKFault(const char* file, TInt line);
 /** @internalComponent */
-void NKIdle(TInt aStage);
+void NKIdle(TUint32 aStage);
 }
 
 /**
@@ -715,13 +715,14 @@
 	Pointer to a function which is called whenever a CPU goes idle
 
 	@param	aPtr	The iPtr stored in the SCpuIdleHandler structure
-	@param	aStage	If positive, the number of processors still active
-					If zero, indicates all processors are now idle
-					-1 indicates that postamble processing is required after waking up
+	@param	aStage	Bits 0-7 give a bitmask of CPUs now active, i.e. 0 means all processors now idle
+					Bit 31 set indicates that the current core can now be powered down
+					Bit 30 set indicates that other cores still remain to be retired
+					Bit 29 set indicates that postamble processing is required after waking up
 
 	@internalComponent
 */
-typedef void (*TCpuIdleHandlerFn)(TAny* aPtr, TInt aStage);
+typedef void (*TCpuIdleHandlerFn)(TAny* aPtr, TUint32 aStage);
 
 /** Idle handler structure
 
@@ -729,6 +730,17 @@
 */
 struct SCpuIdleHandler
 	{
+	/**
+	Defined flag bits in aStage parameter
+	*/
+	enum
+		{
+		EActiveCpuMask=0xFFu,
+		EPostamble=1u<<29,		// postamble needed
+		EMore=1u<<30,			// more cores still to be retired
+		ERetire=1u<<31,			// this core can now be retired
+		};
+
 	TCpuIdleHandlerFn	iHandler;
 	TAny*				iPtr;
 	volatile TBool		iPostambleRequired;
@@ -814,6 +826,7 @@
 	IMPORT_C static void ThreadRelease(NThread* aThread, TInt aReturnValue, NFastMutex* aMutex);
 	IMPORT_C static void ThreadSetPriority(NThread* aThread, TInt aPriority);
 	IMPORT_C static void ThreadSetPriority(NThread* aThread, TInt aPriority, NFastMutex* aMutex);
+	static void ThreadSetNominalPriority(NThread* aThread, TInt aPriority);
 	IMPORT_C static void ThreadRequestSignal(NThread* aThread);
 	IMPORT_C static void ThreadRequestSignal(NThread* aThread, NFastMutex* aMutex);
 	IMPORT_C static void ThreadRequestSignal(NThread* aThread, TInt aCount);
--- a/kernel/eka/include/nkern/nklib.h	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/include/nkern/nklib.h	Fri Apr 16 16:24:37 2010 +0300
@@ -75,6 +75,14 @@
 typedef Int64 TTimeK;
 
 
+/**
+@internalComponent
+*/
+union TUint64HL
+	{
+	TUint64		i64;
+	TUint32		i32[2];
+	};
 
 
 #if defined(__VC32__) || defined(__CW32__)
@@ -109,6 +117,12 @@
 	{}
 #endif //__PLACEMENT_VEC_NEW_INLINE
 
+/******************************************************************************
+ *
+ * SIMPLE DOUBLY-LINKED CIRCULAR LIST
+ *
+ ******************************************************************************/
+
 /**
 	Macro to offset a SDblQueLink pointer back to the base of a class containing it
 	@publishedPartner
@@ -213,7 +227,7 @@
 	
 	@return True, if this is the only link item in the list; false, otherwise.
     */
-	inline TBool Alone() const
+	FORCE_INLINE TBool Alone() const
 		{ return (iNext==iPrev); }
     
     
@@ -363,6 +377,334 @@
 
 
 
+/******************************************************************************
+ *
+ * ITERABLE DOUBLY-LINKED CIRCULAR LIST
+ *
+ ******************************************************************************/
+
+/**
+@internalComponent
+
+An object that forms part of an iterable doubly linked list.
+
+SIterDQLink can also be embedded within another object so that that object
+can form part of the doubly linked list.
+
+@see SIterDQ
+*/
+struct SIterDQ;
+struct SIterDQIterator;
+struct SIterDQLink
+	{
+	
+    /**
+    Default constructor; only defined for debug builds.
+    
+    It initialises the link pointers.
+    */
+	FORCE_INLINE SIterDQLink() {iNext=iPrev=0;}
+
+	enum
+		{
+		ENonAddressMask=3u,
+		EIterator=1u,
+		EAnchor=2u,
+		};
+
+	FORCE_INLINE SIterDQLink* Next() const
+		{ return (SIterDQLink*)(iNext & ~ENonAddressMask); }
+
+	FORCE_INLINE SIterDQLink* Prev() const
+		{ return (SIterDQLink*)(iPrev & ~ENonAddressMask); }
+
+	FORCE_INLINE TBool IsObject() const
+		{ return !(iNext & ENonAddressMask); }
+
+	FORCE_INLINE TBool IsIterator() const
+		{ return iNext & EIterator; }
+
+	FORCE_INLINE TBool IsAnchor() const
+		{ return iNext & EAnchor; }
+
+	FORCE_INLINE void SetNext(SIterDQLink* aNext)
+		{ iNext = (iNext & ENonAddressMask) | (TUintPtr(aNext) & ~ENonAddressMask); }
+
+	FORCE_INLINE void SetPrev(SIterDQLink* aPrev)
+		{ iPrev = (iPrev & ENonAddressMask) | (TUintPtr(aPrev) & ~ENonAddressMask); }
+
+    /**
+    Removes this link item from the doubly linked list.
+    
+    @return A pointer to this link item.
+    */
+	FORCE_INLINE SIterDQLink* Deque()
+		{
+		SIterDQLink* next = Next();
+		SIterDQLink* prev = Prev();
+		next->SetPrev(prev);
+		prev->SetNext(next);
+#ifdef _DEBUG
+		SetNext((SIterDQLink*)4);
+		SetPrev((SIterDQLink*)4);
+#endif
+		return this;
+		}
+
+
+    /**
+    Inserts this link item into the list so that it precedes the specified link item.
+    
+    @param aL A pointer to the link item which is to follow this link item.
+    */
+	FORCE_INLINE void InsertBefore(SIterDQLink* aL)
+		{
+		SIterDQLink* prev = aL->Prev();
+		SetNext(aL);
+		SetPrev(prev);
+		prev->SetNext(this);
+		aL->SetPrev(this);
+		}
+	
+		
+	/**
+	Inserts this link item into the list so that it follows the specified link item.
+    
+    @param aL A pointer to the link item which is to precede this link item.
+    */
+	FORCE_INLINE void InsertAfter(SIterDQLink* aL)
+		{
+		SIterDQLink* next = aL->Next();
+		SetPrev(aL);
+		SetNext(next);
+		next->SetPrev(this);
+		aL->SetNext(this);
+		}
+	
+	
+	/**
+	Tests whether this is the only link item in the list.
+	
+	@return True, if this is the only link item in the list; false, otherwise.
+    */
+	FORCE_INLINE TBool Alone() const
+		{ return (iNext==iPrev); }
+    
+private:
+	/**
+	Bits 2-31 = Address of the next link item in the list.
+	Bit 0 = 1 for iterator, 0 for object
+	*/
+	TUintPtr iNext;
+
+	/**
+	Bits 2-31 = Address of the previous link item in the list.
+	Bit 0 = 1 for iterator, 0 for object
+	*/
+	TUintPtr iPrev;
+
+	friend struct SIterDQ;
+	friend struct SIterDQIterator;
+	};
+
+
+
+
+/**
+@internalComponent
+
+Anchor for an iterable circular doubly linked list of SIterDQLink items.
+
+@see SIterDQLink
+*/
+struct SIterDQ
+	{
+	
+	/**
+	Default constructor.
+	*/
+	FORCE_INLINE SIterDQ()
+		{ iA.iNext = iA.iPrev = TUintPtr(&iA)|SIterDQLink::EAnchor; }
+		
+	
+	/**
+	Moves link items from the specified list onto this list, and clears the specified list
+	
+	@param aQ The source linked list. This list must not be empty.
+	*/	
+	inline SIterDQ(SIterDQ* aQ, TInt)		// move entries from aQ onto this queue and clear aQ - aQ must not be empty
+		{ iA.iNext=aQ->iA.iNext; iA.iPrev=aQ->iA.iPrev; First()->SetPrev(&iA); Last()->SetNext(&iA); new (aQ) SIterDQ; }
+		
+		
+	/**
+	Tests whether this doubly linked list is empty.
+	
+	@return True, if the list is empty; false, otherwise.
+	*/
+	FORCE_INLINE TBool IsEmpty() const
+		{ return (iA.iNext &~ SIterDQLink::ENonAddressMask) == TUintPtr(&iA); }
+	
+		
+    /**
+    Gets a pointer to the first item in this doubly linked list.
+    
+    @return A pointer to the first item.
+    */		
+	FORCE_INLINE SIterDQLink* First() const
+		{ return iA.Next(); }
+	
+		
+    /**
+    Gets a pointer to the last item in this doubly linked list.
+    
+    @return A pointer to the last item.
+    */		
+	FORCE_INLINE SIterDQLink* Last() const
+		{ return iA.Prev(); }
+	
+		
+	/**
+	Adds the specified link item onto the end of this doubly linked list.
+	
+	@param aL A pointer to the link item to be added.
+	*/
+	FORCE_INLINE void Add(SIterDQLink* aL)
+		{
+		aL->InsertBefore(&iA);
+		}
+	
+		
+	/**
+	Adds the specified link item onto the front of this doubly linked list.
+	
+	@param aL A pointer to the link item to be added.
+	*/
+	FORCE_INLINE void AddHead(SIterDQLink* aL)
+		{
+		aL->InsertAfter(&iA);
+		}
+	
+		
+	/**
+	Gets the first link item in the linked list.
+	
+	@return The first link item in the list; NULL, if the list is empty.
+	*/
+	inline SIterDQLink* GetFirst()
+		{ if (IsEmpty()) return NULL; else return First()->Deque(); }
+
+
+	/**
+	Gets the last link item in the linked list.
+	
+	@return The last link item in the list; NULL, if the list is empty.
+	*/
+	inline SIterDQLink* GetLast()
+		{ if (IsEmpty()) return NULL; else return Last()->Deque(); }
+
+
+	/**
+	Appends entries from the specified linked list onto this list, and clears
+	the specified link list anchor.
+	
+	@param aQ The source linked list.
+	*/
+	inline void MoveFrom(SIterDQ* aQ)	// append entries from aQ onto this queue and clear aQ
+		{ if (!aQ->IsEmpty())
+			{
+			SIterDQLink* last = Last();		// last current
+			SIterDQLink* fx = aQ->First();	// first extra
+			SIterDQLink* lx = aQ->Last();	// last extra
+			last->SetNext(fx);
+			fx->SetPrev(last);
+			iA.SetPrev(lx);
+			lx->SetNext(&iA);
+			new (aQ) SIterDQ;
+			}
+		}
+
+private:
+    /**
+    The anchor point for the doubly linked list.
+    */
+	SIterDQLink	iA;
+	};
+
+
+#ifdef __VC32__
+#pragma warning( disable : 4127 )	// conditional expression is constant
+#endif
+
+/**
+@internalComponent
+
+Iterator for an iterable circular doubly linked list of SIterDQLink items.
+
+@see SIterDQLink
+@see SIterDQ
+*/
+struct SIterDQIterator : public SIterDQLink
+	{
+
+	/**
+	Default constructor.
+
+	Iterator starts out not attached to any queue
+	*/
+	FORCE_INLINE SIterDQIterator()
+		{ iNext = iPrev = SIterDQLink::EIterator; }
+
+	/**
+	Destructor ensures iterator detached before destruction
+	*/
+	FORCE_INLINE ~SIterDQIterator()
+		{
+#ifdef _DEBUG
+		if (iNext != SIterDQLink::EIterator) { __crash(); }
+#endif
+		}
+
+	/**
+	Detach the iterator if it is currently attached to a queue
+	*/
+	FORCE_INLINE void Detach()
+		{ if (Next()) {Deque(); SetNext(0);} }
+
+	/**
+	Attach the iterator to a queue at the beginning.
+	*/
+	FORCE_INLINE void Attach(SIterDQ* aQ)
+		{
+#ifdef _DEBUG
+		if (iNext != SIterDQLink::EIterator) { __crash(); }
+#endif
+		aQ->AddHead(this);
+		}
+
+	/**
+	Step the iterator over the next object.
+	Return KErrNone if we stepped over an object.
+	Return KErrEof if we reached the end of the list.
+	Return KErrGeneral if we stepped over aMaxSteps other iterators.
+	In first case aObj is set to point to the object stepped over.
+	In other cases aObj is set to NULL.
+	*/
+	TInt Step(SIterDQLink*& aObj, TInt aMaxSteps=0);	// 0 means use default value
+
+	};
+
+#ifdef __VC32__
+#pragma warning( default : 4127 )	// conditional expression is constant
+#endif
+
+
+
+/******************************************************************************
+ *
+ * ORDERED DOUBLY-LINKED CIRCULAR LIST
+ *
+ ******************************************************************************/
+
 /**
 @publishedPartner
 @released
@@ -383,8 +725,6 @@
 	};
 
 
-
-
 /**
 @publishedPartner
 @released
@@ -416,6 +756,11 @@
 
 
 
+/******************************************************************************
+ *
+ * DELTA-ORDERED DOUBLY-LINKED CIRCULAR LIST
+ *
+ ******************************************************************************/
 
 /**
 @publishedPartner
@@ -539,6 +884,11 @@
 
 
 
+/******************************************************************************
+ *
+ * O(1) PRIORITY ORDERED LIST
+ *
+ ******************************************************************************/
 
 /**
 @publishedPartner
--- a/kernel/eka/include/nkernsmp/arm/arm_tmr.h	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/include/nkernsmp/arm/arm_tmr.h	Fri Apr 16 16:24:37 2010 +0300
@@ -80,5 +80,43 @@
 	};
 
 
+#ifdef	__CPU_ARM_HAS_GLOBAL_TIMER_BLOCK
+
+// r1p0 and later A9s have an additional Global Timer
+struct ArmGlobalTimer
+	{
+	volatile TUint32	iTimerCountLow;			// 00 Timer counter low word
+	volatile TUint32	iTimerCountHigh;		// 04 Timer counter high word
+	volatile TUint32	iTimerCtrl;				// 08 Timer control register
+	volatile TUint32	iTimerStatus;			// 0C Timer status register
+	volatile TUint32	iComparatorLow;			// 10 Comparator value low word (per-CPU register)
+	volatile TUint32	iComparatorHigh;		// 14 Comparator value high word (per-CPU register)
+	volatile TUint32	iComparatorInc;			// 18 Comparator autoincrement value (per-CPU register)
+	volatile TUint32	i_Spare2[57];			// 1C unused
+	};
+
+__ASSERT_COMPILE(sizeof(ArmGlobalTimer)==0x100);
+
+// Global Timer Control Register Bits
+enum TArmGlobalTimerCtrl
+	{
+	E_ArmGTmrCtrl_TmrEnb		=1u,			// when set, timer counts up
+	E_ArmGTmrCtrl_CmpEnb		=2u,			// when set, comparator matching is enabled (per-CPU)
+	E_ArmGTmrCtrl_IntEn			=4u,			// when set enables comparator match interrupt (per-CPU)
+	E_ArmGTmrCtrl_AutoInc		=8u,			// when set enables comparator auto increment (per-CPU)
+	E_ArmGTmrCtrl_PrescaleShift	=8u,
+	E_ArmGTmrCtrl_PrescaleMask	=0xff00u,		// bits 8-15 = prescale value - divides by (P+1)
+												// input to prescaler is PERIPHCLK (=CPUCLK/2 on NE1, CPUCLK/N in general, N>=2)
+	};
+
+enum TArmGlobalTimerStatus
+	{
+	E_ArmGTmrStatus_Event		=1u				// set when timer count value matches comparator value (per-CPU)
+	};
+
+#endif
+
+
+
 
 #endif	// 	__ARM_TMR_H__
--- a/kernel/eka/include/nkernsmp/arm/entry.h	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/include/nkernsmp/arm/entry.h	Fri Apr 16 16:24:37 2010 +0300
@@ -40,6 +40,7 @@
 #endif
 
 extern void handle_crash_ipi();
+extern void handle_indirect_powerdown_ipi();
 
 #ifdef _DEBUG
 extern void __DebugMsgIrq(TUint aIrqNumber);
@@ -124,22 +125,22 @@
 	asm("mov	r5, sp ");
 	asm("str	r1, [sp, #%a0]" : : "i" _FOFF(SThreadExcStack,iExcCode));	// word describing exception type
 	__ASM_STI2_MODE(MODE_SYS);			// mode_sys, IRQs off, FIQs on
-	asm("ldr	sp, [r4, #%a0]" : : "i" _FOFF(TSubScheduler, i_IrqStackTop));
+	asm("ldr	sp, [r4, #%a0]" : : "i" _FOFF(TSubScheduler, iSSX.iIrqStackTop));
 	USER_MEMORY_GUARD_ON(,r8,r0);		// r8 = original DACR if user memory guards in use
 
 	asm("nested_irq_rejoin: ");
-	asm("ldr	r0, [r4, #%a0]" : : "i" _FOFF(TSubScheduler, i_IrqCount));
-	asm("ldr	r7, [r4, #%a0]" : : "i" _FOFF(TSubScheduler, i_IrqNestCount));
+	asm("ldr	r0, [r4, #%a0]" : : "i" _FOFF(TSubScheduler, iSSX.iIrqCount));
+	asm("ldr	r7, [r4, #%a0]" : : "i" _FOFF(TSubScheduler, iSSX.iIrqNestCount));
 	asm("ldr	r12, __ArmInterrupt ");
 	asm("ldr	r10, _ArmVectorIrq ");
 	asm("add	r0, r0, #1 ");
 	asm("add	r7, r7, #1 ");
 	__DATA_MEMORY_BARRIER_Z__(r2);		// ensure memory accesses in interrupted code are observed before
 										// the writes to i_IrqCount, i_IrqNestCount
-	asm("str	r0, [r4, #%a0]" : : "i" _FOFF(TSubScheduler, i_IrqCount));		// increment i_IrqCount
-	asm("ldr	r11, [r12,#%a0]" : : "i" _FOFF(SArmInterruptInfo,iIrqHandler));	// address of IRQ handler
-	asm("ldr	r6, [r4, #%a0]" : : "i" _FOFF(TSubScheduler, i_GicCpuIfcAddr));
-	asm("str	r7, [r4, #%a0]" : : "i" _FOFF(TSubScheduler, i_IrqNestCount));	// increment i_IrqNestCount
+	asm("str	r0, [r4, #%a0]" : : "i" _FOFF(TSubScheduler, iSSX.iIrqCount));		// increment i_IrqCount
+	asm("ldr	r11, [r12,#%a0]" : : "i" _FOFF(SArmInterruptInfo,iIrqHandler));		// address if IRQ handler
+	asm("ldr	r6, [r4, #%a0]" : : "i" _FOFF(TSubScheduler, iSSX.iGicCpuIfcAddr));
+	asm("str	r7, [r4, #%a0]" : : "i" _FOFF(TSubScheduler, iSSX.iIrqNestCount));	// increment i_IrqNestCount
 
 	asm("1: ");
 #ifdef BTRACE_CPU_USAGE
@@ -187,6 +188,8 @@
 	asm("beq	do_generic_ipi ");
 	asm("cmp	r2, #%a0" : : "i" ((TInt)TRANSFERRED_IRQ_VECTOR));
 	asm("beq	do_transferred_ipi ");
+	asm("cmp	r2, #%a0" : : "i" ((TInt)INDIRECT_POWERDOWN_IPI_VECTOR));
+	asm("beq	do_indirect_powerdown_ipi ");
 	asm("cmp	r2, #15 ");
 	__JUMP(hi,	r11);					// if >15 but not TIMESLICE_VECTOR, call dispatcher
 
@@ -198,7 +201,7 @@
 
 	// TIMESLICE, RESCHED or TRANSFERRED
 	asm("do_timeslice_irq: ");
-	asm("ldr	r2, [r4, #%a0]" : : "i" _FOFF(TSubScheduler, i_LocalTimerAddr));
+	asm("ldr	r2, [r4, #%a0]" : : "i" _FOFF(TSubScheduler, iSSX.iLocalTimerAddr));
 	asm("mov	r1, #1 ");
 	asm("str	r1, [r2, #%a0]" : : "i" _FOFF(ArmLocalTimer, iTimerIntStatus));	// clear timer event flag
 	asm("do_resched_ipi: ");
@@ -211,6 +214,16 @@
 	ARM_SEV;							// kick any CPUs waiting for us to enter the ISR
 	asm("b		1b ");
 
+	asm("do_indirect_powerdown_ipi: ");
+	asm("str	r0, [r6, #%a0]" : : "i" _FOFF(GicCpuIfc, iEoi));		// acknowledge interrupt
+	__DATA_SYNC_BARRIER_Z__(r1);		// ensure writes to i_IrqCount, i_IrqNestCount, iRescheduleNeededFlag complete before SEV
+										// also ensure EOI is written before we return from the interrupt
+	ARM_SEV;							// kick any CPUs waiting for us to enter the ISR
+	asm("stmfd	sp!, {r0-r3,r12,lr} ");
+	asm("bl		call_ipd_handler ");
+	asm("ldmfd	sp!, {r0-r3,r12,lr} ");
+	asm("b		1b ");
+
 	// GENERIC_IPI
 	asm("do_generic_ipi: ");
 	asm("ldr	r2, _GenericIPIIsr ");
@@ -222,6 +235,9 @@
 	asm("__DebugMsg_longjump_Irq: ");
 	asm("ldr	pc, _dmIrq ");
 
+	asm("call_ipd_handler: ");
+	asm("ldr	pc, __handle_ipd_ipi ");
+
 	asm("__reset_vector:");
 	asm(".word	__ArmVectorReset "); 
 	asm("__undef_vector:");
@@ -255,6 +271,8 @@
 #endif
 	asm("_dmIrq: ");
 	asm(".word __DebugMsgIrq ");
+	asm("__handle_ipd_ipi: ");
+	asm(".word handle_indirect_powerdown_ipi ");
 	}
 }
 
--- a/kernel/eka/include/nkernsmp/arm/ncern.h	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/include/nkernsmp/arm/ncern.h	Fri Apr 16 16:24:37 2010 +0300
@@ -75,6 +75,27 @@
 	TLinAddr	iInitR13Und;		// initial value for R13_und
 	};
 
+typedef void (*TDetachComplete)(void);
+
+struct SPerCpuUncached
+	{
+	volatile TUint32	iDetachCount;		// Number of times core has detached from SMP cluster
+	volatile TUint32	iAttachCount;		// Number of times core has reattached to SMP cluster
+	volatile TBool		iPowerOffReq;		// TRUE if core needs to be powered off
+	volatile TBool		iPowerOnReq;		// TRUE if core needs to be powered on
+	TDetachComplete		iDetachCompleteFn;	// idle handler jumps to this to request power down if necessary
+											// after cleaning and disabling caches, detaching from SMP cluster
+											// and saving state required to bring the core back up again
+	volatile TUint32	iDetachCompleteCpus;
+	};
+
+union UPerCpuUncached
+	{
+	SPerCpuUncached		iU;
+	volatile TUint64	i__Dummy[8];
+	};
+
+__ASSERT_COMPILE(sizeof(SPerCpuUncached) <= 8*sizeof(TUint64));
 
 /** Timer frequency specification
 
@@ -90,6 +111,18 @@
 	TUint32		iInverse;					// 2^24/(iFreq/2^32) = 2^56/iFreq
 	};
 
+/** Function to power up a CPU
+@publishedPartner
+@prototype
+*/
+typedef void (*TCpuPowerUpFn)(TInt aCpu, SPerCpuUncached* aU);
+
+/** Function to power down a CPU
+@publishedPartner
+@prototype
+*/
+typedef void (*TCpuPowerDownFn)(TInt aCpu, SPerCpuUncached* aU);
+
 /** Variant interface block
 @internalTechnology
 @prototype
@@ -104,8 +137,12 @@
 	TLinAddr	iGicDistAddr;				// address of GIC Distributor
 	TLinAddr	iGicCpuIfcAddr;				// address of GIC CPU interface (must be same for all CPUs)
 	TLinAddr	iLocalTimerAddr;			// address of per-CPU timer (must be same for all CPUs)
-	volatile STimerMult* iTimerMult[KMaxCpus];	// timer[i] frequency / iMaxTimerClock * 2^32
-	volatile TUint32* iCpuMult[KMaxCpus];	// CPU[i] frequency / iMaxCpuClock * 2^32
+	TLinAddr	iGlobalTimerAddr;			// address of global timer if it exists
+	volatile STimerMult*	iTimerMult[KMaxCpus];	// timer[i] frequency / iMaxTimerClock * 2^32
+	volatile TUint32*		iCpuMult[KMaxCpus];		// CPU[i] frequency / iMaxCpuClock * 2^32
+	UPerCpuUncached*		iUncached[KMaxCpus];	// Pointer to uncached memory for each CPU
+	TCpuPowerUpFn			iCpuPowerUpFn;			// function used to power up a retired CPU (NULL if core control not supported)
+	TCpuPowerDownFn			iCpuPowerDownFn;		// function used to power down a CPU (NULL if power down done within idle handler itself)
 	};
 
 // End of file
--- a/kernel/eka/include/nkernsmp/arm/nk_plat.h	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/include/nkernsmp/arm/nk_plat.h	Fri Apr 16 16:24:37 2010 +0300
@@ -37,41 +37,90 @@
 #define __FAST_MUTEX_MACHINE_CODED__
 #define __NTHREAD_WAITSTATE_MACHINE_CODED__
 
+class TSubScheduler;
+class TScheduler;
+struct SFullArmRegSet;
+struct ArmScu;
+struct GicDistributor;
+struct GicCpuIfc;
+struct ArmLocalTimer;
+struct ArmGlobalTimer;
+
 // TSubScheduler member data
-#define	i_ScuAddr			iExtras[4]		// Address of SCU (also in TScheduler)
-#define	i_GicDistAddr		iExtras[5]		// Address of GIC Distributor (also in TScheduler)
-#define	i_GicCpuIfcAddr		iExtras[6]		// Address of GIC CPU Interface (also in TScheduler)
-#define	i_LocalTimerAddr	iExtras[7]		// Address of local timer registers (also in TScheduler)
-#define	i_IrqCount			iExtras[8]		// count of interrupts handled
-#define	i_IrqNestCount		iExtras[9]		// IRQ nest count for this CPU (starts at -1)
-#define	i_ExcInfo			iExtras[10]		// pointer to exception info for crash debugger
-#define	i_CrashState		iExtras[11]		// 0=normal, 1=this CPU faulted, 2=this CPU has received an NMI and halted
-#define	i_AbtStackTop		iExtras[12]		// Top of ABT stack for this CPU, also used to point to SFullArmRegSet
-#define	i_UndStackTop		iExtras[13]		// Top of UND stack for this CPU
-#define	i_FiqStackTop		iExtras[14]		// Top of FIQ stack for this CPU
-#define	i_IrqStackTop		iExtras[15]		// Top of IRQ stack for this CPU
-#define	i_TimerMultF		iExtras[16]		// Timer frequency / Max Timer frequency * 2^32
-#define	i_TimerMultI		iExtras[17]		// Max Timer frequency / Timer frequency * 2^24
-#define	i_CpuMult			iExtras[18]		// CPU frequency / Max CPU frequency * 2^32
-#define	i_LastTimerSet		iExtras[20]		// Value last written to local timer counter
-#define	i_TimestampError	iExtras[21]		// Current error in the timestamp
-#define	i_MaxCorrection		iExtras[22]		// Maximum correction to timestamp in one go
-#define	i_TimerGap			iExtras[23]		// Timestamp ticks taken to read and write local timer counter
+struct TSubSchedulerX
+	{
+	TUint32				iSSXP[3];
+	ArmGlobalTimer*		iGlobalTimerAddr;		// Address of global timer registers (also in TScheduler)
+	ArmScu*				iScuAddr;				// Address of SCU (also in TScheduler)
+	GicDistributor*		iGicDistAddr;			// Address of GIC Distributor (also in TScheduler)
+	GicCpuIfc*			iGicCpuIfcAddr;			// Address of GIC CPU Interface (also in TScheduler)
+	ArmLocalTimer*		iLocalTimerAddr;		// Address of local timer registers (also in TScheduler)
+	volatile TUint32	iIrqCount;				// count of interrupts handled
+	volatile TInt		iIrqNestCount;			// IRQ nest count for this CPU (starts at -1)
+	TAny*				iExcInfo;				// pointer to exception info for crash debugger
+	volatile TInt		iCrashState;			// 0=normal, 1=this CPU faulted, 2=this CPU has received an NMI and halted
+	union {
+		TLinAddr		iAbtStackTop;			// Top of ABT stack for this CPU, also used to point to SFullArmRegSet
+		SFullArmRegSet* iRegs;
+		};
+	TLinAddr			iUndStackTop;			// Top of UND stack for this CPU
+	TLinAddr			iFiqStackTop;			// Top of FIQ stack for this CPU
+	TLinAddr			iIrqStackTop;			// Top of IRQ stack for this CPU
+	volatile TUint32	iCpuFreqM;				// CPU frequency / Max CPU frequency (mantissa, bit 31=1) f/fmax=mantissa/2^shift
+	volatile TInt		iCpuFreqS;				// CPU frequency / Max CPU frequency (shift)
+	volatile TUint32	iCpuPeriodM;			// Max CPU frequency / CPU frequency (mantissa, bit 31=1) fmax/f=mantissa/2^shift
+	volatile TInt		iCpuPeriodS;			// Max CPU frequency / CPU frequency (shift)
+	volatile TUint32	iNTimerFreqM;			// Nominal Timer frequency / Max Timer frequency (mantissa, bit 31=1) f/fmax=mantissa/2^shift
+	volatile TInt		iNTimerFreqS;			// Nominal Timer frequency / Max Timer frequency (shift)
+	volatile TUint32	iNTimerPeriodM;			// Nominal Max Timer frequency / Timer frequency (mantissa, bit 31=1) fmax/f=mantissa/2^shift
+	volatile TInt		iNTimerPeriodS;			// Nominal Max Timer frequency / Timer frequency (shift)
+	volatile TUint32	iTimerFreqM;			// Timer frequency / Max Timer frequency (mantissa, bit 31=1) f/fmax=mantissa/2^shift
+	volatile TInt		iTimerFreqS;			// Timer frequency / Max Timer frequency (shift)
+	volatile TUint32	iTimerPeriodM;			// Max Timer frequency / Timer frequency (mantissa, bit 31=1) fmax/f=mantissa/2^shift
+	volatile TInt		iTimerPeriodS;			// Max Timer frequency / Timer frequency (shift)
+	volatile TUint64	iLastSyncTime;			// Timestamp at which last reference check occurred
+	volatile TUint32	iTicksSinceLastSync;	// Local timer ticks between last ref. check and next zero crossing
+	volatile TUint32	iLastTimerSet;			// Value last written to local timer counter
+	volatile TUint32	iGapEstimate;			// 2^16 * estimated gap in ticks whenever local timer counter is read then written
+	volatile TUint32	iGapCount;				// count of local timer counter RMW ops
+	volatile TUint32	iTotalTicks;			// programmed ticks since last sync
+	volatile TUint32	iDitherer;				// PRNG state for dither generation
+	volatile TInt		iFreqErrorEstimate;		// Current frequency offset between local timer and reference
+	volatile TInt		iFreqErrorLimit;		// Saturation level for frequency offset
+	volatile TInt64		iErrorIntegrator;		// Accumulator to integrate time error measurements
+	volatile TUint64	iRefAtLastCorrection;	// Value of reference timer at last correction
+	volatile TUint8		iM;						// Value controlling loop bandwidth (larger->lower loop bandwidth)
+	volatile TUint8		iN;						// Number of timer ticks between corrections = 2^iN
+	volatile TUint8		iD;						// Value controlling loop damping
+	volatile TUint8		iSSXP1;
 
-#define	i_Regs				iExtras[12]		// Alias for i_AbtStackTop
+	TUint32				iSSXP2[19];
+	TUint64				iSSXP3;					// one 64 bit value to guarantee alignment
+	};
 
 // TScheduler member data
-#define	i_TimerMax			iExtras[16]		// Maximum per-CPU timer frequency (after prescaling)
+struct TSchedulerX
+	{
+	TUint64				iTimerMax;				// Maximum per-CPU timer frequency (after prescaling)
+	TUint32				iSXP[1];
+	ArmGlobalTimer*		iGlobalTimerAddr;		// Address of global timer registers (also in TSubScheduler)
+	ArmScu*				iScuAddr;				// Address of SCU (also in TSubScheduler)
+	GicDistributor*		iGicDistAddr;			// Address of GIC Distributor (also in TSubScheduler)
+	GicCpuIfc*			iGicCpuIfcAddr;			// Address of GIC CPU Interface (also in TSubScheduler)
+	ArmLocalTimer*		iLocalTimerAddr;		// Address of local timer registers (also in TSubScheduler)
+	TUint32				iSXP2[8];
+	};
 
 
-#define	RESCHED_IPI_VECTOR			0x00
-#define	GENERIC_IPI_VECTOR			0x01
-#define	TRANSFERRED_IRQ_VECTOR		0x02
-#define	CRASH_IPI_VECTOR			0x03	// would really like this to be a FIQ
-#define	BOOT_IPI_VECTOR				0x04	// used during boot to handshake with APs
-#define RESERVED_IPI_VECTOR_1		0x05	// reserved for future kernel functionality
-#define RESERVED_IPI_VECTOR_2		0x06	// reserved for future kernel functionality
-#define RESERVED_IPI_VECTOR_3		0x07	// reserved for future kernel functionality
+#define	RESCHED_IPI_VECTOR				0x00
+#define	GENERIC_IPI_VECTOR				0x01
+#define	TRANSFERRED_IRQ_VECTOR			0x02
+#define	CRASH_IPI_VECTOR				0x03	// would really like this to be a FIQ
+#define	BOOT_IPI_VECTOR					0x04	// used during boot to handshake with APs
+#define	INDIRECT_POWERDOWN_IPI_VECTOR	0x04	// used to trigger core power down
+#define RESERVED_IPI_VECTOR_1			0x05	// reserved for future kernel functionality
+#define RESERVED_IPI_VECTOR_2			0x06	// reserved for future kernel functionality
+#define IDLE_WAKEUP_IPI_VECTOR			0x07	// for use of Idle handler/Wakeup handler
 
 #if defined(__CPU_ARM11MP__)
 #define	TIMESLICE_VECTOR			0x1D	// vector 29 is per-CPU timer interrupt
@@ -191,8 +240,7 @@
 	{
 public:
 	TInt Create(SNThreadCreateInfo& aInfo, TBool aInitial);
-	inline void Stillborn()
-		{}
+	void Stillborn();
 
 	/** Value indicating what event caused thread to enter privileged mode.
 		@publishedPartner
@@ -299,14 +347,15 @@
 #define	smp_wmb()	mb()
 
 #ifdef	__IN_KERNEL__
-struct ArmScu;
-struct GicDistributor;
-struct GicCpuIfc;
-struct ArmLocalTimer;
-#define	SCU			(*(ArmScu*)TheScheduler.i_ScuAddr)
-#define	GIC_DIST	(*(GicDistributor*)TheScheduler.i_GicDistAddr)
-#define	GIC_CPU_IFC	(*(GicCpuIfc*)TheScheduler.i_GicCpuIfcAddr)
-#define	LOCAL_TIMER	(*(ArmLocalTimer*)TheScheduler.i_LocalTimerAddr)
+#define	SCU				(*TheScheduler.iSX.iScuAddr)
+#define	GIC_DIST		(*TheScheduler.iSX.iGicDistAddr)
+#define	GIC_CPU_IFC		(*TheScheduler.iSX.iGicCpuIfcAddr)
+#define	LOCAL_TIMER		(*TheScheduler.iSX.iLocalTimerAddr)
+
+#ifdef	__CPU_ARM_HAS_GLOBAL_TIMER_BLOCK
+#define	GLOBAL_TIMER	(*TheScheduler.iSX.iGlobalTimerAddr)
+#endif
+
 #endif
 
 
--- a/kernel/eka/include/nkernsmp/nk_priv.h	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/include/nkernsmp/nk_priv.h	Fri Apr 16 16:24:37 2010 +0300
@@ -27,6 +27,19 @@
 
 class Monitor;
 
+const TInt KNumPriClasses = 4;
+extern const TUint8 KClassFromPriority[KNumPriorities];
+
+#ifndef __LOAD_BALANCE_INFO_DEFINED__
+/**
+@internalComponent
+*/
+struct SLbInfo
+	{
+	TUint64		i__Dummy;
+	};
+#endif
+
 /********************************************
  * Schedulable = thread or thread group
  ********************************************/
@@ -41,13 +54,20 @@
 class NSchedulable : public TPriListLink
 	{
 public:
+	/**
+	@internalComponent
+	*/
 	enum
 		{
 		EReadyGroup=1,
-		EReadyCpuMask=0x7f,
+		EReadyCpuMask=0x1f,
+		EReadyCpuSticky=0x40,
 		EReadyOffset=0x80,
 		};
 
+	/**
+	@internalComponent
+	*/
 	enum NReadyFlags
 		{
 		ENewTimeslice=1,
@@ -55,6 +75,9 @@
 		EUnPause=4,
 		};
 
+	/**
+	@internalComponent
+	*/
 	enum NEventState
 		{
 		EEventCountShift=16u,
@@ -67,32 +90,96 @@
 		EDeferredReady=0x4000u,
 		EEventParent=0x8000u,
 		};
+
+	/**
+	@internalComponent
+	*/
+	enum NLbState
+		{
+		ELbState_Inactive	= 0x00u,	// not currently involved in load balancing
+		ELbState_Global		= 0x01u,	// flag indicating this is on global load balance list
+		ELbState_Temp		= 0x02u,	// flag indicating this is on a temporary load balance list
+		ELbState_CpuMask	= 0x1Fu,	// mask of bits indicating CPU if on per-CPU list
+		ELbState_PerCpu		= 0x20u,	// flag indicating this is on per-CPU load balance list
+		ELbState_ExtraRef	= 0x40u,	// flag indicating extra reference has been taken after thread/group died
+		ELbState_Generation	= 0x80u,	// 1 bit generation number
+		};
+
+	/**
+	@internalComponent
+	*/
+	enum NCpuStatsSelect
+		{
+		E_RunTime=0x01u,
+		E_RunTimeDelta=0x02u,
+		E_ActiveTime=0x04u,
+		E_ActiveTimeDelta=0x08u,
+		E_LastRunTime=0x10u,
+		E_LastActiveTime=0x20u,
+
+		E_AllStats = 0x3fu
+		};
+
+	/**
+	@internalComponent
+	*/
+	struct SCpuStats
+		{
+		TUint64		iRunTime;			// total run time
+		TUint64		iRunTimeDelta;		// run time since we last asked
+		TUint64		iActiveTime;		// total active time
+		TUint64		iActiveTimeDelta;	// active time since we last asked
+		TUint64		iLastRunTime;		// how long ago this last ran
+		TUint64		iLastActiveTime;	// how long ago this was last active
+		};
 public:
-	NSchedulable();
-	void AcqSLock();
-	void RelSLock();
-	void LAcqSLock();
-	void RelSLockU();
-	void ReadyT(TUint aMode);					// make ready, assumes lock held
-	TInt BeginTiedEvent();
-	void EndTiedEvent();
-	TInt AddTiedEvent(NEventHandler* aEvent);
-	TBool TiedEventReadyInterlock(TInt aCpu);
-	void UnPauseT();							// decrement pause count and make ready if necessary
-	static void DeferredReadyIDfcFn(TAny*);
-	void DetachTiedEvents();
+	NSchedulable();								/**< @internalComponent */
+	void AcqSLock();							/**< @internalComponent */
+	void RelSLock();							/**< @internalComponent */
+	void LAcqSLock();							/**< @internalComponent */
+	void RelSLockU();							/**< @internalComponent */
+	void ReadyT(TUint aMode);					/**< @internalComponent */ // make ready, assumes lock held
+	TInt BeginTiedEvent();						/**< @internalComponent */
+	void EndTiedEvent();						/**< @internalComponent */
+	TInt AddTiedEvent(NEventHandler* aEvent);	/**< @internalComponent */
+	TBool TiedEventReadyInterlock(TInt aCpu);	/**< @internalComponent */
+	void UnPauseT();							/**< @internalComponent */ // decrement pause count and make ready if necessary
+	static void DeferredReadyIDfcFn(TAny*);		/**< @internalComponent */
+	void DetachTiedEvents();					/**< @internalComponent */
+	TBool TakeRef();							/**< @internalComponent */
+	TBool DropRef();							/**< @internalComponent */
+	void LbUnlink();							/**< @internalComponent */
+	void LbTransfer(SDblQue& aDestQ);			/**< @internalComponent */
+	void RemoveFromEnumerateList();				/**< @internalComponent */
+	void GetCpuStats(TUint aMask, SCpuStats& aOut);		/**< @internalComponent */
+	void GetCpuStatsT(TUint aMask, SCpuStats& aOut);	/**< @internalComponent */
+	void GetLbStats(TUint64 aTime);				/**< @internalComponent */
+	void LbDone(TUint aFlags);					/**< @internalComponent */
+	TUint32 SetCpuAffinityT(TUint32 aAffinity);	/**< @internalComponent */
+	TBool ShouldMigrate(TInt aCpu);				/**< @internalComponent */
+	void InitLbInfo();							/**< @internalComponent */
+	void NominalPriorityChanged();				/**< @internalComponent */
+	void AddToEnumerateList();					/**< @internalComponent */
+	void SetEventCpu();							/**< @internalComponent */
 public:
-	inline TBool IsGroup()			{return !iParent;}
-	inline TBool IsLoneThread()		{return iParent==this;}
-	inline TBool IsGroupThread()	{return iParent && iParent!=this;}
+	static TUint32 PreprocessCpuAffinity(TUint32 aAffinity);			/**< @internalComponent */
+	inline TBool IsGroup()			{return !iParent;}					/**< @internalComponent */
+	inline TBool IsLoneThread()		{return iParent==this;}				/**< @internalComponent */
+	inline TBool IsGroupThread()	{return iParent && iParent!=this;}	/**< @internalComponent */
 public:
 //	TUint8				iReady;					/**< @internalComponent */	// flag indicating thread on ready list = cpu number | EReadyOffset
 //	TUint8				iCurrent;				/**< @internalComponent */	// flag indicating thread is running
 //	TUint8				iLastCpu;				/**< @internalComponent */	// CPU on which this thread last ran
 	TUint8				iPauseCount;			/**< @internalComponent */	// count of externally requested pauses extending a voluntary wait
 	TUint8				iSuspended;				/**< @internalComponent */	// flag indicating active external suspend (Not used for groups)
-	TUint8				iNSchedulableSpare1;	/**< @internalComponent */
-	TUint8				iNSchedulableSpare2;	/**< @internalComponent */
+	TUint8				iACount;				/**< @internalComponent */	// access count
+	TUint8				iPreferredCpu;			/**< @internalComponent */
+
+	TInt				iActiveState;			/**< @internalComponent */
+	TUint8				i_NSchedulable_Spare2;	/**< @internalComponent */
+	TUint8				iForcedCpu;				/**< @internalComponent */
+	TUint8				iTransientCpu;			/**< @internalComponent */
+	TUint8				iLbState;				/**< @internalComponent */
 
 	TUint8				iCpuChange;				/**< @internalComponent */	// flag showing CPU migration outstanding
 	TUint8				iStopping;				/**< @internalComponent */	// thread is exiting, thread group is being destroyed
@@ -109,21 +196,31 @@
 	TUint32				i_IDfcMem[sizeof(TDfc)/sizeof(TUint32)];	/**< @internalComponent */	// IDFC used to make thread ready after last tied event completes
 //	TDfc				iDeferredReadyIDfc;		/**< @internalComponent */	// IDFC used to make thread ready after last tied event completes
 
-	union
-		{
-		TUint64			iRunCount64;
-		TUint32			iRunCount32[2];
+	union {
+		TUint64HL		iRunCount;				/**< @internalComponent */	// number of times this thread has run
+		TUint64HL		iLastStartTime;			/**< @internalComponent */	// last start time for groups
 		};
-	union
-		{
-		TUint64			iTotalCpuTime64;		/**< @internalComponent */	// total time spent running, in hi-res timer ticks
-		TUint32			iTotalCpuTime32[2];		/**< @internalComponent */	// total time spent running, in hi-res timer ticks
+	TUint64HL			iLastRunTime;			/**< @internalComponent */	// time when this thread last ran
+	TUint64HL			iTotalCpuTime;			/**< @internalComponent */	// total CPU time used by this thread
+	TUint64HL			iLastActivationTime;	/**< @internalComponent */	// time when this thread last became active
+	TUint64HL			iTotalActiveTime;		/**< @internalComponent */	// total time this thread has been active
+	TUint64HL			iSavedCpuTime;			/**< @internalComponent */	// Total CPU time used at last check
+	TUint64HL			iSavedActiveTime;		/**< @internalComponent */	// Total active time at last check
+	SDblQueLink			iLbLink;				/**< @internalComponent */	// Link into queue of tasks requiring load balancing
+	SIterDQLink			iEnumerateLink;			/**< @internalComponent */
+
+	enum {EMaxLbInfoSize = 48};					/**< @internalComponent */
+	union	{
+		TUint64			i__Dummy[EMaxLbInfoSize/sizeof(TUint64)];	/**< @internalComponent */
+		SLbInfo			iLbInfo;				/**< @internalComponent */
 		};
 	};
 
 __ASSERT_COMPILE(!(_FOFF(NSchedulable,iSSpinLock)&7));
-__ASSERT_COMPILE(!(_FOFF(NSchedulable,iRunCount64)&7));
-__ASSERT_COMPILE(!(_FOFF(NSchedulable,iTotalCpuTime64)&7));
+__ASSERT_COMPILE(!(_FOFF(NSchedulable,iRunCount)&7));
+__ASSERT_COMPILE(!(_FOFF(NSchedulable,iTotalCpuTime)&7));
+__ASSERT_COMPILE(!(_FOFF(NSchedulable,iLbInfo)&7));
+__ASSERT_COMPILE(sizeof(SLbInfo) <= NSchedulable::EMaxLbInfoSize);
 __ASSERT_COMPILE(!(sizeof(NSchedulable)&7));
 
 
@@ -261,34 +358,34 @@
 		};
 public:
 	NThreadBase();
-	TInt Create(SNThreadCreateInfo& anInfo,	TBool aInitial);
-	void UnReadyT();
-	TBool SuspendOrKill(TInt aCount);
-	TBool DoSuspendOrKillT(TInt aCount, TSubScheduler* aS);
-	TBool CancelTimerT();
-	void DoReleaseT(TInt aReturnCode, TUint aMode);
-	TBool CheckFastMutexDefer();
-	void DoCsFunctionT();
-	TBool Resume(TBool aForce);
-	IMPORT_C TBool Suspend(TInt aCount);		/**< @internalComponent */
-	IMPORT_C TBool Resume();					/**< @internalComponent */
-	IMPORT_C TBool ForceResume();				/**< @internalComponent */
+	TInt Create(SNThreadCreateInfo& anInfo,	TBool aInitial);	/**< @internalComponent */
+	void UnReadyT();										/**< @internalComponent */
+	TBool SuspendOrKill(TInt aCount);						/**< @internalComponent */
+	TBool DoSuspendOrKillT(TInt aCount, TSubScheduler* aS);	/**< @internalComponent */
+	TBool CancelTimerT();									/**< @internalComponent */
+	void DoReleaseT(TInt aReturnCode, TUint aMode);			/**< @internalComponent */
+	TBool CheckFastMutexDefer();							/**< @internalComponent */
+	void DoCsFunctionT();									/**< @internalComponent */
+	TBool Resume(TBool aForce);								/**< @internalComponent */
+	IMPORT_C TBool Suspend(TInt aCount);					/**< @internalComponent */
+	IMPORT_C TBool Resume();								/**< @internalComponent */
+	IMPORT_C TBool ForceResume();							/**< @internalComponent */
 	IMPORT_C void Release(TInt aReturnCode, TUint aMode);	/**< @internalComponent */
-	IMPORT_C void RequestSignal();				/**< @internalComponent */
-	IMPORT_C void SetPriority(TInt aPriority);	/**< @internalComponent */
-	void SetMutexPriority(NFastMutex* aMutex);
-	void LoseInheritedPriorityT();
-	void ChangeReadyThreadPriority();
-	TUint32 SetCpuAffinity(TUint32 aAffinity);
-	TBool TiedEventLeaveInterlock();
-	TBool TiedEventJoinInterlock();
-	IMPORT_C void Kill();						/**< @internalComponent */
-	void Exit();
+	IMPORT_C void RequestSignal();							/**< @internalComponent */
+	IMPORT_C void SetPriority(TInt aPriority);				/**< @internalComponent */
+	void SetNominalPriority(TInt aPriority);				/**< @internalComponent */
+	void SetMutexPriority(NFastMutex* aMutex);				/**< @internalComponent */
+	void LoseInheritedPriorityT();							/**< @internalComponent */
+	void ChangeReadyThreadPriority();						/**< @internalComponent */
+	TBool TiedEventLeaveInterlock();						/**< @internalComponent */
+	TBool TiedEventJoinInterlock();							/**< @internalComponent */
+	IMPORT_C void Kill();									/**< @internalComponent */
+	void Exit();											/**< @internalComponent */
 	// hooks for platform-specific code
-	void OnKill(); 
-	void OnExit();
+	void OnKill();											/**< @internalComponent */
+	void OnExit();											/**< @internalComponent */
 public:
-	static void TimerExpired(TAny* aPtr);
+	static void TimerExpired(TAny* aPtr);					/**< @internalComponent */
 
 	/** @internalComponent */
 	inline void UnknownState(TInt aOp, TInt aParam)
@@ -321,10 +418,10 @@
 	TPriListLink		iWaitLink;				/**< @internalComponent */	// used to link thread into a wait queue
 //	TUint8				iBasePri;				/**< @internalComponent */	// priority with no fast mutex held
 //	TUint8				iMutexPri;				/**< @internalComponent */	// priority from held fast mutex
-//	TUint8				iInitial;				/**< @internalComponent */	// TRUE if this is an initial thread
+//	TUint8				iNominalPri;			/**< @internalComponent */	// nominal priority of thread (excluding effect of higher level inheritance)
 	TUint8				iLinkedObjType;
 	TUint8				i_ThrdAttr;				/**< @internalComponent */
-	TUint8				iNThreadBaseSpare10;
+	TUint8				iInitial;				/**< @internalComponent */	// TRUE if this is an initial thread
 	TUint8				iFastMutexDefer;		/**< @internalComponent */
 
 	NFastSemaphore		iRequestSemaphore;		/**< @internalComponent */
@@ -357,14 +454,15 @@
 	TAny*				iExtraContext;			/**< @internalComponent */	// parent FPSCR value (iExtraContextSize == -1), coprocessor context (iExtraContextSize > 0) or NULL
 	TInt				iExtraContextSize;		/**< @internalComponent */	// +ve=dynamically allocated, 0=none, -1=iExtraContext stores parent FPSCR value
 
+	TUint8				iCoreCycling;			/**< @internalComponent */	// this thread is currently cycling through all active cores
+	TUint8				iRebalanceAttr;			/**< @internalComponent */	// behaviour of load balancing wrt this thread
+	TUint8				iNThreadBaseSpare4c;	/**< @internalComponent */	// spare to allow growth while preserving BC
+	TUint8				iNThreadBaseSpare4d;	/**< @internalComponent */	// spare to allow growth while preserving BC
+	TUint32				iNThreadBaseSpare5;		/**< @internalComponent */	// spare to allow growth while preserving BC
 	TUint32				iNThreadBaseSpare6;		/**< @internalComponent */	// spare to allow growth while preserving BC
 	TUint32				iNThreadBaseSpare7;		/**< @internalComponent */	// spare to allow growth while preserving BC
 	TUint32				iNThreadBaseSpare8;		/**< @internalComponent */	// spare to allow growth while preserving BC
 	TUint32				iNThreadBaseSpare9;		/**< @internalComponent */	// spare to allow growth while preserving BC
-
-	// For EMI support - HOPEFULLY THIS CAN DIE
-	TUint32	iTag;							/**< @internalComponent */	// User defined set of bits which is ANDed with a mask when the thread is scheduled, and indicates if a DFC should be scheduled.
-	TAny* iVemsData;						/**< @internalComponent */	// This pointer can be used by any VEMS to store any data associated with the thread.  This data must be clean up before the Thread Exit Monitor completes.
 	};
 
 __ASSERT_COMPILE(!(_FOFF(NThreadBase,iWaitLink)&7));
@@ -377,12 +475,14 @@
 
 #define iBasePri			iWaitLink.iSpare1	/**< @internalComponent */
 #define	iMutexPri			iWaitLink.iSpare2	/**< @internalComponent */
-#define	i_NThread_Initial	iWaitLink.iSpare3	/**< @internalComponent */
+#define	iNominalPri			iWaitLink.iSpare3	/**< @internalComponent */
+#define	i_NThread_Initial	iInitial			/**< @internalComponent */
 
 #endif
 
 /** @internalComponent */
-#define	i_NThread_BasePri	iWaitLink.iSpare1
+#define	i_NThread_BasePri		iWaitLink.iSpare1
+#define	i_NThread_NominalPri	iWaitLink.iSpare3
 
 /** @internalComponent */
 #define	NTHREADBASE_CPU_AFFINITY_MASK	0x80000000
@@ -407,6 +507,7 @@
 	NThreadGroup();
 public:
 	TInt iThreadCount;										/**< @internalComponent */
+	TDfc* iDestructionDfc;									/**< @internalComponent */
 	TPriList<NThreadBase, KNumPriorities> iNThreadList;		/**< @internalComponent */
 	};
 
@@ -414,25 +515,49 @@
  * Scheduler
  ********************************************/
 
+#include <nk_plat.h>
+
+/**
+@internalComponent
+*/
+enum
+	{
+	EQueueEvent_Kick=1,
+	EQueueEvent_WakeUp=2,
+	};
+
 /**
 @internalComponent
 */
 class TScheduler;
 class NThread;
 class NIrqHandler;
-class TSubScheduler : public TPriListBase
+struct SIdlePullThread;
+class TSubScheduler
 	{
 public:
 	TSubScheduler();
 	void QueueDfcs();
 	void RotateReadyList(TInt aPriority);
 	NThread* SelectNextThread();
-	TBool QueueEvent(NEventHandler* aEvent);
+	TInt QueueEvent(NEventHandler* aEvent);
 	void QueueEventAndKick(NEventHandler* aEvent);
 	void SaveTimesliceTimer(NThreadBase* aThread);
 	void UpdateThreadTimes(NThreadBase* aOld, NThreadBase* aNew);
+	void SSAddEntry(NSchedulable* aEntry);
+	void SSAddEntryHead(NSchedulable* aEntry);
+	void SSRemoveEntry(NSchedulable* aEntry);
+	void SSChgEntryP(NSchedulable* aEntry, TInt aNewPriority);
+	void IdlePullSearch(SIdlePullThread& a, TSubScheduler* aDest);
+	void GetLbThreads(SDblQue& aQ);
+	TBool Detached();	// platform specific
+
+	inline TInt HighestPriority()
+		{ return iSSList.HighestPriority(); }
+	inline NSchedulable* EntryAtPriority(TInt aPri)
+		{ return (NSchedulable*)iSSList.iQueue[aPri]; }
 private:
-	SDblQueLink*	iExtraQueues[KNumPriorities-1];
+	TPriList<NSchedulable, KNumPriorities>	iSSList;
 public:
 	TSpinLock		iExIDfcLock;				// lock to protect exogenous IDFC queue
 
@@ -456,25 +581,19 @@
 
 	TUint8			iInIDFC;					// TRUE if IDFCs are currently being run on this CPU
 	volatile TUint8	iEventHandlersPending;		// TRUE if an event handler is pending on this CPU
-	TUint8			iSubSchedulerSpare4;
-	TUint8			iSubSchedulerSpare5;
+	TUint8			iCCSyncPending;
+	TUint8			iLbCounter;
 	TAny*			iAddressSpace;
 
 	TUint32			iReschedIPIs;
 	TScheduler*		iScheduler;
 
-	union
-		{
-		TUint64		iLastTimestamp64;			// NKern::Timestamp() value at last reschedule or timestamp sync
-		TUint32		iLastTimestamp32[2];
-		};
-	union
-		{
-		TUint64		iReschedCount64;
-		TUint32		iReschedCount32[2];
-		};
+	TInt			iDeferShutdown;				// counts reasons why this CPU can't shut down
+	TInt			iRdyThreadCount;			// number of ready threads excluding idle thread
+	TUint16			iPriClassThreadCount[KNumPriClasses];
 
-	TAny*			iExtras[24];				// Space for platform-specific extras
+	TUint64HL		iLastTimestamp;				// timestamp at which last reschedule occurred
+	TUint64HL		iReschedCount;
 
 	TGenericIPI*	iNextIPI;					// next generic IPI to run on this CPU
 	NThread*		iInitialThread;				// Initial (idle) thread on this CPU
@@ -485,15 +604,31 @@
 
 	TUint64			iSpinLockOrderCheck;		// bitmask showing which spinlock orders currently held
 
-	TUint32			iSubSchedulerPadding[8];
+	TSubSchedulerX	iSSX;						// platform specific extras
+
+	volatile TAny*	iUncached;					// points to platform specific uncached data structure
+	TUint 			iMadeReadyCounter;			// Number of times this core made a thread ready.
+
+	TUint 			iMadeUnReadyCounter;		// Number of times this core made a thread unready.
+	TUint 			iTimeSliceExpireCounter;	// Number of times this core hass reschedualed due to time slice exireation.
+
+	TUint32			iSubSchedulerPadding[70];
+	SDblQue			iLbQ;						// threads to be considered by subsequent periodic load balance
+
+	TAny*			iSubSchedScratch[16];		// For use by code outside NKern
 	};
 
+const TInt KSubSchedulerShift = 10;				// log2(sizeof(TSubScheduler))
+
 __ASSERT_COMPILE(!(_FOFF(TSubScheduler,iExIDfcLock)&7));
 __ASSERT_COMPILE(!(_FOFF(TSubScheduler,iEventHandlerLock)&7));
 __ASSERT_COMPILE(!(_FOFF(TSubScheduler,iReadyListLock)&7));
-__ASSERT_COMPILE(!(_FOFF(TSubScheduler,iLastTimestamp64)&7));
-__ASSERT_COMPILE(!(_FOFF(TSubScheduler,iReschedCount64)&7));
-__ASSERT_COMPILE(sizeof(TSubScheduler)==512);	// make it a nice power of 2 size for easy indexing
+__ASSERT_COMPILE(!(_FOFF(TSubScheduler,iLastTimestamp)&7));
+__ASSERT_COMPILE(!(_FOFF(TSubScheduler,iReschedCount)&7));
+__ASSERT_COMPILE(sizeof(TSubSchedulerX)==256);
+__ASSERT_COMPILE(sizeof(TSubScheduler)==(1<<KSubSchedulerShift));	// make it a nice power of 2 size for easy indexing
+
+struct SCoreControlAction;
 
 /**
 @internalComponent
@@ -505,22 +640,64 @@
 	static void Reschedule();
 	IMPORT_C static TScheduler* Ptr();
 	inline void SetProcessHandler(TLinAddr aHandler) {iProcessHandler=aHandler;}
+	void PeriodicBalance();
+	TBool ReBalance(SDblQue& aQ, TBool aCC);
+	void CCReactivate(TUint32 aMore);
+	void CCIpiReactivate();
+	void CCRequest();
+	void GetLbThreads(SDblQue& aQ);
+	void CCUnDefer();
+	void ChangeThreadAcceptCpus(TUint32 aNewMask);
+	TUint32 ReschedInactiveCpus(TUint32 aMask);
+	void InitCCAction(SCoreControlAction& aA);
+	TUint32 ModifyCCState(TUint32 aAnd, TUint32 aXor);
+	TUint32 CpuShuttingDown(TSubScheduler& aSS);
+	void AllCpusIdle();
+	void FirstBackFromIdle();
+
+	void InitLB();
+	void StartRebalanceTimer(TBool aRestart);
+	void StopRebalanceTimer(TBool aTemp);
+	static void BalanceTimerExpired(TAny*);
+	static void StartPeriodicBalancing();
+	static void CCSyncDone(TAny*);
+	static void CCReactivateDfcFn(TAny*);
+	static void CCRequestDfcFn(TAny*);
+	static void CCIpiReactivateFn(TAny*);
+	static TDfcQue* RebalanceDfcQ();
+	static NThread* LBThread();
+	static TBool CoreControlSupported();
+	static void CCInitiatePowerUp(TUint32 aCores);
+	static void CCIndirectPowerDown(TAny*);
 public:
 	TLinAddr		iMonitorExceptionHandler;
 	TLinAddr		iProcessHandler;
 
-	TLinAddr		iRescheduleHook;
-	TUint32			iActiveCpus1;				// bit n set if CPU n is accepting unlocked threads
+	volatile TUint32 iThreadAcceptCpus;			// bit n set if CPU n is accepting unlocked threads
+	volatile TUint32 iIpiAcceptCpus;			// bit n set if CPU n is accepting generic IPIs
+	volatile TUint32 iCpusComingUp;				// bit n set if CPU n is in the process of powering up
+	volatile TUint32 iCpusGoingDown;			// bit n set if CPU n is in the process of powering down and is no longer accepting IPIs
+	volatile TInt	 iCCDeferCount;				// >0 means CPUs on the way down will stop just before the 'point of no return'
+	volatile TUint32 iCCSyncCpus;				// bit n set if CPU n has not yet observed a change to iThreadAcceptCpus
+	volatile TUint32 iCCReactivateCpus;
+	volatile TUint32 iCCState;
 
-	TUint32			iActiveCpus2;				// bit n set if CPU n is accepting generic IPIs
 	TInt			iNumCpus;					// number of CPUs under the kernel's control
+	TLinAddr		iRescheduleHook;
+
+	SDblQue			iGenIPIList;				// list of active generic IPIs
+	TSpinLock		iGenIPILock;				// spin lock protects iGenIPIList, also iIpiAcceptCpus, iCpusComingUp, iCpusGoingDown, iCCDeferCount
 
 	TSubScheduler*	iSub[KMaxCpus];				// one subscheduler per CPU
 
-	TAny*			iExtras[24];				// Space for platform-specific extras
+	TAny*			iSchedScratch[16];			// for use by code outside NKern
+
+	TSchedulerX		iSX;						// platform specific extras
 
 	NFastMutex		iLock;						// the 'system lock' fast mutex
 
+	TSpinLock		iIdleBalanceLock;
+
 	TSpinLock		iIdleSpinLock;				// lock to protect list of DFCs to be run on idle
 
 	SDblQue			iIdleDfcs;					// list of DFCs to run when all CPUs go idle
@@ -528,27 +705,42 @@
 	TUint32			iCpusNotIdle;				// bitmask - Bit n set => CPU n is not idle
 	TUint8			iIdleGeneration;			// Toggles between 0 and 1 each time iIdleDfcs list is spilled to a CPU IDFC queue
 	TUint8			iIdleSpillCpu;				// Which CPU last spilled the iIdleDfcs list to its IDFC queue
-	TUint8			iTSchedulerSpare1;
-	TUint8			iTSchedulerSpare2;
+	TUint8			iLbCounter;
+	volatile TUint8	iNeedBal;
 
 	TUint32			iIdleGenerationCount;		// Incremented each time iIdleDfcs list is spilled to a CPU IDFC queue
-	TUint32			i_Scheduler_Padding[3];
+	TDfcQue*		iRebalanceDfcQ;
+
+	TSpinLock		iEnumerateLock;				// lock to protect iAllThreads, iAllGroups
+	SIterDQ			iAllThreads;				// list of all nanokernel threads in order of creation
+	SIterDQ			iAllGroups;					// list of all thread groups in order of creation
+	TSpinLock		iBalanceListLock;			// lock to protect iBalanceList
+	TUint64			iLastBalanceTime;			// time at which last rebalance occurred
+	SDblQue			iBalanceList;				// list of threads/groups for load balancing
+	NTimer			iBalanceTimer;				// triggers periodic rebalancing
+	TDfc			iCCSyncIDFC;				// runs when a change to iThreadAcceptCpus has been observed by all CPUs
+	TDfc			iCCReactivateDfc;			// runs when a reschedule IPI is targeted to an inactive CPU
 
-	// For EMI support - HOPEFULLY THIS CAN DIE
-	NThread* iSigma;	
-	TDfc* iEmiDfc;
-	TUint32 iEmiMask;
-	TUint32 iEmiState;
-	TUint32 iEmiDfcTrigger;
-	TBool iLogging;
-	TAny* iBufferStart;
-	TAny* iBufferEnd;
-	TAny* iBufferTail;
-	TAny* iBufferHead;
+	TUint32			iCCRequestLevel;			// Number of active cores last requested
+	volatile TUint32 iCCIpiReactivate;			// Cores to be woken up because of IPIs
+
+	TDfc			iCCRequestDfc;				// runs when a request is made to change the number of active cores
+	TDfc			iCCPowerDownDfc;			// runs when indirect power down of core(s) is required
+	TDfc			iCCIpiReactIDFC;			// runs when an IPI needs to wake up a core
+
+	TSubScheduler*	iPoweringOff;				// CPU last to power off
+	TUint32			iDetachCount;				// detach count before power off
+
+	TUint32			i_Scheduler_Padding[54];
 	};
 
+__ASSERT_COMPILE(!(_FOFF(TScheduler,iGenIPILock)&7));
 __ASSERT_COMPILE(!(_FOFF(TScheduler,iIdleSpinLock)&7));
-__ASSERT_COMPILE(sizeof(TScheduler)==512);
+__ASSERT_COMPILE(!(_FOFF(TScheduler,iIdleBalanceLock)&7));
+__ASSERT_COMPILE(!(_FOFF(TScheduler,iEnumerateLock)&7));
+__ASSERT_COMPILE(!(_FOFF(TScheduler,iBalanceListLock)&7));
+__ASSERT_COMPILE(sizeof(TSchedulerX)==16*4);
+__ASSERT_COMPILE(sizeof(TScheduler)==1024);
 
 extern TScheduler TheScheduler;
 extern TSubScheduler TheSubSchedulers[KMaxCpus];
@@ -574,11 +766,6 @@
 /**
 @internalComponent
 */
-extern "C" void send_resched_ipis(TUint32 aMask);
-
-/**
-@internalComponent
-*/
 extern "C" void send_resched_ipi(TInt aCpu);
 
 /**
@@ -586,9 +773,6 @@
 */
 extern "C" void send_resched_ipi_and_wait(TInt aCpu);
 
-
-#include <nk_plat.h>
-
 /**
 Call with kernel locked
 
@@ -619,6 +803,20 @@
 	return aAffinity==(TUint32)aCpu;
 	}
 
+/** @internalComponent */
+inline TBool CheckCpuAgainstAffinity(TInt aCpu, TUint32 aAffinity, TUint32 aActive)
+	{
+	if (aAffinity & NTHREADBASE_CPU_AFFINITY_MASK)
+		return aActive & aAffinity & (1<<aCpu);
+	return (aAffinity==(TUint32)aCpu) && (aActive & (1<<aCpu));
+	}
+
+/** @internalComponent */
+inline TUint32 AffinityToMask(TUint32 aAffinity)
+	{
+	return (aAffinity & NTHREADBASE_CPU_AFFINITY_MASK) ? (aAffinity & ~NTHREADBASE_CPU_AFFINITY_MASK) : (1u<<aAffinity);
+	}
+
 /**
 @internalComponent
 */
@@ -694,7 +892,20 @@
 public:
 	STimerQ			iTickQ[ENumTimerQueues];	/**< @internalComponent */	// NOTE: the order of member data is important
 	TUint32			iPresent;					/**< @internalComponent */	// The assembler code relies on it
-	TUint32			iMsCount;					/**< @internalComponent */
+
+	/**
+	This member is intended for use by ASSP/variant interrupt code as a convenient
+	location to store the value of a free running counter at the point where the
+	system tick is started.
+	@publishedPartner
+	@prototype
+	*/
+	TUint32			iFRCOffset;
+
+	union {
+		TUint32			iMsCount;				/**< @internalComponent */
+		TUint64			iMsCount64;				/**< @internalComponent */
+		};
 	SDblQue			iHoldingQ;					/**< @internalComponent */
 	SDblQue			iOrderedQ;					/**< @internalComponent */
 	SDblQue			iCompletedQ;				/**< @internalComponent */
@@ -753,17 +964,6 @@
 /**
 @internalComponent
 */
-class TGenIPIList : public SDblQue
-	{
-public:
-	TGenIPIList();
-public:
-	TSpinLock			iGenIPILock;
-	};
-
-/**
-@internalComponent
-*/
 class TCancelIPI : public TGenericIPI
 	{
 public:
@@ -797,23 +997,24 @@
 /**
 @internalComponent
 */
-#define MASK_NO_FAST_MUTEX 0x1
-#define MASK_CRITICAL 0x2
-#define MASK_NO_CRITICAL 0x4
-#define MASK_KERNEL_LOCKED 0x8
-#define MASK_KERNEL_UNLOCKED 0x10
-#define MASK_KERNEL_LOCKED_ONCE 0x20
-#define MASK_INTERRUPTS_ENABLED 0x40
-#define MASK_INTERRUPTS_DISABLED 0x80
-#define MASK_SYSTEM_LOCKED 0x100
-#define MASK_NOT_ISR 0x400
-#define MASK_NOT_IDFC 0x800 
-#define MASK_NOT_THREAD 0x1000
-#define MASK_NO_CRITICAL_IF_USER 0x2000
-#define MASK_THREAD_STANDARD ( MASK_NO_FAST_MUTEX | MASK_KERNEL_UNLOCKED | MASK_INTERRUPTS_ENABLED | MASK_NOT_ISR | MASK_NOT_IDFC )
-#define MASK_THREAD_CRITICAL ( MASK_THREAD_STANDARD | MASK_CRITICAL )
-#define MASK_ALWAYS_FAIL 0x4000
-#define	MASK_NO_RESCHED 0x8000
+#define	MASK_NO_FAST_MUTEX			0x1
+#define	MASK_CRITICAL				0x2
+#define	MASK_NO_CRITICAL			0x4
+#define	MASK_KERNEL_LOCKED			0x8
+#define	MASK_KERNEL_UNLOCKED		0x10
+#define	MASK_KERNEL_LOCKED_ONCE		0x20
+#define	MASK_INTERRUPTS_ENABLED		0x40
+#define	MASK_INTERRUPTS_DISABLED	0x80
+#define	MASK_SYSTEM_LOCKED			0x100
+#define	MASK_NOT_ISR				0x400
+#define	MASK_NOT_IDFC				0x800 
+#define	MASK_NOT_THREAD				0x1000
+#define	MASK_NO_CRITICAL_IF_USER	0x2000
+#define	MASK_ALWAYS_FAIL			0x4000
+#define	MASK_NO_RESCHED				0x8000
+#define	MASK_NO_KILL_OR_SUSPEND		0x10000
+#define	MASK_THREAD_STANDARD		( MASK_NO_FAST_MUTEX | MASK_KERNEL_UNLOCKED | MASK_INTERRUPTS_ENABLED | MASK_NOT_ISR | MASK_NOT_IDFC )
+#define	MASK_THREAD_CRITICAL		( MASK_THREAD_STANDARD | MASK_CRITICAL )
 
 #if defined(__STANDALONE_NANOKERNEL__) || (!defined (__KERNEL_APIS_CONTEXT_CHECKS_WARNING__)&&!defined (__KERNEL_APIS_CONTEXT_CHECKS_FAULT__))
 #define CHECK_PRECONDITIONS(mask,function)
--- a/kernel/eka/include/nkernsmp/nkern.h	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/include/nkernsmp/nkern.h	Fri Apr 16 16:24:37 2010 +0300
@@ -37,7 +37,7 @@
 /** @internalComponent */
 IMPORT_C void NKFault(const char* file, TInt line);
 /** @internalComponent */
-void NKIdle(TInt aStage);
+void NKIdle(TUint32 aStage);
 }
 
 /**
@@ -144,6 +144,7 @@
 		EOrderThread			=0x91u,		// Thread locks
 		EOrderFastMutex			=0x98u,		// Fast mutex locks
 		EOrderEventHandlerTied	=0x9Cu,		// Event handler tied lock
+		EOrderEnumerate			=0x9Du,		// Thread/Group enumeration lists
 		EOrderGenericPreHigh0	=0x9Eu,		// Device driver spin locks, high range
 		EOrderGenericPreHigh1	=0x9Fu,		// Device driver spin locks, high range
 
@@ -810,13 +811,15 @@
 	};
 
 // Thread iAttributes Constants
-const TUint8 KThreadAttImplicitSystemLock=1;	/**< @internalComponent */
-const TUint8 KThreadAttAddressSpace=2;			/**< @internalComponent */
-const TUint8 KThreadAttLoggable=4;				/**< @internalComponent */
+const TUint8 KThreadAttImplicitSystemLock=1;		/**< @internalComponent */
+const TUint8 KThreadAttAddressSpace=2;				/**< @internalComponent */
+const TUint8 KThreadAttLoggable=4;					/**< @internalComponent */
 
 
 // Thread CPU
-const TUint32 KCpuAffinityAny=0xffffffffu;		/**< @internalComponent */
+const TUint32 KCpuAffinityAny=0xffffffffu;			/**< @internalComponent */
+const TUint32 KCpuAffinityPref=0x40000000u;			/**< @internalComponent */
+const TUint32 KCpuAffinityTransient=0x20000000u;	/**< @internalComponent */
 
 /** Information needed for creating a nanothread.
 
@@ -849,6 +852,7 @@
 struct SNThreadGroupCreateInfo
 	{
 	TUint32 iCpuAffinity;
+	TDfc* iDestructionDfc;
 	};
 
 /**	Constant for use with NKern:: functions which release a fast mutex as well
@@ -859,27 +863,37 @@
 */
 #define	SYSTEM_LOCK		(NFastMutex*)0
 
-
 /** Idle handler function
 	Pointer to a function which is called whenever a CPU goes idle
 
 	@param	aPtr	The iPtr stored in the SCpuIdleHandler structure
-	@param	aStage	If positive, the number of processors still active
-					If zero, indicates all processors are now idle
-					-1 indicates that postamble processing is required after waking up
+	@param	aStage	Bits 0-7 give a bitmask of CPUs now active, i.e. 0 means all processors now idle
+					Bit 31 set indicates that the current core can now be powered down
+					Bit 30 set indicates that other cores still remain to be retired
+					Bit 29 set indicates that postamble processing is required after waking up
+	@param	aU		Points to some per-CPU uncached memory used for handshaking during power down/power up
 
-	@publishedPartner
-	@prototype
+	@internalComponent
 */
-typedef void (*TCpuIdleHandlerFn)(TAny* aPtr, TInt aStage);
+typedef void (*TCpuIdleHandlerFn)(TAny* aPtr, TUint32 aStage, volatile TAny* aU);
 
 /** Idle handler structure
 
-	@publishedPartner
-	@prototype
+	@internalComponent
 */
 struct SCpuIdleHandler
 	{
+	/**
+	Defined flag bits in aStage parameter
+	*/
+	enum
+		{
+		EActiveCpuMask=0xFFu,
+		EPostamble=1u<<29,		// postamble needed
+		EMore=1u<<30,			// more cores still to be retired
+		ERetire=1u<<31,			// this core can now be retired
+		};
+
 	TCpuIdleHandlerFn	iHandler;
 	TAny*				iPtr;
 	volatile TBool		iPostambleRequired;
@@ -988,6 +1002,7 @@
 	IMPORT_C static void ThreadRelease(NThread* aThread, TInt aReturnValue, NFastMutex* aMutex);
 	IMPORT_C static void ThreadSetPriority(NThread* aThread, TInt aPriority);
 	IMPORT_C static void ThreadSetPriority(NThread* aThread, TInt aPriority, NFastMutex* aMutex);
+	static void ThreadSetNominalPriority(NThread* aThread, TInt aPriority);
 	IMPORT_C static void ThreadRequestSignal(NThread* aThread);
 	IMPORT_C static void ThreadRequestSignal(NThread* aThread, NFastMutex* aMutex);
 	IMPORT_C static void ThreadRequestSignal(NThread* aThread, TInt aCount);
@@ -1013,6 +1028,7 @@
 	static TInt QueueUserModeCallback(NThreadBase* aThread, TUserModeCallback* aCallback);	/**< @internalComponent */
 	static void MoveUserModeCallbacks(NThreadBase* aSrcThread, NThreadBase* aDestThread);	/**< @internalComponent */
 	static void CancelUserModeCallbacks();												/**< @internalComponent */
+	static void JumpTo(TInt aCpu);														/**< @internalComponent */
 
 	// Thread Groups
 	IMPORT_C static TInt GroupCreate(NThreadGroup* aGroup, SNThreadGroupCreateInfo& aInfo);
@@ -1104,6 +1120,7 @@
 	IMPORT_C static NThread* CurrentThread();
 	IMPORT_C static TInt CurrentCpu();										/**< @internalComponent */
 	IMPORT_C static TInt NumberOfCpus();									/**< @internalComponent */
+	IMPORT_C static void SetNumberOfActiveCpus(TInt aNumber);
 	IMPORT_C static void LockSystem();
 	IMPORT_C static void UnlockSystem();
 	IMPORT_C static TBool FlashSystem();
@@ -1130,7 +1147,8 @@
 	static TInt BootAP(volatile SAPBootInfo* aInfo);
 	IMPORT_C static TBool KernelLocked(TInt aCount=0);						/**< @internalTechnology */
 	IMPORT_C static NFastMutex* HeldFastMutex();							/**< @internalTechnology */
-	static void Idle();	
+	static void Idle();
+	static void DoIdle();
 	IMPORT_C static SCpuIdleHandler* CpuIdleHandler();						/**< @internalTechnology */
 	static void NotifyCrash(const TAny* a0, TInt a1);						/**< @internalTechnology */
 	IMPORT_C static TBool Crashed();
@@ -1232,5 +1250,27 @@
 	volatile TInt iFlag;
 	};
 
+
+/**
+@internalComponent
+*/
+class TCoreCycler
+	{
+public:
+	TCoreCycler();
+	TInt Next();
+private:
+	void Init();
+private:
+	TUint32			iCores;
+	TUint32			iRemain;
+	TInt			iInitialCpu;
+	TInt			iCurrentCpu;
+	NThreadGroup*	iG;
+	TInt			iFrz;
+	};
+
+
+
 #include <ncern.h>
 #endif
--- a/kernel/eka/include/nkernsmp/x86/nk_plat.h	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/include/nkernsmp/x86/nk_plat.h	Fri Apr 16 16:24:37 2010 +0300
@@ -27,23 +27,46 @@
 #define __NK_X86_H__
 #include <nk_cpu.h>
 
+class TSubScheduler;
+class TScheduler;
+struct TX86Tss;
+
 // TSubScheduler member data
-#define	i_IrqCount			iExtras[9]		// count of interrupts handled
-#define	i_ExcInfo			iExtras[10]		// pointer to exception info for crash debugger
-#define	i_CrashState		iExtras[11]		// 0=normal, 1=this CPU faulted, 2=this CPU has received an NMI and halted
-#define	i_APICID			iExtras[12]		// Local APIC ID for this CPU (starts at -1)
-#define	i_IrqNestCount		iExtras[13]		// IRQ nest count for this CPU (starts at -1)
-#define	i_IrqStackTop		iExtras[14]		// Top of IRQ stack for this CPU
-#define	i_Tss				iExtras[15]		// Address of TSS for this CPU
-#define	i_TimerMultF		iExtras[16]		// Timer frequency / Max Timer frequency * 2^32
-#define	i_TimerMultI		iExtras[17]		// Max Timer frequency / Timer frequency * 2^24
-#define	i_CpuMult			iExtras[18]		// CPU frequency / Max CPU frequency * 2^32
-#define	i_TimestampOffset	iExtras[20]		// 64 bit value to add to CPU TSC to give NKern::Timestamp()
-#define	i_TimestampOffsetL	iExtras[20]		// 
-#define	i_TimestampOffsetH	iExtras[21]		// 
+struct TSubSchedulerX
+	{
+	TUint32				iSSXP[9];
+	volatile TUint32	iIrqCount;				// count of interrupts handled
+	TAny*				iExcInfo;				// pointer to exception info for crash debugger
+	volatile TInt		iCrashState;			// 0=normal, 1=this CPU faulted, 2=this CPU has received an NMI and halted
+	TUint32				iAPICID;				// Local APIC ID for this CPU (starts at -1)
+	volatile TInt		iIrqNestCount;			// IRQ nest count for this CPU (starts at -1)
+	TLinAddr			iIrqStackTop;			// Top of IRQ stack for this CPU
+	TX86Tss*			iTss;					// Address of TSS for this CPU
+	volatile TUint32	iCpuFreqM;				// CPU frequency / Max CPU frequency (mantissa, bit 31=1) f/fmax=M/2^(S+32) <=1
+	volatile TInt		iCpuFreqS;				// CPU frequency / Max CPU frequency (shift)
+	volatile TUint32	iCpuPeriodM;			// Max CPU frequency / CPU frequency (mantissa, bit 31=1) fmax/f=M/2^S >=1
+	volatile TInt		iCpuPeriodS;			// Max CPU frequency / CPU frequency (shift)
+	volatile TUint32	iNTimerFreqM;			// Nominal Timer frequency / Max Timer frequency (mantissa, bit 31=1) f/fmax=M/2^(S+32) <=1
+	volatile TInt		iNTimerFreqS;			// Nominal Timer frequency / Max Timer frequency (shift)
+	volatile TUint32	iNTimerPeriodM;			// Nominal Max Timer frequency / Timer frequency (mantissa, bit 31=1) fmax/f=M/2^S >=1
+	volatile TInt		iNTimerPeriodS;			// Nominal Max Timer frequency / Timer frequency (shift)
+	volatile TUint32	iTimerFreqM;			// Timer frequency / Max Timer frequency (mantissa, bit 31=1) f/fmax=M/2^(S+32) <=1
+	volatile TInt		iTimerFreqS;			// Timer frequency / Max Timer frequency (shift)
+	volatile TUint32	iTimerPeriodM;			// Max Timer frequency / Timer frequency (mantissa, bit 31=1) fmax/f=M/2^S >=1
+	volatile TInt		iTimerPeriodS;			// Max Timer frequency / Timer frequency (shift)
+	volatile TUint64HL	iTimestampOffset;		// 64 bit value to add to CPU TSC to give NKern::Timestamp()
+
+	TUint32				iSSXP2[32];
+	TUint64				iSSXP3;					// one 64 bit value to guarantee alignment
+	};
 
 // TScheduler member data
-#define	i_TimerMax		iExtras[16]		// Maximum per-CPU timer frequency (after prescaling)
+struct TSchedulerX
+	{
+	TUint64				iTimerMax;				// Maximum per-CPU timer frequency (after prescaling)
+	TUint32				iSXP[14];
+	};
+
 
 #define CRASH_IPI_VECTOR			0x27
 #define RESCHED_IPI_VECTOR			0x28
@@ -68,8 +91,7 @@
 	{
 public:
 	TInt Create(SNThreadCreateInfo& anInfo, TBool aInitial);
-	inline void Stillborn()
-		{}
+	void Stillborn();
 	void GetUserContext(TX86RegSet& aContext, TUint32& aAvailRegMask);
 	void SetUserContext(const TX86RegSet& aContext, TUint32& aRegMask);
 	void GetSystemContext(TX86RegSet& aContext, TUint32& aAvailRegMask);
@@ -187,6 +209,11 @@
 #define smp_mb()	mb()
 
 
+/**
+@internalComponent
+*/
+extern "C" void send_resched_ipis(TUint32 aMask);
+
 
 // End of file
 #endif
--- a/kernel/eka/include/opensystemtrace.h	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/include/opensystemtrace.h	Fri Apr 16 16:24:37 2010 +0300
@@ -19,6 +19,11 @@
 
 #include <opensystemtrace_types.h>
 
+/**
+This macro defines the version of the Open System Trace instrumentation API.
+*/
+#define OST_INSTRUMENTATION_API_VERSION 2.1.0
+
 
 /**
 Methods for tracing from user side.
@@ -117,7 +122,9 @@
 #define OST_TRACE_CATEGORY_NONE 0x00000000
 
 /**
-Preprocessor category for production traces
+Preprocessor category for traces that should be compiled
+into all builds including UREL. As a result these traces
+will end up in production images used by consumers.
 */
 #define OST_TRACE_CATEGORY_PRODUCTION 0x00000001
 
@@ -132,6 +139,12 @@
 #define OST_TRACE_CATEGORY_PERFORMANCE_MEASUREMENT 0x00000004
 
 /**
+Preprocessor category for traces that by default should only 
+be compiled into UDEB builds.
+*/
+#define OST_TRACE_CATEGORY_DEBUG 0x00000008
+
+/**
 Preprocessor level for all traces on.
 This should not be used from traces
 */
@@ -145,13 +158,24 @@
 
 
 /**
-The default preprocessor category is RND
-Component may override this by defining
+The default preprocessor categories are defined here.
+A component may override this by defining
 OST_TRACE_CATEGORY before including this file
+
+The RND category is defined for UREL and UDEB to 
+preserve source compatibility.
 */
-#if !defined( OST_TRACE_CATEGORY )
-#define OST_TRACE_CATEGORY OST_TRACE_CATEGORY_RND
-#endif
+#ifndef OST_TRACE_CATEGORY
+#ifdef _DEBUG
+#define OST_TRACE_CATEGORY (OST_TRACE_CATEGORY_RND | \
+                            OST_TRACE_CATEGORY_PRODUCTION | \
+                            OST_TRACE_CATEGORY_DEBUG)
+#else // _DEBUG
+#define OST_TRACE_CATEGORY (OST_TRACE_CATEGORY_RND | \
+                            OST_TRACE_CATEGORY_PRODUCTION)
+#endif // _DEBUG
+#endif // OST_TRACE_CATEGORY
+
 
 /**
 Trace with no parameters
--- a/kernel/eka/include/rm_debug_api.h	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/include/rm_debug_api.h	Fri Apr 16 16:24:37 2010 +0300
@@ -1638,7 +1638,7 @@
 inline TInt RSecuritySvrSession::Connect(const TVersion aVersion)
 	{
 	// default message slots for the server
-	const TUint KDefaultMessageSlots = 4;
+	const TUint KDefaultMessageSlots = 32;
 	TInt retry=2;
 	for (;;)
 		{
--- a/kernel/eka/include/sm_debug_api.h	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/include/sm_debug_api.h	Fri Apr 16 16:24:37 2010 +0300
@@ -237,7 +237,7 @@
 				IMPORT_C static TInt TestAPI(const TListItem* aItem);
 
 			public:	
-				static TInt ExitPoint(const TInt aReturnValue);
+				IMPORT_C static TInt ExitPoint(const TInt aReturnValue);
 
 			private:
 				/** Code segment list routines */
--- a/kernel/eka/include/u32hal.h	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/include/u32hal.h	Fri Apr 16 16:24:37 2010 +0300
@@ -368,6 +368,30 @@
 	};
 
 
+/**
+@internalComponent
+*/
+struct SCpuStates
+	{
+	TUint32	iTA;
+	TUint32 iIA;
+	TUint32	iCU;
+	TUint32	iGD;
+	TInt	iDC;
+	TUint32	iSC;
+	TUint32	iRC;
+	TUint32	iCCS;
+	TUint8	iPO;
+	TUint8	iSpare1;
+	TUint8	iSpare2;
+	TUint8	iSpare3;
+	TUint32	iPODC;
+	TInt	iDS[8];
+	TUint32	iUDC[8];
+	TUint32	iUAC[8];
+	TUint32	iOP[8];
+	TUint32	iF[8];
+	};
 
 
 /**
@@ -396,6 +420,8 @@
 	EKernelHalFloatingPointSystemId,
 	EKernelHalLockThreadToCpu,
 	EKernelHalConfigFlags,
+	EKernelHalCpuStates,
+	EKernelHalSetNumberOfCpus,
 	};
 
 
@@ -2868,6 +2894,7 @@
 	EPagingBmDeleteNotifyDataPage,
 	EPagingBmReadDataMedia,
 	EPagingBmWriteDataMedia,
+	EPagingBmRejuvenate,  // only implemented on FMM
 		
 	EMaxPagingBm
 	};
--- a/kernel/eka/include/ws_std.h	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/include/ws_std.h	Fri Apr 16 16:24:37 2010 +0300
@@ -79,6 +79,7 @@
 	{
 	TKeyData iKeyData;
     TInt iType;
+    TUint8 iPointerNumber;
     TPoint iMousePos;
 	TSglQueLink iLink;
 	};
--- a/kernel/eka/kernel/arm/bootmain.s	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/kernel/arm/bootmain.s	Fri Apr 16 16:24:37 2010 +0300
@@ -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	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/kernel/arm/cache_external.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -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));
@@ -552,7 +558,7 @@
 		for (index = 0 ; index <indexNo ; index++)
 			{
 		    L220_COMMAND_PREAMBLE;
-            *ctrlReg = (way<<29) | (index<<5); //this will clean,purge or flush cache line
+		    *ctrlReg = (way<<ARML2C_WayShift) | (index<<ARML2C_IndexShift); //this will maintain a single cache line
             L220_COMMAND_POSTAMBLE;
 			PL310_SPIN_FLASH;
 			}
--- a/kernel/eka/kernel/arm/cache_maintenance.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/kernel/arm/cache_maintenance.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -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: 
@@ -1096,33 +1116,11 @@
 void TCacheBroadcast::DoThreadOp()
 	{
 	CHECK_PRECONDITIONS(MASK_THREAD_STANDARD,"TCacheBroadcast::DoThreadOp");
-	NKern::ThreadEnterCS();
-	NThreadGroup* g = NKern::LeaveGroup();
-	TInt frz = NKern::FreezeCpu();
-	if (frz)
-		__crash();	// already frozen so won't be able to migrate :-(
-	TInt orig_cpu = NKern::CurrentCpu();
-	TInt ncpu = NKern::NumberOfCpus();
-	TInt cpu = orig_cpu;
-	TUint32 orig_affinity = 0;
-	do	{
-		TUint32 affinity = NKern::ThreadSetCpuAffinity(NKern::CurrentThread(), (TUint32)cpu);
-		if (cpu == orig_cpu)
-			{
-			orig_affinity = affinity;
-			NKern::EndFreezeCpu(frz);
-			}
-		TInt cpu_now = NKern::CurrentCpu();
-		if (cpu_now != cpu)
-			__crash();
+	TCoreCycler cycler;
+	while (cycler.Next()==KErrNone)
+		{
 		Isr(this);
-		if (++cpu == ncpu)
-			cpu = 0;
-		} while (cpu != orig_cpu);
-	NKern::ThreadSetCpuAffinity(NKern::CurrentThread(), orig_affinity);
-	if (g)
-		NKern::JoinGroup(g);
-	NKern::ThreadLeaveCS();
+		}
 	}
 
 void InternalCache::Invalidate(TUint aMask, TLinAddr aBase, TUint aSize)
--- a/kernel/eka/kernel/arm/cinit.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/kernel/arm/cinit.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -22,11 +22,17 @@
 #include <arm_scu.h>
 #endif
 
-extern "C" void NKIdle(TInt aStage)
+extern "C" void NKIdle(TUint32 aStage)
 	{
 	SCpuIdleHandler* cih = NKern::CpuIdleHandler();
+#ifdef __SMP__
+	TSubScheduler& ss = SubScheduler();
+	if (cih && cih->iHandler)
+		(*cih->iHandler)(cih->iPtr, aStage, ss.iUncached);
+#else
 	if (cih && cih->iHandler)
 		(*cih->iHandler)(cih->iPtr, aStage);
+#endif
 	else if (K::PowerModel)
 		K::PowerModel->CpuIdle();
 	else
@@ -56,6 +62,17 @@
 				__KTRACE_OPT(KBOOT,Kern::Printf("VariantInitialise returns %08x", p));
 				}
 			}
+#ifdef __SMP__
+		SVariantInterfaceBlock* vib = (SVariantInterfaceBlock*)K::VariantData[0];
+		TSuperPage& spg = TheSuperPage();
+		for (i=0; i<KMaxCpus; ++i)
+			{
+			if (!vib->iUncached[i])
+				{
+				vib->iUncached[i] = (UPerCpuUncached*)(spg.iAPBootPageLin + 0xE00 + (i<<6));
+				}
+			}
+#endif
 		}
 	return KErrNone;
 	}
--- a/kernel/eka/kernel/arm/ckernel.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/kernel/arm/ckernel.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -357,8 +357,8 @@
 	TSubScheduler* ss = &SubScheduler();
 	if (!ss)
 		ss = &TheSubSchedulers[0];
-	ss->i_ExcInfo = aExcInfo;
-	SFullArmRegSet* a = (SFullArmRegSet*)ss->i_Regs;
+	ss->iSSX.iExcInfo = aExcInfo;
+	SFullArmRegSet* a = ss->iSSX.iRegs;
 	if (!a)
 		a = &DefaultRegSet;
 #else
--- a/kernel/eka/kernel/arm/cutils.cia	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/kernel/arm/cutils.cia	Fri Apr 16 16:24:37 2010 +0300
@@ -143,6 +143,7 @@
 	asm("adr	r2, __UartBase ");
 	asm("ldr	r1, [r1] ");
 	asm("ldr	r1, [r1, #%a0]" : : "i" _FOFF(TSuperPage,iDebugPort));
+	asm("and	r1, r1, #255 ");
 	asm("cmp	r1, #0 ");
 	asm("ldrne	r2, [r2, #4] ");
 	asm("ldreq	r2, [r2, #0] ");
@@ -352,7 +353,7 @@
 	__JUMP(ne,lr);						// if debugger entry point invalid, return
 #ifdef __SMP__
 	GET_RWNO_TID(,r0);
-	asm("ldr r0, [r0, #%a0]" : : "i" _FOFF(TSubScheduler,i_Regs));	// pass in address of stored registers
+	asm("ldr r0, [r0, #%a0]" : : "i" _FOFF(TSubScheduler,iSSX.iRegs));	// pass in address of stored registers
 #else
 	asm("ldr r0, __TheScheduler ");
 	asm("ldr r0, [r0, #%a0]" : : "i" _FOFF(TScheduler,i_Regs));	// pass in address of stored registers
--- a/kernel/eka/kernel/arm/cutils.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/kernel/arm/cutils.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -157,7 +157,7 @@
 		return;
 		}
 #ifdef __SMP__
-	SFullArmRegSet* regs = (SFullArmRegSet*)SubScheduler().i_Regs;
+	SFullArmRegSet* regs = SubScheduler().iSSX.iRegs;
 #else
 	SFullArmRegSet* regs = (SFullArmRegSet*)TheScheduler.i_Regs;
 #endif
--- a/kernel/eka/kernel/ekern.mmp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/kernel/ekern.mmp	Fri Apr 16 16:24:37 2010 +0300
@@ -27,14 +27,19 @@
 #include <variant.mmh>
 macro	__IN_KERNEL__
 
-target					VariantTarget(ekern,exe)
+#ifdef MEMORY_MODEL_OPTIONS
+#include		<memmodel.mmh>
+target			MemoryModelTarget(ekern,exe)
+firstlib		MemoryModelTarget(kc_exe,lib)
+#else
+target			VariantTarget(ekern,exe)
+firstlib		VariantTarget(kc_exe,lib)
+#endif
 
 targettype				exexp
 
 #include "kern_int.mmh"
 
-firstlib				VariantTarget(kc_exe,lib)
-
 // For emulator, specify newlib containing kernel-side definitions of new and delete operators
 // to override default library, containing user-side definitions, linked by toolchain for EXE and DLL targets
 #ifdef WINS
@@ -139,6 +144,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 +156,8 @@
 source					 sbtrace.cpp
 source					 stest.cpp
 source					 sshbuf.cpp smap.cpp
+source					 srandombuff.cpp
+source					 kerncorestats.cpp
 
 sourcepath				../klib
 source					dbase.cpp kdes8.cpp
--- a/kernel/eka/kernel/eventq.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/kernel/eventq.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -18,6 +18,7 @@
 #include <kernel/kern_priv.h>
 #include "execs.h"
 #include <e32btrace.h>
+#include <kerncorestats.h>
 /******************************************************
  * Event Queue
  ******************************************************/
@@ -115,6 +116,7 @@
 	BTraceContext4(BTrace::ERawEvent, BTrace::EKernelAddEvent ,(TUint32)aEvent.Type());
 #endif
 	NKern::FMWait(&K::EventQueueMutex);
+	KernCoreStats::AddEvent();
     TInt r=KErrOverflow;
 	TRawEvent *pE=K::EventHeadPtr+1;
 	if (pE>=K::EventBufferEnd)
--- a/kernel/eka/kernel/execs.txt	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/kernel/execs.txt	Fri Apr 16 16:24:37 2010 +0300
@@ -640,7 +640,6 @@
 	name = MathRandom
 	return = TUint32
 	kernel = Kern::Random
-	lock
 }
 
 slow {
@@ -1529,9 +1528,8 @@
 slow {
 	name = ThreadGetCpuTime
 	return = TInt
+	arg1 = TInt
 	arg2 = EXEC_INT64&
-	handle = thread
-	norelease
 }
 
 slow {
@@ -2431,6 +2429,20 @@
 	norelease
 }
 
+slow {
+	name = MathSecureRandom
+	return = TInt
+	arg1 = TDes8&
+}
+
+slow {
+	name = TimerAgainHighRes
+	arg2 = TRequestStatus&
+	arg3 = TInt
+	handle = timer
+}
+
+
 /******************************************************************************
  * End of normal executive functions
  ******************************************************************************/
@@ -2461,3 +2473,4 @@
 	return = TInt
 }
 
+
--- a/kernel/eka/kernel/exmoncommon.mmp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/kernel/exmoncommon.mmp	Fri Apr 16 16:24:37 2010 +0300
@@ -18,6 +18,9 @@
 #ifdef EPOC32
 
 #include <variant.mmh>
+#ifdef MEMORY_MODEL_OPTIONS
+#include <memmodel.mmh>
+#endif
 
 #define INCLUDE_EKERN_LIB
 #include "kern_int.mmh"
@@ -30,6 +33,13 @@
 sourcepath			../kernel
 source				smonitor.cpp
 
+#ifdef SMP
+sourcepath			../nkernsmp
+#else
+sourcepath			../nkern
+#endif
+source				nk_mon.cpp
+
 #if defined(MARM)
 #ifdef SMP
 sourcepath			../nkernsmp/arm
@@ -108,7 +118,11 @@
 noexportlibrary
 linkas				exmoncommon.dll
 
+#ifdef MEMORY_MODEL_OPTIONS
+target				MemoryModelTarget(exmoncommon,dll)
+#else
 target				VariantTarget(exmoncommon,dll)
+#endif
 
 deffile				exmoncommon.def
 
--- a/kernel/eka/kernel/kc_exe.mmp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/kernel/kc_exe.mmp	Fri Apr 16 16:24:37 2010 +0300
@@ -14,11 +14,17 @@
 // e32/kernel/kc_exe.mmp
 // 
 //
+#include		<variant.mmh>
 
-#include		<variant.mmh>
+#ifdef MEMORY_MODEL_OPTIONS
+#include		<memmodel.mmh>
+target			MemoryModelTarget(kc_exe,lib)
+#else
+target			VariantTarget(kc_exe,lib)
+#endif
+
 #include		"kern_int.mmh"
 
-target			VariantTarget(kc_exe,lib)
 targettype		klib
 
 #if defined(MARM)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kernel/eka/kernel/kerncorestats.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,609 @@
+// Copyright (c) 1994-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "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:
+// e32\kernel\kerncorestats.cpp
+// 
+// WARNING: This file contains some APIs which are internal and are subject
+//          to change without notice. Such APIs should therefore not be used
+//          outside the Kernel and Hardware Services package.
+//
+
+/** @file
+@internalComponent
+@prototype
+*/
+
+#include <kerncorestats.h>
+#include <nk_priv.h>
+
+// The following differ between unicore and smp, so use define to unify.
+#ifdef __SMP__
+#define FASTTIMER NKern::Timestamp()
+#define FASTTIMERFREQ NKern::TimestampFrequency()
+#define NUMCPUS TheScheduler.iNumCpus
+#else
+#define FASTTIMER (TUint64) NKern::FastCounter()
+#define FASTTIMERFREQ NKern::FastCounterFrequency()
+#define NUMCPUS 1
+#endif
+
+KernCoreStats* KernCoreStats::StatsData=NULL;
+TSpinLock KernCoreStats::Lock(TSpinLock::EOrderGenericIrqLow0);
+
+/**
+This method is called to initiate the KernCoreStats system.
+It can only be called once, and the is no way to disable the system again afterwards. 
+
+@param aStatSelection
+
+The bitfield defining which statistics to be collected.
+
+@return KErrNone on success. KErrInUse is the system has already been configured.
+*/
+EXPORT_C TInt KernCoreStats::Configure(TUint aStatSelection)
+	{
+	if (StatsData)
+		return KErrInUse;
+
+	TInt cores = NUMCPUS;
+
+// Calculate size needed
+
+	TInt dataSize = 0;
+	dataSize+= (aStatSelection & KStatsCoreTotalTimeInIdle)?	sizeof(TUint64)*cores*2 :0;
+	dataSize+= (aStatSelection & KStatsTimeCrossIdleAndActive)?	sizeof(TUint64)*(cores+1) :0;
+	dataSize+= (aStatSelection & KStatsCoreNumTimesInIdle)?		sizeof(TUint)*cores :0;
+	dataSize+= (aStatSelection & KStatsCoreTotalTimeInIdle)?	sizeof(TUint)*cores :0;
+	dataSize+= (aStatSelection & KStatsReadyStateChanges)?		sizeof(TUint)*2*cores:0;
+	dataSize+= (aStatSelection & KStatsNumTimeSliceExpire)?		sizeof(TUint)*cores:0;
+	
+// Create stats object object
+
+	KernCoreStats* kks = (KernCoreStats*) Kern::Alloc(sizeof(KernCoreStats) + dataSize); //coreTimesSize + offset);
+	if (kks==NULL)
+		return KErrNoMemory;
+
+	kks->Construct(aStatSelection);
+
+	__e32_memory_barrier();
+	StatsData = kks;	
+	return KErrNone;
+	};
+
+
+
+/**
+
+  This is a utility class, for calculating address offsets within kerncorestats, and offsets where the data will be copied
+  to at a later point.  This is made more complicated by every item being optional.
+
+@internal
+*/ 
+
+class DynamicObject
+	{
+public:
+	DynamicObject(TAny* aPointer);
+	void Add(TBool, TUint, TAny**, TUint, TUint16&);
+private:
+	TUint iOffset;
+	TUint* iPointer;
+	};
+
+
+/**
+ 
+Contructor which takes the address of the allocated memory object, for which items are to be added into.
+
+@internal
+*/
+
+DynamicObject::DynamicObject(TAny* aPointer)
+	:iOffset(0),
+	iPointer((TUint*) aPointer)
+	{};
+
+/**
+Workes out the address of a data item within the alloceted memory object, placeing it after the previosely added one.
+It also works out the target offset, for which the data will be used too fill, within a later provided data block.
+
+@param aFeatureEnabled
+
+A bool used to indicate if the feature is enabled or not.  If not, the refranced offsets are set to indicate the feature is disabled.
+
+@param aSizeInWordsP
+
+The amount of memory for which the object shall use within the internal data object.
+
+@aPointer
+
+The pointer to hold the location of the data item, within the internal object.
+If the feature is disabled, this is set to NULL.
+
+@param aSizeInWordsO
+
+The amount of memory for which the object shall use within the exteral data object.
+
+@param aOffset
+
+The offset to point to the location of the data item, within the external object.  
+This offset can be added to the provided pointer, to form a pointer to it.
+If the feature is disabled, this is set to KStatDisabled.
+
+
+@internal
+*/
+
+void DynamicObject::Add(TBool aFeatureEnabled, TUint aSizeInWordsP,TAny** aPointer, TUint aSizeInWordsO, TUint16& aOffset)
+	{
+	if (aFeatureEnabled)
+		{	
+		*aPointer = iPointer;
+		aOffset = (TUint16) iOffset;
+		iPointer+= aSizeInWordsP;
+		iOffset+=sizeof(TInt)* aSizeInWordsO;
+		}
+	else
+		{
+		*aPointer=NULL;
+		aOffset=KernCoreStats::KStatDisabled;
+		}
+	}	      
+
+/**
+@internal
+
+This second stage constructor is used initialise the KernCoreStats object.
+It is called by KernCoreStats::Configure.
+
+@param aBF
+
+The bitfield defining which statistics to be collected.
+
+@param aSizeToCopy
+
+The size of the section of the data buffer used for holding the stats, which
+can be directly copied into the destination buffer.  The remaining must be calculated.
+
+@pre If user thread, it must be in a critical section.
+
+*/
+void KernCoreStats::Construct(TUint aBF)
+	{
+	TInt cores = NUMCPUS;
+
+	// Here we calculate the offsets and pointers of the data we are collecting.
+	// We need pointers for internal data collection, and offsets for where we will put the data in the structure at collection.
+
+	DynamicObject o((TUint8*) this + sizeof(KernCoreStats));
+	TUint16 dummy=0;
+
+	//	Flag to turn feature on,		size of/and location of internal data,	size of/and location of target data,
+	o.Add(aBF & KStatsCoreTotalTimeInIdle, 		cores*2, 	(TAny**)& iTotalTimeIdle, 	cores,	iOffsTotalTimeIdle);
+	o.Add(aBF & KStatsCoreTotalTimeInIdle, 		cores*2, 	(TAny**)& iLastTimeCore,	0,	dummy);
+	o.Add(aBF & KStatsTimeCrossIdleAndActive, 	(cores+1)*2,	(TAny**)& iTimesCIA,		cores+1, iOffsTimesCIA);
+	o.Add(aBF & KStatsCoreNumTimesInIdle, 		cores,		(TAny**)& iNumberIdles,		cores,	iOffsNumberIdles);
+	o.Add(aBF & KStatsNumEvents, 			0,		(TAny**)& dummy,		1,	iOffsNumEvents);
+	o.Add(aBF & KStatsReadyStateChanges,		cores,		(TAny**)& iLastAddReadyCount,	1, 	iOffsReadyStateAdd);
+	o.Add(aBF & KStatsReadyStateChanges,		cores,		(TAny**)& iLastSubReadyCount,	1,	iOffsReadyStateRemove);
+	o.Add(aBF & KStatsNumTimeSliceExpire,		cores,		(TAny**)& iLastSlicesCount,	1, 	iOffsNumTimeSliceExpire);
+
+
+	TUint64 timeNow = FASTTIMER;
+	TInt core;
+
+	// set up varables needed for CoreTotalTimeInIdle
+	if (iLastTimeCore)
+		{
+		for (core=0; core<cores; core++) // Start core times time now.
+			iLastTimeCore[core]=timeNow;
+		}
+
+	// Set up variables used for KTimeCrossIdleAndActive (iTimesCIA) calculations.
+	// (Could make conditional, but wouldnt save time)
+
+	iLastTime=timeNow;
+	iCoresIdle= 0;
+	};
+
+
+/**
+This method fills the provided buffer with the kernel statistics that have been collected.
+
+@param aBuffer
+
+The pre-allocated buffer for which the collected data should be copied to.
+
+@return KErrNone on success.
+*/
+
+EXPORT_C TInt KernCoreStats::Stats(TAny* aBuffer)
+	{
+	if (StatsData)
+		return StatsData->StatsCopy(aBuffer);
+	else
+		return KErrNotReady;
+	};
+
+
+
+/**
+@internal
+  
+This method implements the functionality of KernCoreStats::Stats.
+This method fills the provided buffer with the kernel statistics that have been collected.
+
+@param aBuffer
+
+The pre-allocated buffer for which the collected data should be copied to.
+
+@return KErrNone on success.
+*/
+
+TInt KernCoreStats::StatsCopy(TAny* aBuffer)
+	{
+	TUint32 timerFrequency = FASTTIMERFREQ;
+	TUint32 targetFrequency=1000000;
+	TInt cores = NUMCPUS;
+	
+	TInt core;
+	TInt ints = __SPIN_LOCK_IRQSAVE(Lock); // This spinlock is doubley important, as it acts as memory barrier for "if (StatsData)"
+
+	TUint64 timeNow = FASTTIMER;
+
+	// For the core idle times, we must add in the time for any core which is currently idle,
+	// so that the values are properly framed.
+	if (iTotalTimeIdle)
+		{
+		TUint u;
+		TUint64 idletime;
+		for(core=0, u = iCoreMask; core<cores; u>>=1, core++)
+			{
+			if (u & 0x1u)
+				{
+				iTotalTimeIdle[core]+=timeNow-iLastTimeCore[core];
+				iLastTimeCore[core]=timeNow;
+				}
+
+			idletime = (iTotalTimeIdle[core]*targetFrequency)/timerFrequency;
+			Value32(aBuffer, iOffsTotalTimeIdle)[core] = ((idletime>>32)?KMaxTUint32:(TUint32)idletime);
+
+			iTotalTimeIdle[core]=0;
+			}
+
+		__SPIN_FLASH_IRQRESTORE(Lock,ints); 
+		timeNow = FASTTIMER;
+		}
+	
+
+	// For times across idle and active, we must add in the time for the current state of the cores
+	// so that the values are properly framed.
+	if (iTimesCIA)
+		{
+		iTimesCIA[iCoresIdle]+= timeNow-iLastTime;
+		iLastTime=timeNow;
+
+		// Copy to structure
+		TUint64 timecia;
+		for(core=0; core<cores+1; core++) // here we are not actally talking about cores, but CIA.
+			{
+			timecia =  (iTimesCIA[core]*targetFrequency)/timerFrequency;
+
+			Value32(aBuffer, iOffsTimesCIA)[core] = (timecia>>32)?KMaxTUint32:(TUint32)timecia;
+			iTimesCIA[core]=0;
+			}
+		__SPIN_FLASH_IRQRESTORE(Lock,ints);
+		}
+	
+	if (iNumberIdles)
+		{
+		for(core=0; core<cores; core++)
+			{
+			Value32(aBuffer, iOffsNumberIdles)[core] =iNumberIdles[core];
+			iNumberIdles[core]=0;
+			}
+		}
+
+	if (iOffsNumEvents!=KStatDisabled)
+		{
+		*Value32(aBuffer, iOffsNumEvents)= iNumEvents;
+		iNumEvents=0;
+		}
+
+	__SPIN_UNLOCK_IRQRESTORE(Lock, ints);
+
+	// Calculate the MadeReady couter, and the MadeUnready counter.
+
+	if (iOffsReadyStateAdd!=KStatDisabled)
+		{
+		TUint addTot=0;
+		TUint subTot=0;
+
+		TUint addReadyCount;
+		TUint subReadyCount;
+
+#ifndef __X86__
+#ifdef __SMP__
+		// for each core, the previous ready and unready values are subtracted from
+		// the current counter value, and then these values added together.
+
+		for (core=0; core<cores; core++)
+			{
+			addReadyCount= TheSubSchedulers[core].iMadeReadyCounter;
+			subReadyCount= TheSubSchedulers[core].iMadeUnReadyCounter;
+			
+			addTot+= addReadyCount - iLastAddReadyCount[core];
+			iLastAddReadyCount[core]=addReadyCount;
+			
+			subTot+= subReadyCount - iLastSubReadyCount[core];
+			iLastSubReadyCount[core]=subReadyCount;
+			}
+#else
+
+		addReadyCount= TheScheduler.iMadeReadyCounter;
+		subReadyCount= TheScheduler.iMadeUnReadyCounter;
+			
+		addTot= addReadyCount - *iLastAddReadyCount;
+		*iLastAddReadyCount=addReadyCount;
+			
+		subTot= subReadyCount - *iLastSubReadyCount;
+		*iLastSubReadyCount=subReadyCount;
+#endif
+#endif
+		// write the calculated values into the provided data buffer.
+		*Value32(aBuffer, iOffsReadyStateAdd)=addTot; 
+		*Value32(aBuffer, iOffsReadyStateRemove)=subTot; 
+		}
+
+
+	// Calculate the time slice expire value
+	if (iOffsNumTimeSliceExpire != KStatDisabled)
+		{
+		TUint slicesTot=0;
+		TUint slicesCount;
+
+#ifndef __X86__
+#ifdef __SMP__	
+
+		// for each core, the previous time slice values are subtracted from
+		// the current counter values, and then these values added together.
+		for (core=0; core<cores ;core++)
+			{
+			slicesCount= TheSubSchedulers[core].iTimeSliceExpireCounter;
+			slicesTot+= slicesCount - iLastSlicesCount[core];
+			iLastSlicesCount[core]=slicesCount;
+			}
+#else
+		slicesCount= TheScheduler.iTimeSliceExpireCounter;
+		slicesTot= slicesCount - *iLastSlicesCount;
+		*iLastSlicesCount=slicesCount;
+#endif
+#endif	
+		// write the calculated values into the provided data buffer.
+		*Value32(aBuffer, iOffsNumTimeSliceExpire) = slicesTot;
+		}
+
+	return KErrNone;
+	}
+
+
+/**
+@internal
+   
+This is called from idle thread, before it entered its idle state.
+For SMP kernels, this is done by the kernel, and the base ports should not call EnterIdle.
+
+@param aCore
+
+The core for which this code in executing.
+
+@pre Interrupts must be disabled
+*/
+
+extern "C" TUint KernCoreStats_EnterIdle(TUint aCore)
+	{
+	CHECK_PRECONDITIONS(MASK_INTERRUPTS_DISABLED , "KernCoreStats_EnterIdle");
+	if (KernCoreStats::StatsData)
+		{
+			KernCoreStats::StatsData->DoEnterIdle(aCore); 
+		return (TUint) ETrue;
+		}
+	return (TUint) EFalse;	
+	}
+#ifndef __WINS__
+#ifndef __SMP__
+
+/**
+This is called from idle thread, before it enters its idle state.
+For non-SMP kernels, the base port must call this explicitly.
+SMP base ports should not call this, as its called from within the kernel.
+
+@pre Interrupts must be disabled
+
+@return a cookie that should be passed to LeaveIdle(), after the core leaves idle.
+*/
+
+EXPORT_C TUint KernCoreStats::EnterIdle()
+	{
+	CHECK_PRECONDITIONS(MASK_INTERRUPTS_DISABLED , "KernCoreStats::EnterIdle");
+	if (StatsData)
+		{
+		StatsData->DoEnterIdle(0); 
+		return (TUint) ETrue;
+		}
+	return (TUint) EFalse;
+	}
+
+#endif
+#endif
+
+/**
+@internal
+
+The implementation code for KernCoreStats::EnterIdle and KernCoreStats_EnterIdle.
+
+@param aCore
+
+The core for which this code in executing.
+
+@pre Interrupts must be disabled
+
+*/
+
+void KernCoreStats::DoEnterIdle(TUint aCore)
+	{
+	__SPIN_LOCK(Lock); // This spinlock is doubley important, as it acts as memory barrier for "if (StatsData)"
+	TUint64 timeNow = FASTTIMER;
+
+	__ASSERT_DEBUG( ((iCoreMask & (1<<aCore) )==0), FAULT() );
+
+
+	if (iLastTimeCore)
+		{
+		iLastTimeCore[aCore]=timeNow;
+		iCoreMask|=1<<aCore;
+		}
+
+	if (iNumberIdles)
+		iNumberIdles[aCore]++;
+
+	if (iTimesCIA)
+		{
+		iTimesCIA[iCoresIdle]+= timeNow-iLastTime;
+
+#ifdef __SMP__
+		__ASSERT_DEBUG((iCoresIdle<TheScheduler.iNumCpus), FAULT() );
+#else
+		__ASSERT_DEBUG((iCoresIdle==0), FAULT() );
+#endif
+
+		iLastTime=timeNow;
+		iCoresIdle++;
+		}
+
+	__SPIN_UNLOCK(Lock);
+	}
+
+/**
+This is called from idle thread, after it comes out of its idle state.
+For SMP kernels, this is done by the kernel, and the base ports should not call LeaveIdle.
+
+@param aCookie
+
+The value returned from EnterIdle should be passed here.
+
+@param aCore
+
+The core for which this code in executing.
+
+@pre Interrupts must be disabled
+*/
+
+extern "C" void KernCoreStats_LeaveIdle(TInt aCookie,TUint aCore)
+	{
+	CHECK_PRECONDITIONS(MASK_INTERRUPTS_DISABLED , "KernCoreStats_LeaveIdle");
+	if (aCookie)
+		KernCoreStats::StatsData->DoLeaveIdle(aCore);
+	}
+
+#ifndef __WINS__
+#ifndef __SMP__
+
+/**
+This is called from idle thread, after it comes out of its idle state.
+For non-SMP kernels, the base port must call this explicitly.
+SMP base ports should not call this, as its called from within the kernel.
+
+@param aCookie
+
+The value returned from EnterIdle should be passed here.
+
+@pre Interrupts must be disabled
+*/
+
+EXPORT_C void KernCoreStats::LeaveIdle(TUint aCookie)
+	{
+	CHECK_PRECONDITIONS(MASK_INTERRUPTS_DISABLED , "KernCoreStats::LeaveIdle");
+	if (aCookie)
+		StatsData->DoLeaveIdle(0);
+	}
+
+#endif
+#endif
+
+/**
+@internal
+
+The implementation code for KernCoreStats::LeaveIdle and KernCoreStats_LeaveIdle.
+
+@param aCore
+
+The core for which this code in executing.
+
+@pre Interrupts must be disabled
+*/
+
+void KernCoreStats::DoLeaveIdle(TUint aCore)
+	{
+	__SPIN_LOCK(Lock);// This spinlock is doubley important, as it acts as memory barrier for "if (StatsData)"
+
+	TUint64 timeNow = FASTTIMER;
+
+	if (iTotalTimeIdle)
+		{
+		__ASSERT_DEBUG(iCoreMask&(1<<aCore), FAULT() );
+		iCoreMask&= ~(1<<aCore);
+		iTotalTimeIdle[aCore] += timeNow - iLastTimeCore[aCore];
+		}
+	if (iTimesCIA)
+		{
+		__ASSERT_DEBUG((StatsData->iCoresIdle>0), FAULT() );
+		iTimesCIA[iCoresIdle]+= timeNow-iLastTime;
+		iLastTime=timeNow;
+		iCoresIdle--;
+		}
+	__SPIN_UNLOCK(Lock);
+	}
+
+
+/**
+@internal
+
+Called from Kern::AddEvent
+
+This is used to increment the KernCoreStats event counter.
+*/
+void KernCoreStats::AddEvent()
+	{
+	if (StatsData)
+		{
+		TInt ints = __SPIN_LOCK_IRQSAVE(Lock);
+		if (StatsData->iOffsNumEvents!= KStatDisabled)
+			StatsData->iNumEvents++;
+		__SPIN_UNLOCK_IRQRESTORE(Lock, ints);
+		}
+	};
+
+
+EXPORT_C TInt KernCoreStats::Retire(TInt, TInt)
+	{
+	// DUMMY METHOD
+	return KErrNone;
+	};
+
+EXPORT_C TInt KernCoreStats::Engage(TInt)
+	{
+	// DUMMY METHOD
+
+	return KErrNone;
+	}
--- a/kernel/eka/kernel/random.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/kernel/random.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -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;
+	}
--- a/kernel/eka/kernel/sbtrace.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/kernel/sbtrace.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -445,6 +445,11 @@
 		return ETrue;
 #endif
 
+#ifdef __SMP__
+	case EHSched:
+		return ETrue;
+#endif
+
 	default:
 		return aCategory>=128; // all categories >=128 are 'supported'
 		}
--- a/kernel/eka/kernel/scodeseg.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/kernel/scodeseg.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -1782,7 +1782,7 @@
 				// must remove thread
 				DThread* pT=_LOFF(aProcess->iThreadQ.First()->Deque(),DThread,iProcessLink);
 				pT->iProcessLink.iNext=NULL;
-				pT->Release();
+				pT->Stillborn();
 				}
 			aProcess->Release();
 			}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kernel/eka/kernel/securerng.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -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/server.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/kernel/server.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -1009,7 +1009,7 @@
 */
 EXPORT_C void DBase::AsyncDelete()
 	{
-	CHECK_PRECONDITIONS(MASK_KERNEL_UNLOCKED | MASK_INTERRUPTS_ENABLED | MASK_NOT_ISR | MASK_NOT_IDFC | MASK_CRITICAL, "DObject::AsyncDelete");
+	CHECK_PRECONDITIONS(MASK_NO_KILL_OR_SUSPEND | MASK_INTERRUPTS_ENABLED | MASK_NOT_ISR | MASK_NOT_IDFC, "DObject::AsyncDelete");
 	__KTRACE_OPT(KSERVER,Kern::Printf("DBase::AsyncDelete() %08x",this));
 	
 	DBase* oldHead = K::AsyncDeleteHead;
@@ -1039,22 +1039,14 @@
 // Asynchronously free a kernel heap cell (must be >=4 bytes in length)
 //
 	{
-	CHECK_PRECONDITIONS(MASK_KERNEL_UNLOCKED | MASK_INTERRUPTS_ENABLED | MASK_NOT_ISR | MASK_NOT_IDFC | MASK_CRITICAL, "Kern::AsyncFree");
+	CHECK_PRECONDITIONS(MASK_NO_KILL_OR_SUSPEND | MASK_INTERRUPTS_ENABLED | MASK_NOT_ISR | MASK_NOT_IDFC, "Kern::AsyncFree");
 	__KTRACE_OPT(KSERVER,Kern::Printf("Kern::AsyncFree(%08x)",aPtr));
-	DThread* pT=TheCurrentThread;
-
-	// if we are already running in the kernel server, just free the cell now
-	if (pT==K::TheKernelThread)
-		Kern::Free(aPtr);
-	else
-		{
-		TAny* oldHead = K::AsyncFreeHead;
-		do	{
-			*(TAny**)aPtr = oldHead;	// use first word of cell as link field
-			} while (!__e32_atomic_cas_rel_ptr(&K::AsyncFreeHead, &oldHead, aPtr));
-		if (!oldHead)
-			K::AsyncFreeDfc.Enque();
-		}
+	TAny* oldHead = K::AsyncFreeHead;
+	do	{
+		*(TAny**)aPtr = oldHead;	// use first word of cell as link field
+		} while (!__e32_atomic_cas_rel_ptr(&K::AsyncFreeHead, &oldHead, aPtr));
+	if (!oldHead)
+		K::AsyncFreeDfc.Enque();
 	}
 
 
--- a/kernel/eka/kernel/sexec.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/kernel/sexec.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -2146,18 +2146,23 @@
 	}
 
 #ifdef MONITOR_THREAD_CPU_TIME
-TInt ExecHandler::ThreadGetCpuTime(DThread* aThread, Int64& aTime)
+TInt ExecHandler::ThreadGetCpuTime(TInt aThreadHandle, Int64& aTime)
 	{
-#ifndef __SMP__
-	TInt64 time = (1000000 * aThread->iNThread.iTotalCpuTime) / NKern::FastCounterFrequency();
-	NKern::UnlockSystem();
-	kumemput32(&aTime, &time, sizeof(TInt64));
-#else
-	TUint64 t = NKern::ThreadCpuTime(&aThread->iNThread);
-	NKern::UnlockSystem();
+	TUint64 t = 0;
+	if (aThreadHandle == KCurrentThreadHandle)
+		{
+		t = NKern::ThreadCpuTime(NKern::CurrentThread());
+		}
+	else
+		{
+		NKern::LockSystem();
+		DThread* pT = (DThread*)K::ObjectFromHandle(aThreadHandle, EThread);
+		t = NKern::ThreadCpuTime(&pT->iNThread);
+		NKern::UnlockSystem();
+		}
 	TUint32 f = NKern::CpuTimeMeasFreq();
 	TUint64 t2 = t>>32;
-	t = ((t<<32)>>32)*1000000;
+	t = (t & KMaxTUint32)*1000000;
 	t2 *= 1000000;
 	t2 += (t>>32);
 	t &= TUint64(KMaxTUint32);
@@ -2167,13 +2172,11 @@
 	TUint64 q = t/f;
 	q += (q2<<32);
 	kumemput32(&aTime, &q, sizeof(TInt64));
-#endif
 	return KErrNone;
 	}
-#else		
-TInt ExecHandler::ThreadGetCpuTime(DThread* /*aThread*/, Int64& /*aTime*/)
+#else
+TInt ExecHandler::ThreadGetCpuTime(TInt /*aThreadHandle*/, Int64& /*aTime*/)
 	{
-	NKern::UnlockSystem();
 	return KErrNotSupported;
 	}
 #endif
--- a/kernel/eka/kernel/sglobals.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/kernel/sglobals.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -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	Fri Apr 16 16:24:37 2010 +0300
@@ -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	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/kernel/sinit.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -21,6 +21,7 @@
 #include <kernel/emi.h>
 #include <kernel/sshbuf.h>
 #include "platform.h"
+#include "securerng.h"
 
 #ifdef __VC32__
     #pragma setlocale("english")
@@ -44,8 +45,14 @@
 const TInt KDfcThread1Priority=48;
 const TInt KMaxEventQueue=40;
 
+#ifdef __SMP__
+_LIT(KRebalanceName, "LB");
+const TInt KRebalancePriority=26;
+#endif
+
 TInt SupervisorThread(TAny*);
 TInt DebuggerInit();
+extern TInt InitialiseEntropyBuffers();
 
 extern const SNThreadHandlers EpocThreadHandlers;
 
@@ -392,6 +399,14 @@
 		K::Fault(K::EInit3Failed);
 
 	P::StartExtensions();
+
+	M::Init4();
+
+#ifdef __SMP__
+	TheScheduler.InitLB();
+	TheScheduler.StartPeriodicBalancing();
+#endif
+
 	K::StartKernelServer();
 	return 0;
 	}
@@ -432,6 +447,18 @@
 	if (r!=KErrNone)
 		return r;
 
+#ifdef __SMP__
+	// create thread and DFC queue for load balancing
+	TScheduler& s = TheScheduler;
+	r = Kern::DfcQCreate(s.iRebalanceDfcQ, KRebalancePriority, &KRebalanceName);
+	if (r!=KErrNone)
+		return r;
+	NThread* nt = TScheduler::LBThread();
+	NKern::ThreadSetCpuAffinity(nt, KCpuAffinityAny);
+	pT = _LOFF(nt, DThread, iNThread);
+	pT->iFlags |= KThreadFlagSystemPermanent;
+#endif
+
 	// Initialise the RAM drive
 	K::InitNvRam();
 
@@ -442,6 +469,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 +485,6 @@
 	// Mark the super page signature valid
 	P::SetSuperPageSignature();
 
-	// Initialise the random pool
-	K::Randomize();
-
 	return KErrNone;
 	}
 
--- a/kernel/eka/kernel/sipc.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/kernel/sipc.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -1517,7 +1517,9 @@
 	DSession* session = (DSession*)K::ObjectFromHandle(aHandle, ESession);
 	RMessageK* m = TheCurrentThread->iSyncMsgPtr;
 	__ASSERT_ALWAYS(m->IsFree(), K::PanicCurrentThread(ESyncMsgSentTwice));
-	return session->Send(m, aFunction, aPtr ? &msgArgs : NULL, aStatus);
+	TInt r = session->Send(m, aFunction, aPtr ? &msgArgs : NULL, aStatus);
+	NKern::YieldTimeslice();
+	return r;
 	}
 
 TInt DSession::Send(RMessageK* aMsg, TInt aFunction, const RMessageK::TMsgArgs* aArgs, TRequestStatus* aStatus)
--- a/kernel/eka/kernel/skernel.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/kernel/skernel.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -375,7 +375,7 @@
 		// return value is set at the point where the thread is released from its wait
 		// condition). However we can still detect this situation since the thread will
 		// have been placed into the EReady state when the mutex was reset.
-		TInt r=NKern::Block(0,NKern::ERelease|NKern::EClaim,SYSTEM_LOCK);
+		TInt r=NKern::Block(0, NKern::ERelease|NKern::EClaim|NKern::EObstruct, SYSTEM_LOCK);
 		if (r==KErrNone && pC->iMState==DThread::EReady)
 			r = KErrGeneral;	// mutex has been reset
 		if (r!=KErrNone)		// if we get an error here...
@@ -825,6 +825,9 @@
 				m.iCleanup.ChangePriority(p);
 			}
 		TInt tmout = pC->iMState==DThread::EWaitCondVar ? aTimeout : 0;
+		TUint mode = NKern::ERelease|NKern::EClaim;
+		if (pC->iMState == DThread::EWaitMutex)
+			mode |= NKern::EObstruct;
 		BTRACE_KS2(BTrace::ECondVarBlock, this, &m);
 
 		// The following possibilities exist here:
@@ -841,7 +844,7 @@
 		//		s=KErrNone, thread state EReady
 		// 6.	Thread killed while waiting for mutex or condition variable
 		//		Function doesn't return since exit handler runs instead.
-		TInt s = NKern::Block(tmout, NKern::ERelease|NKern::EClaim, SYSTEM_LOCK);
+		TInt s = NKern::Block(tmout, mode, SYSTEM_LOCK);
 		if (s==KErrNone && pC->iMState==DThread::EReady)
 			s = KErrGeneral;
 		if (s!=KErrNone && s!=KErrTimedOut)	// if we get an error here...
@@ -1750,7 +1753,7 @@
 @see Kern::ReleaseMemoryFromDMA
 
 @param aThread          The thread in whose process the given address lies. If zero, the current thread is used.
-@param aAddress         An address in the given threads process.
+@param aAddress         An address in the given thread's process.
 @param aSize            The size of the region.
 @param aPageList        Points to an array of TUint32 (or TPhysAddr) objects. The length of the array must
 						be at least aSize/MMU_page_size+1, where MMU_page_size = Kern::RoundToPageSize(1).
@@ -1759,7 +1762,7 @@
                         (they are a multiple of the physical page size), therefore the byte corresponding
                         to aOffset is at physical address aPageList[0]+aOffset%MMU_page_size.
 
-@return 0 				 if successful.
+@return KErrNone		 if successful.
         KErrAccessDenied if any part of region doesn't belong to "trusted" chunk.
         Other			 if memory region is invalid, or mapped in 1MB sections or large pages.
 
@@ -1779,16 +1782,16 @@
 
 /**
 Unlocks the physical pages that have been locked by PrepareMemoryForDMA.
-All input paramemers are the same as those in PrepareMemoryForDMA.
+All input parameters are the same as those in PrepareMemoryForDMA.
 
 @see Kern::PrepareMemoryForDMA
 
 @param aThread          The thread in whose process the given address lies. If zero, the current thread is used.
-@param aAddress         An address in the given threads process.
+@param aAddress         An address in the given thread's process.
 @param aSize            The size of the region.
 @param aPageList        Points to the list of pages returned by PrepareMemoryForDMA.
 
-@return 0 				if successful.
+@return KErrNone		if successful.
         KErrArgument	if the list of physical pages is invalid.
         
 @pre	Calling thread must be in critical section.
--- a/kernel/eka/kernel/sprocess.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/kernel/sprocess.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -342,7 +342,6 @@
 	if (iSMPUnsafeGroup)
 		{
 		NKern::GroupDestroy(iSMPUnsafeGroup);
-		Kern::Free(iSMPUnsafeGroup);
 		}
 #endif
 
@@ -726,6 +725,11 @@
 	}
 
 #ifdef __SMP__
+void SMPUnsafeGroupDestroyFn(TAny* aGroup)
+	{
+	Kern::Free(aGroup);
+	}
+
 TInt DProcess::UpdateSMPSafe()
 	{
 	TUint32 config = TheSuperPage().KernelConfigFlags();
@@ -739,10 +743,21 @@
 		{
 		SNThreadGroupCreateInfo info;
 		info.iCpuAffinity = KCpuAffinityAny;
-		iSMPUnsafeGroup = (NThreadGroup*)Kern::Alloc(sizeof(NThreadGroup));
+		NThreadGroup* g = (NThreadGroup*)Kern::Alloc(sizeof(NThreadGroup));
 		r = KErrNoMemory;
-		if (iSMPUnsafeGroup)
-			r = NKern::GroupCreate(iSMPUnsafeGroup, info);
+		if (g)
+			{
+			info.iDestructionDfc = new TDfc(&SMPUnsafeGroupDestroyFn, g, K::SvMsgQ, 2);
+			if (info.iDestructionDfc)
+				r = NKern::GroupCreate(g, info);
+			if (r != KErrNone)
+				{
+				delete info.iDestructionDfc;
+				Kern::Free(g);
+				g = 0;
+				}
+			iSMPUnsafeGroup = g;
+			}
 		}
 	if (r==KErrNone)
 		{
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kernel/eka/kernel/srandombuff.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -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], &currentstatus, 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	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/kernel/stest.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -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/kernel/sthread.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/kernel/sthread.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -455,6 +455,7 @@
 		aDefaultPriority = 1;
 #endif
 	iDefaultPriority=aDefaultPriority;
+	NKern::ThreadSetNominalPriority(&iNThread, aDefaultPriority);
 	K::PINestLevel=0;
 	SetRequiredPriority();
 	}
@@ -637,12 +638,49 @@
 	return &pT->iKillDfc;	// NKERN will queue this before terminating this thread
 	}
 
+#if defined(__SMP__) && defined(KTIMING)
+TUint64 tix2us(TUint64 aTicks, TUint32 aFreq)
+	{
+	TUint64 e6(1000000);
+	aTicks *= e6;
+	aTicks += TUint64(aFreq>>1);
+	aTicks /= TUint64(aFreq);
+	TUint64 us = aTicks % e6;
+	TUint64 sec = aTicks / e6;
+	return (sec<<32)|us;
+	}
+#endif
+
 void DThread::Exit()
 //
 // This function runs in the context of the exiting thread
 // Enter and leave with system unlocked
 //
 	{
+#if defined(__SMP__) && defined(KTIMING)
+	if (KDebugNum(KTIMING))
+		{
+		TUint64 rc = iNThread.iRunCount.i64;
+		NSchedulable::SCpuStats stats;
+		NKern::Lock();
+		iNThread.GetCpuStats(NSchedulable::E_RunTime|NSchedulable::E_ActiveTime, stats);
+		NKern::Unlock();
+		TUint64 cputime = stats.iRunTime;
+		TUint64 acttime = stats.iActiveTime;
+		TUint32 f = NKern::CpuTimeMeasFreq();
+		TUint64 avgcpu = rc ? cputime / rc : 0;
+		TUint64 ratio = (acttime*100)/cputime;
+		TUint64 cpud = tix2us(cputime, f);
+		TUint64 actd = tix2us(acttime, f);
+		TUint64 avgd = tix2us(avgcpu, f);
+		Kern::Printf("Thread %O RC=%u CPU=%u.%06us ACT=%u.%06us AVG=%u.%06us RATIO=%d%%",
+						this, TUint32(rc),
+						I64HIGH(cpud), I64LOW(cpud),
+						I64HIGH(actd), I64LOW(actd),
+						I64HIGH(avgd), I64LOW(avgd),
+						TUint32(ratio));
+		}
+#endif
 #ifdef KPANIC
 	if (iExitType==EExitPanic)
 		{
--- a/kernel/eka/kernel/stimer.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/kernel/stimer.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -1071,18 +1071,31 @@
 	DTimer* pT=FromPtr(aTimer);
 	NKern::LockSystem();
 	pT->iTimer.iState = (TUint8)TTimer::EIdle;
-	Kern::QueueRequestComplete(pT->Owner(), pT->iTimer.iRequest,KErrNone);
+	Kern::QueueRequestComplete(pT->Owner(), pT->iTimer.iRequest, KErrNone);
 	NKern::UnlockSystem();
 	}
 
-void DTimer::HighRes(TRequestStatus& aStatus, TInt anInterval)
+void DTimer::HighRes(TRequestStatus& aStatus, TInt aInterval)
 	{
 	// enter and return with system locked
-	TInt r=iTimer.AfterHighRes(anInterval,MsComplete,aStatus);
+	TInt r=iTimer.AfterHighRes(aInterval,MsComplete,aStatus);
 	if (r!=KErrNone)
 		K::PanicCurrentThread(ETimerAlreadyPending);
 	}
 
+void DTimer::AgainHighRes(TRequestStatus& aStatus, TInt aInterval)
+	{
+	// enter and return with system locked
+	TInt r=iTimer.AgainHighRes(aInterval,MsComplete,aStatus);
+	if (r==KErrInUse)
+		K::PanicCurrentThread(ETimerAlreadyPending);
+	else if (r!=KErrNone)
+		{
+		TRequestStatus* status = &aStatus;
+		Kern::RequestComplete(status, r);
+		}
+	}
+
 void DTimer::Cancel()
 //
 // Cancel an outstanding request.
@@ -1191,7 +1204,7 @@
 	iType=(TUint8)aType;
 	}
 
-TInt TTimer::AfterHighRes(TInt anInterval, NTimerFn aFunction, TRequestStatus& aStatus)
+TInt TTimer::AfterHighRes(TInt aInterval, NTimerFn aFunction, TRequestStatus& aStatus)
 	{
 	// enter and return with system locked
 	if (iState!=EIdle || iRequest->SetStatus(&aStatus) != KErrNone)
@@ -1199,12 +1212,37 @@
 	iState = (TUint8)EWaitHighRes;
 	SetType(EHighRes);
 	TInt msp=NTickPeriod();
-	TInt t=(TInt)(((TUint)anInterval+msp-1)/msp);	// convert microseconds to milliseconds, rounding up
+	TInt t=(TInt)(((TUint)aInterval+msp-1)/msp);	// convert microseconds to milliseconds, rounding up
 	new (&Ms()) NTimer(aFunction,this);
 	Ms().OneShot(t,ETrue);			// start millisecond timer, complete in DFC
 	return KErrNone;
 	}
 
+TInt TTimer::AgainHighRes(TInt aInterval, NTimerFn aFunction, TRequestStatus& aStatus)
+	{
+	// enter and return with system locked
+	if (iState!=EIdle)
+		return KErrInUse;
+	if (iType!=EHighRes)
+		return AfterHighRes(aInterval, aFunction, aStatus);
+	if (iRequest->SetStatus(&aStatus) != KErrNone)
+		return KErrInUse;
+	iState = (TUint8)EWaitHighRes;
+	TInt msp=NTickPeriod();
+	TInt t;
+	if (aInterval>=0)
+		t = (TInt)(((TUint)aInterval+msp-1)/msp);	// convert microseconds to milliseconds, rounding up
+	else
+		t = aInterval/msp;		// convert microseconds to milliseconds, rounding up
+	TInt r = Ms().Again(t);		// start millisecond timer, complete in DFC
+	if (r != KErrNone)
+		{
+		iState=(TUint8)EIdle;
+		iRequest->Reset();
+		}
+	return r;
+	}
+
 void TTimer::Cancel(DThread* aThread)
 //
 // Cancel an outstanding request.
@@ -1393,6 +1431,12 @@
 	aTimer->HighRes(aStatus,aTime);
 	}
 
+void ExecHandler::TimerAgainHighRes(DTimer* aTimer, TRequestStatus& aStatus, TInt aTime)
+	{
+	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::TimerAgainHighRes"));
+	aTimer->AgainHighRes(aStatus,aTime);
+	}
+
 void ExecHandler::TimerAt(DTimer* aTimer, TRequestStatus& aStatus, TUint32 aTimeLo, TUint32 aTimeHi)
 	{
 	__KTRACE_OPT(KEXEC,Kern::Printf("Exec::TimerAt"));
--- a/kernel/eka/kernel/sutils.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/kernel/sutils.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -2538,8 +2538,9 @@
 	return KErrNone;
 	}
 
-TInt K::KernelHal(TInt aFunction, TAny* a1, TAny* /*a2*/)
+TInt K::KernelHal(TInt aFunction, TAny* a1, TAny* a2)
 	{
+	(void)a2;
 	TInt r=KErrNone;
 	switch (aFunction)
 		{
@@ -2682,15 +2683,23 @@
 		case EKernelHalLockThreadToCpu:
 			{
 #ifdef __SMP__
+			r = KErrArgument;
 			TUint32 cpuId = (TUint32)a1;
-			if (cpuId < (TUint32)NKern::NumberOfCpus())
+			TUint32 ncpus = NKern::NumberOfCpus();
+			if (cpuId < ncpus)
 				{
 				NKern::ThreadSetCpuAffinity(NKern::CurrentThread(), cpuId);
 				r = KErrNone;
 				}
-			else
+			else if (cpuId & NTHREADBASE_CPU_AFFINITY_MASK)
 				{
-				r = KErrArgument;
+				TUint32 mask = cpuId & ~NTHREADBASE_CPU_AFFINITY_MASK;
+				TUint32 amask = ~((~0u)<<ncpus);
+				if (cpuId==KCpuAffinityAny || ((mask & amask) && (mask &~ amask)==0))
+					{
+					NKern::ThreadSetCpuAffinity(NKern::CurrentThread(), cpuId);
+					r = KErrNone;
+					}
 				}
 #else
 			r = KErrNone;
@@ -2702,7 +2711,57 @@
 			// return bottom 31 bits of config flags so as not to signal an error
 			r=K::KernelConfigFlags() & 0x7fffffff;
 			break;
-	
+
+#ifdef __SMP__
+		case EKernelHalCpuStates:
+			{
+			SCpuStates states;
+			memclr(&states, sizeof(states));
+
+			TScheduler& s = TheScheduler;
+			TInt irq = s.iGenIPILock.LockIrqSave();
+			states.iTA = s.iThreadAcceptCpus;
+			states.iIA = s.iIpiAcceptCpus;
+			states.iCU = s.iCpusComingUp;
+			states.iGD = s.iCpusGoingDown;
+			states.iDC = s.iCCDeferCount;
+			states.iSC = s.iCCSyncCpus;
+			states.iRC = s.iCCReactivateCpus;
+			states.iCCS = s.iCCState;
+			states.iPO = TUint8(s.iPoweringOff ? (s.iPoweringOff->iCpuNum|0x80) : 0);
+			states.iPODC = s.iDetachCount;
+			TInt i;
+			TInt nc = NKern::NumberOfCpus();
+			for (i=0; i<nc; ++i)
+				{
+				TSubScheduler& ss = TheSubSchedulers[i];
+				states.iDS[i] = ss.iDeferShutdown;
+#ifdef __CPU_ARM
+				volatile TUint32* p = (volatile TUint32*)ss.iUncached;
+				states.iUDC[i] = p[0];
+				states.iUAC[i] = p[1];
+#endif
+				}
+			s.iGenIPILock.UnlockIrqRestore(irq);
+
+			kumemput32(a1, &states, sizeof(states));
+			r = KErrNone;
+			break;
+			}
+
+		case EKernelHalSetNumberOfCpus:
+			{
+			TInt n = (TInt)a1;
+			if (n<=0 || n>NKern::NumberOfCpus())
+				r = KErrArgument;
+			else
+				{
+				NKern::SetNumberOfActiveCpus(n);
+				r = KErrNone;
+				}
+			break;
+			}
+#endif
 		default:
 			r=KErrNotSupported;
 			break;
@@ -2967,12 +3026,17 @@
 		else if (!nt || nt->iCsCount==0)
 			m &= ~MASK_NO_CRITICAL;
 		}
-	if (m & MASK_CRITICAL)
+	if (m & (MASK_CRITICAL|MASK_NO_KILL_OR_SUSPEND))
 		{
 		if (t && (t->iThreadType!=EThreadUser || nt->iCsCount>0))
-			m &= ~MASK_CRITICAL;
+			m &= ~(MASK_CRITICAL|MASK_NO_KILL_OR_SUSPEND);
 		else if (!nt || nt->iCsCount>0)
-			m &= ~MASK_CRITICAL;
+			m &= ~(MASK_CRITICAL|MASK_NO_KILL_OR_SUSPEND);
+		}
+	if (m & MASK_NO_KILL_OR_SUSPEND)
+		{
+		if (!nt || NKern::KernelLocked() || NKern::HeldFastMutex())
+			m &= ~MASK_NO_KILL_OR_SUSPEND;
 		}
 	if (m & MASK_KERNEL_LOCKED)
 		{
@@ -3074,6 +3138,8 @@
 		Kern::Printf("Assertion failed");
 	if (m & MASK_NO_RESCHED)
 		Kern::Printf("Assertion failed: Don't call from thread with kernel unlocked");
+	if (m & MASK_NO_KILL_OR_SUSPEND)
+		Kern::Printf("Assertion failed: Must not be suspended or killed here");
 
 #ifdef __KERNEL_APIS_CONTEXT_CHECKS_FAULT__
 	if (aFunction)
--- a/kernel/eka/kernel/win32/cinit.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/kernel/win32/cinit.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -25,7 +25,7 @@
 
 GLREF_D TBool EmulRunExe;
 
-extern "C" void NKIdle(TInt aStage)
+extern "C" void NKIdle(TUint32 aStage)
 	{
 	SCpuIdleHandler* cih = NKern::CpuIdleHandler();
 	if (cih && cih->iHandler)
--- a/kernel/eka/kernel/x86/ckernel.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/kernel/x86/ckernel.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -201,7 +201,7 @@
 	TheSuperPage().iKernelExcInfo=e;
 	NKern::DisableAllInterrupts();
 #ifdef __SMP__
-	SubScheduler().i_ExcInfo = aPtr;
+	SubScheduler().iSSX.iExcInfo = aPtr;
 #else
 	TheScheduler.i_ExcInfo = aPtr;
 #endif
--- a/kernel/eka/kernel/x86/cutils.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/kernel/x86/cutils.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -106,7 +106,7 @@
 		return;
 		}
 #ifdef __SMP__
-	SFullX86RegSet* regs = &(((SCpuData*)SubScheduler().i_Tss)->iRegs);
+	SFullX86RegSet* regs = &(((SCpuData*)SubScheduler().iSSX.iTss)->iRegs);
 #else
 	SFullX86RegSet* regs = &X86_Regs;
 #endif
@@ -119,7 +119,7 @@
 void A::StartCrashDebugger(const TAny* a0, TInt a1)
 	{
 #ifdef __SMP__
-	SFullX86RegSet* regs = &(((SCpuData*)SubScheduler().i_Tss)->iRegs);
+	SFullX86RegSet* regs = &(((SCpuData*)SubScheduler().iSSX.iTss)->iRegs);
 #else
 	SFullX86RegSet* regs = &X86_Regs;
 #endif
@@ -150,8 +150,8 @@
 	TInt i;
 	for (i=0; i<KMaxCpus; ++i)
 		{
-		TheSubSchedulers[i].i_CrashState = (TAny*)f;
-		TheSubSchedulers[i].i_ExcInfo = (TAny*)aMode;
+		TheSubSchedulers[i].iSSX.iCrashState = f;
+		TheSubSchedulers[i].iSSX.iExcInfo = (TAny*)aMode;
 		}
 	write_apic_reg(ICRH, 0);
 	write_apic_reg(ICRL, 0xC4400);	// send NMI to all processors other than this one - will call vector
--- a/kernel/eka/memmodel/emul/win32/minit.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/memmodel/emul/win32/minit.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -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/emul/win32/mprocess.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/memmodel/emul/win32/mprocess.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -191,14 +191,18 @@
 	
 	TInt count=0;
 	TInt err = KErrNone;
-	data.iDataCopy = Kern::Alloc(seg->iRealDataSize);
-	data.iBssCopy = Kern::Alloc(seg->iRealBssSize);
+
+	// Scheduling must be disabled while we are allocating memory from Windows' heap
+	NKern::Lock();
+	data.iDataCopy = GlobalAlloc(GMEM_FIXED, seg->iRealDataSize);
+	data.iBssCopy = GlobalAlloc(GMEM_FIXED, seg->iRealBssSize);
+	NKern::Unlock();
 	if (!data.iDataCopy || !data.iBssCopy)
 		{
 		err = KErrNoMemory;
 		goto failed;
 		}
-		
+
 	memcpy(data.iDataCopy, seg->iDataCopy, seg->iRealDataSize);	// start with init data
 	memclr(data.iBssCopy, seg->iRealBssSize);					// initialized to zeros
 
@@ -215,8 +219,11 @@
 	return KErrNone;	
 
 failed:
-	Kern::Free(data.iDataCopy);
-	Kern::Free(data.iBssCopy);
+	// Scheduling must be disabled while we are freeing memory from Windows' heap
+	NKern::Lock();
+	GlobalFree(data.iDataCopy);
+	GlobalFree(data.iBssCopy);
+	NKern::Unlock();
 
 	return err;
 	}
@@ -245,9 +252,13 @@
 	
 	if (ix < 0)
 		return;
-	
-	Kern::Free(data.iDataCopy);
-	Kern::Free(data.iBssCopy);
+
+	// Scheduling must be disabled while we are freeing memory from Windows' heap
+	NKern::Lock();
+	GlobalFree(data.iDataCopy);
+	GlobalFree(data.iBssCopy);
+	NKern::Unlock();
+
 	__KTRACE_OPT(KDLL,Kern::Printf("Process %O UnmapCodeSeg(%C)", this, aSeg));
 	}
 
@@ -261,10 +272,10 @@
 		NKern::Lock();
 		if (data.iCodeSeg->iLiveProcess == this)
 			data.iCodeSeg->iLiveProcess = NULL;
+		iDllData.Remove(ii);
+		GlobalFree(data.iDataCopy);
+		GlobalFree(data.iBssCopy);
 		NKern::Unlock();
-		iDllData.Remove(ii);
-		Kern::Free(data.iDataCopy);
-		Kern::Free(data.iBssCopy);
 		}
 	}
 
--- a/kernel/eka/memmodel/emul/win32/mutils.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/memmodel/emul/win32/mutils.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -412,6 +412,12 @@
 
 // Misc DPagingDevice methods
 
+EXPORT_C NFastMutex* DPagingDevice::NotificationLock()
+	{
+	// use the system lock
+	return &TheScheduler.iLock;
+	}
+
 EXPORT_C void DPagingDevice::NotifyIdle()
 	{
 	// Not used on this memory model
--- a/kernel/eka/memmodel/epoc/direct/arm/xinit.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/memmodel/epoc/direct/arm/xinit.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -77,10 +77,10 @@
 	volatile SArmAPBootInfo& info = *(volatile SArmAPBootInfo*)aInfo;
 	TSubScheduler& ss = SubScheduler();
 	TUint32 delta = aCpu*0x2000;
-	info.iInitR13Fiq = TLinAddr(ss.i_FiqStackTop) + delta;
-	info.iInitR13Irq = TLinAddr(ss.i_IrqStackTop) + delta;
-	info.iInitR13Abt = TLinAddr(ss.i_AbtStackTop) + delta;
-	info.iInitR13Und = TLinAddr(ss.i_UndStackTop) + delta;
+	info.iInitR13Fiq = TLinAddr(ss.iSSX.iFiqStackTop) + delta;
+	info.iInitR13Irq = TLinAddr(ss.iSSX.iIrqStackTop) + delta;
+	info.iInitR13Abt = TLinAddr(ss.iSSX.iAbtStackTop) + delta;
+	info.iInitR13Und = TLinAddr(ss.iSSX.iUndStackTop) + delta;
 	}
 
 void M::Init2AP()
--- a/kernel/eka/memmodel/epoc/direct/minit.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/memmodel/epoc/direct/minit.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -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/direct/mutils.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/memmodel/epoc/direct/mutils.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -673,6 +673,12 @@
 
 // Misc DPagingDevice methods
 
+EXPORT_C NFastMutex* DPagingDevice::NotificationLock()
+	{
+	// use the system lock
+	return &TheScheduler.iLock;
+	}
+
 EXPORT_C void DPagingDevice::NotifyIdle()
 	{
 	// Not used on this memory model
--- a/kernel/eka/memmodel/epoc/flexible/mcodeseg.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/memmodel/epoc/flexible/mcodeseg.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -221,12 +221,17 @@
 	TInt exportDirSize = iRamInfo.iExportDirCount * sizeof(TLinAddr);
 	if(exportDirSize > 0 || (exportDirSize==0 && (iCodeSeg->iAttr&ECodeSegAttNmdExpData)) )
 		{
+		TLinAddr expDirLoad = iRamInfo.iExportDir - iRamInfo.iCodeRunAddr + iRamInfo.iCodeLoadAddr;
+		if (expDirLoad < iRamInfo.iCodeLoadAddr ||
+			expDirLoad + exportDirSize > iRamInfo.iCodeLoadAddr + iRamInfo.iCodeSize)
+			{// Invalid export section but the loader should have checked this.
+			return KErrCorrupt;
+			}
 		exportDirSize += sizeof(TLinAddr);
 		TLinAddr* expDir = (TLinAddr*)Kern::Alloc(exportDirSize);
 		if(!expDir)
 			return KErrNoMemory;
 		iCopyOfExportDir = expDir;
-		TLinAddr expDirLoad = iRamInfo.iExportDir-iRamInfo.iCodeRunAddr+iRamInfo.iCodeLoadAddr;
 		UNLOCK_USER_MEMORY();
 		memcpy(expDir,(TAny*)(expDirLoad-sizeof(TLinAddr)),exportDirSize);
 		LOCK_USER_MEMORY();
--- a/kernel/eka/memmodel/epoc/flexible/minit.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/memmodel/epoc/flexible/minit.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -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	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/memmodel/epoc/flexible/mmu/arm/xmmu.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -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;
 			}
@@ -882,13 +928,11 @@
 	// Now we have the os asid check access to kernel memory.
 	if(aAddr >= KUserMemoryLimit && osAsid != (TUint)KKernelOsAsid)
 		{
-		NKern::ThreadEnterCS();
-		MmuLock::Unlock();
 		if (!iAliasLinAddr)
 			{// Close the new reference as RemoveAlias won't do as iAliasLinAddr is not set.
 			aProcess->AsyncCloseOsAsid();	// Asynchronous close as this method should be quick.
 			}
-		NKern::ThreadLeaveCS();
+		MmuLock::Unlock();
 		return KErrBadDescriptor; // prevent access to supervisor only memory
 		}
 
@@ -898,10 +942,8 @@
 		// address is in global section, don't bother aliasing it...
 		if (!iAliasLinAddr)
 			{// Close the new reference as not required.
-			NKern::ThreadEnterCS();
+			aProcess->AsyncCloseOsAsid(); // Asynchronous close as this method should be quick.
 			MmuLock::Unlock();
-			aProcess->AsyncCloseOsAsid(); // Asynchronous close as this method should be quick.
-			NKern::ThreadLeaveCS();
 			}
 		else
 			{// Remove the existing alias as it is not required.
@@ -1015,15 +1057,9 @@
 	iCpuRestoreCookie = -1;
 #endif
 
-	// Must close the os asid while in critical section to prevent it being 
-	// leaked.  However, we can't hold the mmu lock so we have to enter an 
-	// explict crtical section. It is ok to release the mmu lock as the 
-	// iAliasLinAddr and iAliasProcess members are only ever updated by the 
-	// current thread.
-	NKern::ThreadEnterCS();
+	// Must close the os asid while holding MmuLock so we are in an implicit critical section.
+	iAliasProcess->AsyncCloseOsAsid(); // Asynchronous close as this method should be quick.
 	MmuLock::Unlock();
-	iAliasProcess->AsyncCloseOsAsid(); // Asynchronous close as this method should be quick.
-	NKern::ThreadLeaveCS();
 	}
 
 
--- a/kernel/eka/memmodel/epoc/flexible/mmu/mcodepaging.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/memmodel/epoc/flexible/mmu/mcodepaging.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -239,7 +239,8 @@
 	{
 	TRACE2(("DCodePagedMemoryManager::ReadPage(0x%08x,0x%08x,0x%08x,?,?)",aMemory,aIndex,aCount));
 
-	__NK_ASSERT_DEBUG(aRequest->CheckUse(aMemory,aIndex,aCount));
+	__NK_ASSERT_DEBUG(aRequest->CheckUseContiguous(aMemory,aIndex,aCount));
+	__ASSERT_CRITICAL;
 
 	START_PAGING_BENCHMARK;
 
@@ -256,6 +257,7 @@
 
 	TLinAddr linAddr = aRequest->MapPages(aIndex,aCount,aPages);
 	TInt r = KErrNone;
+	TThreadMessage message;
 
 	if(!info.iCodeSize)
 		{
@@ -292,7 +294,7 @@
 												device.iReadUnitShift,
 												ReadFunc,
 												(TAny*)info.iCodeLocalDrive,
-												(TAny*)&aRequest->iMessage);
+												(TAny*)&message);
 
 		if(bufferStart<0)
 			{
@@ -332,7 +334,7 @@
 
 	pagedCodeInfo->AsyncClose();
 
-	END_PAGING_BENCHMARK(EPagingBmReadCodePage);
+	END_PAGING_BENCHMARK_N(EPagingBmReadCodePage, aCount);
 	return r;
 	}
 
--- a/kernel/eka/memmodel/epoc/flexible/mmu/mdatapaging.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/memmodel/epoc/flexible/mmu/mdatapaging.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -31,17 +31,26 @@
 	{
 public:
 
-	enum TSwapFlags
+	/// The state of swap for a logical page in a memory object.
+	///
+	/// Note that this does not always correspond to the state of the page in RAM - for example a
+	/// page can be dirty in RAM but blank in swap if it has never been written out.
+	enum TSwapState
 		{
-		EAllocated		= 1 << 0,
-		EUninitialised	= 1 << 1,
-		ESaved			= 1 << 2,
-		ESwapFlagsMask 	= 0x7,
-
-		ESwapIndexShift = 3,
-		ESwapIndexMask = 0xffffffff << ESwapIndexShift,
+		EStateUnreserved = 0,	///< swap space not yet reserved, or page is being decommitted
+		EStateBlank      = 1,	///< swap page has never been written
+		EStateWritten    = 2,	///< swap page has been written out at least once
+		EStateWriting    = 3	///< swap page is in the process of being written out
+		};
+	
+	enum
+		{
+		ESwapIndexShift = 2,
+		ESwapStateMask 	= (1 << ESwapIndexShift) - 1,
+		ESwapIndexMask  = 0xffffffff & ~ESwapStateMask
 		};
 
+public:
 	TInt Create(DPagingDevice* aDevice);
 
 	TInt ReserveSwap(DMemoryObject* aMemory, TUint aStartIndex, TUint aPageCount);
@@ -49,21 +58,32 @@
 	TBool IsReserved(DMemoryObject* aMemory, TUint aStartIndex, TUint aPageCount);
 
 	TInt ReadSwapPages(DMemoryObject* aMemory, TUint aIndex, TUint aCount, TLinAddr aLinAddr, DPageReadRequest* aRequest, TPhysAddr* aPhysAddrs);
-	TInt WriteSwapPages(DMemoryObject* aMemory, TUint aIndex, TUint aCount, TLinAddr aLinAddr, DPageWriteRequest* aRequest);
-	void DoDeleteNotify(TUint aSwapData);
+	TInt WriteSwapPages(DMemoryObject** aMemory, TUint* aIndex, TUint aCount, TLinAddr aLinAddr, TBool aBackground);
 
 	void GetSwapInfo(SVMSwapInfo& aInfoOut);
 	TInt SetSwapThresholds(const SVMSwapThresholds& aThresholds);
-	void CheckSwapThresholds(TUint aInitial, TUint aFinal);
+
+private:
+	inline TSwapState SwapState(TUint aSwapData);
+	inline TInt SwapIndex(TUint aSwapData);
+	inline TUint SwapData(TSwapState aSwapState, TInt aSwapIndex);
+	
+	TInt AllocSwapIndex(TInt aCount);
+	void FreeSwapIndex(TInt aSwapIndex);
+	void CheckSwapThresholdsAndUnlock(TUint aInitial);
 	
-protected:
-	DPagingDevice* iDevice;
-	TBitMapAllocator* iBitMap;
-	TUint iBitMapFree;
-	TUint iAllocOffset;
+	void DoDeleteNotify(TUint aSwapIndex);
+	TInt DoWriteSwapPages(DMemoryObject** aMemory, TUint* aIndex, TUint aCount, TLinAddr aLinAddr, TInt aSwapIndex, TBool aBackground);
+	
+private:
+	DPagingDevice* iDevice;			///< Paging device used to read and write swap pages
+	
+	NFastMutex iSwapLock;			///< Fast mutex protecting access to all members below
+	TUint iFreePageCount;			///< Number of swap pages that have not been reserved
+	TBitMapAllocator* iBitMap;		///< Bitmap of swap pages that have been allocated
+	TUint iAllocOffset;				///< Next offset to try when allocating a swap page
  	TUint iSwapThesholdLow;
  	TUint iSwapThesholdGood;
-	TThreadMessage iDelNotifyMsg;
 	};
 
 
@@ -81,15 +101,14 @@
 	virtual TInt Alloc(DMemoryObject* aMemory, TUint aIndex, TUint aCount);
 	virtual void Free(DMemoryObject* aMemory, TUint aIndex, TUint aCount);
 	virtual TInt Wipe(DMemoryObject* aMemory);
-	virtual TInt CleanPage(DMemoryObject* aMemory, SPageInfo* aPageInfo, TPhysAddr*& aPageArrayEntry);
+	virtual void CleanPages(TUint aPageCount, SPageInfo** aPageInfos, TBool aBackground);
 
 	// Methods inherited from DPagedMemoryManager
 	virtual void Init3();
 	virtual TInt InstallPagingDevice(DPagingDevice* aDevice);
 	virtual TInt AcquirePageReadRequest(DPageReadRequest*& aRequest, DMemoryObject* aMemory, TUint aIndex, TUint aCount);
-	virtual TInt AcquirePageWriteRequest(DPageWriteRequest*& aRequest, DMemoryObject* aMemory, TUint aIndex, TUint aCount);
+	virtual TInt AcquirePageWriteRequest(DPageWriteRequest*& aRequest, DMemoryObject** aMemory, TUint* aIndex, TUint aCount);
 	virtual TInt ReadPages(DMemoryObject* aMemory, TUint aIndex, TUint aCount, TPhysAddr* aPages, DPageReadRequest* aRequest);
-	virtual TInt WritePages(DMemoryObject* aMemory, TUint aIndex, TUint aCount, TPhysAddr* aPages, DPageWriteRequest* aRequest);
 	virtual TBool IsAllocated(DMemoryObject* aMemory, TUint aIndex, TUint aCount);
 
 public:
@@ -97,6 +116,9 @@
 	TInt SetSwapThresholds(const SVMSwapThresholds& aThresholds);
 
 private:
+	TInt WritePages(DMemoryObject** aMemory, TUint* aIndex, TPhysAddr* aPages, TUint aCount, DPageWriteRequest *aRequest, TBool aAnyExecutable, TBool aBackground);
+
+private:
 	/**
 	The paging device used for accessing the backing store.
 	This is set by #InstallPagingDevice.
@@ -127,7 +149,7 @@
 */
 TInt DSwapManager::Create(DPagingDevice* aDevice)
 	{
-	__ASSERT_COMPILE(!(ESwapIndexMask & ESwapFlagsMask));
+	__ASSERT_COMPILE(!(ESwapIndexMask & ESwapStateMask));
 	__NK_ASSERT_DEBUG(iDevice == NULL);
 	iDevice = aDevice;
 
@@ -147,12 +169,88 @@
 		{// Not enough RAM to keep track of the swap.
 		return KErrNoMemory;
 		}
-	iBitMapFree = swapPages;
+	iFreePageCount = swapPages;
 	iAllocOffset = 0;
 	return KErrNone;
 	}
 
 
+inline DSwapManager::TSwapState DSwapManager::SwapState(TUint aSwapData)
+	{
+	TSwapState state = (TSwapState)(aSwapData & ESwapStateMask);
+	__NK_ASSERT_DEBUG(state >= EStateWritten || (aSwapData & ~ESwapStateMask) == 0);
+	return state;
+	}
+
+
+inline TInt DSwapManager::SwapIndex(TUint aSwapData)
+	{
+	return aSwapData >> ESwapIndexShift;
+	}
+
+
+inline TUint DSwapManager::SwapData(TSwapState aSwapState, TInt aSwapIndex)
+	{
+	return (aSwapIndex << ESwapIndexShift) | aSwapState;
+	}
+
+
+/**
+Allocate one or more page's worth of space within the swap area.
+
+The location is represented by a page-based index into the swap area.
+
+@param aCount The number of page's worth of space to allocate.
+
+@return The swap index of the first location allocated.
+*/
+TInt DSwapManager::AllocSwapIndex(TInt aCount)
+	{
+	__NK_ASSERT_DEBUG(aCount > 0 && aCount <= KMaxPagesToClean);
+	NKern::FMWait(&iSwapLock);
+
+	// search for run of aCount from iAllocOffset to end
+	TInt carry = 0;
+	TInt l = KMaxTInt;
+	TInt swapIndex = iBitMap->AllocAligned(aCount, 0, 0, EFalse, carry, l, iAllocOffset);
+
+	// if search failed, retry from beginning
+	if (swapIndex < 0)
+		{
+		iAllocOffset = 0;
+		carry = 0;
+		swapIndex = iBitMap->AllocAligned(aCount, 0, 0, EFalse, carry, l, iAllocOffset);
+		}
+
+	// if we found one then mark it as allocated and update iAllocOffset
+	if (swapIndex >= 0)
+		{
+		__NK_ASSERT_DEBUG(swapIndex <= (iBitMap->iSize - aCount));
+		iBitMap->Alloc(swapIndex, aCount);
+		iAllocOffset = (swapIndex + aCount) % iBitMap->iSize;
+		}
+	
+	NKern::FMSignal(&iSwapLock);
+	__NK_ASSERT_DEBUG(swapIndex >= 0 || aCount > 1); // can't fail to allocate single page
+	return swapIndex;
+	}
+
+
+/**
+Free one page's worth of space within the swap area.
+
+The index must have been previously allocated with AllocSwapIndex().
+*/
+void DSwapManager::FreeSwapIndex(TInt aSwapIndex)
+	{
+	__NK_ASSERT_DEBUG(aSwapIndex >= 0 && aSwapIndex < iBitMap->iSize);
+	DoDeleteNotify(aSwapIndex);
+	NKern::FMWait(&iSwapLock);
+	iBitMap->Free(aSwapIndex);
+	NKern::FMSignal(&iSwapLock);
+	}
+
+
 /**
 Reserve some swap pages for the requested region of the memory object
 
@@ -167,40 +265,29 @@
 TInt DSwapManager::ReserveSwap(DMemoryObject* aMemory, TUint aStartIndex, TUint aPageCount)
 	{
 	__NK_ASSERT_DEBUG(MemoryObjectLock::IsHeld(aMemory));
-	__NK_ASSERT_DEBUG(RamAllocLock::IsHeld());
 
-	const TUint indexEnd = aStartIndex + aPageCount;
-	TUint index = aStartIndex;
-
-#ifdef _DEBUG
-	for (; index < indexEnd; index++)
-		{// This page shouldn't already be in use.
-		MmuLock::Lock();
-		__NK_ASSERT_DEBUG(!(aMemory->PagingManagerData(index) & ESwapFlagsMask));
-		MmuLock::Unlock();
-		}
-#endif
-
-	if (iBitMapFree < aPageCount)
+	NKern::FMWait(&iSwapLock);
+	TUint initFree = iFreePageCount;
+	if (iFreePageCount < aPageCount)
 		{
+		NKern::FMSignal(&iSwapLock);
 		Kern::AsyncNotifyChanges(EChangesOutOfMemory);
 		return KErrNoMemory;
 		}
-	// Reserve the required swap space and mark each page as allocated and uninitialised.
-	TUint initFree = iBitMapFree;
-	iBitMapFree -= aPageCount;
-	for (index = aStartIndex; index < indexEnd; index++)
+	iFreePageCount -= aPageCount;
+	CheckSwapThresholdsAndUnlock(initFree);		
+	
+	// Mark each page as allocated and uninitialised.
+	const TUint indexEnd = aStartIndex + aPageCount;
+	for (TUint index = aStartIndex; index < indexEnd; index++)
 		{		
 		// Grab MmuLock to stop manager data being accessed.
 		MmuLock::Lock();
-		TUint swapData = aMemory->PagingManagerData(index);
-		__NK_ASSERT_DEBUG(!(swapData & EAllocated));
-		swapData = EAllocated | EUninitialised;
-		aMemory->SetPagingManagerData(index, swapData);
+		__NK_ASSERT_DEBUG(SwapState(aMemory->PagingManagerData(index)) == EStateUnreserved);
+		aMemory->SetPagingManagerData(index, EStateBlank);
 		MmuLock::Unlock();
 		}
 
-	CheckSwapThresholds(initFree, iBitMapFree);		
 	return KErrNone;
 	}
 
@@ -219,9 +306,7 @@
 TInt DSwapManager::UnreserveSwap(DMemoryObject* aMemory, TUint aStartIndex, TUint aPageCount)
 	{
 	__NK_ASSERT_DEBUG(MemoryObjectLock::IsHeld(aMemory));
-	__NK_ASSERT_DEBUG(RamAllocLock::IsHeld());
 
-	TUint initFree = iBitMapFree;
 	TUint freedPages = 0;
 	const TUint indexEnd = aStartIndex + aPageCount;
 	for (TUint index = aStartIndex; index < indexEnd; index++)
@@ -229,30 +314,35 @@
 		// Grab MmuLock to stop manager data being accessed.
 		MmuLock::Lock();
 		TUint swapData = aMemory->PagingManagerData(index);
-		TUint swapIndex = swapData >> ESwapIndexShift;
-		TBool notifyDelete = EFalse;
-		if (swapData & EAllocated)
+		TSwapState state = SwapState(swapData);
+		if (state != EStateUnreserved)
 			{
-			if (swapData & ESaved)
-				{
-				notifyDelete = ETrue;
-				iBitMap->Free(swapIndex);
-				}
 			freedPages++;
-			aMemory->SetPagingManagerData(index, 0);
+			aMemory->SetPagingManagerData(index, EStateUnreserved);
 			}
-#ifdef _DEBUG
-		else
-			__NK_ASSERT_DEBUG(swapData == 0);
-#endif
-
 		MmuLock::Unlock();
 
-		if (notifyDelete)
-			DoDeleteNotify(swapIndex);
+		if (state == EStateWritten)
+			FreeSwapIndex(SwapIndex(swapData));
+		else if (state == EStateWriting)
+			{
+			// Wait for cleaning to finish before deallocating swap space
+			PageCleaningLock::Lock();
+			PageCleaningLock::Unlock();
+			
+#ifdef _DEBUG
+			MmuLock::Lock();
+			__NK_ASSERT_DEBUG(SwapState(aMemory->PagingManagerData(index)) == EStateUnreserved);
+			MmuLock::Unlock();
+#endif
+			}
 		}
-	iBitMapFree += freedPages;
-	CheckSwapThresholds(initFree, iBitMapFree);	
+	
+	NKern::FMWait(&iSwapLock);
+	TUint initFree = iFreePageCount;
+	iFreePageCount += freedPages;
+	CheckSwapThresholdsAndUnlock(initFree);	
+	
 	return freedPages;
 	}
 
@@ -275,7 +365,7 @@
 	const TUint indexEnd = aStartIndex + aPageCount;
 	for (TUint index = aStartIndex; index < indexEnd; index++)
 		{
-		if (!(aMemory->PagingManagerData(index) & DSwapManager::EAllocated))
+		if (SwapState(aMemory->PagingManagerData(index)) == EStateUnreserved)
 			{// This page is not allocated by swap manager.
 			return EFalse;
 			}
@@ -296,15 +386,12 @@
 */
 TInt DSwapManager::ReadSwapPages(DMemoryObject* aMemory, TUint aIndex, TUint aCount, TLinAddr aLinAddr, DPageReadRequest* aRequest, TPhysAddr* aPhysAddrs)
 	{
+	__ASSERT_CRITICAL;
+	
 	TInt r = KErrNone;
 	const TUint readUnitShift = iDevice->iReadUnitShift;
 	TUint readSize = KPageSize >> readUnitShift;
-	TThreadMessage* msg = const_cast<TThreadMessage*>(&aRequest->iMessage);
-
-	// Determine the wipe byte values for uninitialised pages.
-	TUint allocFlags = aMemory->RamAllocFlags();
-	TBool wipePages = !(allocFlags & Mmu::EAllocNoWipe);
-	TUint8 wipeByte = (allocFlags & Mmu::EAllocUseCustomWipeByte) ? (allocFlags >> Mmu::EAllocWipeByteShift) & 0xff : 0x03;
+	TThreadMessage message;
 
 	const TUint indexEnd = aIndex + aCount;
 	for (TUint index = aIndex; index < indexEnd; index++, aLinAddr += KPageSize, aPhysAddrs++)
@@ -313,36 +400,43 @@
 
 		MmuLock::Lock();	// MmuLock required for atomic access to manager data.
 		TUint swapData = aMemory->PagingManagerData(index);
+		TSwapState state = SwapState(swapData);
 
-		if (!(swapData & EAllocated))
+		if (state == EStateUnreserved)
 			{// This page is not committed to the memory object
 			MmuLock::Unlock();
 			return KErrNotFound;			
 			}
-		if (swapData & EUninitialised)
+		else if (state == EStateBlank)
 			{// This page has not been written to yet so don't read from swap 
 			// just wipe it if required.
+			TUint allocFlags = aMemory->RamAllocFlags();
 			MmuLock::Unlock();
+			TBool wipePages = !(allocFlags & Mmu::EAllocNoWipe);
 			if (wipePages)
 				{
+				TUint8 wipeByte = (allocFlags & Mmu::EAllocUseCustomWipeByte) ?
+					(allocFlags >> Mmu::EAllocWipeByteShift) & 0xff :
+					0x03;
 				memset((TAny*)aLinAddr, wipeByte, KPageSize);
 				}
 			}
 		else
 			{
-			__NK_ASSERT_DEBUG(swapData & ESaved);
-			TUint swapIndex = swapData >> ESwapIndexShift;
+			// It is not possible to get here if the page is in state EStateWriting as if so it must
+			// be present in RAM, and so will not need to be read in.
+			__NK_ASSERT_DEBUG(state == EStateWritten);
+			
 			// OK to release as if the object's data is decommitted the pager 
 			// will check that data is still valid before mapping it.
 			MmuLock::Unlock();
-			TUint readStart = (swapIndex << KPageShift) >> readUnitShift;
+			TUint readStart = (SwapIndex(swapData) << KPageShift) >> readUnitShift;
 			START_PAGING_BENCHMARK;
-			r = iDevice->Read(msg, aLinAddr, readStart, readSize, DPagingDevice::EDriveDataPaging);
+			r = iDevice->Read(&message, aLinAddr, readStart, readSize, DPagingDevice::EDriveDataPaging);
 			if (r != KErrNone)
 				__KTRACE_OPT(KPANIC, Kern::Printf("DSwapManager::ReadSwapPages: error reading media at %08x + %x: %d", readStart << readUnitShift, readSize << readUnitShift, r));				
 			__NK_ASSERT_DEBUG(r!=KErrNoMemory); // not allowed to allocate memory, therefore can't fail with KErrNoMemory
 			END_PAGING_BENCHMARK(EPagingBmReadDataMedia);
-			// TODO: Work out what to do if page in fails, unmap all pages????
 			__NK_ASSERT_ALWAYS(r == KErrNone);
 			}
 		END_PAGING_BENCHMARK(EPagingBmReadDataPage);
@@ -359,102 +453,166 @@
 @param	aIndex		The index within the memory object.
 @param 	aCount		The number of pages to write out.
 @param	aLinAddr	The location of the pages to write out.
-@param	aRequest	The demand paging request to use.
+@param  aBackground Whether this is being called in the background by the page cleaning thread
+                    as opposed to on demand when a free page is required.
 
+@pre Called with page cleaning lock held
 */
-TInt DSwapManager::WriteSwapPages(DMemoryObject* aMemory, TUint aIndex, TUint aCount, TLinAddr aLinAddr, DPageWriteRequest* aRequest)
-	{// The RamAllocLock prevents the object's swap pages being reassigned.
-	__NK_ASSERT_DEBUG(RamAllocLock::IsHeld());
-
-	// Write the page out to the swap.
-	TInt r = KErrNone;
-	const TUint readUnitShift = iDevice->iReadUnitShift;
-	TUint writeSize = KPageSize >> readUnitShift;
-	TThreadMessage* msg = const_cast<TThreadMessage*>(&aRequest->iMessage);
+TInt DSwapManager::WriteSwapPages(DMemoryObject** aMemory, TUint* aIndex, TUint aCount, TLinAddr aLinAddr, TBool aBackground)
+	{
+	__ASSERT_CRITICAL;  // so we can pass the paging device a stack-allocated TThreadMessage
+	__NK_ASSERT_DEBUG(PageCleaningLock::IsHeld());
 
-	const TUint indexEnd = aIndex + aCount;
-	for (TUint index = aIndex; index < indexEnd; index++)
+	START_PAGING_BENCHMARK;
+	
+	TUint i;
+	TUint swapData[KMaxPagesToClean + 1];
+	 
+	MmuLock::Lock();
+	for (i = 0 ; i < aCount ; ++i)
 		{
-		START_PAGING_BENCHMARK;
+		swapData[i] = aMemory[i]->PagingManagerData(aIndex[i]);
+		TSwapState s = SwapState(swapData[i]);
+		// It's not possible to write a page while it's already being written, because we always hold
+		// the PageCleaning mutex when we clean
+		__NK_ASSERT_DEBUG(s == EStateUnreserved || s == EStateBlank || s == EStateWritten);
+		if (s == EStateBlank || s == EStateWritten)
+			aMemory[i]->SetPagingManagerData(aIndex[i], SwapData(EStateWriting, 0));
+		}
+	MmuLock::Unlock();
 
-		MmuLock::Lock();
-		TUint swapData = aMemory->PagingManagerData(index);
-		// OK to release as ram alloc lock prevents manager data being updated.
-		MmuLock::Unlock();
-		if (!(swapData & EAllocated))
-			{// This page is being decommited from aMemory so it is clean/unrequired.
-			continue;
+	// By the time we get here, some pages may have been decommitted, so write out only those runs
+	// of pages which are still committed.
+
+	TInt r = KErrNone;
+	TInt startIndex = -1;
+	swapData[aCount] = SwapData(EStateUnreserved, 0); // end of list marker
+	for (i = 0 ; i < (aCount + 1) ; ++i)
+		{
+		if (SwapState(swapData[i]) != EStateUnreserved)
+			{
+			if (startIndex == -1)
+				startIndex = i;
+
+			// Free swap page corresponding to old version of the pages we are going to write
+			if (SwapState(swapData[i]) == EStateWritten)
+				FreeSwapIndex(SwapIndex(swapData[i]));
 			}
-		TInt swapIndex = swapData >> ESwapIndexShift;
-		if (swapData & ESaved)
-			{// An old version of this page has been saved to swap so free it now
-			// as it will be out of date.
-			iBitMap->Free(swapIndex);
-			DoDeleteNotify(swapIndex);
-			}
-		// Get a new swap location for this page.
-		swapIndex = iBitMap->AllocFrom(iAllocOffset);
-		__NK_ASSERT_DEBUG(swapIndex != -1 && swapIndex < iBitMap->iSize);
-		iAllocOffset = swapIndex + 1;
-		if (iAllocOffset == (TUint)iBitMap->iSize)
-			iAllocOffset = 0;
+		else
+			{
+			if (startIndex != -1)
+				{
+				// write pages from startIndex to i exclusive
+				TInt count = i - startIndex;
+				__NK_ASSERT_DEBUG(count > 0 && count <= KMaxPagesToClean);
 
-		TUint writeOffset = (swapIndex << KPageShift) >> readUnitShift;
-		{
-		START_PAGING_BENCHMARK;
-		r = iDevice->Write(msg, aLinAddr, writeOffset, writeSize, EFalse);
-		if (r != KErrNone)
-			__KTRACE_OPT(KPANIC, Kern::Printf("DSwapManager::WriteSwapPages: error writing media at %08x + %x: %d", writeOffset << readUnitShift, writeSize << readUnitShift, r));				
-		__NK_ASSERT_DEBUG(r!=KErrNoMemory); // not allowed to allocate memory, therefore can't fail with KErrNoMemory
-		END_PAGING_BENCHMARK(EPagingBmWriteDataMedia);
+				// Get a new swap location for these pages, writing them all together if possible
+				TInt swapIndex = AllocSwapIndex(count);
+				if (swapIndex >= 0)
+					r = DoWriteSwapPages(&aMemory[startIndex], &aIndex[startIndex], count, aLinAddr + (startIndex << KPageShift), swapIndex, aBackground);
+				else
+					{
+					// Otherwise, write them individually
+					for (TUint j = startIndex ; j < i ; ++j)
+						{
+						swapIndex = AllocSwapIndex(1);
+						__NK_ASSERT_DEBUG(swapIndex >= 0);
+						r = DoWriteSwapPages(&aMemory[j], &aIndex[j], 1, aLinAddr + (j << KPageShift), swapIndex, aBackground);
+						if (r != KErrNone)
+							break;
+						}
+					}
+
+				startIndex = -1;
+				}
+			}
 		}
-		// TODO: Work out what to do if page out fails.
-		__NK_ASSERT_ALWAYS(r == KErrNone);
-		MmuLock::Lock();
-		// The swap data should not have been modified.
-		__NK_ASSERT_DEBUG(swapData == aMemory->PagingManagerData(index));
-		// Store the new swap location and mark the page as saved.
-		swapData &= ~(EUninitialised | ESwapIndexMask);
-		swapData |= (swapIndex << ESwapIndexShift) | ESaved;
-		aMemory->SetPagingManagerData(index, swapData);
-		MmuLock::Unlock();
-
-		END_PAGING_BENCHMARK(EPagingBmWriteDataPage);
-		}
+	
+	END_PAGING_BENCHMARK_N(EPagingBmWriteDataPage, aCount);
 	
 	return r;
 	}
 
+TInt DSwapManager::DoWriteSwapPages(DMemoryObject** aMemory, TUint* aIndex, TUint aCount, TLinAddr aLinAddr, TInt aSwapIndex, TBool aBackground)
+	{	
+		
+	const TUint readUnitShift = iDevice->iReadUnitShift;
+	const TUint writeSize = aCount << (KPageShift - readUnitShift);
+	const TUint writeOffset = aSwapIndex << (KPageShift - readUnitShift);
+		
+	TThreadMessage msg;
+	START_PAGING_BENCHMARK;
+	TInt r = iDevice->Write(&msg, aLinAddr, writeOffset, writeSize, aBackground);
+	if (r != KErrNone)
+		{
+		__KTRACE_OPT(KPANIC, Kern::Printf("DSwapManager::WriteSwapPages: error writing media from %08x to %08x + %x: %d", aLinAddr, writeOffset << readUnitShift, writeSize << readUnitShift, r));
+		}
+	__NK_ASSERT_DEBUG(r!=KErrNoMemory); // not allowed to allocate memory, therefore can't fail with KErrNoMemory
+	__NK_ASSERT_ALWAYS(r == KErrNone);
+	END_PAGING_BENCHMARK(EPagingBmWriteDataMedia);
+
+	TUint i;
+	TUint swapData[KMaxPagesToClean];
+	
+	MmuLock::Lock();
+	for (i = 0 ; i < aCount ; ++i)
+		{
+		// Re-check the swap state in case page was decommitted while we were writing
+		swapData[i] = aMemory[i]->PagingManagerData(aIndex[i]);
+		TSwapState s = SwapState(swapData[i]);
+		__NK_ASSERT_DEBUG(s == EStateUnreserved || s == EStateWriting);
+		if (s == EStateWriting)
+			{
+			// Store the new swap location and mark the page as saved.
+			aMemory[i]->SetPagingManagerData(aIndex[i], SwapData(EStateWritten, aSwapIndex + i));
+			}
+		}
+	MmuLock::Unlock();
+
+	for (i = 0 ; i < aCount ; ++i)
+		{
+		TSwapState s = SwapState(swapData[i]);
+		if (s == EStateUnreserved)
+			{
+			// The page was decommitted while we were cleaning it, so free the swap page we
+			// allocated and continue, leaving this page in the unreserved state.
+			FreeSwapIndex(aSwapIndex + i);
+			}
+		}
+
+	return KErrNone;
+	}
+	
 
 /**
 Notify the media driver that the page written to swap is no longer required.
 */
 void DSwapManager::DoDeleteNotify(TUint aSwapIndex)
 	{
-	// Ram Alloc lock prevents the swap location being assigned to another page.
-	__NK_ASSERT_DEBUG(RamAllocLock::IsHeld());
-
+	__ASSERT_CRITICAL;  // so we can pass the paging device a stack-allocated TThreadMessage
 #ifdef __PAGING_DELETE_NOTIFY_ENABLED
 	const TUint readUnitShift = iDevice->iReadUnitShift;
 	const TUint size = KPageSize >> readUnitShift;
 	TUint offset = (aSwapIndex << KPageShift) >> readUnitShift;
+	TThreadMessage msg;
 
 	START_PAGING_BENCHMARK;
 	// Ignore the return value as this is just an optimisation that is not supported on all media.
-	(void)iDevice->DeleteNotify(&iDelNotifyMsg, offset, size);
+	(void)iDevice->DeleteNotify(&msg, offset, size);
 	END_PAGING_BENCHMARK(EPagingBmDeleteNotifyDataPage);
 #endif
 	}
 
 
 // Check swap thresholds and notify (see K::CheckFreeMemoryLevel)
-void DSwapManager::CheckSwapThresholds(TUint aInitial, TUint aFinal)
+void DSwapManager::CheckSwapThresholdsAndUnlock(TUint aInitial)
 	{
 	TUint changes = 0;
-	if (aFinal < iSwapThesholdLow && aInitial >= iSwapThesholdLow)
+	if (iFreePageCount < iSwapThesholdLow && aInitial >= iSwapThesholdLow)
 		changes |= (EChangesFreeMemory | EChangesLowMemory);
-	if (aFinal >= iSwapThesholdGood && aInitial < iSwapThesholdGood)
+	if (iFreePageCount >= iSwapThesholdGood && aInitial < iSwapThesholdGood)
 		changes |= EChangesFreeMemory;
+	NKern::FMSignal(&iSwapLock);
 	if (changes)
 		Kern::AsyncNotifyChanges(changes);
 	}
@@ -462,23 +620,25 @@
 
 void DSwapManager::GetSwapInfo(SVMSwapInfo& aInfoOut)
 	{
-	__NK_ASSERT_DEBUG(RamAllocLock::IsHeld());
 	aInfoOut.iSwapSize = iBitMap->iSize << KPageShift;
-	aInfoOut.iSwapFree = iBitMapFree << KPageShift;
+	NKern::FMWait(&iSwapLock);
+	aInfoOut.iSwapFree = iFreePageCount << KPageShift;
+	NKern::FMSignal(&iSwapLock);
 	}
 
 
 TInt DSwapManager::SetSwapThresholds(const SVMSwapThresholds& aThresholds)
 	{
-	__NK_ASSERT_DEBUG(RamAllocLock::IsHeld());
 	if (aThresholds.iLowThreshold > aThresholds.iGoodThreshold)
 		return KErrArgument;		
 	TInt low = (aThresholds.iLowThreshold + KPageSize - 1) >> KPageShift;
 	TInt good = (aThresholds.iGoodThreshold + KPageSize - 1) >> KPageShift;
 	if (good > iBitMap->iSize)
 		return KErrArgument;
+	NKern::FMWait(&iSwapLock);
 	iSwapThesholdLow = low;
 	iSwapThesholdGood = good;
+	NKern::FMSignal(&iSwapLock);
 	return KErrNone;
 	}
 
@@ -527,7 +687,7 @@
 	}
 
 
-TInt DDataPagedMemoryManager::AcquirePageWriteRequest(DPageWriteRequest*& aRequest, DMemoryObject* aMemory, TUint aIndex, TUint aCount)
+TInt DDataPagedMemoryManager::AcquirePageWriteRequest(DPageWriteRequest*& aRequest, DMemoryObject** aMemory, TUint* aIndex, TUint aCount)
 	{
 	aRequest = iDevice->iRequestPool->AcquirePageWriteRequest(aMemory,aIndex,aCount);
 	return KErrNone;
@@ -547,11 +707,7 @@
 	ReAllocDecommitted(aMemory,aIndex,aCount);
 
 	// Reserve the swap pages required.
-	RamAllocLock::Lock();
-	TInt r = iSwapManager->ReserveSwap(aMemory, aIndex, aCount);
-	RamAllocLock::Unlock();
-
-	return r;
+	return iSwapManager->ReserveSwap(aMemory, aIndex, aCount);
 	}
 
 
@@ -562,10 +718,8 @@
 
 	// Unreserve the swap pages associated with the memory object.  Do this before
 	// removing the page array entries to prevent a page fault reallocating these pages.
-	RamAllocLock::Lock();
 	TInt freed = iSwapManager->UnreserveSwap(aMemory, aIndex, aCount);
 	(void)freed;
-	RamAllocLock::Unlock();
 
 	DoFree(aMemory,aIndex,aCount);
 	}
@@ -573,12 +727,16 @@
 
 /**
 @copydoc DMemoryManager::Wipe
-@todo	Not yet implemented.
-		Need to handle this smartly, e.g. throw RAM away and set to uninitialised 
 */
 TInt DDataPagedMemoryManager::Wipe(DMemoryObject* aMemory)
 	{
-	__NK_ASSERT_ALWAYS(0); // not implemented yet
+	// This is not implemented
+	//
+	// It's possible to implement this by throwing away all pages that are paged in and just setting
+	// the backing store state to EStateBlank, however there are currently no use cases which
+	// involve calling Wipe on paged memory.
+	
+	__NK_ASSERT_ALWAYS(0);
 
 	return KErrNotSupported;
 	}
@@ -586,7 +744,7 @@
 
 TInt DDataPagedMemoryManager::ReadPages(DMemoryObject* aMemory, TUint aIndex, TUint aCount, TPhysAddr* aPages, DPageReadRequest* aRequest)
 	{
-	__NK_ASSERT_DEBUG(aRequest->CheckUse(aMemory,aIndex,aCount));
+	__NK_ASSERT_DEBUG(aRequest->CheckUseContiguous(aMemory,aIndex,aCount));
 
 	// Map pages temporarily so that we can copy into them.
 	const TLinAddr linAddr = aRequest->MapPages(aIndex, aCount, aPages);
@@ -600,70 +758,78 @@
 	}
 
 
-TInt DDataPagedMemoryManager::WritePages(DMemoryObject* aMemory, TUint aIndex, TUint aCount, TPhysAddr* aPages, DPageWriteRequest* aRequest)
+TInt DDataPagedMemoryManager::WritePages(DMemoryObject** aMemory, TUint* aIndex, TPhysAddr* aPages, TUint aCount, DPageWriteRequest* aRequest, TBool aAnyExecutable, TBool aBackground)
 	{
-	__NK_ASSERT_DEBUG(aRequest->CheckUse(aMemory,aIndex,aCount));
+	// Map pages temporarily so that we can copy into them.
+	const TLinAddr linAddr = aRequest->MapPages(aIndex[0], aCount, aPages);
 
-	// Map pages temporarily so that we can copy into them.
-	const TLinAddr linAddr = aRequest->MapPages(aIndex, aCount, aPages);
-
-	TInt r = iSwapManager->WriteSwapPages(aMemory, aIndex, aCount, linAddr, aRequest);
+	TInt r = iSwapManager->WriteSwapPages(aMemory, aIndex, aCount, linAddr, aBackground);
 
 	// The memory object allows executable mappings then need IMB.
-	aRequest->UnmapPages(aMemory->IsExecutable());
+	aRequest->UnmapPages(aAnyExecutable);
 
 	return r;
 	}
 
 
-TInt DDataPagedMemoryManager::CleanPage(DMemoryObject* aMemory, SPageInfo* aPageInfo, TPhysAddr*& aPageArrayEntry)
+void DDataPagedMemoryManager::CleanPages(TUint aPageCount, SPageInfo** aPageInfos, TBool aBackground)
 	{
-	if(aPageInfo->IsDirty()==false)
-		return KErrNone;
-
-	// shouldn't be asked to clean a page which is writable...
-	__NK_ASSERT_DEBUG(aPageInfo->IsWritable()==false);
+	__NK_ASSERT_DEBUG(PageCleaningLock::IsHeld());
+	__NK_ASSERT_DEBUG(MmuLock::IsHeld());
+	__NK_ASSERT_DEBUG(aPageCount <= (TUint)KMaxPagesToClean);
+	
+	TUint i;
+	DMemoryObject* memory[KMaxPagesToClean];
+	TUint index[KMaxPagesToClean];
+	TPhysAddr physAddr[KMaxPagesToClean];
+	TBool anyExecutable = EFalse;
+	
+	for (i = 0 ; i < aPageCount ; ++i)
+		{
+		SPageInfo* pi = aPageInfos[i];
 
-	// mark page as being modified by us...
-	TUint modifierInstance; // dummy variable used only for it's storage address on the stack
-	aPageInfo->SetModifier(&modifierInstance);
+		__NK_ASSERT_DEBUG(!pi->IsWritable());
+		__NK_ASSERT_DEBUG(pi->IsDirty());
+		
+		// mark page as being modified by us...
+		pi->SetModifier(&memory[0]);
+		
+		// get info about page...
+		memory[i] = pi->Owner();
+		index[i] = pi->Index();
+		physAddr[i] = pi->PhysAddr();
+		anyExecutable = anyExecutable || memory[i]->IsExecutable();
+		}
 
-	// get info about page...
-	TUint index = aPageInfo->Index();
-	TPhysAddr physAddr = aPageInfo->PhysAddr();
-
-	// Release the mmu lock while we write out the page.  This is safe as the 
-	// RamAllocLock stops the physical address being freed from this object.
 	MmuLock::Unlock();
 
 	// get paging request object...
 	DPageWriteRequest* req;
-	TInt r = AcquirePageWriteRequest(req, aMemory, index, 1);
-	__NK_ASSERT_DEBUG(r==KErrNone); // we should always get a write request because the previous function blocks until it gets one
-	__NK_ASSERT_DEBUG(req); // we should always get a write request because the previous function blocks until it gets one
-
-	r = WritePages(aMemory, index, 1, &physAddr, req);
+	TInt r = AcquirePageWriteRequest(req, memory, index, aPageCount);
+	__NK_ASSERT_DEBUG(r==KErrNone && req);
+	
+	r = WritePages(memory, index, physAddr, aPageCount, req, anyExecutable, aBackground);
+	__NK_ASSERT_DEBUG(r == KErrNone);  // this should never return an error
 
 	req->Release();
 
 	MmuLock::Lock();
 
-	if(r!=KErrNone)
-		return r;
-
-	// check if page is clean...
-	if(aPageInfo->CheckModified(&modifierInstance) || aPageInfo->IsWritable())
+	for (i = 0 ; i < aPageCount ; ++i)
 		{
-		// someone else modified the page, or it became writable, so fail...
-		r = KErrInUse;
+		SPageInfo* pi = aPageInfos[i];
+		// check if page is clean...
+		if(pi->CheckModified(&memory[0]) || pi->IsWritable())
+			{
+			// someone else modified the page, or it became writable, so mark as not cleaned
+			aPageInfos[i] = NULL;
+			}
+		else
+			{
+			// page is now clean!
+			ThePager.SetClean(*pi);
+			}
 		}
-	else
-		{
-		// page is now clean!
-		ThePager.SetClean(*aPageInfo);
-		}
-
-	return r;
 	}
 
 
@@ -680,22 +846,13 @@
 
 void DDataPagedMemoryManager::GetSwapInfo(SVMSwapInfo& aInfoOut)
 	{
-	NKern::ThreadEnterCS();
-	RamAllocLock::Lock();
 	iSwapManager->GetSwapInfo(aInfoOut);
-	RamAllocLock::Unlock();
-	NKern::ThreadLeaveCS();
 	}
 
 
 TInt DDataPagedMemoryManager::SetSwapThresholds(const SVMSwapThresholds& aThresholds)
 	{
-	NKern::ThreadEnterCS();
-	RamAllocLock::Lock();
-	TInt r = iSwapManager->SetSwapThresholds(aThresholds);
-	RamAllocLock::Unlock();
-	NKern::ThreadLeaveCS();
-	return r;
+	return iSwapManager->SetSwapThresholds(aThresholds);
 	}
 
 
--- a/kernel/eka/memmodel/epoc/flexible/mmu/mexport.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/memmodel/epoc/flexible/mmu/mexport.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -823,11 +823,3 @@
 	}
 
 
-
-EXPORT_C void DPagingDevice::NotifyIdle()
-	{
-	}
-
-EXPORT_C void DPagingDevice::NotifyBusy()
-	{
-	}
--- a/kernel/eka/memmodel/epoc/flexible/mmu/mm.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/memmodel/epoc/flexible/mmu/mm.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -204,17 +204,18 @@
 
 void DReferenceCountedObject::Open()
 	{
-	__ASSERT_CRITICAL
-	TBool ok = __e32_atomic_tas_ord32(&iReferenceCount, 1, 1, 0);
-	__NK_ASSERT_ALWAYS(ok);
+	CHECK_PRECONDITIONS(MASK_NO_KILL_OR_SUSPEND, "DReferenceCountedObject::Open");
+	TInt orig = __e32_atomic_tas_ord32(&iReferenceCount, 1, 1, 0);
+	if (orig <= 0)
+		__crash();
 	}
 
 
 TBool DReferenceCountedObject::TryOpen()
 	{
-	__ASSERT_CRITICAL
-	TBool ok = __e32_atomic_tas_ord32(&iReferenceCount, 1, 1, 0);
-	return ok;
+	CHECK_PRECONDITIONS(MASK_NO_KILL_OR_SUSPEND, "DReferenceCountedObject::Open");
+	TInt orig = __e32_atomic_tas_ord32(&iReferenceCount, 1, 1, 0);
+	return (orig>0);
 	}
 
 
@@ -243,38 +244,25 @@
 	}
 
 
-TBool DReferenceCountedObject::CheckAsyncCloseIsSafe()
-	{
-	__ASSERT_CRITICAL
-#ifdef _DEBUG
-	NFastMutex* fm = NKern::HeldFastMutex();
-	if(fm)
-		{
-		Kern::Printf("DReferenceCountedObject[0x%08x]::AsyncClose() fast mutex violation %M",this,fm);
-		return false;
-		}
-#endif
-	return true;
-	}
-
-
 void DReferenceCountedObject::Close()
 	{
-	__ASSERT_CRITICAL
 	__NK_ASSERT_DEBUG(CheckCloseIsSafe());
-	__NK_ASSERT_DEBUG(iReferenceCount>0);
-	if (__e32_atomic_tas_ord32(&iReferenceCount, 1, -1, 0) == 1)
+	TInt orig = __e32_atomic_tas_ord32(&iReferenceCount, 1, -1, 0);
+	if (orig == 1)
 		delete this;
+	else if (orig <= 0)
+		__crash();
 	}
 
 
 void DReferenceCountedObject::AsyncClose()
 	{
-	__ASSERT_CRITICAL
-	__NK_ASSERT_DEBUG(CheckAsyncCloseIsSafe());
-	__NK_ASSERT_DEBUG(iReferenceCount>0);
-	if (__e32_atomic_tas_ord32(&iReferenceCount, 1, -1, 0) == 1)
+	CHECK_PRECONDITIONS(MASK_NO_KILL_OR_SUSPEND, "DReferenceCountedObject::AsyncClose");
+	TInt orig = __e32_atomic_tas_ord32(&iReferenceCount, 1, -1, 0);
+	if (orig == 1)
 		AsyncDelete();
+	else if (orig <= 0)
+		__crash();
 	}
 
 
@@ -905,9 +893,6 @@
 	// initialise address spaces...
 	DAddressSpace::Init2();
 
-	// init pager...
-	ThePager.Init2();
-
 	TheMmu.Init2Final();
 	}
 
--- a/kernel/eka/memmodel/epoc/flexible/mmu/mmanager.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/memmodel/epoc/flexible/mmu/mmanager.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -108,12 +108,10 @@
 	}
 
 
-TInt DMemoryManager::CleanPage(DMemoryObject* aMemory, SPageInfo* aPageInfo, TPhysAddr*& /*aPageArrayEntry*/)
+void DMemoryManager::CleanPages(TUint aPageCount, SPageInfo** aPageInfos, TBool /*aBackground*/)
 	{
-	if(aPageInfo->IsDirty()==false)
-		return KErrNone;
-	__NK_ASSERT_DEBUG(0);
-	return KErrNotSupported;
+	for (TUint i = 0 ; i < aPageCount ; ++i)
+		__NK_ASSERT_DEBUG(!aPageInfos[i]->IsDirty());
 	}
 
 
@@ -1039,6 +1037,9 @@
 	__NK_ASSERT_DEBUG(MmuLock::IsHeld());
 	__UNLOCK_GUARD_START(MmuLock);
 
+	// must always hold the PageCleaningLock if the page needs to be cleaned
+	__NK_ASSERT_DEBUG(!aPageInfo->IsDirty() || PageCleaningLock::IsHeld());
+
 	TUint index = aPageInfo->Index();
 	TInt r;
 
@@ -1096,10 +1097,11 @@
 			// page successfully unmapped...
 			aPageInfo->SetReadOnly(); // page not mapped, so must be read-only
 
-			// if the page can be made clean...
-			r = aMemory->iManager->CleanPage(aMemory,aPageInfo,p);
+			// attempt to clean the page if it is dirty...
+			if (aPageInfo->IsDirty())
+				aMemory->iManager->CleanPages(1, &aPageInfo, EFalse);
 
-			if(r==KErrNone)
+			if(aPageInfo)
 				{
 				// page successfully stolen...
 				__NK_ASSERT_DEBUG((*p^page)<(TUint)KPageSize); // sanity check, page should still be allocated to us
@@ -1111,13 +1113,10 @@
 				__NK_ASSERT_ALWAYS((pagerInfo&(RPageArray::EFlagsMask|RPageArray::EStateMask)) == RPageArray::ENotPresent);
 
 				TheMmu.PageFreed(aPageInfo);
+				r = KErrNone;
 				}
 			else
-				{
-				// only legitimate reason for failing the clean is if the page state was changed
-				// by a page fault or by pinning, this should return KErrInUse...
-				__NK_ASSERT_DEBUG(r==KErrInUse);
-				}
+				r = KErrInUse;
 			}
 		}
 
@@ -2030,14 +2029,6 @@
 	__NK_ASSERT_ALWAYS(0);
 	return KErrNotSupported;
 	}
-
-
-TInt DPagedMemoryManager::WritePages(DMemoryObject* aMemory, TUint aIndex, TUint aCount, TPhysAddr* aPages, DPageWriteRequest* aRequest)
-	{
-	__NK_ASSERT_ALWAYS(0);
-	return KErrNotSupported;
-	}
-
 TZonePageType DPagedMemoryManager::PageType()
 	{// Paged manager's pages should be discardable and will actaully be freed by 
 	// the pager so this value won't be used.
--- a/kernel/eka/memmodel/epoc/flexible/mmu/mmanager.h	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/memmodel/epoc/flexible/mmu/mmanager.h	Fri Apr 16 16:24:37 2010 +0300
@@ -242,6 +242,7 @@
 			otherwise one of the system wide error codes.
 
  	@pre RamAllocLock held.
+	@pre If the page is dirty the PageCleaning lock must be held.
 	@pre MmuLock held.
 	*/
 	virtual TInt StealPage(DMemoryObject* aMemory, SPageInfo* aPageInfo);
@@ -265,31 +266,31 @@
 	virtual TInt RestrictPage(DMemoryObject* aMemory, SPageInfo* aPageInfo, TRestrictPagesType aRestriction);
 
 	/**
-	Clean a page of RAM by saving any modifications to it out to backing store.
+	Clean multiple pages of RAM by saving any modifications to it out to backing store.
 
-	This function must only be called when there are no writable MMU mappings of the page.
+	This function must only be called when there are no writable MMU mappings of the pages.
 
-	The function must only return a success after determining no writable MMU mappings
-	were created for the page, in which case it should also mark the page as clean using
-	SPageInfo::SetClean.
-
-	This is only intended for use by #StealPage.
+	The function takes an array of SPageInfo pointers indicating the pages to clean.  On return, the
+	elements of this array are unchanged if the page was successfully cleaned, or set to NULL if
+	cleaning was abandoned (by the page being written to, for example).
 
-	@param aMemory			A memory object associated with this manager.
-	@param aPageInfo		The page information structure of the page to be cleaned.
-							This must be owned by \a aMemory.
-	@param aPageArrayEntry	Reference to the page's page array entry in \a aMemory->iPages.
+	The pages passed must be sequential in their page colour (index & KPageColourMask).
+
+	Those pages that are successfully cleaned are marked as clean using SPageInfo::SetClean.
 
-	@return KErrNone if successful,
-			KErrInUse if the page state changed, e.g. became pinned or was subject to a page fault making it writable,
-			KErrNotSupported if the manager doesn't support this function,
-			otherwise one of the system wide error codes.
+	This is intended for use by #StealPage and #CleanSomePages.
+
+	@param aPageCount		Number of pages to clean.
+	@param aPageInfos		Pointer to an array of aPageCount page info pointers.
+	@param aBackground      Whether the activity should be ignored when determining whether the
+	                        paging device is busy.
 
 	@pre MmuLock held
+	@pre PageCleaning lock held
 	@pre The memory page must not have any writeable MMU mappings.
 	@post MmuLock held (but may have been released by this function)
 	*/
-	virtual TInt CleanPage(DMemoryObject* aMemory, SPageInfo* aPageInfo, TPhysAddr*& aPageArrayEntry);
+	virtual void CleanPages(TUint aPageCount, SPageInfo** aPageInfos, TBool aBackground);
 
 	/**
 	Process a page fault in memory associated with this manager.
@@ -567,25 +568,6 @@
 	virtual TInt ReadPages(DMemoryObject* aMemory, TUint aIndex, TUint aCount, TPhysAddr* aPages, DPageReadRequest* aRequest) =0;
 
 	/**
-	Save the data content of a specified region of a memory object by writing it to
-	storage media. This is intended for use by an implementation of #CleanPage.
-
-	The memory region must be the same as, or a subset of, the region used when obtaining
-	the request object \a aRequest.
-
-	@param aMemory	A memory object associated with this manager.
-	@param aIndex	Page index for the start of the region.
-	@param aCount	Number of pages in the region.
-	@param aPages	Pointer to array of pages to read into. This must contain \a aCount
-					number of physical page addresses which are each page aligned.
-	@param aRequest	A request object previously obtained with #AcquirePageWriteRequest.
-
-	@return KErrNone if successful,
-			otherwise one of the system wide error codes.
-	*/
-	virtual TInt WritePages(DMemoryObject* aMemory, TUint aIndex, TUint aCount, TPhysAddr* aPages, DPageWriteRequest* aRequest);
-
-	/**
 	Check if a region of a memory object has been allocated. E.g. that #Alloc
 	has reserved backing store for the memory and this has has not yet been freed
 	by #Free or #Destruct.
--- a/kernel/eka/memmodel/epoc/flexible/mmu/mmapping.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/memmodel/epoc/flexible/mmu/mmapping.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -1307,7 +1307,7 @@
 											EMappingCreateDefault, 
 											KKernelOsAsid, 
 											0, 
-											aCount, 
+											aCount << KPageShift, 
 											0);
 		if (r != KErrNone)
 			return r;
@@ -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/mmu.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/memmodel/epoc/flexible/mmu/mmu.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -526,6 +526,9 @@
 
 	// update this to stop assert triggering in RamAllocLock::Lock()
 	iRamAllocInitialFreePages = maxFreePages;
+
+	// Get the allocator to signal to the variant which RAM zones are in use so far
+	iRamPageAllocator->InitialCallback();
 	}
 
  
--- a/kernel/eka/memmodel/epoc/flexible/mmu/mmu.h	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/memmodel/epoc/flexible/mmu/mmu.h	Fri Apr 16 16:24:37 2010 +0300
@@ -21,8 +21,6 @@
 #ifndef __MMU_H__
 #define __MMU_H__
 
-#define _USE_OLDEST_LISTS
-
 #include "mm.h"
 #include "mmboot.h"
 #include <mmtypes.h>
@@ -145,7 +143,7 @@
 	enum TPagedState
 		{
 		/**
-		Page is not being managed for demand paging purposes, is has been transiently
+		Page is not being managed for demand paging purposes, or has been transiently
 		removed from the demand paging live list.
 		*/
 		EUnpaged 			= 0x0,
@@ -171,7 +169,6 @@
 		// NOTE - This must be the same value as EStatePagedLocked as defined in mmubase.h
 		EPagedPinned 		= 0x4,
 
-#ifdef _USE_OLDEST_LISTS
 		/**
 		Page is in the live list as one of oldest pages that is clean.
 		*/
@@ -180,8 +177,7 @@
 		/**
 		Page is in the live list as one of oldest pages that is dirty.
 		*/
-		EPagedOldestDirty 	= 0x6
-#endif
+		EPagedOldestDirty 	= 0x6	
 		};
 
 
@@ -677,7 +673,7 @@
 
 	/**
 	Flag this page as 'dirty', indicating that its contents may no longer match those saved
-	to a backing store. This sets the flag #EWritable.
+	to a backing store. This sets the flag #EDirty.
 
 	This is used in the management of demand paged memory.
 
@@ -686,12 +682,13 @@
 	FORCE_INLINE void SetDirty()
 		{
 		CheckAccess("SetDirty");
+		__NK_ASSERT_DEBUG(IsWritable());
 		iFlags |= EDirty;
 		}
 
 	/**
 	Flag this page as 'clean', indicating that its contents now match those saved
-	to a backing store. This clears the flag #EWritable.
+	to a backing store. This clears the flag #EDirty.
 
 	This is used in the management of demand paged memory.
 
@@ -700,6 +697,7 @@
 	FORCE_INLINE void SetClean()
 		{
 		CheckAccess("SetClean");
+		__NK_ASSERT_DEBUG(!IsWritable());
 		iFlags &= ~EDirty;
 		}
 
@@ -1750,11 +1748,12 @@
 		#endif
 		}
 
-private:
+public:
 	/** The lock */
 	static NFastMutex iLock;
 
 #ifdef _DEBUG
+private:
 	static TUint UnlockGuardNest;
 	static TUint UnlockGuardFail;
 #endif
--- a/kernel/eka/memmodel/epoc/flexible/mmu/mobject.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/memmodel/epoc/flexible/mmu/mobject.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -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;
 			}
@@ -579,7 +587,16 @@
 
 void DCoarseMemory::DPageTables::AsyncClose()
 	{
-	__NK_ASSERT_DEBUG(CheckAsyncCloseIsSafe());
+	__ASSERT_CRITICAL
+#ifdef _DEBUG
+	NFastMutex* fm = NKern::HeldFastMutex();
+	if(fm)
+		{
+		Kern::Printf("DCoarseMemory::DPageTables::[0x%08x]::AsyncClose() fast mutex violation %M",this,fm);
+		__NK_ASSERT_DEBUG(0);
+		}
+#endif
+
 	MmuLock::Lock();
 	if (__e32_atomic_tas_ord32(&iReferenceCount, 1, -1, 0) != 1)
 		{
@@ -1689,11 +1706,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/mobject.h	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/memmodel/epoc/flexible/mmu/mobject.h	Fri Apr 16 16:24:37 2010 +0300
@@ -916,6 +916,7 @@
 		/**
 		Overriding DReferenceCountedObject::AsyncClose.
 		This removes the linkage with #iMemory if this object is deleted.
+		@pre No fast mutex must be held.  Unlike DReferenceCountedObject::AsyncClose().
 		*/
 		void AsyncClose();
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kernel/eka/memmodel/epoc/flexible/mmu/mpagecleaner.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,244 @@
+// 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 "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:
+//
+
+#include <kernel.h>
+#include "mpagecleaner.h"
+#include "mm.h"
+#include "mmu.h"
+#include "mpager.h"
+
+#ifdef __PAGING_PRE_CLEAN_DIRTY_PAGES
+
+inline void IgnorePrintf(...) { }
+
+#define PAGE_CLEANER_TRACE IgnorePrintf
+//#define PAGE_CLEANER_TRACE Kern::Printf
+
+_LIT(KThreadName, "PageCleaner");
+
+const TInt KThreadPriority = 25;
+
+// The length of time the paging device is idle before we decide to use it for cleaning dirty
+// pages, in milliseconds.
+const TInt KIdleDelayInMillis = 2;
+
+class DPageCleaner
+	{
+public:
+	DPageCleaner();
+	void Start();
+	void NotifyPagingDeviceIdle();
+	void NotifyPagingDeviceBusy();
+	void NotifyPagesToClean();
+
+private:
+	inline TBool IsRunning();
+	void UpdateBusyCount(TInt aChange);
+	void IdleTimerExpired(TUint aInitialNotificationCount);
+	void TryToClean();
+	
+private:
+	static void TimerDfcFn(TAny*);
+	static void CleanerDfcFn(TAny*);
+	
+private:
+	TInt iIdleDelayInTicks;
+	NTimer iDelayTimer;
+	TDfcQue iDfcQue;
+	TDfc iTimerDfc;
+	TDfc iCleanerDfc;
+	TBool iRunning;
+
+	// All state below is accessed with the MmuLock held.
+
+	// Whether the paging device is currently idle.
+	TBool iPagingDeviceIdle;
+
+	// Whether the paging device has been idle for longer than the wait period.
+	TBool iIdleForAWhile;
+	
+	// Whether the page cleaner is currently running.
+	TBool iCleaningInProgress;	
+	};
+
+DPageCleaner ThePageCleaner;
+
+DPageCleaner::DPageCleaner() :
+	iTimerDfc(TimerDfcFn, NULL, 1),
+	iCleanerDfc(CleanerDfcFn, NULL, 1),
+	iRunning(EFalse),
+	iPagingDeviceIdle(ETrue),
+	iIdleForAWhile(ETrue),
+	iCleaningInProgress(EFalse)
+	{
+	}
+
+void DPageCleaner::Start()
+	{
+	TBool alreadyRunning = __e32_atomic_swp_ord32(&iRunning, ETrue);
+	if (alreadyRunning)
+		return;
+
+	iIdleDelayInTicks = NKern::TimerTicks(KIdleDelayInMillis);
+	
+	TInt r = Kern::DfcQInit(&iDfcQue, KThreadPriority, &KThreadName);
+	__NK_ASSERT_ALWAYS(r == KErrNone);
+	iTimerDfc.SetDfcQ(&iDfcQue);
+	iCleanerDfc.SetDfcQ(&iDfcQue);
+
+	PAGE_CLEANER_TRACE("PageCleaner started");
+	}
+
+FORCE_INLINE TBool DPageCleaner::IsRunning()
+	{
+	return __e32_atomic_load_acq32(&iRunning);
+	}
+
+void DPageCleaner::NotifyPagingDeviceIdle()
+	{
+	__NK_ASSERT_DEBUG(MmuLock::IsHeld());
+	if (IsRunning())
+		{
+		iPagingDeviceIdle = ETrue;
+		if (!iDelayTimer.IsPending())
+			iDelayTimer.OneShot(iIdleDelayInTicks, iTimerDfc);
+		}
+	}
+
+void DPageCleaner::NotifyPagingDeviceBusy()
+	{
+	__NK_ASSERT_DEBUG(MmuLock::IsHeld());
+	if (IsRunning())
+		{
+		iDelayTimer.Cancel();
+		iPagingDeviceIdle = EFalse;
+		iIdleForAWhile = EFalse;
+		}		
+	}
+
+void DPageCleaner::NotifyPagesToClean()
+	{
+	__NK_ASSERT_DEBUG(MmuLock::IsHeld());
+	if (IsRunning())
+		{
+		if (!iCleaningInProgress && iIdleForAWhile)
+			iCleanerDfc.Enque();
+		}
+	}
+
+void DPageCleaner::TimerDfcFn(TAny* aPtr)
+	{
+	ThePageCleaner.IdleTimerExpired((TUint)aPtr);	
+	}
+
+void DPageCleaner::IdleTimerExpired(TUint aInitialNotificationCount)
+	{
+	MmuLock::Lock();	
+	if (iPagingDeviceIdle)
+		{
+		iIdleForAWhile = ETrue;
+		if (!iCleaningInProgress && ThePager.HasPagesToClean())
+			iCleanerDfc.Enque();
+		}
+	MmuLock::Unlock();
+	}
+
+void DPageCleaner::CleanerDfcFn(TAny*)
+	{
+	ThePageCleaner.TryToClean();
+	}
+
+void DPageCleaner::TryToClean()
+	{
+	MmuLock::Lock();
+	TBool workToDo = iIdleForAWhile && ThePager.HasPagesToClean();
+	iCleaningInProgress = workToDo;
+	MmuLock::Unlock();
+	
+	if (!workToDo)
+		{
+		PAGE_CLEANER_TRACE("PageCleaner - started but no work to do");
+		return;
+		}
+
+	for (;;)
+		{
+		PageCleaningLock::Lock();
+		MmuLock::Lock();
+		if (!iIdleForAWhile)
+			break;
+		TInt attempted = ThePager.CleanSomePages(ETrue);
+		if (attempted == 0)
+			break;
+		PAGE_CLEANER_TRACE("PageCleaner - attempted to clean %d pages", attempted);
+		MmuLock::Unlock();
+		PageCleaningLock::Unlock();
+		}
+	
+	if (iIdleForAWhile)
+		PAGE_CLEANER_TRACE("PageCleaner - no more pages to clean");
+	else
+		PAGE_CLEANER_TRACE("PageCleaner - device now busy");
+	
+	iCleaningInProgress = EFalse;
+	MmuLock::Unlock();
+	PageCleaningLock::Unlock();
+	}
+
+void PageCleaner::Start()
+	{
+	ThePageCleaner.Start();
+	}
+
+void PageCleaner::NotifyPagesToClean()
+	{
+	ThePageCleaner.NotifyPagesToClean();
+	}
+
+EXPORT_C void DPagingDevice::NotifyIdle()
+	{
+	ThePageCleaner.NotifyPagingDeviceIdle();
+	}
+
+EXPORT_C void DPagingDevice::NotifyBusy()
+	{
+	ThePageCleaner.NotifyPagingDeviceBusy();
+	}
+
+#else  // __PAGING_PRE_CLEAN_DIRTY_PAGES not defined
+
+void PageCleaner::Start()
+	{
+	}
+
+void PageCleaner::NotifyPagesToClean()
+	{
+	}
+
+EXPORT_C void DPagingDevice::NotifyIdle()
+	{
+	}
+
+EXPORT_C void DPagingDevice::NotifyBusy()
+	{
+	}
+
+#endif
+
+EXPORT_C NFastMutex* DPagingDevice::NotificationLock()
+	{
+	// use the MmuLock
+	return &MmuLock::iLock;
+	}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kernel/eka/memmodel/epoc/flexible/mmu/mpagecleaner.h	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,39 @@
+// 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 "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:
+//
+//   Handles pre-cleaning of dirty pages.
+//
+//   When the paging device is idle (as determined by it calling NotifyIdle/NotifyBusy), a thread
+//   writes cleans dirty pages in the oldest section of the live list.
+//
+
+/**
+ @file
+ @internalComponent
+*/
+
+#ifndef MPAGECLEANER_H
+#define MPAGECLEANER_H
+
+#include <e32def.h>
+#include <nkern.h>
+
+class PageCleaner
+	{
+public:
+	static void Start();
+	static void NotifyPagesToClean();
+	};
+
+#endif
--- a/kernel/eka/memmodel/epoc/flexible/mmu/mpager.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/memmodel/epoc/flexible/mmu/mpager.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -27,14 +27,14 @@
 #include "mpagearray.h"
 #include "mswap.h"
 #include "mthrash.h"
+#include "mpagecleaner.h"
+
 #include "cache_maintenance.inl"
 
 
 const TUint16 KDefaultYoungOldRatio = 3;
 const TUint16 KDefaultMinPages = 256;
-#ifdef _USE_OLDEST_LISTS
 const TUint16 KDefaultOldOldestRatio = 3;
-#endif
 
 const TUint KMinOldPages = 1;
 
@@ -43,21 +43,39 @@
 */
 const TUint	KAbsoluteMaxPageCount = (1u<<(32-KPageShift))-1u;
 
-
+/*
+Limit the maximum number of oldest pages to bound the time taken by SelectPagesToClean(), which is
+called with the MmuLock held.
+*/
+const TUint KMaxOldestPages = 32;
+
+static DMutex* ThePageCleaningLock = NULL;
 
 DPager ThePager;
 
 
 DPager::DPager()
 	: iMinimumPageCount(0), iMaximumPageCount(0), iYoungOldRatio(0),
-	  iYoungCount(0),iOldCount(0),iNumberOfFreePages(0)
+	  iYoungCount(0), iOldCount(0), iOldestCleanCount(0),
+	  iNumberOfFreePages(0), iReservePageCount(0), iMinimumPageLimit(0)
+#ifdef __DEMAND_PAGING_BENCHMARKS__
+	, iBenchmarkLock(TSpinLock::EOrderGenericIrqHigh3)
+#endif	  
 	{
 	}
 
 
-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)
 
@@ -90,13 +108,8 @@
 
 #ifdef __SMP__
 	// Adjust min page count so that all CPUs are guaranteed to make progress.
-	// NOTE: Can't use NKern::NumberOfCpus here because we haven't finished booting yet and will
-	// always have only one CPU running at this point...
-
-	// TODO: Before we can enable this the base test configuration needs
-	// updating to have a sufficient minimum page size...
-	//
-	// iMinYoungPages *= KMaxCpus;
+	TInt numberOfCpus = NKern::NumberOfCpus();
+	iMinYoungPages *= numberOfCpus;
 #endif
 
 	// A minimum young/old ratio of 1 means that we need at least twice iMinYoungPages pages...
@@ -104,85 +117,83 @@
 
 	__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;
+	// Set the list ratios...
+	iYoungOldRatio = KDefaultYoungOldRatio;
+	if(config.iYoungOldRatio)
+		iYoungOldRatio = config.iYoungOldRatio;
+	iOldOldestRatio = KDefaultOldOldestRatio;
+	if(config.iSpare[2])
+		iOldOldestRatio = config.iSpare[2];
+
+	// Set the minimum page counts...
+	iMinimumPageLimit = iMinYoungPages * (1 + iYoungOldRatio) / iYoungOldRatio
+									   + DPageReadRequest::ReservedPagesRequired();
+	
+	if(iMinimumPageLimit < iAbsoluteMinPageCount)
+		iMinimumPageLimit = iAbsoluteMinPageCount;
+
+	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)
+	if(iMinimumPageCount < iAbsoluteMinPageCount)
 		iMinimumPageCount = iAbsoluteMinPageCount;
+	if (iMinimumPageLimit + iReservePageCount > iMinimumPageCount)
+		iMinimumPageCount = iMinimumPageLimit + iReservePageCount;
+
 	iInitMinimumPageCount = iMinimumPageCount;
 
+	// Set the maximum page counts...
 	iMaximumPageCount = KMaxTInt;
-	if(maximumPageCount)
-		iMaximumPageCount = maximumPageCount;
 	if(config.iMaxPages)
 		iMaximumPageCount = config.iMaxPages;
 	if (iMaximumPageCount > KAbsoluteMaxPageCount)
 		iMaximumPageCount = KAbsoluteMaxPageCount;
 	iInitMaximumPageCount = iMaximumPageCount;
 
-	iYoungOldRatio = KDefaultYoungOldRatio;
-	if(config.iYoungOldRatio)
-		iYoungOldRatio = config.iYoungOldRatio;
+	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);
+	__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;
+	__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;
-	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)
-		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
-	TUint minOldAndOldest = iMinimumPageCount / (1 + iYoungOldRatio);
-	if(minOldAndOldest < KMinOldPages)
-		__NK_ASSERT_ALWAYS(0);
-	if (iMinimumPageCount < minOldAndOldest)
-		__NK_ASSERT_ALWAYS(0);
-	TUint minYoung = iMinimumPageCount - minOldAndOldest;
-	if(minYoung < iMinYoungPages)
-		__NK_ASSERT_ALWAYS(0); // Need at least iMinYoungPages pages mapped to execute worst case CPU instruction
-#ifdef _USE_OLDEST_LISTS
+	__NK_ASSERT_ALWAYS(iYoungOldRatio <= ratioLimit);
+
 	// There should always be enough old pages to allow the oldest lists ratio.
 	TUint oldestCount = minOldAndOldest / (1 + iOldOldestRatio);
-	if (!oldestCount)
-		__NK_ASSERT_ALWAYS(0);
-#endif
+	__NK_ASSERT_ALWAYS(oldestCount);
+
 	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;
 	iOldCount = 0;
-#ifdef _USE_OLDEST_LISTS
-	iOldestCleanCount = 0;
 	iOldestDirtyCount = 0;
-#endif
+	__NK_ASSERT_DEBUG(iOldestCleanCount == iReservePageCount);
 	Mmu& m = TheMmu;
-	for(TUint i=0; i<iMinimumPageCount; i++)
+	for(TUint i = iReservePageCount; i < iMinimumPageCount; i++)
 		{
 		// Allocate a single page
 		TPhysAddr pagePhys;
@@ -197,11 +208,8 @@
 		}
 	RamAllocLock::Unlock();
 
-#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));
-#else
-	TRACEB(("DPager::Init2() end with young=%d old=%d min=%d free=%d max=%d",iYoungCount,iOldCount,iMinimumPageCount,iNumberOfFreePages,iMaximumPageCount));
-#endif
+	__NK_ASSERT_DEBUG(CacheInitialised());
+	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));
 	}
 
 
@@ -290,15 +298,9 @@
 	__NK_ASSERT_DEBUG(aPageInfo->PagedState()==SPageInfo::EUnpaged);
 
 	// add as oldest page...
-#ifdef _USE_OLDEST_LISTS
 	aPageInfo->SetPagedState(SPageInfo::EPagedOldestClean);
 	iOldestCleanList.Add(&aPageInfo->iLink);
 	++iOldestCleanCount;
-#else
-	aPageInfo->SetPagedState(SPageInfo::EPagedOld);
-	iOldList.Add(&aPageInfo->iLink);
-	++iOldCount;
-#endif
 
 	Event(EEventPageInFree,aPageInfo);
 	}
@@ -326,7 +328,6 @@
 		--iOldCount;
 		break;
 
-#ifdef _USE_OLDEST_LISTS
 	case SPageInfo::EPagedOldestClean:
 		__NK_ASSERT_DEBUG(iOldestCleanCount);
 		aPageInfo->iLink.Deque();
@@ -338,7 +339,6 @@
 		aPageInfo->iLink.Deque();
 		--iOldestDirtyCount;
 		break;
-#endif
 
 	case SPageInfo::EPagedPinned:
 		// this can occur if a pinned mapping is being unmapped when memory is decommitted.
@@ -361,18 +361,15 @@
 
 	// Update the dirty page count as required...
 	if (aPageInfo->IsDirty())
+		{
+		aPageInfo->SetReadOnly();
 		SetClean(*aPageInfo);
+		}
 
 	// add as oldest page...
-#ifdef _USE_OLDEST_LISTS
 	aPageInfo->SetPagedState(SPageInfo::EPagedOldestClean);
 	iOldestCleanList.Add(&aPageInfo->iLink);
 	++iOldestCleanCount;
-#else
-	aPageInfo->SetPagedState(SPageInfo::EPagedOld);
-	iOldList.Add(&aPageInfo->iLink);
-	++iOldCount;
-#endif
 
 	return KErrNone;
 	}
@@ -399,7 +396,6 @@
 		--iOldCount;
 		break;
 
-#ifdef _USE_OLDEST_LISTS
 	case SPageInfo::EPagedOldestClean:
 		__NK_ASSERT_DEBUG(iOldestCleanCount);
 		aPageInfo->iLink.Deque();
@@ -411,7 +407,6 @@
 		aPageInfo->iLink.Deque();
 		--iOldestDirtyCount;
 		break;
-#endif
 
 	case SPageInfo::EPagedPinned:
 		__NK_ASSERT_DEBUG(0);
@@ -482,52 +477,253 @@
 	}
 
 
-SPageInfo* DPager::StealOldestPage()
+TInt DPager::TryStealOldestPage(SPageInfo*& aPageInfoOut)
 	{
 	__NK_ASSERT_DEBUG(RamAllocLock::IsHeld());
 	__NK_ASSERT_DEBUG(MmuLock::IsHeld());
 
+	// find oldest page in list...
+	SDblQueLink* link;
+	if (iOldestCleanCount)
+		{
+		__NK_ASSERT_DEBUG(!iOldestCleanList.IsEmpty());
+		link = iOldestCleanList.Last();
+		}
+	else if (iOldestDirtyCount)
+		{
+		__NK_ASSERT_DEBUG(!iOldestDirtyList.IsEmpty());
+		link = iOldestDirtyList.Last();
+		}
+	else if (iOldCount)
+		{
+		__NK_ASSERT_DEBUG(!iOldList.IsEmpty());
+		link = iOldList.Last();
+		}
+	else
+		{
+		__NK_ASSERT_DEBUG(iYoungCount);
+		__NK_ASSERT_ALWAYS(!iYoungList.IsEmpty());
+		link = iYoungList.Last();
+		}
+	SPageInfo* pageInfo = SPageInfo::FromLink(link);
+
+	if (pageInfo->IsDirty() && !PageCleaningLock::IsHeld())
+		return 1;
+
+	// try to steal it from owning object...
+	TInt r = StealPage(pageInfo);	
+	if (r == KErrNone)
+		{
+		BalanceAges();
+		aPageInfoOut = pageInfo;
+		}
+	
+	return r;
+	}
+
+
+SPageInfo* DPager::StealOldestPage()
+	{
+	__NK_ASSERT_DEBUG(MmuLock::IsHeld());
+	TBool pageCleaningLockHeld = EFalse;
 	for(;;)
 		{
-		// find oldest page in list...
-		SDblQueLink* link;
-#ifdef _USE_OLDEST_LISTS
-		if (iOldestCleanCount)
+		SPageInfo* pageInfo = NULL;
+		TInt r = TryStealOldestPage(pageInfo);
+		
+		if (r == KErrNone)
 			{
-			__NK_ASSERT_DEBUG(!iOldestCleanList.IsEmpty());
-			link = iOldestCleanList.Last();
+			if (pageCleaningLockHeld)
+				{
+				MmuLock::Unlock();
+				PageCleaningLock::Unlock();
+				MmuLock::Lock();
+				}
+			return pageInfo;
+			}
+		else if (r == 1)
+			{
+			__NK_ASSERT_ALWAYS(!pageCleaningLockHeld);
+			MmuLock::Unlock();
+			PageCleaningLock::Lock();
+			MmuLock::Lock();
+			pageCleaningLockHeld = ETrue;
 			}
-		else if (iOldestDirtyCount)
+		// else retry...
+		}
+	}
+
+#ifdef __CPU_CACHE_HAS_COLOUR
+
+template <class T, TInt maxObjects> class TSequentialColourSelector
+	{
+public:
+	static const TInt KMaxLength = maxObjects;
+	static const TInt KArrayLength = _ALIGN_UP(KMaxLength, KPageColourCount);
+	
+	FORCE_INLINE TSequentialColourSelector()
+		{
+		memclr(this, sizeof(*this));
+		}
+
+	FORCE_INLINE TBool FoundLongestSequence()
+		{
+		return iLongestLength >= KMaxLength;
+		}
+
+	FORCE_INLINE void AddCandidate(T* aObject, TInt aColour)
+		{
+		// allocate objects to slots based on colour
+		for (TInt i = aColour ; i < KArrayLength ; i += KPageColourCount)
 			{
-			__NK_ASSERT_DEBUG(!iOldestDirtyList.IsEmpty());
-			link = iOldestDirtyList.Last();
+			if (!iSlot[i])
+				{
+				iSlot[i] = aObject;
+				iSeqLength[i] = i == 0 ? 1 : iSeqLength[i - 1] + 1;
+				TInt j = i + 1;
+				while(j < KArrayLength && iSeqLength[j])
+					iSeqLength[j++] += iSeqLength[i];
+				TInt currentLength = iSeqLength[j - 1];
+				if (currentLength > iLongestLength)
+					{
+					iLongestLength = currentLength;
+					iLongestStart = j - currentLength;
+					}
+				break;
+				}
 			}
-		else if (iOldCount)
-#else
-		if (iOldCount)
-#endif
+		}
+
+	FORCE_INLINE TInt FindLongestRun(T** aObjectsOut)
+		{
+		if (iLongestLength == 0)
+			return 0;
+
+		if (iLongestLength < KMaxLength && iSlot[0] && iSlot[KArrayLength - 1])
 			{
-			__NK_ASSERT_DEBUG(!iOldList.IsEmpty());
-			link = iOldList.Last();
-			}
-		else
+			// check possibility of wrapping
+
+			TInt i = 1;
+			while (iSlot[i]) ++i;  // find first hole
+			TInt wrappedLength = iSeqLength[KArrayLength - 1] + iSeqLength[i - 1];
+			if (wrappedLength > iLongestLength)
+				{
+				iLongestLength = wrappedLength;
+				iLongestStart = KArrayLength - iSeqLength[KArrayLength - 1];
+				}
+			}		
+
+		iLongestLength = Min(iLongestLength, KMaxLength);
+
+		__NK_ASSERT_DEBUG(iLongestStart >= 0 && iLongestStart < KArrayLength);
+		__NK_ASSERT_DEBUG(iLongestStart + iLongestLength < 2 * KArrayLength);
+
+		TInt len = Min(iLongestLength, KArrayLength - iLongestStart);
+		wordmove(aObjectsOut, &iSlot[iLongestStart], len * sizeof(T*));
+		wordmove(aObjectsOut + len, &iSlot[0], (iLongestLength - len) * sizeof(T*));
+		
+		return iLongestLength;
+		}
+
+private:
+	T* iSlot[KArrayLength];
+	TInt8 iSeqLength[KArrayLength];
+	TInt iLongestStart;
+	TInt iLongestLength;
+	};
+
+TInt DPager::SelectPagesToClean(SPageInfo** aPageInfosOut)
+	{
+	// select up to KMaxPagesToClean oldest dirty pages with sequential page colours
+	
+	__NK_ASSERT_DEBUG(MmuLock::IsHeld());
+
+	TSequentialColourSelector<SPageInfo, KMaxPagesToClean> selector;
+
+	SDblQueLink* link = iOldestDirtyList.Last();
+	while (link != &iOldestDirtyList.iA)
+		{
+		SPageInfo* pi = SPageInfo::FromLink(link);
+		if (!pi->IsWritable())  
 			{
-			__NK_ASSERT_DEBUG(iYoungCount);
-			__NK_ASSERT_ALWAYS(!iYoungList.IsEmpty());
-			link = iYoungList.Last();
+			// the page may be in the process of being restricted, stolen or decommitted, but don't
+			// check for this as it will occur infrequently and will be detected by CheckModified
+			// anyway
+			TInt colour = pi->Index() & KPageColourMask;
+			selector.AddCandidate(pi, colour);
+			if (selector.FoundLongestSequence())
+				break;
 			}
-		SPageInfo* pageInfo = SPageInfo::FromLink(link);
-
-		// steal it from owning object...
-		TInt r = StealPage(pageInfo);
-
-		BalanceAges();
-
-		if(r==KErrNone)
-			return pageInfo; // done
-
-		// loop back and try again
+		link = link->iPrev;
+		}
+	
+	return selector.FindLongestRun(aPageInfosOut);
+	}
+
+#else
+
+TInt DPager::SelectPagesToClean(SPageInfo** aPageInfosOut)
+	{
+	// no page colouring restrictions, so just take up to KMaxPagesToClean oldest dirty pages
+	__NK_ASSERT_DEBUG(MmuLock::IsHeld());
+	TInt pageCount = 0;
+	SDblQueLink* link = iOldestDirtyList.Last();
+	while (link != &iOldestDirtyList.iA && pageCount < KMaxPagesToClean)
+		{
+		SPageInfo* pi = SPageInfo::FromLink(link);
+		if (!pi->IsWritable())
+			{
+			// the page may be in the process of being restricted, stolen or decommitted, but don't
+			// check for this as it will occur infrequently and will be detected by CheckModified
+			// anyway
+			aPageInfosOut[pageCount++] = pi;
+			}
+		link = link->iPrev;
 		}
+	return pageCount;
+	}
+
+#endif
+
+
+TInt DPager::CleanSomePages(TBool aBackground)
+	{
+	__NK_ASSERT_DEBUG(MmuLock::IsHeld());
+	__NK_ASSERT_DEBUG(PageCleaningLock::IsHeld());
+	// ram alloc lock may or may not be held
+
+	SPageInfo* pageInfos[KMaxPagesToClean];
+	TInt pageCount = SelectPagesToClean(&pageInfos[0]);
+	
+	if (pageCount == 0)
+		return 0;
+	
+	TheDataPagedMemoryManager->CleanPages(pageCount, pageInfos, aBackground);
+
+	for (TInt i = 0 ; i < pageCount ; ++i)
+		{
+		SPageInfo* pi = pageInfos[i];
+		if (pi)
+			{
+			__NK_ASSERT_DEBUG(pi->PagedState() == SPageInfo::EPagedOldestDirty && iOldestDirtyCount);
+			__NK_ASSERT_DEBUG(!pi->IsDirty() && !pi->IsWritable());
+		
+			pi->iLink.Deque();
+			iOldestCleanList.AddHead(&pi->iLink);
+			--iOldestDirtyCount;
+			++iOldestCleanCount;
+			pi->SetPagedState(SPageInfo::EPagedOldestClean);
+			}
+		}
+
+	return pageCount;
+	}
+
+
+TBool DPager::HasPagesToClean()
+	{
+	__NK_ASSERT_DEBUG(MmuLock::IsHeld());
+	return iOldestDirtyCount > 0;
 	}
 
 
@@ -608,97 +804,144 @@
 	}
 
 
+static TBool DiscardCanStealPage(SPageInfo* aOldPageInfo, TBool aBlockRest)
+	{
+ 	// If the page is pinned or if the page is dirty and a general defrag is being performed then
+	// don't attempt to steal it
+	return aOldPageInfo->Type() == SPageInfo::EUnused ||
+		(aOldPageInfo->PagedState() != SPageInfo::EPagedPinned && (!aBlockRest || !aOldPageInfo->IsDirty()));	
+	}
+
+
 TInt DPager::DiscardPage(SPageInfo* aOldPageInfo, TUint aBlockZoneId, TBool aBlockRest)
 	{
+	// todo: assert MmuLock not released
+	
+	TRACE(("> DPager::DiscardPage %08x", aOldPageInfo));
+	
 	__NK_ASSERT_DEBUG(RamAllocLock::IsHeld());
 	__NK_ASSERT_DEBUG(MmuLock::IsHeld());
 
-	TInt r;
-	// If the page is pinned or if the page is dirty and a general defrag is being 
-	// performed then don't attempt to steal it.
-	if (aOldPageInfo->Type() != SPageInfo::EUnused && 
-		(aOldPageInfo->PagedState() == SPageInfo::EPagedPinned ||
-		(aBlockRest && aOldPageInfo->IsDirty())))
-		{// The page is pinned or is dirty and this is a general defrag so move the page.
+	if (!DiscardCanStealPage(aOldPageInfo, aBlockRest))
+		{
+		// The page is pinned or is dirty and this is a general defrag so move the page.
 		DMemoryObject* memory = aOldPageInfo->Owner();
 		// Page must be managed if it is pinned or dirty.
 		__NK_ASSERT_DEBUG(aOldPageInfo->Type()==SPageInfo::EManaged);
 		__NK_ASSERT_DEBUG(memory);
 		MmuLock::Unlock();
 		TPhysAddr newAddr;
-		return memory->iManager->MovePage(memory, aOldPageInfo, newAddr, aBlockZoneId, aBlockRest);
+		TRACE2(("DPager::DiscardPage delegating pinned/dirty page to manager"));
+		TInt r = memory->iManager->MovePage(memory, aOldPageInfo, newAddr, aBlockZoneId, aBlockRest);
+		TRACE(("< DPager::DiscardPage %d", r));
+		return r;
 		}
 
-	if (!iNumberOfFreePages)
+	TInt r = KErrNone;
+	SPageInfo* newPageInfo = NULL;
+	TBool havePageCleaningLock = EFalse;
+
+	TBool needNewPage;
+	TBool needPageCleaningLock;
+	while(needNewPage = (iNumberOfFreePages == 0 && newPageInfo == NULL),
+		  needPageCleaningLock = (aOldPageInfo->IsDirty() && !havePageCleaningLock),
+		  needNewPage || needPageCleaningLock)
 		{
-		// Allocate a new page for the live list as it has reached its minimum size.
 		MmuLock::Unlock();
-		SPageInfo* newPageInfo = GetPageFromSystem((Mmu::TRamAllocFlags)(EMemAttNormalCached|Mmu::EAllocNoWipe),
-													aBlockZoneId, aBlockRest);
-		 if (!newPageInfo)
-			return KErrNoMemory;
+
+		if (needNewPage)
+			{
+			// Allocate a new page for the live list as it has reached its minimum size.
+			TUint flags = EMemAttNormalCached | Mmu::EAllocNoWipe;
+			newPageInfo = GetPageFromSystem((Mmu::TRamAllocFlags)flags, aBlockZoneId, aBlockRest);
+			if (!newPageInfo)
+				{
+				TRACE(("< DPager::DiscardPage KErrNoMemory"));
+				r = KErrNoMemory;
+				MmuLock::Lock();
+				break;
+				}
+			}
+
+		if (needPageCleaningLock)
+			{
+			// Acquire the page cleaning mutex so StealPage can clean it
+			PageCleaningLock::Lock();
+			havePageCleaningLock = ETrue;
+			}
 
 		// Re-acquire the mmulock and re-check that the page is not pinned or dirty.
 		MmuLock::Lock();
-		if (aOldPageInfo->Type() != SPageInfo::EUnused && 
-			(aOldPageInfo->PagedState() == SPageInfo::EPagedPinned ||
-			(aBlockRest && aOldPageInfo->IsDirty())))
-			{// Page is now pinned or dirty so give up as it is inuse.
-			ReturnPageToSystem(*newPageInfo);
-			MmuLock::Unlock();
-			return KErrInUse;
-			}
-
-		// Attempt to steal the page
-		r = StealPage(aOldPageInfo);
-		__NK_ASSERT_DEBUG(MmuLock::IsHeld());
-
-		if (r == KErrCompletion)
-			{// This was a page table that has been freed but added to the 
-			// live list as a free page.  Remove from live list and continue.
-			__NK_ASSERT_DEBUG(!aOldPageInfo->IsDirty());
-			RemovePage(aOldPageInfo);
-			r = KErrNone;
-			}
-
-		if (r == KErrNone)
-			{// Add the new page to the live list as discarding the old page 
-			// will reduce the live list below the minimum.
-			AddAsFreePage(newPageInfo);
-			// We've successfully discarded the page so return it to the free pool.
-			ReturnPageToSystem(*aOldPageInfo);
-			BalanceAges();
-			}
-		 else
+		if (!DiscardCanStealPage(aOldPageInfo, aBlockRest))
 			{
-			// New page not required so just return it to the system.  This is safe as 
-			// iNumberOfFreePages will have this page counted but as it is not on the live list
-			// noone else can touch it.
-			ReturnPageToSystem(*newPageInfo);
+			// Page is now pinned or dirty so give up as it is in use.
+			r = KErrInUse;
+			break;
 			}
 		}
-	else
+
+	if (r == KErrNone)
 		{
 		// Attempt to steal the page
-		r = StealPage(aOldPageInfo);
-
-		__NK_ASSERT_DEBUG(MmuLock::IsHeld());
-
-		if (r == KErrCompletion)
-			{// This was a page table that has been freed but added to the 
-			// live list as a free page.  Remove from live list.
-			__NK_ASSERT_DEBUG(!aOldPageInfo->IsDirty());
-			RemovePage(aOldPageInfo);
-			r = KErrNone;
+		r = StealPage(aOldPageInfo);  // temporarily releases MmuLock if page is dirty
+		}
+	__NK_ASSERT_DEBUG(MmuLock::IsHeld());
+
+	if (r == KErrCompletion)
+		{// This was a page table that has been freed but added to the 
+		// live list as a free page.  Remove from live list and continue.
+		__NK_ASSERT_DEBUG(!aOldPageInfo->IsDirty());
+		RemovePage(aOldPageInfo);
+		r = KErrNone;
+		}
+
+	if (r == KErrNone && iNumberOfFreePages == 0)
+		{
+		if (newPageInfo)
+			{
+			// Add a new page to the live list if we have one as discarding the old page will reduce
+			// the live list below the minimum.
+			AddAsFreePage(newPageInfo);
+			newPageInfo = NULL;
 			}
-
-		if (r == KErrNone)
-			{// We've successfully discarded the page so return it to the free pool.
-			ReturnPageToSystem(*aOldPageInfo);
-			BalanceAges();
+		else
+			{
+			// Otherwise the live list shrank when page was being cleaned so have to give up
+			AddAsFreePage(aOldPageInfo);
+			BalanceAges();                  // temporarily releases MmuLock
+			r = KErrInUse;
 			}
 		}
+
+	if (r == KErrNone)
+		{
+		// We've successfully discarded the page and ensured the live list is large enough, so
+		// return it to the free pool.
+		ReturnPageToSystem(*aOldPageInfo);  // temporarily releases MmuLock
+		BalanceAges();                      // temporarily releases MmuLock
+		}
+
+	if (newPageInfo)
+		{
+		// New page not required so just return it to the system.  This is safe as
+		// iNumberOfFreePages will have this page counted but as it is not on the live list noone
+		// else can touch it.
+		if (iNumberOfFreePages == 0)
+			AddAsFreePage(newPageInfo);
+		else
+			ReturnPageToSystem(*newPageInfo);   // temporarily releases MmuLock
+		}
+
+	if (havePageCleaningLock)
+		{
+		// Release the page cleaning mutex
+		MmuLock::Unlock();
+		PageCleaningLock::Unlock();
+		MmuLock::Lock();
+		}	
+	
 	MmuLock::Unlock();
+	TRACE(("< DPager::DiscardPage returns %d", r));
 	return r;	
 	}
 
@@ -754,6 +997,9 @@
 	__NK_ASSERT_DEBUG(RamAllocLock::IsHeld());
 	__NK_ASSERT_DEBUG(MmuLock::IsHeld());
 
+	// should be unpaged at this point, otherwise Mmu::FreeRam will just give it back to us
+	__NK_ASSERT_DEBUG(aPageInfo.PagedState() == SPageInfo::EUnpaged);
+
 	__NK_ASSERT_DEBUG(iNumberOfFreePages>0);
 	--iNumberOfFreePages;
 
@@ -768,28 +1014,22 @@
 
 SPageInfo* DPager::PageInAllocPage(Mmu::TRamAllocFlags aAllocFlags)
 	{
+	TBool pageCleaningLockHeld = EFalse;
 	SPageInfo* pageInfo;
 	TPhysAddr pagePhys;
-
+	TInt r = KErrGeneral;
+	
 	RamAllocLock::Lock();
 	MmuLock::Lock();
 
+find_a_page:
 	// try getting a free page from our live list...
-#ifdef _USE_OLDEST_LISTS
 	if (iOldestCleanCount)
 		{
 		pageInfo = SPageInfo::FromLink(iOldestCleanList.Last());
 		if(pageInfo->Type()==SPageInfo::EUnused)
-			goto get_oldest;
+			goto try_steal_oldest_page;
 		}
-#else
-	if(iOldCount)
-		{
-		pageInfo = SPageInfo::FromLink(iOldList.Last());
-		if(pageInfo->Type()==SPageInfo::EUnused)
-			goto get_oldest;
-		}
-#endif
 
 	// try getting a free page from the system pool...
 	if(!HaveMaximumPages())
@@ -801,14 +1041,62 @@
 		MmuLock::Lock();
 		}
 
+	// try stealing a clean page...
+	if (iOldestCleanCount)
+		goto try_steal_oldest_page;
+
+	// see if we can clean multiple dirty pages in one go...
+	if (KMaxPagesToClean > 1 && iOldestDirtyCount > 1)
+		{
+		// if we don't hold the page cleaning mutex then temporarily release ram alloc mutex and
+		// acquire page cleaning mutex; if we hold it already just proceed
+		if (!pageCleaningLockHeld)
+			{
+			MmuLock::Unlock();
+			RamAllocLock::Unlock();
+			PageCleaningLock::Lock();			
+			MmuLock::Lock();
+			}
+		
+		// there may be clean pages now if we've waited on the page cleaning mutex, if so don't
+		// bother cleaning but just restart
+		if (iOldestCleanCount == 0)
+			CleanSomePages(EFalse);
+		
+		if (!pageCleaningLockHeld)
+			{
+			MmuLock::Unlock();
+			PageCleaningLock::Unlock();			
+			RamAllocLock::Lock();
+			MmuLock::Lock();
+			}
+		
+		if (iOldestCleanCount > 0)
+			goto find_a_page;
+		}
+
 	// as a last resort, steal a page from the live list...
-get_oldest:
-#ifdef _USE_OLDEST_LISTS
+	
+try_steal_oldest_page:
 	__NK_ASSERT_ALWAYS(iOldestCleanCount|iOldestDirtyCount|iOldCount|iYoungCount);
-#else
-	__NK_ASSERT_ALWAYS(iOldCount|iYoungCount);
-#endif
-	pageInfo = StealOldestPage();
+	r = TryStealOldestPage(pageInfo);
+	// if this fails we restart whole process
+	if (r < KErrNone)
+		goto find_a_page;
+
+	// if we need to clean, acquire page cleaning mutex for life of this function
+	if (r == 1)
+		{
+		__NK_ASSERT_ALWAYS(!pageCleaningLockHeld);
+		MmuLock::Unlock();
+		PageCleaningLock::Lock();
+		MmuLock::Lock();
+		pageCleaningLockHeld = ETrue;
+		goto find_a_page;		
+		}
+
+	// otherwise we're done!
+	__NK_ASSERT_DEBUG(r == KErrNone);
 	MmuLock::Unlock();
 
 	// make page state same as a freshly allocated page...
@@ -816,7 +1104,10 @@
 	TheMmu.PagesAllocated(&pagePhys,1,aAllocFlags);
 
 done:
+	if (pageCleaningLockHeld)
+		PageCleaningLock::Unlock();
 	RamAllocLock::Unlock();
+
 	return pageInfo;
 	}
 
@@ -873,10 +1164,8 @@
 
 		case SPageInfo::EPagedYoung:
 		case SPageInfo::EPagedOld:
-#ifdef _USE_OLDEST_LISTS
 		case SPageInfo::EPagedOldestDirty:
 		case SPageInfo::EPagedOldestClean:
-#endif
 			continue; // discard already been allowed
 
 		case SPageInfo::EPagedPinned:
@@ -935,10 +1224,8 @@
 
 		case SPageInfo::EPagedYoung:
 		case SPageInfo::EPagedOld:
-#ifdef _USE_OLDEST_LISTS
 		case SPageInfo::EPagedOldestClean:
 		case SPageInfo::EPagedOldestDirty:
-#endif
 			changeType = ETrue;
 			break; // remove from live list
 
@@ -1004,6 +1291,7 @@
 	TheCodePagedMemoryManager->Init3();
 	TInt r = Kern::AddHalEntry(EHalGroupVM, VMHalFunction, 0);
 	__NK_ASSERT_ALWAYS(r==KErrNone);
+	PageCleaningLock::Init();
 	}
 
 
@@ -1018,12 +1306,8 @@
 	__NK_ASSERT_DEBUG(MmuLock::IsHeld());
 	TBool restrictPage = EFalse;
 	SPageInfo* pageInfo = NULL;
-#ifdef _USE_OLDEST_LISTS
 	TUint oldestCount = iOldestCleanCount + iOldestDirtyCount;
 	if((iOldCount + oldestCount) * iYoungOldRatio < iYoungCount)
-#else
-	if (iOldCount * iYoungOldRatio < iYoungCount)
-#endif
 		{
 		// Need more old pages so make one young page into an old page...
 		__NK_ASSERT_DEBUG(!iYoungList.IsEmpty());
@@ -1042,9 +1326,9 @@
 		restrictPage = ETrue;
 		}
 
-#ifdef _USE_OLDEST_LISTS
 	// Check we have enough oldest pages.
-	if (oldestCount * iOldOldestRatio < iOldCount)
+	if (oldestCount < KMaxOldestPages &&
+		oldestCount * iOldOldestRatio < iOldCount)
 		{
 		__NK_ASSERT_DEBUG(!iOldList.IsEmpty());
 		__NK_ASSERT_DEBUG(iOldCount);
@@ -1057,6 +1341,7 @@
 			oldestPageInfo->SetPagedState(SPageInfo::EPagedOldestDirty);
 			iOldestDirtyList.AddHead(link);
 			++iOldestDirtyCount;
+			PageCleaner::NotifyPagesToClean();
 			Event(EEventPageAgedDirty,oldestPageInfo);
 			}
 		else
@@ -1067,7 +1352,7 @@
 			Event(EEventPageAgedClean,oldestPageInfo);
 			}
 		}
-#endif
+
 	if (restrictPage)
 		{
 		// Make the recently aged old page inaccessible.  This is done last as it 
@@ -1102,10 +1387,8 @@
 		{
 	case SPageInfo::EPagedYoung:
 	case SPageInfo::EPagedOld:
-#ifdef _USE_OLDEST_LISTS
 	case SPageInfo::EPagedOldestClean:
 	case SPageInfo::EPagedOldestDirty:
-#endif
 		RemovePage(pi);
 		AddAsYoungestPage(pi);
 		BalanceAges();
@@ -1125,6 +1408,7 @@
 		}
 	}
 
+
 TInt DPager::PteAndInfoFromLinAddr(	TInt aOsAsid, TLinAddr aAddress, DMemoryMappingBase* aMapping, 
 									TUint aMapInstanceCount, TPte*& aPte, SPageInfo*& aPageInfo)
 	{
@@ -1150,11 +1434,13 @@
 	return KErrNone;
 	}
 
+
 TInt DPager::TryRejuvenate(	TInt aOsAsid, TLinAddr aAddress, TUint aAccessPermissions, TLinAddr aPc,
 							DMemoryMappingBase* aMapping, TUint aMapInstanceCount, DThread* aThread, 
 							TAny* aExceptionInfo)
 	{
 	__NK_ASSERT_DEBUG(MmuLock::IsHeld());
+	START_PAGING_BENCHMARK;
 
 	SPageInfo* pi;
 	TPte* pPte;
@@ -1250,12 +1536,8 @@
 	Event(EEventPageRejuvenate,pi,aPc,aAddress,aAccessPermissions);
 
 	TBool balance = false;
-#ifdef _USE_OLDEST_LISTS
 	if(	state==SPageInfo::EPagedYoung || state==SPageInfo::EPagedOld || 
 		state==SPageInfo::EPagedOldestClean || state==SPageInfo::EPagedOldestDirty)
-#else
-	if(state==SPageInfo::EPagedYoung || state==SPageInfo::EPagedOld)
-#endif
 		{
 		RemovePage(pi);
 		AddAsYoungestPage(pi);
@@ -1276,6 +1558,7 @@
 	if(balance)
 		BalanceAges();
 
+	END_PAGING_BENCHMARK(EPagingBmRejuvenate);
 	return KErrNone;
 	}
 
@@ -1307,10 +1590,8 @@
 			{
 		case SPageInfo::EPagedYoung:
 		case SPageInfo::EPagedOld:
-#ifdef _USE_OLDEST_LISTS
 		case SPageInfo::EPagedOldestClean:
 		case SPageInfo::EPagedOldestDirty:
-#endif
 			RemovePage(pi);
 			// fall through...
 		case SPageInfo::EUnpaged:
@@ -1344,10 +1625,8 @@
 		{
 	case SPageInfo::EPagedYoung:
 	case SPageInfo::EPagedOld:
-#ifdef _USE_OLDEST_LISTS
 	case SPageInfo::EPagedOldestClean:
 	case SPageInfo::EPagedOldestDirty:
-#endif
 		RemovePage(aPageInfo);
 		AddAsYoungestPage(aPageInfo);
 		BalanceAges();
@@ -1404,7 +1683,6 @@
 		__NK_ASSERT_DEBUG(aPageInfo->PinCount()==1);
 		break;
 
-#ifdef _USE_OLDEST_LISTS
 	case SPageInfo::EPagedOldestClean:
 		__NK_ASSERT_DEBUG(iOldestCleanCount);
 		aPageInfo->iLink.Deque();
@@ -1418,7 +1696,6 @@
 		--iOldestDirtyCount;
 		__NK_ASSERT_DEBUG(aPageInfo->PinCount()==1);
 		break;
-#endif
 
 	case SPageInfo::EPagedPinned:
 		// nothing more to do...
@@ -1688,6 +1965,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 +1984,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();
@@ -1789,6 +2070,7 @@
 	{
 	NKern::ThreadEnterCS();
 	RamAllocLock::Lock();
+	PageCleaningLock::Lock();
 
 	TRACE(("DPager::FlushAll() live list young=%d old=%d min=%d free=%d max=%d",iYoungCount,iOldCount,iMinimumPageCount,iNumberOfFreePages,iMaximumPageCount));
 
@@ -1811,12 +2093,8 @@
 			do
 				{
 				SPageInfo::TPagedState state = pi->PagedState();
-#ifdef _USE_OLDEST_LISTS
 				if (state==SPageInfo::EPagedYoung || state==SPageInfo::EPagedOld ||
 					state==SPageInfo::EPagedOldestClean || state==SPageInfo::EPagedOldestDirty)
-#else
-				if(state==SPageInfo::EPagedYoung || state==SPageInfo::EPagedOld)
-#endif
 					{
 					if (pi->Type() != SPageInfo::EUnused)
 						{
@@ -1842,6 +2120,7 @@
 
 	TRACE(("DPager::FlushAll() end with young=%d old=%d min=%d free=%d max=%d",iYoungCount,iOldCount,iMinimumPageCount,iNumberOfFreePages,iMaximumPageCount));
 
+	PageCleaningLock::Unlock();
 	RamAllocLock::Unlock();
 	NKern::ThreadLeaveCS();
 	}
@@ -2016,9 +2295,8 @@
 		TUint index = (TInt) a1;
 		if (index >= EMaxPagingBm)
 			return KErrNotFound;
-		NKern::LockSystem();
-		SPagingBenchmarkInfo info = ThePager.iBenchmarkInfo[index];
-		NKern::UnlockSystem();
+		SPagingBenchmarkInfo info;
+		ThePager.ReadBenchmarkData((TPagingBenchmark)index, info);
 		kumemput32(a2,&info,sizeof(info));
 		}		
 		return KErrNone;
@@ -2028,9 +2306,7 @@
 		TUint index = (TInt) a1;
 		if (index >= EMaxPagingBm)
 			return KErrNotFound;
-		NKern::LockSystem();
 		ThePager.ResetBenchmarkData((TPagingBenchmark)index);
-		NKern::UnlockSystem();
 		}
 		return KErrNone;
 #endif
@@ -2046,28 +2322,39 @@
 void DPager::ResetBenchmarkData(TPagingBenchmark aBm)
     {
     SPagingBenchmarkInfo& info = iBenchmarkInfo[aBm];
+	__SPIN_LOCK_IRQ(iBenchmarkLock);
     info.iCount = 0;
     info.iTotalTime = 0;
     info.iMaxTime = 0;
     info.iMinTime = KMaxTInt;
+	__SPIN_UNLOCK_IRQ(iBenchmarkLock);
     }
  
-void DPager::RecordBenchmarkData(TPagingBenchmark aBm, TUint32 aStartTime, TUint32 aEndTime)
+void DPager::RecordBenchmarkData(TPagingBenchmark aBm, TUint32 aStartTime, TUint32 aEndTime, TUint aCount)
     {
     SPagingBenchmarkInfo& info = iBenchmarkInfo[aBm];
-    ++info.iCount;
 #if !defined(HIGH_RES_TIMER) || defined(HIGH_RES_TIMER_COUNTS_UP)
     TInt64 elapsed = aEndTime - aStartTime;
 #else
     TInt64 elapsed = aStartTime - aEndTime;
 #endif
+	__SPIN_LOCK_IRQ(iBenchmarkLock);
+    info.iCount +=  aCount;
     info.iTotalTime += elapsed;
     if (elapsed > info.iMaxTime)
         info.iMaxTime = elapsed;
     if (elapsed < info.iMinTime)
         info.iMinTime = elapsed;
+	__SPIN_UNLOCK_IRQ(iBenchmarkLock);
     }
 
+void DPager::ReadBenchmarkData(TPagingBenchmark aBm, SPagingBenchmarkInfo& aDataOut)
+	{
+	__SPIN_LOCK_IRQ(iBenchmarkLock);
+	aDataOut = iBenchmarkInfo[aBm];
+	__SPIN_UNLOCK_IRQ(iBenchmarkLock);
+	}
+
 #endif //__DEMAND_PAGING_BENCHMARKS__
 
 
@@ -2079,62 +2366,86 @@
 // DPagingRequest
 //
 
-DPagingRequest::DPagingRequest(DPagingRequestPool::TGroup& aPoolGroup)
-	: iPoolGroup(aPoolGroup), iUseRegionMemory(0), iUseRegionIndex(0), iUseRegionCount(0)
+DPagingRequest::DPagingRequest()
+	: iMutex(NULL), iUseRegionCount(0)
 	{
 	}
 
 
-FORCE_INLINE void DPagingRequest::SetUse(DMemoryObject* aMemory, TUint aIndex, TUint aCount)
+void DPagingRequest::SetUseContiguous(DMemoryObject* aMemory, TUint aIndex, TUint aCount)
 	{
 	__ASSERT_SYSTEM_LOCK;
-	iUseRegionMemory = aMemory;
-	iUseRegionIndex = aIndex;
+	__NK_ASSERT_DEBUG(iUseRegionCount == 0);
+	__NK_ASSERT_DEBUG(aCount > 0 && aCount <= EMaxPages);
+	for (TUint i = 0 ; i < aCount ; ++i)
+		{
+		iUseRegionMemory[i] = aMemory;
+		iUseRegionIndex[i] = aIndex + i;		
+		}
+	iUseRegionCount = aCount;
+	}
+
+
+void DPagingRequest::SetUseDiscontiguous(DMemoryObject** aMemory, TUint* aIndex, TUint aCount)
+	{
+	__ASSERT_SYSTEM_LOCK;
+	__NK_ASSERT_DEBUG(iUseRegionCount == 0);
+	__NK_ASSERT_DEBUG(aCount > 0 && aCount <= EMaxPages);
+	for (TUint i = 0 ; i < aCount ; ++i)
+		{
+		iUseRegionMemory[i] = aMemory[i];
+		iUseRegionIndex[i] = aIndex[i];
+		}
 	iUseRegionCount = aCount;
 	}
 
 
-TBool DPagingRequest::CheckUse(DMemoryObject* aMemory, TUint aIndex, TUint aCount)
-	{
-	return aMemory==iUseRegionMemory
-		&& TUint(aIndex-iUseRegionIndex) < iUseRegionCount
-		&& TUint(iUseRegionCount-TUint(aIndex-iUseRegionIndex)) <= aCount;
-	}
-
-
-void DPagingRequest::Release()
-	{
-	NKern::LockSystem();
-	SetUse(0,0,0);
-	Signal();
-	}
-
-
-void DPagingRequest::Wait()
+void DPagingRequest::ResetUse()
 	{
 	__ASSERT_SYSTEM_LOCK;
-	++iUsageCount;
-	TInt r = iMutex->Wait();
-	__NK_ASSERT_ALWAYS(r == KErrNone);
+	__NK_ASSERT_DEBUG(iUseRegionCount > 0);
+	iUseRegionCount = 0;
 	}
 
 
-void DPagingRequest::Signal()
+TBool DPagingRequest::CheckUseContiguous(DMemoryObject* aMemory, TUint aIndex, TUint aCount)
 	{
-	__ASSERT_SYSTEM_LOCK;
-	iPoolGroup.Signal(this);
+	if (iUseRegionCount != aCount)
+		return EFalse;
+	for (TUint i = 0 ; i < iUseRegionCount ; ++i)
+		{
+		if (iUseRegionMemory[i] != aMemory || iUseRegionIndex[i] != aIndex + i)
+			return EFalse;
+		}
+	return ETrue;
 	}
 
 
-FORCE_INLINE TBool DPagingRequest::IsCollision(DMemoryObject* aMemory, TUint aIndex, TUint aCount)
+TBool DPagingRequest::CheckUseDiscontiguous(DMemoryObject** aMemory, TUint* aIndex, TUint aCount)
 	{
+	if (iUseRegionCount != aCount)
+		return EFalse;
+	for (TUint i = 0 ; i < iUseRegionCount ; ++i)
+		{
+		if (iUseRegionMemory[i] != aMemory[i] || iUseRegionIndex[i] != aIndex[i])
+			return EFalse;
+		}
+	return ETrue;
+	}
+
+
+ TBool DPagingRequest::IsCollisionContiguous(DMemoryObject* aMemory, TUint aIndex, TUint aCount)
+	{
+	// note this could be optimised as most of the time we will be checking read/read collusions,
+	// both of which will be contiguous
 	__ASSERT_SYSTEM_LOCK;
-	DMemoryObject* memory = iUseRegionMemory;
-	TUint index = iUseRegionIndex;
-	TUint count = iUseRegionCount;
-	// note, this comparison would fail if either region includes page number KMaxTUint,
-	// but it isn't possible to create a memory object which is > KMaxTUint pages...
-	return memory == aMemory && index+count > aIndex && index < aIndex+aCount;
+	for (TUint i = 0 ; i < iUseRegionCount ; ++i)
+		{
+		if (iUseRegionMemory[i] == aMemory &&
+			TUint(iUseRegionIndex[i] - aIndex) < aCount)
+			return ETrue;
+		}
+	return EFalse;
 	}
 
 
@@ -2151,6 +2462,38 @@
 	iTempMapping.Unmap(aIMBRequired);
 	}
 
+//
+// DPoolPagingRequest
+//
+
+DPoolPagingRequest::DPoolPagingRequest(DPagingRequestPool::TGroup& aPoolGroup) :
+	iPoolGroup(aPoolGroup)
+	{
+	}
+
+
+void DPoolPagingRequest::Release()
+	{
+	NKern::LockSystem();
+	ResetUse();
+	Signal();
+	}
+
+
+void DPoolPagingRequest::Wait()
+	{
+	__ASSERT_SYSTEM_LOCK;
+	++iUsageCount;
+	TInt r = iMutex->Wait();
+	__NK_ASSERT_ALWAYS(r == KErrNone);
+	}
+
+
+void DPoolPagingRequest::Signal()
+	{
+	__ASSERT_SYSTEM_LOCK;
+	iPoolGroup.Signal(this);
+	}
 
 //
 // DPageReadRequest
@@ -2158,6 +2501,13 @@
 
 TInt DPageReadRequest::iAllocNext = 0;
 
+DPageReadRequest::DPageReadRequest(DPagingRequestPool::TGroup& aPoolGroup) :
+	DPoolPagingRequest(aPoolGroup)
+	{
+	// allocate space for mapping pages whilst they're being loaded...
+	iTempMapping.Alloc(EMaxPages);
+	}
+
 TInt DPageReadRequest::Construct()
 	{
 	// allocate id and mutex...
@@ -2169,9 +2519,6 @@
 	if(r!=KErrNone)
 		return r;
 
-	// allocate space for mapping pages whilst they're being loaded...
-	iTempMapping.Alloc(EMaxPages);
-
 	// create memory buffer...
 	TUint bufferSize = EMaxPages+1;
 	DMemoryObject* bufferMemory;
@@ -2190,11 +2537,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;
 	}
 
@@ -2203,23 +2545,20 @@
 // DPageWriteRequest
 //
 
-TInt DPageWriteRequest::iAllocNext = 0;
-
-TInt DPageWriteRequest::Construct()
+
+DPageWriteRequest::DPageWriteRequest()
 	{
-	// allocate id and mutex...
-	TUint id = (TUint)__e32_atomic_add_ord32(&iAllocNext, 1);
-	_LIT(KLitPagingRequest,"PageWriteRequest-");
-	TBuf<sizeof("PageWriteRequest-")+10> mutexName(KLitPagingRequest);
-	mutexName.AppendNum(id);
-	TInt r = K::MutexCreate(iMutex, mutexName, NULL, EFalse, KMutexOrdPageOut);
-	if(r!=KErrNone)
-		return r;
-
+	iMutex = ThePageCleaningLock;
 	// allocate space for mapping pages whilst they're being loaded...
-	iTempMapping.Alloc(EMaxPages);
-
-	return r;
+	iTempMapping.Alloc(KMaxPagesToClean);
+	}
+
+
+void DPageWriteRequest::Release()
+	{
+	NKern::LockSystem();
+	ResetUse();
+	NKern::UnlockSystem();
 	}
 
 
@@ -2227,11 +2566,10 @@
 // DPagingRequestPool
 //
 
-DPagingRequestPool::DPagingRequestPool(TUint aNumPageReadRequest,TUint aNumPageWriteRequest)
-	: iPageReadRequests(aNumPageReadRequest), iPageWriteRequests(aNumPageWriteRequest)
+DPagingRequestPool::DPagingRequestPool(TUint aNumPageReadRequest, TBool aWriteRequest)
+	: iPageReadRequests(aNumPageReadRequest)
 	{
 	TUint i;
-
 	for(i=0; i<aNumPageReadRequest; ++i)
 		{
 		DPageReadRequest* req = new DPageReadRequest(iPageReadRequests);
@@ -2242,14 +2580,10 @@
 		iPageReadRequests.iFreeList.Add(req);
 		}
 
-	for(i=0; i<aNumPageWriteRequest; ++i)
+	if (aWriteRequest)
 		{
-		DPageWriteRequest* req = new DPageWriteRequest(iPageWriteRequests);
-		__NK_ASSERT_ALWAYS(req);
-		TInt r = req->Construct();
-		__NK_ASSERT_ALWAYS(r==KErrNone);
-		iPageWriteRequests.iRequests[i] = req;
-		iPageWriteRequests.iFreeList.Add(req);
+		iPageWriteRequest = new DPageWriteRequest();
+		__NK_ASSERT_ALWAYS(iPageWriteRequest);
 		}
 	}
 
@@ -2264,24 +2598,23 @@
 	{
 	NKern::LockSystem();
 
-	DPagingRequest* req;
-
-	// if we collide with page write operation...
-	req = iPageWriteRequests.FindCollision(aMemory,aIndex,aCount);
-	if(req)
+	DPoolPagingRequest* req;
+	
+	// check for collision with existing write
+	if(iPageWriteRequest && iPageWriteRequest->IsCollisionContiguous(aMemory,aIndex,aCount))
 		{
-		// wait until write completes...
-		req->Wait();
-		req->Signal();
+		NKern::UnlockSystem();
+		PageCleaningLock::Lock();
+		PageCleaningLock::Unlock();
 		return 0; // caller expected to retry if needed
 		}
 
 	// get a request object to use...
 	req = iPageReadRequests.GetRequest(aMemory,aIndex,aCount);
 
-	// check no new requests collide with us...
-	if(iPageWriteRequests.FindCollision(aMemory,aIndex,aCount)
-		|| iPageReadRequests.FindCollision(aMemory,aIndex,aCount))
+	// check no new read or write requests collide with us...
+	if ((iPageWriteRequest && iPageWriteRequest->IsCollisionContiguous(aMemory,aIndex,aCount)) ||
+		iPageReadRequests.FindCollisionContiguous(aMemory,aIndex,aCount))
 		{
 		// another operation is colliding with this region, give up and retry...
 		req->Signal();
@@ -2289,61 +2622,57 @@
 		}
 
 	// we have a request object which we can use...
-	req->SetUse(aMemory,aIndex,aCount);
+	req->SetUseContiguous(aMemory,aIndex,aCount);
 
 	NKern::UnlockSystem();
 	return (DPageReadRequest*)req;
 	}
 
 
-DPageWriteRequest* DPagingRequestPool::AcquirePageWriteRequest(DMemoryObject* aMemory, TUint aIndex, TUint aCount)
+DPageWriteRequest* DPagingRequestPool::AcquirePageWriteRequest(DMemoryObject** aMemory, TUint* aIndex, TUint aCount)
 	{
+	__NK_ASSERT_DEBUG(iPageWriteRequest);
+	__NK_ASSERT_DEBUG(PageCleaningLock::IsHeld());
+
 	NKern::LockSystem();
 
-	DPagingRequest* req;
-
-	for(;;)
-		{
-		// get a request object to use...
-		req = iPageWriteRequests.GetRequest(aMemory,aIndex,aCount);
-
-		if(iPageWriteRequests.FindCollision(aMemory,aIndex,aCount))
-			{
-			// another write operation is colliding with this region, give up and retry...
-			req->Signal();
-			// Reacquire the system lock as Signal() above will release it.
-			NKern::LockSystem();
-			continue;
-			}
-
-		break;
-		}
-
-	// we have a request object which we can use...
-	req->SetUse(aMemory,aIndex,aCount);
-
+	// Collision with existing read requests is not possible here.  For a page to be read it must
+	// not be present, and for it to be written it must be present and dirty.  There is no way for a
+	// page to go between these states without an intervening read on an uninitialised (freshly
+	// committed) page, which will wait on the first read request.  In other words something like
+	// this:
+	//
+	//   read (blocks), decommit, re-commit, read (waits on mutex), write (now no pending reads!)
+	//
+	// Note that a read request can be outstanding and appear to collide with this write, but only
+	// in the case when the thread making the read has blocked just after acquiring the request but
+	// before it checks whether the read is still necessasry.  This makes it difficult to assert
+	// that no collisions take place.
+	
+	iPageWriteRequest->SetUseDiscontiguous(aMemory,aIndex,aCount);
 	NKern::UnlockSystem();
-	return (DPageWriteRequest*)req;
+	
+	return iPageWriteRequest;
 	}
 
 
 DPagingRequestPool::TGroup::TGroup(TUint aNumRequests)
 	{
 	iNumRequests = aNumRequests;
-	iRequests = new DPagingRequest*[aNumRequests];
+	iRequests = new DPoolPagingRequest*[aNumRequests];
 	__NK_ASSERT_ALWAYS(iRequests);
 	}
 
 
-DPagingRequest* DPagingRequestPool::TGroup::FindCollision(DMemoryObject* aMemory, TUint aIndex, TUint aCount)
+DPoolPagingRequest* DPagingRequestPool::TGroup::FindCollisionContiguous(DMemoryObject* aMemory, TUint aIndex, TUint aCount)
 	{
 	__ASSERT_SYSTEM_LOCK;
-	DPagingRequest** ptr = iRequests;
-	DPagingRequest** ptrEnd = ptr+iNumRequests;
+	DPoolPagingRequest** ptr = iRequests;
+	DPoolPagingRequest** ptrEnd = ptr+iNumRequests;
 	while(ptr<ptrEnd)
 		{
-		DPagingRequest* req = *ptr++;
-		if(req->IsCollision(aMemory,aIndex,aCount))
+		DPoolPagingRequest* req = *ptr++;
+		if(req->IsCollisionContiguous(aMemory,aIndex,aCount))
 			return req;
 		}
 	return 0;
@@ -2352,16 +2681,16 @@
 
 static TUint32 RandomSeed = 33333;
 
-DPagingRequest* DPagingRequestPool::TGroup::GetRequest(DMemoryObject* aMemory, TUint aIndex, TUint aCount)
+DPoolPagingRequest* DPagingRequestPool::TGroup::GetRequest(DMemoryObject* aMemory, TUint aIndex, TUint aCount)
 	{
 	__NK_ASSERT_DEBUG(iNumRequests > 0);
 
 	// try using an existing request which collides with this region...
-	DPagingRequest* req  = FindCollision(aMemory,aIndex,aCount);
+	DPoolPagingRequest* req  = FindCollisionContiguous(aMemory,aIndex,aCount);
 	if(!req)
 		{
 		// use a free request...
-		req = (DPagingRequest*)iFreeList.GetFirst();
+		req = (DPoolPagingRequest*)iFreeList.GetFirst();
 		if(req)
 			{
 			// free requests aren't being used...
@@ -2384,7 +2713,7 @@
 	}
 
 
-void DPagingRequestPool::TGroup::Signal(DPagingRequest* aRequest)
+void DPagingRequestPool::TGroup::Signal(DPoolPagingRequest* aRequest)
 	{
 	// if there are no threads waiting on the mutex then return it to the free pool...
 	__NK_ASSERT_DEBUG(aRequest->iUsageCount > 0);
@@ -2406,13 +2735,14 @@
 	{
 	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
 
 	// create the pools of page out and page in requests...
-	const TInt writeReqs = (aDevice->iType & DPagingDevice::EData) ? KPagingRequestsPerDevice : 0;
-	aDevice->iRequestPool = new DPagingRequestPool(KPagingRequestsPerDevice,writeReqs);
+	const TBool writeReq = (aDevice->iType & DPagingDevice::EData) != 0;
+	aDevice->iRequestPool = new DPagingRequestPool(KPagingRequestsPerDevice, writeReq);
 	if(!aDevice->iRequestPool)
 		{
 		r = KErrNoMemory;
@@ -2442,6 +2772,9 @@
 
  	if (K::MemModelAttributes & (EMemModelAttrRomPaging | EMemModelAttrCodePaging | EMemModelAttrDataPaging))
 		TheThrashMonitor.Start();
+	
+ 	if (K::MemModelAttributes & EMemModelAttrDataPaging)
+		PageCleaner::Start();
 
 exit:
 	TRACEB(("Kern::InstallPagingDevice returns %d",r));
@@ -2591,3 +2924,32 @@
 	}
 
 
+
+//
+// PageCleaningLock
+//
+
+_LIT(KLitPageCleaningLock,"PageCleaningLock");
+
+void PageCleaningLock::Init()
+	{
+	__NK_ASSERT_DEBUG(!ThePageCleaningLock);
+	TInt r = Kern::MutexCreate(ThePageCleaningLock, KLitPageCleaningLock, KMutexOrdPageOut);
+	__NK_ASSERT_ALWAYS(r == KErrNone);
+	}
+
+void PageCleaningLock::Lock()
+	{
+	Kern::MutexWait(*ThePageCleaningLock);
+	}
+
+
+void PageCleaningLock::Unlock()
+	{
+	Kern::MutexSignal(*ThePageCleaningLock);
+	}
+
+TBool PageCleaningLock::IsHeld()
+	{
+	return ThePageCleaningLock->iCleanup.iThread == &Kern::CurrentThread();
+	}
--- a/kernel/eka/memmodel/epoc/flexible/mmu/mpager.h	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/memmodel/epoc/flexible/mmu/mpager.h	Fri Apr 16 16:24:37 2010 +0300
@@ -21,6 +21,13 @@
 #ifndef MPAGER_H
 #define MPAGER_H
 
+#include <kern_priv.h>
+
+/**
+Maximum number of pages to attempt to clean in one go.
+*/
+const TInt KMaxPagesToClean = 4;
+
 struct SVMCacheInfo;
 class DMemModelThread;
 class DMemoryMappingBase;
@@ -29,9 +36,14 @@
 	{
 public:
 	DPager();
-	void Init2();
+	void InitCache();
 	void Init3();
 
+	FORCE_INLINE TBool CacheInitialised()
+		{
+		return iYoungOldRatio && iMinimumPageLimit;
+		}
+
 	FORCE_INLINE TUint NumberOfFreePages()
 		{
 		return iNumberOfFreePages;
@@ -51,9 +63,9 @@
 		if (!aPageInfo.IsDirty())
 			{// This is the first mapping to write to the page so increase the 
 			// dirty page count.
-			aPageInfo.SetWritable();
 			iNumberOfDirtyPages++;
 			}
+		aPageInfo.SetWritable();
 		}
 	
 	FORCE_INLINE void SetClean(SPageInfo& aPageInfo)
@@ -236,6 +248,31 @@
 	void UnreservePages(TUint& aCount);
 
 	/**
+	Indicates whether there are any dirty pages available to be cleaned by #CleanSomePages.
+
+	This is called by the page cleaner to work out whether it has any work to do.
+
+	@return Whether there are any dirty pages in the oldest section of the live list.
+	*/
+	TBool HasPagesToClean();
+
+	/**
+	Attempt to clean one or more dirty pages in one go.
+
+	Called by the page cleaner to clean pages and by PageInAllocPage when needs to steal a page from
+	the live list, but the oldest clean list is empty.
+
+	May or may not succeed in acually cleaning any pages.
+
+	@param aBackground Whether the activity should be ignored when determining whether the paging
+	                   device is busy.  This is used by the page cleaner.
+
+	@return The number of pages this method attempted to clean.  If it returns zero, there were no
+	        pages eligible to be cleaned.
+	*/
+	TInt CleanSomePages(TBool aBackground);
+
+	/**
 	Enumeration of instrumented paging events which only require the
 	SPageInfo object as an argument. 
 	*/
@@ -347,10 +384,23 @@
 	void RemovePage(SPageInfo* aPageInfo);
 
 	/**
+	Try to remove the oldest page from the live page list and perform #StealPage.
+
+	@param aPageInfoOut Set to the SPageInfo pointer for the stolen page if any.
+	
+	@return KErrNone on success, KErrInUse if stealing failed or 1 to indicate the the oldest page
+	was dirty and the PageCleaning mutex was not held.
+	
+	@pre MmuLock held
+	@post MmuLock left unchanged.
+	*/
+	TInt TryStealOldestPage(SPageInfo*& aPageInfoOut);
+
+	/**
 	Remove the oldest page from the live page list and perform #StealPage.
 
 	@pre MmuLock held
-	@post MmuLock left unchanged.
+	@post MmuLock held (but may have been released by this function)
 	*/
 	SPageInfo* StealOldestPage();
 
@@ -361,6 +411,7 @@
 	if the page had been allocated by Mmu::AllocRam.
 
 	@pre RamAlloc mutex held
+	@pre If the page is dirty the PageCleaning lock must be held.
 	@pre MmuLock held
 	@post MmuLock held (but may have been released by this function)
 	*/
@@ -418,6 +469,22 @@
 	SPageInfo* PageInAllocPage(Mmu::TRamAllocFlags aAllocFlags);
 
 	/**
+	Called by CleanSomePages() to determine which pages should be cleaned.
+
+	This deals with the complexity of page colouring, which means that pages can only be mapped at
+	certain locations.  When cleaning multiple pages at once we need to find a set of pages that we
+	can map in memory sequentially.
+
+	@pre MmuLock held
+	
+	@param aPageInfosOut Pointer to an array of SPageInfo pointers, which must be at least
+	KMaxPagesToClean long.  This will be filled in to indicate the pages to clean.
+	
+	@return The numnber of pages to clean.
+	*/
+	TInt SelectPagesToClean(SPageInfo** aPageInfosOut);
+
+	/**
 	If the number of young pages exceeds that specified by iYoungOldRatio then a
 	single page is made 'old'. Call this after adding a new 'young' page.
 
@@ -511,13 +578,11 @@
 	TUint iYoungCount;			/**< Number of young pages */
 	SDblQue iOldList;			/**< Head of 'old' page list. */
 	TUint iOldCount;			/**< Number of old pages */
-#ifdef _USE_OLDEST_LISTS
 	SDblQue iOldestCleanList;	/**< Head of 'oldestClean' page list. */
 	TUint iOldestCleanCount;	/**< Number of 'oldestClean' pages */
 	SDblQue iOldestDirtyList;	/**< Head of 'oldestDirty' page list. */
 	TUint iOldestDirtyCount;	/**< Number of 'oldestDirty' pages */
 	TUint16 iOldOldestRatio;	/**< Ratio of old pages to oldest to clean and dirty in the live page list*/
-#endif
 	TUint iNumberOfFreePages;
 	TUint iNumberOfDirtyPages;	/**< The total number of dirty pages in the paging cache. Protected by MmuLock */
 	TUint iInitMinimumPageCount;/**< Initial value for iMinimumPageCount */
@@ -529,8 +594,10 @@
 
 #ifdef __DEMAND_PAGING_BENCHMARKS__
 public:
-	void RecordBenchmarkData(TPagingBenchmark aBm, TUint32 aStartTime, TUint32 aEndTime);
+	void RecordBenchmarkData(TPagingBenchmark aBm, TUint32 aStartTime, TUint32 aEndTime, TUint aCount);
 	void ResetBenchmarkData(TPagingBenchmark aBm);
+	void ReadBenchmarkData(TPagingBenchmark aBm, SPagingBenchmarkInfo& aDataOut);
+	TSpinLock iBenchmarkLock;
 	SPagingBenchmarkInfo iBenchmarkInfo[EMaxPagingBm];
 #endif //__DEMAND_PAGING_BENCHMARKS__
 	};
@@ -541,12 +608,14 @@
 #ifdef __DEMAND_PAGING_BENCHMARKS__
 
 #define START_PAGING_BENCHMARK TUint32 _bmStart = NKern::FastCounter()
-#define END_PAGING_BENCHMARK(bm) ThePager.RecordBenchmarkData(bm, _bmStart, NKern::FastCounter())
+#define END_PAGING_BENCHMARK(bm) ThePager.RecordBenchmarkData(bm, _bmStart, NKern::FastCounter(), 1)
+#define END_PAGING_BENCHMARK_N(bm, n) ThePager.RecordBenchmarkData(bm, _bmStart, NKern::FastCounter(), (n))
 
 #else
 
 #define START_PAGING_BENCHMARK
 #define END_PAGING_BENCHMARK(bm)
+#define END_PAGING_BENCHMARK_N(bm, n)
 #endif // __DEMAND_PAGING_BENCHMARKS__
 
 
@@ -688,7 +757,7 @@
 const TInt KPagingRequestsPerDevice = 2;
 
 
-class DPagingRequest;
+class DPoolPagingRequest;
 class DPageReadRequest;
 class DPageWriteRequest;
 
@@ -698,9 +767,9 @@
 class DPagingRequestPool : public DBase
 	{
 public:
-	DPagingRequestPool(TUint aNumPageReadRequest,TUint aNumPageWriteRequest);
+	DPagingRequestPool(TUint aNumPageReadRequest, TBool aWriteRequest);
 	DPageReadRequest* AcquirePageReadRequest(DMemoryObject* aMemory, TUint aIndex, TUint aCount);
-	DPageWriteRequest* AcquirePageWriteRequest(DMemoryObject* aMemory, TUint aIndex, TUint aCount);
+	DPageWriteRequest* AcquirePageWriteRequest(DMemoryObject** aMemory, TUint* aIndex, TUint aCount);
 private:
 	~DPagingRequestPool();
 private:
@@ -708,18 +777,18 @@
 		{
 	public:
 		TGroup(TUint aNumRequests);
-		DPagingRequest* FindCollision(DMemoryObject* aMemory, TUint aIndex, TUint aCount);
-		DPagingRequest* GetRequest(DMemoryObject* aMemory, TUint aIndex, TUint aCount);
-		void Signal(DPagingRequest* aRequest);
+		DPoolPagingRequest* FindCollisionContiguous(DMemoryObject* aMemory, TUint aIndex, TUint aCount);
+		DPoolPagingRequest* GetRequest(DMemoryObject* aMemory, TUint aIndex, TUint aCount);
+		void Signal(DPoolPagingRequest* aRequest);
 	public:
 		TUint iNumRequests;
-		DPagingRequest** iRequests;
+		DPoolPagingRequest** iRequests;
 		SDblQue iFreeList;
 		};
 	TGroup iPageReadRequests;
-	TGroup iPageWriteRequests;
+	DPageWriteRequest* iPageWriteRequest;
 
-	friend class DPagingRequest;
+	friend class DPoolPagingRequest;
 	friend class DPageReadRequest;
 	friend class DPageWriteRequest;
 	};
@@ -731,45 +800,59 @@
 class DPagingRequest : public SDblQueLink
 	{
 public:
-	DPagingRequest(DPagingRequestPool::TGroup& aPoolGroup);
-	void Release();
-	void Wait();
-	void Signal();
-	void SetUse(DMemoryObject* aMemory, TUint aIndex, TUint aCount);
-	TBool CheckUse(DMemoryObject* aMemory, TUint aIndex, TUint aCount);
-	TBool IsCollision(DMemoryObject* aMemory, TUint aIndex, TUint aCount);
-	TLinAddr MapPages(TUint aColour, TUint aCount, TPhysAddr* aPages);
-	void UnmapPages(TBool aIMBRequired);
-public:
-	TThreadMessage	iMessage;	/**< Used by the media driver to queue requests */
-	DMutex*			iMutex;		/**< A mutex for synchronisation and priority inheritance. */
-	TInt			iUsageCount;/**< How many threads are using or waiting for this object. */
-	TLinAddr		iBuffer;	/**< A buffer to read compressed data into. Size is EMaxPages+1 pages.*/
-protected:
-	Mmu::TTempMapping	iTempMapping;
-private:
-	DPagingRequestPool::TGroup& iPoolGroup;
-	// used to identify memory request is used for...
-	DMemoryObject*	iUseRegionMemory;
-	TUint			iUseRegionIndex;
-	TUint			iUseRegionCount;
-	};
-
-
-/**
-Resources needed to service a page in request.
-*/
-class DPageReadRequest : public DPagingRequest
-	{
-public:
-	inline DPageReadRequest(DPagingRequestPool::TGroup& aPoolGroup)
-		: DPagingRequest(aPoolGroup)
-		{}
-	TInt Construct();
 	enum
 		{
 		EMaxPages = 4
 		};
+	DPagingRequest();
+	TLinAddr MapPages(TUint aColour, TUint aCount, TPhysAddr* aPages);
+	void UnmapPages(TBool aIMBRequired);
+	void SetUseContiguous(DMemoryObject* aMemory, TUint aIndex, TUint aCount);
+	void SetUseDiscontiguous(DMemoryObject** aMemory, TUint* aIndex, TUint aCount);
+	void ResetUse();
+	TBool CheckUseContiguous(DMemoryObject* aMemory, TUint aIndex, TUint aCount);
+	TBool CheckUseDiscontiguous(DMemoryObject** aMemory, TUint* aIndex, TUint aCount);
+	TBool IsCollisionContiguous(DMemoryObject* aMemory, TUint aIndex, TUint aCount);
+public:
+	DMutex*			iMutex;		/**< A mutex for synchronisation and priority inheritance. */
+protected:
+	Mmu::TTempMapping	iTempMapping;
+private:
+	// used to identify memory request is used for...
+	TUint			iUseRegionCount;
+	DMemoryObject*	iUseRegionMemory[EMaxPages];
+	TUint			iUseRegionIndex[EMaxPages];
+	};
+
+
+__ASSERT_COMPILE(DPagingRequest::EMaxPages >= KMaxPagesToClean);
+
+
+/**
+A paging request that is part of a pool of similar request objects.
+*/
+class DPoolPagingRequest : public DPagingRequest
+	{
+public:
+	DPoolPagingRequest(DPagingRequestPool::TGroup& aPoolGroup);
+ 	void Release();
+	void Wait();
+	void Signal();
+public:
+	TInt			iUsageCount;	/**< How many threads are using or waiting for this object. */	
+private:
+	DPagingRequestPool::TGroup& iPoolGroup;
+	};
+
+	
+/**
+Resources needed to service a page in request.
+*/
+class DPageReadRequest : public DPoolPagingRequest
+	{
+public:
+	DPageReadRequest(DPagingRequestPool::TGroup& aPoolGroup);
+	TInt Construct();
 	static TUint ReservedPagesRequired();
 private:
 	~DPageReadRequest(); // can't delete
@@ -794,18 +877,45 @@
 class DPageWriteRequest : public DPagingRequest
 	{
 public:
-	inline DPageWriteRequest(DPagingRequestPool::TGroup& aPoolGroup)
-		: DPagingRequest(aPoolGroup)
-		{}
-	TInt Construct();
-	enum
-		{
-		EMaxPages = 1
-		};
+	DPageWriteRequest();
+ 	void Release();
 private:
 	~DPageWriteRequest(); // can't delete
-private:
-	static TInt iAllocNext;
+	};
+
+
+/**
+Class providing access to the mutex used to protect page cleaning operations;
+this is the mutex DPager::iPageCleaningLock.
+*/
+class PageCleaningLock
+	{
+public:
+	/**
+	Acquire the lock.
+	The lock may be acquired multiple times by a thread, and will remain locked
+	until #Unlock has been used enough times to balance this.
+	*/
+	static void Lock();
+
+	/**
+	Release the lock.
+
+	@pre The current thread has previously acquired the lock.
+	*/
+	static void Unlock();
+
+	/**
+	Return true if the current thread holds the lock.
+	This is used for debug checks.
+	*/
+	static TBool IsHeld();
+
+	/**
+	Create the lock.
+	Called by DPager::Init3().
+	*/
+	static void Init();	
 	};
 
 
--- a/kernel/eka/memmodel/epoc/flexible/mmu/mrefcntobj.h	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/memmodel/epoc/flexible/mmu/mrefcntobj.h	Fri Apr 16 16:24:37 2010 +0300
@@ -97,12 +97,6 @@
 	*/
 	TBool CheckCloseIsSafe();
 
-	/**
-	Return true if the preconditions for #AsyncClose are met.
-	This is for use by derived classes which overload the #AsyncClose method.
-	*/
-	TBool CheckAsyncCloseIsSafe();
-
 protected:
 
 	/**
--- a/kernel/eka/memmodel/epoc/flexible/mmu/mrom.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/memmodel/epoc/flexible/mmu/mrom.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -530,15 +530,18 @@
 
 TInt DRomMemoryManager::ReadPages(DMemoryObject* aMemory, TUint aIndex, TUint aCount, TPhysAddr* aPages, DPageReadRequest* aRequest)
 	{
-	__NK_ASSERT_DEBUG(aRequest->CheckUse(aMemory,aIndex,aCount));
+	__NK_ASSERT_DEBUG(aRequest->CheckUseContiguous(aMemory,aIndex,aCount));
+	__ASSERT_CRITICAL;
 
 	TLinAddr linAddr = aRequest->MapPages(aIndex,aCount,aPages);
 	TInt r = KErrNone;
+	TThreadMessage message;
 
 	const TInt readUnitShift = iDevice->iReadUnitShift;
 
 	for(; aCount; ++aIndex, --aCount, linAddr+=KPageSize)
 		{
+		
 		START_PAGING_BENCHMARK;
 		if(!iRomPageIndex)
 			{
@@ -548,7 +551,7 @@
 			// by readUnitShift.
 			const TInt dataOffset = aIndex << KPageShift;
 			START_PAGING_BENCHMARK;
-			r = iDevice->Read(	const_cast<TThreadMessage*>(&aRequest->iMessage), 
+			r = iDevice->Read(	&message, 
 								linAddr, dataOffset >> readUnitShift, 
 								KPageSize >> readUnitShift, DPagingDevice::EDriveRomPaging);
 			__NK_ASSERT_DEBUG(r!=KErrNoMemory); // not allowed to allocated memory, therefore can't fail with KErrNoMemory
@@ -571,13 +574,12 @@
 				__NK_ASSERT_ALWAYS(romPageInfo->iPagingAttributes & SRomPageInfo::EPageable);
 
 				// Read data for page...
-				TThreadMessage* msg = const_cast<TThreadMessage*>(&aRequest->iMessage);
 				const TLinAddr buffer = aRequest->iBuffer;
 				const TUint readStart = dataOffset >> readUnitShift;
 				const TUint readSize = ((dataOffset + dataSize - 1) >> readUnitShift) - readStart + 1;
 				__NK_ASSERT_DEBUG((readSize << readUnitShift) <= (DPageReadRequest::EMaxPages << KPageShift));
 				START_PAGING_BENCHMARK;
-				r = iDevice->Read(msg, buffer, readStart, readSize, DPagingDevice::EDriveRomPaging);
+				r = iDevice->Read(&message, buffer, readStart, readSize, DPagingDevice::EDriveRomPaging);
 				__NK_ASSERT_DEBUG(r!=KErrNoMemory); // not allowed to allocated memory, therefore can't fail with KErrNoMemory
 				END_PAGING_BENCHMARK(EPagingBmReadMedia);
 				if(r==KErrNone)
--- a/kernel/eka/memmodel/epoc/mmubase/mmubase.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/memmodel/epoc/mmubase/mmubase.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -2683,8 +2683,8 @@
 	SPageInfo::TType type = aPageInfo->Type();
 	if(type==SPageInfo::EChunk)
 		{
-		//Must not donate locked page. An example is DMA trasferred memory.
-		__NK_ASSERT_DEBUG(0 == aPageInfo->LockCount());
+		// Must not donate locked page. An example is DMA transferred memory.
+		__NK_ASSERT_DEBUG(!aPageInfo->LockCount());
 
 		aPageInfo->Change(SPageInfo::EPagedCache,SPageInfo::EStatePagedYoung);
 		iPageList.Add(&aPageInfo->iLink);
@@ -3698,8 +3698,8 @@
 	SPageInfo::TType type = aPageInfo->Type();
 	if(type==SPageInfo::EChunk)
 		{
-		//Must not donate locked page. An example is DMA trasferred memory.
-		__NK_ASSERT_DEBUG(0 == aPageInfo->LockCount());
+		// Must not donate locked page. An example is DMA transferred memory.
+		__NK_ASSERT_DEBUG(!aPageInfo->LockCount());
 		
 		aPageInfo->Change(SPageInfo::EPagedCache,SPageInfo::EStatePagedYoung);
 
@@ -5225,6 +5225,12 @@
 
 // Misc DPagingDevice methods
 
+EXPORT_C NFastMutex* DPagingDevice::NotificationLock()
+	{
+	// use the system lock
+	return &TheScheduler.iLock;
+	}
+
 EXPORT_C void DPagingDevice::NotifyIdle()
 	{
 	// Not used on this memory model
--- a/kernel/eka/memmodel/epoc/moving/arm/xmmu.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/memmodel/epoc/moving/arm/xmmu.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -444,14 +444,18 @@
 	return phys;
 	}
 
+
 TInt ArmMmu::PreparePagesForDMA(TLinAddr aLinAddr, TInt aSize, TPhysAddr* aPhysicalPageList)
 //Returns the list of physical pages belonging to the specified memory space.
 //Checks these pages belong to a chunk marked as being trusted. 
-//Locks these pages so they can not be moved by e.g. ram defragmenation.
+//Locks these pages so they can not be moved by e.g. ram defragmentation.
 	{
 	SPageInfo* pi = NULL;
 	DChunk* chunk = NULL;
 	TInt err = KErrNone;
+
+	__NK_ASSERT_DEBUG(MM::MaxPagesInOneGo == 32);	// Needs to be a power of 2.
+	TUint flashMask = MM::MaxPagesInOneGo - 1;
 	
 	__KTRACE_OPT(KMMU2,Kern::Printf("ArmMmu::PreparePagesForDMA %08x+%08x, asid=%d",aLinAddr,aSize));
 
@@ -474,41 +478,64 @@
 		
 		pagesLeft -= pagesLeftInChunk;
 
-		TPte* pt = SafePageTableFromPde(*pdePtr++);
-		if(!pt) { err = KErrNotFound; goto fail; }// Cannot get page table.
-
-		pt += pageIndex;
+		TPte* pPte = SafePageTableFromPde(*pdePtr++);
+		if(!pPte) 
+			{// Cannot get page table. 
+			err = KErrNotFound; 
+			goto fail; 
+			}
+		
+		pPte += pageIndex;
 
 		for(;pagesLeftInChunk--;)
 			{
-			TPhysAddr phys = (*pt++ & KPteSmallPageAddrMask);
+			TPhysAddr phys = (*pPte++ & KPteSmallPageAddrMask);
 			pi =  SPageInfo::SafeFromPhysAddr(phys);
-			if(!pi)	{ err = KErrNotFound; goto fail; }// Invalid address
-
+			if(!pi)	
+				{// Invalid address
+				err = KErrNotFound; 
+				goto fail; 
+				}
+			
 			__KTRACE_OPT(KMMU2,Kern::Printf("PageInfo: PA:%x T:%x S:%x O:%x C:%x",phys, pi->Type(), pi->State(), pi->Owner(), pi->LockCount()));
-			if (chunk==NULL)
+			if (chunk == NULL)
 				{//This is the first page. Check 'trusted' bit.
 				if (pi->Type()!= SPageInfo::EChunk)
-					{ err = KErrAccessDenied; goto fail; }// The first page do not belong to chunk.	
+					{// The first page does not belong to a chunk.
+					err = KErrAccessDenied;
+					goto fail;
+					}
 
 				chunk = (DChunk*)pi->Owner();
-				if ( (chunk == NULL) || ((chunk->iAttributes & DChunk::ETrustedChunk)== 0) )
-					{ err = KErrAccessDenied; goto fail; } // Not a trusted chunk
+				if ((chunk == NULL) || ((chunk->iAttributes & DChunk::ETrustedChunk) == 0))
+					{// Not a trusted chunk
+					err = KErrAccessDenied;
+					goto fail;
+					}
 				}
 			pi->Lock();
 
 			*pageList++ = phys;
-			if ( (++pagesInList&127) == 0) //release system lock temporarily on every 512K
+
+			if(!(++pagesInList & flashMask))
+				{
 				NKern::FlashSystem();
+				}
 			}
 		pageIndex = 0;
 		}
 
-	if (pi->Type()!= SPageInfo::EChunk)
-		{ err = KErrAccessDenied; goto fail; }// The last page do not belong to chunk.	
+	if (pi->Type() != SPageInfo::EChunk)
+		{// The last page does not belong to a chunk.
+		err = KErrAccessDenied;
+		goto fail;
+		}
 
 	if (chunk && (chunk != (DChunk*)pi->Owner()))
-		{ err = KErrArgument; goto fail; }//The first & the last page do not belong to the same chunk.
+		{//The first & the last page do not belong to the same chunk.
+		err = KErrArgument;
+		goto fail;
+		}
 
 	NKern::UnlockSystem();
 	MmuBase::Signal();
@@ -522,6 +549,7 @@
 	return err;
 	}
 
+
 TInt ArmMmu::ReleasePagesFromDMA(TPhysAddr* aPhysicalPageList, TInt aPageCount)
 // Unlocks physical pages.
 // @param aPhysicalPageList - points to the list of physical pages that should be released.
@@ -530,6 +558,7 @@
 	NKern::LockSystem();
 	__KTRACE_OPT(KMMU2,Kern::Printf("ArmMmu::ReleasePagesFromDMA count:%d",aPageCount));
 
+	TUint flashMask = MM::MaxPagesInOneGo - 1;
 	while (aPageCount--)
 		{
 		SPageInfo* pi =  SPageInfo::SafeFromPhysAddr(*aPhysicalPageList++);
@@ -540,12 +569,18 @@
 			}
 		__KTRACE_OPT(KMMU2,Kern::Printf("PageInfo: T:%x S:%x O:%x C:%x",pi->Type(), pi->State(), pi->Owner(), pi->LockCount()));
 		pi->Unlock();
+
+		if(!(aPageCount & flashMask))
+			{
+			NKern::FlashSystem();
+			}
 		}
 	NKern::UnlockSystem();
 	return KErrNone;
 	}
 
 
+
 void ArmMmu::Init1()
 	{
 	__KTRACE_OPT2(KBOOT,KMMU,Kern::Printf("ArmMmu::Init1"));
--- a/kernel/eka/memmodel/epoc/moving/minit.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/memmodel/epoc/moving/minit.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -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/moving/mprocess.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/memmodel/epoc/moving/mprocess.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -899,7 +899,7 @@
 		goto retry;
 #endif
 	
-	return K::ParseDesHeader(aSrc, header, aDest);
+	return (r < 0) ? r : K::ParseDesHeader(aSrc, header, aDest);
 	}
 
 DMemModelChunk* ChunkFromAddress(DThread* aThread, const TAny* aAddress)
--- a/kernel/eka/memmodel/epoc/multiple/arm/xmmu.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/memmodel/epoc/multiple/arm/xmmu.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -365,14 +365,18 @@
 		}
 	}
 
+
 TInt ArmMmu::PreparePagesForDMA(TLinAddr aLinAddr, TInt aSize, TInt aOsAsid, TPhysAddr* aPhysicalPageList)
 //Returns the list of physical pages belonging to the specified memory space.
 //Checks these pages belong to a chunk marked as being trusted. 
-//Locks these pages so they can not be moved by e.g. ram defragmenation.
+//Locks these pages so they can not be moved by e.g. ram defragmentation.
 	{
 	SPageInfo* pi = NULL;
 	DChunk* chunk = NULL;
 	TInt err = KErrNone;
+
+	__NK_ASSERT_DEBUG(MM::MaxPagesInOneGo == 32);	// Needs to be a power of 2.
+	TUint flashMask = MM::MaxPagesInOneGo - 1;
 	
 	__KTRACE_OPT(KMMU2,Kern::Printf("ArmMmu::PreparePagesForDMA %08x+%08x, asid=%d",aLinAddr,aSize,aOsAsid));
 
@@ -388,6 +392,10 @@
 	MmuBase::Wait(); 	// RamAlloc Mutex for accessing page/directory tables.
 	NKern::LockSystem();// SystemlLock for accessing SPageInfo objects.
 
+	// Get the page directory entry that maps aLinAddr.
+	// If the address is in the global region check whether this asid maps
+	// global pdes (i.e. the LSB of iAsidInfo is set), if not find the pde from 
+	// the kernel's initial page directory.
 	TPde* pdePtr = (pdeIndex<(iLocalPdSize>>2) || (iAsidInfo[aOsAsid]&1)) ? PageDirectory(aOsAsid) : ::InitPageDirectory;
 	pdePtr += pdeIndex;//This points to the first pde 
 
@@ -399,41 +407,66 @@
 		
 		pagesLeft -= pagesLeftInChunk;
 
-		TPte* pt = SafePageTableFromPde(*pdePtr++);
-		if(!pt) { err = KErrNotFound; goto fail; }// Cannot get page table.
+		TPte* pPte = SafePageTableFromPde(*pdePtr++);
+		if(!pPte) 
+			{// Cannot get page table. 
+			err = KErrNotFound; 
+			goto fail; 
+			}
 		
-		pt += pageIndex;
+		pPte += pageIndex;
 
 		for(;pagesLeftInChunk--;)
-			{
-			TPhysAddr phys = (*pt++ & KPteSmallPageAddrMask);
+			{// This pte must be of type ArmV6 small page, the pde type will 
+			// have already been checked by SafePageTableFromPde().
+			__NK_ASSERT_DEBUG((*pPte & KArmV6PteTypeMask) >= KArmV6PteSmallPage);
+			TPhysAddr phys = (*pPte++ & KPteSmallPageAddrMask);
 			pi =  SPageInfo::SafeFromPhysAddr(phys);
-			if(!pi)	{ err = KErrNotFound; goto fail; }// Invalid address
+			if(!pi)	
+				{// Invalid address
+				err = KErrNotFound; 
+				goto fail; 
+				}
 			
 			__KTRACE_OPT(KMMU2,Kern::Printf("PageInfo: PA:%x T:%x S:%x O:%x C:%x",phys, pi->Type(), pi->State(), pi->Owner(), pi->LockCount()));
-			if (chunk==NULL)
+			if (chunk == NULL)
 				{//This is the first page. Check 'trusted' bit.
 				if (pi->Type()!= SPageInfo::EChunk)
-					{ err = KErrAccessDenied; goto fail; }// The first page do not belong to chunk.	
+					{// The first page does not belong to a chunk.
+					err = KErrAccessDenied;
+					goto fail;
+					}
 
 				chunk = (DChunk*)pi->Owner();
-				if ( (chunk == NULL) || ((chunk->iAttributes & DChunk::ETrustedChunk)== 0) )
-					{ err = KErrAccessDenied; goto fail; }// Not a trusted chunk
+				if ((chunk == NULL) || ((chunk->iAttributes & DChunk::ETrustedChunk) == 0))
+					{// Not a trusted chunk
+					err = KErrAccessDenied;
+					goto fail;
+					}
 				}
 			pi->Lock();
 
 			*pageList++ = phys;
-			if ( (++pagesInList&127) == 0) //release system lock temporarily on every 512K
+
+			if(!(++pagesInList & flashMask))
+				{
 				NKern::FlashSystem();
+				}
 			}
 		pageIndex = 0;
 		}
 
-	if (pi->Type()!= SPageInfo::EChunk)
-		{ err = KErrAccessDenied; goto fail; }// The last page do not belong to chunk.	
+	if (pi->Type() != SPageInfo::EChunk)
+		{// The last page does not belong to a chunk.
+		err = KErrAccessDenied;
+		goto fail;
+		}
 
 	if (chunk && (chunk != (DChunk*)pi->Owner()))
-		{ err = KErrArgument; goto fail; }//The first & the last page do not belong to the same chunk.
+		{//The first & the last page do not belong to the same chunk.
+		err = KErrArgument;
+		goto fail;
+		}
 
 	NKern::UnlockSystem();
 	MmuBase::Signal();
@@ -447,6 +480,7 @@
 	return err;
 	}
 
+
 TInt ArmMmu::ReleasePagesFromDMA(TPhysAddr* aPhysicalPageList, TInt aPageCount)
 // Unlocks physical pages.
 // @param aPhysicalPageList - points to the list of physical pages that should be released.
@@ -455,6 +489,7 @@
 	NKern::LockSystem();
 	__KTRACE_OPT(KMMU2,Kern::Printf("ArmMmu::ReleasePagesFromDMA count:%d",aPageCount));
 
+	TUint flashMask = MM::MaxPagesInOneGo - 1;
 	while (aPageCount--)
 		{
 		SPageInfo* pi =  SPageInfo::SafeFromPhysAddr(*aPhysicalPageList++);
@@ -465,11 +500,17 @@
 			}
 		__KTRACE_OPT(KMMU2,Kern::Printf("PageInfo: T:%x S:%x O:%x C:%x",pi->Type(), pi->State(), pi->Owner(), pi->LockCount()));
 		pi->Unlock();
+
+		if(!(aPageCount & flashMask))
+			{
+			NKern::FlashSystem();
+			}
 		}
 	NKern::UnlockSystem();
 	return KErrNone;
 	}
 
+
 TPhysAddr ArmMmu::LinearToPhysical(TLinAddr aLinAddr, TInt aOsAsid)
 //
 // Find the physical address corresponding to a given linear address in a specified OS
--- a/kernel/eka/memmodel/epoc/multiple/mcodeseg.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/memmodel/epoc/multiple/mcodeseg.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -173,15 +173,21 @@
 
 		// copy export directory (this will now have fixups applied)...
 		TInt exportDirSize = iRamInfo.iExportDirCount * sizeof(TLinAddr);
-		if (exportDirSize > 0 || (exportDirSize==0 && (iCodeSeg->iAttr&ECodeSegAttNmdExpData)) )
+		if (exportDirSize > 0 || (exportDirSize == 0 && (iCodeSeg->iAttr & ECodeSegAttNmdExpData)) )
 			{
 			exportDirSize += sizeof(TLinAddr);
+			TLinAddr expDirRunAddr = iRamInfo.iExportDir - sizeof(TLinAddr);
+			if (expDirRunAddr < iRamInfo.iCodeRunAddr ||
+				expDirRunAddr + exportDirSize > iRamInfo.iCodeRunAddr + iRamInfo.iCodeSize)
+				{// Invalid export section.
+				return KErrCorrupt;
+				}
 			TLinAddr* expDir = (TLinAddr*)Kern::Alloc(exportDirSize);
 			if (!expDir)
 				return KErrNoMemory;
 			iCopyOfExportDir = expDir;
 			UNLOCK_USER_MEMORY();
-			memcpy(expDir,(TAny*)(iRamInfo.iExportDir-sizeof(TLinAddr)),exportDirSize);
+			memcpy(expDir, (TAny*)expDirRunAddr, exportDirSize);
 			LOCK_USER_MEMORY();
 			}
 		}
--- a/kernel/eka/memmodel/epoc/multiple/minit.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/memmodel/epoc/multiple/minit.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -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	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/memmodel/epoc/putils.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -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/memmodel/memmodel.mmp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/memmodel/memmodel.mmp	Fri Apr 16 16:24:37 2010 +0300
@@ -102,6 +102,7 @@
 source			mpager.cpp mrom.cpp mdatapaging.cpp mcodepaging.cpp
 source			mexport.cpp mthrash.cpp
 source			mdefrag.cpp mlargemappings.cpp
+source			mpagecleaner.cpp
 sourcepath		../memmodel/epoc/mmubase
 source			kblockmap.cpp ramalloc.cpp defragbase.cpp
 
--- a/kernel/eka/nkern/arm/ncmonitor.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/nkern/arm/ncmonitor.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -22,31 +22,9 @@
 #include "nk_priv.h"
 #include <arm.h>
 
-EXPORT_C void Monitor::DisplayNThreadInfo(NThread* pT)
+void DisplayNThreadPlatformSpecific(Monitor& m, NThread* pT)
 	{
-	TBuf8<80> buf=_L8("NThread @ ");
-	buf.AppendNumFixedWidth((TUint)pT,EHex,8);
-	buf+=_L8(" Pri ");
-	buf.AppendNum((TUint)pT->iPriority);
-	buf+=_L8(" NState ");
-	switch (pT->iSpare1)
-		{
-		case NThread::EReady: buf+=_L8("READY"); break;
-		case NThread::ESuspended: buf+=_L8("SUSPENDED"); break;
-		case NThread::EWaitFastSemaphore: buf+=_L8("WAITFSEM "); buf.AppendNumFixedWidth((TUint)pT->iWaitObj,EHex,8); break;
-		case NThread::ESleep: buf+=_L8("SLEEP"); break;
-		case NThread::EBlocked: buf+=_L8("BLOCKED"); break;
-		case NThread::EDead: buf+=_L8("DEAD"); break;
-		case NThread::EWaitDfc: buf+=_L8("WAITDFC"); break;
-		default: buf+=_L8("??"); buf.AppendNumFixedWidth((TUint)pT->iSpare1,EHex,8); break;
-		}
-	PrintLine(buf);
-	Printf("Next=%08x Prev=%08x Att=%02x iUserContextType=%02x\r\n",pT->iNext,pT->iPrev,pT->iSpare2,pT->iSpare3);
-	Printf("HeldFM=%08x WaitFM=%08x AddrSp=%08x\r\n",pT->iHeldFastMutex,pT->iWaitFastMutex,pT->iAddressSpace);
-	Printf("Time=%d Timeslice=%d ReqCount=%d\r\n",pT->iTime,pT->iTimeslice,pT->iRequestSemaphore.iCount);
-	Printf("SuspendCount=%d CsCount=%d CsFunction=%08x\r\n",pT->iSuspendCount,pT->iCsCount,pT->iCsFunction);
-	Printf("SavedSP=%08x ExtraContext=%08x ExtraContextSize=%04x\r\n",pT->iSavedSP,pT->iExtraContext,pT->iExtraContextSize);
-	Printf("iUserModeCallbacks=%08x iSpare7=%08x iSpare8=%08x\r\n", pT->iUserModeCallbacks, pT->iSpare7, pT->iSpare8);
+	m.Printf("iUserContextType=%02x ExtraContext=%08x ExtraContextSize=%04x\r\n",pT->iSpare3,pT->iExtraContext,pT->iExtraContextSize);
 	if (pT != TScheduler::Ptr()->iCurrentThread)
 		{
 		TUint32* pS=(TUint32*)pT->iSavedSP;
@@ -56,51 +34,26 @@
 			{
 			TUint32* pR=reg;
 #ifdef __CPU_SUPPORT_THUMB2EE
-			Printf("TEEHBR %08x ",*pR++);
+			m.Printf("TEEHBR %08x ",*pR++);
 #endif
 #ifdef __CPU_HAS_CP15_THREAD_ID_REG
-			Printf("RWRWTID %08x ",*pR++);
+			m.Printf("RWRWTID %08x ",*pR++);
 #endif
 #ifdef __CPU_HAS_VFP
-			Printf("FPEXC %08x ",*pR++);
+			m.Printf("FPEXC %08x ",*pR++);
 #endif
 #ifdef __CPU_HAS_COPROCESSOR_ACCESS_REG
-			Printf("CAR %08x ",*pR++);
+			m.Printf("CAR %08x ",*pR++);
 #endif
 #ifdef __CPU_ARM_USE_DOMAINS
-			Printf("DACR %08x\r\n",*pR++);
+			m.Printf("DACR %08x\r\n",*pR++);
 #endif
-			Printf("R13_USR %08x R14_USR %08x SPSR_SVC %08x\r\n",pR[0],pR[1],pR[2]);
-			Printf(" R4 %08x  R5 %08x  R6 %08x  R7 %08x\r\n",pR[3],pR[4],pR[5],pR[6]);
-			Printf(" R8 %08x  R9 %08x R10 %08x R11 %08x\r\n",pR[7],pR[8],pR[9],pR[10]);
-			Printf(" PC %08x\r\n",pR[11]);
+			m.Printf("R13_USR %08x R14_USR %08x SPSR_SVC %08x\r\n",pR[0],pR[1],pR[2]);
+			m.Printf(" R4 %08x  R5 %08x  R6 %08x  R7 %08x\r\n",pR[3],pR[4],pR[5],pR[6]);
+			m.Printf(" R8 %08x  R9 %08x R10 %08x R11 %08x\r\n",pR[7],pR[8],pR[9],pR[10]);
+			m.Printf(" PC %08x\r\n",pR[11]);
 			}
 		}
-	NewLine();
-	}
-
-void Monitor::DisplayNFastSemInfo(NFastSemaphore* pS)
-	{
-	Printf("NFastSemaphore @ %08x Count %d OwningThread %08x\r\n",pS,pS->iCount,pS->iOwningThread);
-	}
-
-void Monitor::DisplayNFastMutexInfo(NFastMutex* pM)
-	{
-	Printf("NFastMutex @ %08x HoldingThread %08x iWaiting %08x\r\n",pM,pM->iHoldingThread,pM->iWaiting);
-	}
-
-void Monitor::DisplaySchedulerInfo()
-	{
-	TScheduler* pS=TScheduler::Ptr();
-	Printf("SCHEDULER @%08x: CurrentThread %08x\r\n",pS,pS->iCurrentThread);
-	Printf("RescheduleNeeded=%02x DfcPending=%02x KernCSLocked=%08x\r\n",pS->iRescheduleNeededFlag,pS->iDfcPendingFlag,pS->iKernCSLocked);
-	Printf("DFCS: next %08x prev %08x\r\n",pS->iDfcs.iA.iNext,pS->iDfcs.iA.iPrev);
-	Printf("ProcessHandler=%08x, AddressSpace=%08x\r\n",pS->iProcessHandler,pS->iAddressSpace);
-	Printf("SYSLOCK: HoldingThread %08x iWaiting %08x\r\n",pS->iLock.iHoldingThread,pS->iLock.iWaiting);
-	Printf("Extras 0: %08x 1: %08x 2: %08x 3: %08x\r\n",pS->iExtras[0],pS->iExtras[1],pS->iExtras[2],pS->iExtras[3]);
-	Printf("Extras 4: %08x 5: %08x 6: %08x 7: %08x\r\n",pS->iExtras[4],pS->iExtras[5],pS->iExtras[6],pS->iExtras[7]);
-	Printf("Extras 8: %08x 9: %08x A: %08x B: %08x\r\n",pS->iExtras[8],pS->iExtras[9],pS->iExtras[10],pS->iExtras[11]);
-	Printf("Extras C: %08x D: %08x E: %08x F: %08x\r\n",pS->iExtras[12],pS->iExtras[13],pS->iExtras[14],pS->iExtras[15]);
 	}
 
 void DumpRegisters(Monitor& m, SFullArmRegSet& a)
--- a/kernel/eka/nkern/arm/ncsched.cia	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/nkern/arm/ncsched.cia	Fri Apr 16 16:24:37 2010 +0300
@@ -448,6 +448,11 @@
 //
 	{
 	asm("unready: ");
+	
+	asm("ldr r2, [r0, #%a0]" : : "i" _FOFF(TScheduler,iMadeUnReadyCounter)); 	// Update Made UnReady count here, 
+	asm("add r2, r2, #1"); 								// ie equiv of 'iMadeUnReadyCounter++;'.
+	asm("str r2, [r0, #%a0]" : : "i" _FOFF(TScheduler,iMadeUnReadyCounter));
+
 #ifdef _DEBUG
 	asm("ldr r2, [r1, #%a0]" : : "i" _FOFF(NThread,iHeldFastMutex));
 	asm("mov r12, #0xd8000003 ");
@@ -609,7 +614,12 @@
 	{
 	asm("ldr r1, __TheScheduler ");
 	asm("ldrb r2, [r0, #%a0]" : : "i" _FOFF(NThread,iPriority));	// r2=priority of aThread
+
 	asm("DoReadyInner: ");
+	asm("ldr r3, [r1, #%a0]" : : "i" _FOFF(TScheduler,iMadeReadyCounter)); 	// Update Made Ready count here, 
+	asm("add r3, r3, #1"); 							// ie equiv of 'iMadeReadyCounter++;'.
+	asm("str r3, [r1, #%a0]" : : "i" _FOFF(TScheduler,iMadeReadyCounter));
+
 	asm("mov r3, #%a0" : : "i" (NThread::EReady));
 	asm("strb r3, [r0, #%a0]" : : "i" _FOFF(NThread,iNState));
 	asm("ldmia r1!, {r3,r12} ");			// r3=present mask low, r12=present mask high, r1=&iQueue[0]
@@ -1649,6 +1659,11 @@
 
 	asm("round_robin: ");					// get here if thread's timeslice has expired and there is another
 											// thread ready at the same priority
+	
+	asm("ldr r6, [r0, #%a0]" : : "i" _FOFF(TScheduler,iTimeSliceExpireCounter)); 	// Update Time Slice Expire count here, 
+	asm("add r6,r6, #1"); 								// ie equiv of 'iTimeSliceExpireCounter++;'.
+	asm("str r6, [r0, #%a0]" : : "i" _FOFF(TScheduler,iTimeSliceExpireCounter));
+
 	asm("cmp r7, #0 ");						// does this thread hold a fast mutex?
 	asm("bne rr_holds_fast_mutex ");
 	asm("ldr lr, [r2, #%a0]" : : "i" _FOFF(NThread,iTimeslice));
--- a/kernel/eka/nkern/arm/ncutils.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/nkern/arm/ncutils.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -84,6 +84,21 @@
 	ArmInterruptInfo.iFiqHandler=aHandler;
 	}
 
+/** Register the global Idle handler
+	Called by the base port at boot time to register a handler containing a pointer to
+	a function that is called by the Kernel when each core reaches idle.
+	Should not be called at any other time.
+
+	@param	aHandler Pointer to idle handler function
+	@param	aPtr Idle handler function argument
+*/
+EXPORT_C void Arm::SetIdleHandler(TCpuIdleHandlerFn aHandler, TAny* aPtr)
+	{
+	ArmInterruptInfo.iCpuIdleHandler.iHandler = aHandler;
+	ArmInterruptInfo.iCpuIdleHandler.iPtr = aPtr;
+	ArmInterruptInfo.iCpuIdleHandler.iPostambleRequired = EFalse;
+	}
+
 extern void initialiseState();
 void Arm::Init1Interrupts()
 //
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kernel/eka/nkern/nk_mon.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,76 @@
+// Copyright (c) 2009-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:
+// e32\nkern\nk_mon.cpp
+// Kernel crash debugger - NKERN platform-independent portion
+// 
+//
+
+#include <kernel/monitor.h>
+#include "nk_priv.h"
+
+extern void DisplayNThreadPlatformSpecific(Monitor& m, NThread* pT);
+
+
+EXPORT_C void Monitor::DisplayNThreadInfo(NThread* pT)
+	{
+	TBuf8<80> buf=_L8("NThread @ ");
+	buf.AppendNumFixedWidth((TUint)pT,EHex,8);
+	buf+=_L8(" Pri ");
+	buf.AppendNum((TUint)pT->iPriority);
+	buf+=_L8(" NState ");
+	switch (pT->iSpare1)
+		{
+		case NThread::EReady: buf+=_L8("READY"); break;
+		case NThread::ESuspended: buf+=_L8("SUSPENDED"); break;
+		case NThread::EWaitFastSemaphore: buf+=_L8("WAITFSEM "); buf.AppendNumFixedWidth((TUint)pT->iWaitObj,EHex,8); break;
+		case NThread::ESleep: buf+=_L8("SLEEP"); break;
+		case NThread::EBlocked: buf+=_L8("BLOCKED"); break;
+		case NThread::EDead: buf+=_L8("DEAD"); break;
+		case NThread::EWaitDfc: buf+=_L8("WAITDFC"); break;
+		default: buf+=_L8("??"); buf.AppendNumFixedWidth((TUint)pT->iSpare1,EHex,8); break;
+		}
+	PrintLine(buf);
+	Printf("SavedSP=%08x Next=%08x Prev=%08x Att=%02x\r\n",pT->iSavedSP,pT->iNext,pT->iPrev,pT->iSpare2);
+	Printf("HeldFM=%08x WaitFM=%08x AddrSp=%08x\r\n",pT->iHeldFastMutex,pT->iWaitFastMutex,pT->iAddressSpace);
+	Printf("Time=%d Timeslice=%d ReqCount=%d\r\n",pT->iTime,pT->iTimeslice,pT->iRequestSemaphore.iCount);
+	Printf("SuspendCount=%d CsCount=%d CsFunction=%08x\r\n",pT->iSuspendCount,pT->iCsCount,pT->iCsFunction);
+	Printf("iUserModeCallbacks=%08x iSpare7=%08x iSpare8=%08x\r\n", pT->iUserModeCallbacks, pT->iSpare7, pT->iSpare8);
+	DisplayNThreadPlatformSpecific(*this, pT);
+	NewLine();
+	}
+
+void Monitor::DisplayNFastSemInfo(NFastSemaphore* pS)
+	{
+	Printf("NFastSemaphore @ %08x Count %d OwningThread %08x\r\n",pS,pS->iCount,pS->iOwningThread);
+	}
+
+void Monitor::DisplayNFastMutexInfo(NFastMutex* pM)
+	{
+	Printf("NFastMutex @ %08x HoldingThread %08x iWaiting %08x\r\n",pM,pM->iHoldingThread,pM->iWaiting);
+	}
+
+void Monitor::DisplaySchedulerInfo()
+	{
+	TScheduler* pS=TScheduler::Ptr();
+	Printf("SCHEDULER @%08x: CurrentThread %08x\r\n",pS,pS->iCurrentThread);
+	Printf("RescheduleNeeded=%02x DfcPending=%02x KernCSLocked=%08x\r\n",pS->iRescheduleNeededFlag,pS->iDfcPendingFlag,pS->iKernCSLocked);
+	Printf("DFCS: next %08x prev %08x\r\n",pS->iDfcs.iA.iNext,pS->iDfcs.iA.iPrev);
+	Printf("ProcessHandler=%08x, AddressSpace=%08x\r\n",pS->iProcessHandler,pS->iAddressSpace);
+	Printf("SYSLOCK: HoldingThread %08x iWaiting %08x\r\n",pS->iLock.iHoldingThread,pS->iLock.iWaiting);
+	Printf("Extras 0: %08x 1: %08x 2: %08x 3: %08x\r\n",pS->iExtras[0],pS->iExtras[1],pS->iExtras[2],pS->iExtras[3]);
+	Printf("Extras 4: %08x 5: %08x 6: %08x 7: %08x\r\n",pS->iExtras[4],pS->iExtras[5],pS->iExtras[6],pS->iExtras[7]);
+	Printf("Extras 8: %08x 9: %08x A: %08x B: %08x\r\n",pS->iExtras[8],pS->iExtras[9],pS->iExtras[10],pS->iExtras[11]);
+	Printf("Extras C: %08x D: %08x E: %08x F: %08x\r\n",pS->iExtras[12],pS->iExtras[13],pS->iExtras[14],pS->iExtras[15]);
+	}
+
--- a/kernel/eka/nkern/nk_timer.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/nkern/nk_timer.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -153,7 +153,6 @@
 // Wait aTime from last trigger time - used for periodic timers
 //
 	{
-	__NK_ASSERT_DEBUG(aTime>0);
 	TInt irq=NKern::DisableAllInterrupts();
 	if (iState!=EIdle)
 		{
--- a/kernel/eka/nkern/nkern.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/nkern/nkern.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -1415,6 +1415,22 @@
 	NKern::Unlock();
 	}
 
+
+/** Changes the nominal priority of a thread.
+
+	This function is intended to be used by the EPOC layer and personality layers.
+	Do not use this function directly on a Symbian OS thread - use Kern::ThreadSetPriority().
+
+    @param aThread Thread to receive the new priority.
+    @param aPriority New inherited priority for aThread.
+    
+	@see Kern::SetThreadPriority()
+*/
+void NKern::ThreadSetNominalPriority(NThread* /*aThread*/, TInt /*aPriority*/)
+	{
+	}
+
+
 #ifndef __SCHEDULER_MACHINE_CODED__
 
 /** Signals the request semaphore of a nanothread.
--- a/kernel/eka/nkern/sched.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/nkern/sched.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -69,6 +69,7 @@
 void TScheduler::Remove(NThreadBase* aThread)
 	{
 	__NK_ASSERT_DEBUG(!aThread->iHeldFastMutex);	// can't block while holding fast mutex
+	iMadeUnReadyCounter++;
 	aThread->iTime=aThread->iTimeslice;		// thread has blocked so it gets a fresh timeslice for next time
 	TPriListBase::Remove(aThread);
 	}
--- a/kernel/eka/nkern/win32/ncsched.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/nkern/win32/ncsched.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -835,6 +835,61 @@
 
 #include <winnt.h>
 
+// Uncomment the following line to turn on tracing when we examine the call stack
+// #define DUMP_STACK_BACKTRACE
+
+#ifdef DUMP_STACK_BACKTRACE
+
+#include <psapi.h>
+
+typedef BOOL (WINAPI GMIFunc)(HANDLE hProcess, HMODULE hModule, LPMODULEINFO lpmodinfo, DWORD cb);
+typedef BOOL (WINAPI EPMFunc)(HANDLE hProcess, HMODULE *lphModule, DWORD cb, LPDWORD lpcbNeeded);
+typedef DWORD (WINAPI GMBNFunc)(HANDLE hProcess, HMODULE hModule, LPSTR lpBaseName, DWORD nSize);
+
+void PrintAllModuleInfo()
+	{
+	HMODULE psapiLibrary = LoadLibraryA("psapi.dll");
+	__NK_ASSERT_ALWAYS(psapiLibrary != NULL);
+
+	EPMFunc* epmFunc = (EPMFunc*)GetProcAddress(psapiLibrary, "EnumProcessModules");
+	__NK_ASSERT_ALWAYS(epmFunc != NULL);
+	
+	GMIFunc* gmiFunc = (GMIFunc*)GetProcAddress(psapiLibrary, "GetModuleInformation");
+	__NK_ASSERT_ALWAYS(gmiFunc != NULL);
+	
+	GMBNFunc* gmbnFunc = (GMBNFunc*)GetProcAddress(psapiLibrary, "GetModuleBaseNameA");
+	__NK_ASSERT_ALWAYS(gmbnFunc != NULL);
+
+	const TInt maxModules = 256;
+	HMODULE modules[maxModules];
+
+	DWORD spaceNeeded;
+	BOOL r = epmFunc(GetCurrentProcess(), modules, sizeof(HMODULE) * maxModules, &spaceNeeded);
+	__NK_ASSERT_ALWAYS(r);
+	__NK_ASSERT_ALWAYS(spaceNeeded <= sizeof(HMODULE) * maxModules);
+
+	for (TUint i = 0 ; i < spaceNeeded / sizeof(HMODULE) ; ++i)
+		{
+		HMODULE library = modules[i];
+		
+		const TUint maxNameLen = 64;
+		char name[maxNameLen];
+		WORD len = gmbnFunc(GetCurrentProcess(), library, name, sizeof(name));
+		__NK_ASSERT_ALWAYS(len > 0 && len < maxNameLen);
+		
+		MODULEINFO info;
+		r = gmiFunc(GetCurrentProcess(), library, &info, sizeof(info));
+		__NK_ASSERT_ALWAYS(r);
+		
+		DEBUGPRINT("Module %s found at %08x to %08x", name, (TUint)info.lpBaseOfDll, (TUint)info.lpBaseOfDll + info.SizeOfImage);
+		}
+
+	r = FreeLibrary(psapiLibrary);
+	__NK_ASSERT_ALWAYS(r);
+	}
+
+#endif
+
 const TInt KWin32NonPreemptibleFunctionCount = 2;
 
 struct TWin32FunctionInfo
@@ -845,14 +900,37 @@
 
 static TWin32FunctionInfo Win32NonPreemptibleFunctions[KWin32NonPreemptibleFunctionCount];
 
-TWin32FunctionInfo Win32FindExportedFunction(const char* aModuleName, const char* aFunctionName)
+HMODULE GetFirstLoadedModuleHandleA(const char* aModuleName1, const char* aModuleName2)
+	{
+	HMODULE result = GetModuleHandleA(aModuleName1);
+	return result ? result : GetModuleHandleA(aModuleName2);
+	}
+
+TWin32FunctionInfo Win32FindExportedFunction(const char* aFunctionName, ...)
 	{
-	HMODULE library = GetModuleHandleA(aModuleName);
+	const char *libname;
+	HMODULE library = NULL;
+
+	va_list arg;
+	va_start(arg, aFunctionName);
+
+	// Loop through arguments until we find a library we can get a handle to.  List of library names
+	// is NULL-terminated.
+	while ((libname = va_arg(arg, const char *)) != NULL)
+		{
+		library = GetModuleHandleA(libname);
+		if (library != NULL)
+			break;
+		}
+
+	va_end(arg);
+
+	// Make sure we did get a valid library
 	__NK_ASSERT_ALWAYS(library != NULL);
-
+	
 	// Find the start address of the function
 	TUint start = (TUint)GetProcAddress(library, aFunctionName);
-	__NK_ASSERT_ALWAYS(start);
+	__NK_ASSERT_ALWAYS(start != 0);
 
 	// Now have to check all other exports to find the end of the function
 	TUint end = 0xffffffff;
@@ -867,15 +945,26 @@
 		++i;
 		}
 	__NK_ASSERT_ALWAYS(end != 0xffffffff);
-
+	
 	TWin32FunctionInfo result = { start, end - start };
+	
+#ifdef DUMP_STACK_BACKTRACE
+	DEBUGPRINT("Function %s found at %08x to %08x", aFunctionName, start, end);
+#endif
+	
 	return result;
 	}
 
 void Win32FindNonPreemptibleFunctions()
 	{
-	Win32NonPreemptibleFunctions[0] = Win32FindExportedFunction("kernel32.dll", "RaiseException");
-	Win32NonPreemptibleFunctions[1] = Win32FindExportedFunction("ntdll.dll", "KiUserExceptionDispatcher");
+#ifdef DUMP_STACK_BACKTRACE
+	PrintAllModuleInfo();
+#endif
+
+	TUint i = 0;
+	Win32NonPreemptibleFunctions[i++] = Win32FindExportedFunction("RaiseException", "kernelbase.dll", "kernel32.dll", NULL);
+	Win32NonPreemptibleFunctions[i++] = Win32FindExportedFunction("KiUserExceptionDispatcher", "ntdll.dll", NULL);
+	__NK_ASSERT_ALWAYS(i == KWin32NonPreemptibleFunctionCount);
 	}
 	
 TBool Win32IsThreadInNonPreemptibleFunction(HANDLE aWinThread, TLinAddr aStackTop)
@@ -892,9 +981,17 @@
 	TUint ebp = c.Ebp;
 	TUint lastEbp = c.Esp;
 
+	#ifdef DUMP_STACK_BACKTRACE
+	DEBUGPRINT("Stack backtrace for thread %x", aWinThread);
+	#endif	
+
 	// Walk the call stack
 	for (TInt i = 0 ; i < KMaxSearchDepth ; ++i)
 		{
+		#ifdef DUMP_STACK_BACKTRACE
+		DEBUGPRINT("  %08x", eip);
+		#endif
+		
 		for (TInt j = 0 ; j < KWin32NonPreemptibleFunctionCount ; ++j)
 			{
 			const TWin32FunctionInfo& info = Win32NonPreemptibleFunctions[j];
--- a/kernel/eka/nkern/x86/ncmonitor.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/nkern/x86/ncmonitor.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -21,31 +21,9 @@
 #include <kernel/monitor.h>
 
 
-EXPORT_C void Monitor::DisplayNThreadInfo(NThread* pT)
+void DisplayNThreadPlatformSpecific(Monitor& m, NThread* pT)
 	{
-	TBuf8<80> buf=_L8("NThread @ ");
-	buf.AppendNumFixedWidth((TUint)pT,EHex,8);
-	buf+=_L8(" Pri ");
-	buf.AppendNum((TUint)pT->iPriority);
-	buf+=_L8(" NState ");
-	switch (pT->iSpare1)
-		{
-		case NThread::EReady: buf+=_L8("READY"); break;
-		case NThread::ESuspended: buf+=_L8("SUSPENDED"); break;
-		case NThread::EWaitFastSemaphore: buf+=_L8("WAITFSEM "); buf.AppendNumFixedWidth((TUint)pT->iWaitObj,EHex,8); break;
-		case NThread::ESleep: buf+=_L8("SLEEP"); break;
-		case NThread::EBlocked: buf+=_L8("BLOCKED"); break;
-		case NThread::EDead: buf+=_L8("DEAD"); break;
-		case NThread::EWaitDfc: buf+=_L8("WAITDFC"); break;
-		default: buf+=_L8("??"); buf.AppendNumFixedWidth((TUint)pT->iSpare1,EHex,8); break;
-		}
-	PrintLine(buf);
-	Printf("Next=%08x Prev=%08x Att=%02x ExcInUserMode=%02x\r\n",pT->iNext,pT->iPrev,pT->iSpare2,pT->iSpare3);
-	Printf("HeldFM=%08x WaitFM=%08x AddrSp=%08x\r\n",pT->iHeldFastMutex,pT->iWaitFastMutex,pT->iAddressSpace);
-	Printf("Time=%d Timeslice=%d ReqCount=%d\r\n",pT->iTime,pT->iTimeslice,pT->iRequestSemaphore.iCount);
-	Printf("SuspendCount=%d CsCount=%d CsFunction=%08x\r\n",pT->iSuspendCount,pT->iCsCount,pT->iCsFunction);
-	Printf("iUserModeCallbacks=%08x iSpare7=%08x iSpare8=%08x\r\n", pT->iUserModeCallbacks, pT->iSpare7, pT->iSpare8);
-	Printf("SavedSP=%08x\r\n",pT->iSavedSP);
+	m.Printf("ExcInUserMode=%02x\r\n",pT->iSpare3);
 	if (pT != TScheduler::Ptr()->iCurrentThread)
 		{
 		TUint32* pS=(TUint32*)pT->iSavedSP;
@@ -53,35 +31,10 @@
 		MTRAPD(r,wordmove(&reg,pS,sizeof(SThreadStack)));
 		if (r==KErrNone)
 			{
-			Printf("EBX %08x ESI %08x EDI %08x EBP %08x\r\n",reg.iEbx,reg.iEsi,reg.iEdi,reg.iEbp);
-			Printf("EIP %08x CR0 %08x  FS %08x  GS %08x\r\n",reg.iEip,reg.iCR0,reg.iFs,reg.iGs);
+			m.Printf("EBX %08x ESI %08x EDI %08x EBP %08x\r\n",reg.iEbx,reg.iEsi,reg.iEdi,reg.iEbp);
+			m.Printf("EIP %08x CR0 %08x  FS %08x  GS %08x\r\n",reg.iEip,reg.iCR0,reg.iFs,reg.iGs);
 			}
 		}
-	NewLine();
-	}
-
-void Monitor::DisplayNFastSemInfo(NFastSemaphore* pS)
-	{
-	Printf("NFastSemaphore @ %08x Count %d OwningThread %08x\r\n",pS,pS->iCount,pS->iOwningThread);
-	}
-
-void Monitor::DisplayNFastMutexInfo(NFastMutex* pM)
-	{
-	Printf("NFastMutex @ %08x HoldingThread %08x iWaiting %08x\r\n",pM,pM->iHoldingThread,pM->iWaiting);
-	}
-
-void Monitor::DisplaySchedulerInfo()
-	{
-	TScheduler* pS=TScheduler::Ptr();
-	Printf("SCHEDULER @%08x: CurrentThread %08x\r\n",pS,pS->iCurrentThread);
-	Printf("RescheduleNeeded=%02x DfcPending=%02x KernCSLocked=%08x\r\n",pS->iRescheduleNeededFlag,pS->iDfcPendingFlag,pS->iKernCSLocked);
-	Printf("DFCS: next %08x prev %08x\r\n",pS->iDfcs.iA.iNext,pS->iDfcs.iA.iPrev);
-	Printf("ProcessHandler=%08x, AddressSpace=%08x\r\n",pS->iProcessHandler,pS->iAddressSpace);
-	Printf("SYSLOCK: HoldingThread %08x iWaiting %08x\r\n",pS->iLock.iHoldingThread,pS->iLock.iWaiting);
-	Printf("Extras 0: %08x 1: %08x 2: %08x 3: %08x\r\n",pS->iExtras[0],pS->iExtras[1],pS->iExtras[2],pS->iExtras[3]);
-	Printf("Extras 4: %08x 5: %08x 6: %08x 7: %08x\r\n",pS->iExtras[4],pS->iExtras[5],pS->iExtras[6],pS->iExtras[7]);
-	Printf("Extras 8: %08x 9: %08x A: %08x B: %08x\r\n",pS->iExtras[8],pS->iExtras[9],pS->iExtras[10],pS->iExtras[11]);
-	Printf("Extras C: %08x D: %08x E: %08x F: %08x\r\n",pS->iExtras[12],pS->iExtras[13],pS->iExtras[14],pS->iExtras[15]);
 	}
 
 void Monitor::DumpCpuRegisters()
--- a/kernel/eka/nkern/x86/ncutils.cia	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/nkern/x86/ncutils.cia	Fri Apr 16 16:24:37 2010 +0300
@@ -23,7 +23,7 @@
 	asm("ret");
 	}
 
-extern "C" __NAKED__ void NKIdle(TInt)
+extern "C" __NAKED__ void NKIdle(TUint32)
 	{
 	asm("hlt");
 	asm("ret");
--- a/kernel/eka/nkernsmp/arm/nccpu.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/nkernsmp/arm/nccpu.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -33,8 +33,15 @@
 	volatile T_UintPtr	iBootFlags4;
 	volatile TUint64	iBPTimestamp;
 	volatile TUint64	iAPTimestamp;
+
+	TUint32				i_SAPBootPage_Spare[624];
+
+	UPerCpuUncached		iPerCpu[KMaxCpus];
 	};
 
+__ASSERT_COMPILE(sizeof(SAPBootPage)==4096);
+
+
 extern "C" void _ApEntry();
 extern "C" void KickCpu(volatile T_UintPtr* aPtr, T_UintPtr aRegsPhys);
 extern void DumpFullRegSet(SFullArmRegSet& a);
@@ -100,41 +107,30 @@
 	__KTRACE_OPT(KBOOT,DEBUGPRINT("SCU: iCtrl=%08x iConfig=%08x iCpuStat=%08x", SCU.iCtrl, SCU.iConfig, SCU.iCpuStatus));
 	if (n==0)
 		return KErrTimedOut;
-	NKern::DisableAllInterrupts();
-	arm_dsb();
-	while (bootPage.iBootFlags2==0)
-		{}
-	arm_dsb();
-	bootPage.iBootFlags2 = 2;
-	arm_dsb();
-	bootPage.iBPTimestamp = NKern::Timestamp();
-	arm_dsb();
-	while (bootPage.iBootFlags2==2)
-		{}
-	arm_dsb();
-	NKern::EnableAllInterrupts();
+
+#if defined(__NKERN_TIMESTAMP_USE_LOCAL_TIMER__)
+#error Use of local timer for NKern::Timestamp() no longer supported
+#endif
+
 	return KErrNone;
 	}
 
-void InitAPTimestamp(SNThreadCreateInfo& aInfo)
+void InitTimestamp(TSubScheduler* aSS, SNThreadCreateInfo& aInfo)
 	{
-	volatile SArmAPBootInfo& a = *(volatile SArmAPBootInfo*)aInfo.iParameterBlock;
-	volatile SAPBootPage& bootPage = *(volatile SAPBootPage*)a.iAPBootLin;
-	NKern::DisableAllInterrupts();
-	bootPage.iBootFlags2 = 1;
-	arm_dsb();
-	while (bootPage.iBootFlags2==1)
-		{}
-	arm_dsb();
-	bootPage.iAPTimestamp = NKern::Timestamp();
-	arm_dsb();
-	TUint64 bpt = bootPage.iBPTimestamp;
-	TUint64 apt = bootPage.iAPTimestamp;
-	TUint64 delta = bpt - apt;
-	SubScheduler().iLastTimestamp64 += delta;
-	__KTRACE_OPT(KBOOT,DEBUGPRINT("APT=0x%lx BPT=0x%lx Delta=0x%lx", apt, bpt, delta));
-	arm_dsb();
-	bootPage.iBootFlags2 = 3;
-	NKern::EnableAllInterrupts();
+	NThread* t = (NThread*)aSS->iCurrentThread;
+	t->iActiveState = 1;
+	if (aSS->iCpuNum == 0)
+		{
+		aSS->iLastTimestamp.i64 = 0;
+		t->iLastActivationTime.i64 = 0;
+		return;
+		}
+	TUint64 ts = 0;
+#if defined(__NKERN_TIMESTAMP_USE_LOCAL_TIMER__)
+#error Use of local timer for NKern::Timestamp() no longer supported
+#endif
+	ts = NKern::Timestamp();
+	aSS->iLastTimestamp.i64 = ts;
+	t->iLastActivationTime.i64 = ts;
 	}
 
--- a/kernel/eka/nkernsmp/arm/ncmonitor.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/nkernsmp/arm/ncmonitor.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -26,130 +26,39 @@
 	{
 	TScheduler* pS = TScheduler::Ptr();
 	TSubScheduler& ss = *pS->iSub[aCpu];
-	return *(SFullArmRegSet*)ss.i_AbtStackTop;
+	return *ss.iSSX.iRegs;
 	}
 
-void Monitor::DisplaySpinLock(const char* aTitle, TSpinLock* aLock)
+void DisplayNThreadStackedRegs(Monitor& m, SThreadReschedStack& reg)
 	{
-	volatile TUint32* p = (volatile TUint32*)aLock;
-	Printf("%s %08x %08x\r\n", aTitle, p[0], p[1]);
-	}
-
-EXPORT_C void Monitor::DisplayNThreadInfo(NThread* aT)
-	{
-	DisplayNSchedulableInfo(aT);
+	m.Printf("TEEHBR %08x UROTID %08x URWTID %08x  FPEXC %08x\r\n", reg.iTEEHBR, reg.iRWROTID, reg.iRWRWTID, reg.iFpExc);
+	m.Printf("   CAR %08x   DACR %08x\r\n", reg.iCar, reg.iDacr);
+	m.Printf(" SPARE %08x   SPSR %08x SPRSCH %08x    R15 %08x\r\n", reg.iSpare, reg.iSpsrSvc, reg.iSPRschdFlg, reg.iR15);
 	}
 
-void Monitor::DisplayNSchedulableInfo(NSchedulable* aS)
+void DisplaySubSchedulerExt(Monitor& m, TSubScheduler& ss)
 	{
-	NThread* t = aS->iParent ? (NThread*)aS : 0;
-	NThreadGroup* g = aS->iParent ? 0 : (NThreadGroup*)aS;
-
-	if (t && aS->iParent==aS)
-		Printf("NThread @%08x Pri %d\r\n",aS,aS->iPriority);
-	else if (t)
-		Printf("NThread @%08x (G:%08x) Pri %d\r\n",aS,aS->iParent,aS->iPriority);
-	else
-		Printf("NThreadGroup @%08x Pri %d\r\n",aS,aS->iPriority);
-	Printf("Rdy=%02x Curr=%02x LastCpu=%d CpuChg=%02x FrzCpu=%d\r\n", aS->iReady, aS->iCurrent, aS->iLastCpu, aS->iCpuChange, aS->iFreezeCpu);
-	Printf("Next=%08x Prev=%08x Parent=%08x CPUaff=%08x\r\n", aS->iNext, aS->iPrev, aS->iParent, aS->iCpuAffinity);
-	Printf("PauseCount %02x Susp %1x\r\n", aS->iPauseCount, aS->iSuspended);
-	DisplaySpinLock("SpinLock", &aS->iSSpinLock);
-	Printf("Stopping %02x Events %08x %08x EventState %08x\r\n", aS->iStopping, aS->iEvents.iA.iNext, aS->iEvents.iA.iPrev, aS->iEventState);
-	Printf("TotalCpuTime %08x %08x RunCount %08x %08x\r\n", aS->iTotalCpuTime32[1], aS->iTotalCpuTime32[0], aS->iRunCount32[1], aS->iRunCount32[0]);
-
-	if (g)
-		{
-		// Thread group
-		return;
-		}
-
-	Printf("WaitState %02x %02x [%02x %02x] (%08x)\r\n", t->iWaitState.iWtC.iWtStFlags, t->iWaitState.iWtC.iWtObjType,
-											t->iWaitState.iWtC.iWtStSpare1, t->iWaitState.iWtC.iWtStSpare2, t->iWaitState.iWtC.iWtObj);
-	Printf("BasePri %d MutexPri %d Att=%02x\r\n", t->iBasePri, t->iMutexPri, t->i_ThrdAttr);
-	Printf("HeldFM=%08x FMDef=%02x AddrSp=%08x\r\n", t->iHeldFastMutex, t->iFastMutexDefer, t->iAddressSpace);
-	Printf("Time=%d Timeslice=%d ReqCount=%08x\r\n", t->iTime, t->iTimeslice, t->iRequestSemaphore.iCount);
-	Printf("SuspendCount=%d CsCount=%d CsFunction=%08x\r\n", t->iSuspendCount, t->iCsCount, t->iCsFunction);
-	Printf("LinkedObjType %02x LinkedObj %08x\r\n", t->iLinkedObjType, t->iLinkedObj);
-	Printf("SavedSP=%08x WaitLink:%08x %08x %d\r\n", t->iSavedSP, t->iWaitLink.iNext, t->iWaitLink.iPrev, t->iWaitLink.iPriority);
-	Printf("iNewParent=%08x iExtraContext=%08x, iExtraContextSize=%08x\r\n", t->iNewParent, t->iExtraContext, t->iExtraContextSize);
-	Printf("iUserModeCallbacks=%08x iNThreadBaseSpare6=%08x\r\n", t->iUserModeCallbacks, t->iNThreadBaseSpare6);
-	Printf("iNThreadBaseSpare7=%08x iNThreadBaseSpare8=%08x iNThreadBaseSpare9=%08x\r\n", t->iNThreadBaseSpare7, t->iNThreadBaseSpare8, t->iNThreadBaseSpare9);
-	if (!aS->iCurrent)
-		{
-		TUint32* pS=(TUint32*)t->iSavedSP;
-		SThreadReschedStack reg;
-		MTRAPD(r,wordmove(&reg,pS,sizeof(SThreadReschedStack)));
-		if (r==KErrNone)
-			{
-			Printf("TEEHBR %08x UROTID %08x URWTID %08x  FPEXC %08x\r\n", reg.iTEEHBR, reg.iRWROTID, reg.iRWRWTID, reg.iFpExc);
-			Printf("   CAR %08x   DACR %08x\r\n", reg.iCar, reg.iDacr);
-			Printf(" SPARE %08x   SPSR %08x SPRSCH %08x    R15 %08x\r\n", reg.iSpare, reg.iSpsrSvc, reg.iSPRschdFlg, reg.iR15);
-			}
-		}
-	NewLine();
+	TSubSchedulerX& x = ss.iSSX;
+	m.Printf("Extras[ 0] %08x Extras[ 1] %08x Extras[ 2] %08x i_GblTmrA  %08x\r\n", x.iSSXP[0], x.iSSXP[1], x.iSSXP[2], x.iGlobalTimerAddr);
+	m.Printf("i_ScuAddr  %08x i_GicDist  %08x i_GicCpuIf %08x i_LocTmrA  %08x\r\n", x.iScuAddr, x.iGicDistAddr, x.iGicCpuIfcAddr, x.iLocalTimerAddr);
+	m.Printf("i_IrqCount %08x i_IrqNest  %08x i_ExcInfo  %08x i_CrashSt  %08x\r\n", x.iIrqCount, x.iIrqNestCount, x.iExcInfo, x.iCrashState);
+	m.Printf("i_AbtStkTp %08x i_UndSktTp %08x i_FiqStkTp %08x i_IrqStkTp %08x\r\n", x.iAbtStackTop, x.iUndStackTop, x.iFiqStackTop, x.iIrqStackTop);
+	m.Printf("CpuFreqM   %08x CpuFreqS   %08x CpuPeriodM %08x CpuPeriodS %08x\r\n", x.iCpuFreqM, x.iCpuFreqS, x.iCpuPeriodM, x.iCpuPeriodS);
+	m.Printf("NTmrFreqM  %08x NTmrFreqS  %08x NTmPeriodM %08x NTmPeriodS %08x\r\n", x.iNTimerFreqM, x.iNTimerFreqS, x.iNTimerPeriodM, x.iNTimerPeriodS);
+	m.Printf("TmrFreqM   %08x TmrFreqS   %08x TmrPeriodM %08x TmrPeriodS %08x\r\n", x.iTimerFreqM, x.iTimerFreqS, x.iTimerPeriodM, x.iTimerPeriodS);
+	m.Printf("iLastSyncT %08x %08x            TicksSince %08x LastTmrSet %08x\r\n", I64HIGH(x.iLastSyncTime), I64LOW(x.iLastSyncTime), x.iTicksSinceLastSync, x.iLastTimerSet);
+	m.Printf("GapEstimat %08x GapCount   %08x TotalTicks %08x Ditherer   %08x\r\n", x.iGapEstimate, x.iGapCount, x.iTotalTicks, x.iDitherer);
+	m.Printf("FreqErrEst %08x FreqErrLim %08x ErrorInteg %08x %08x\r\n", x.iFreqErrorEstimate, x.iFreqErrorLimit, I64HIGH(x.iErrorIntegrator), I64LOW(x.iErrorIntegrator));
+	m.Printf("RefAtLastC %08x %08x            M=%02x N=%02x D=%02x\r\n", I64HIGH(x.iRefAtLastCorrection), I64LOW(x.iRefAtLastCorrection), x.iM, x.iN, x.iD);
 	}
 
-void Monitor::DisplayNFastSemInfo(NFastSemaphore* pS)
-	{
-	if (pS->iCount >= 0)
-		Printf("NFastSemaphore @ %08x Count %d OwningThread %08x\r\n",pS,pS->iCount,pS->iOwningThread);
-	else
-		Printf("NFastSemaphore @ %08x Count %08x (%08x) OwningThread %08x\r\n",pS,pS->iCount,pS->iCount<<2,pS->iOwningThread);
-	}
-
-void Monitor::DisplayNFastMutexInfo(NFastMutex* aM)
-	{
-	Printf("NFastMutex @ %08x HoldingThread %08x iWaitQ Pri Mask %08x %08x\r\n", aM, aM->iHoldingThread, aM->iWaitQ.iPresent[1], aM->iWaitQ.iPresent[0]);
-	DisplaySpinLock("SpinLock", &aM->iMutexLock);
-	}
-
-void DisplaySubSchedulerInfo(Monitor& m, TSubScheduler& ss)
+void DisplaySchedulerExt(Monitor& m, TScheduler& s)
 	{
-	m.Printf("\r\nSUBSCHEDULER %d @%08x:\r\n", ss.iCpuNum, &ss);
-	m.Printf("CurrentThread=%08x\r\n", ss.iCurrentThread);
-	m.Printf("IDFCs   %08x %08x    CPU# %08x CPUmask %08x\r\n", ss.iDfcs.iA.iNext, ss.iDfcs.iA.iPrev, ss.iCpuNum, ss.iCpuMask);
-	m.Printf("ExIDFCs %08x %08x CurIDFC %08x PendFlg %08x\r\n", ss.iExIDfcs.iA.iNext, ss.iExIDfcs.iA.iPrev, ss.iCurrentIDFC, *(TUint32*)&ss.iRescheduleNeededFlag);
-	m.DisplaySpinLock("ExIDfcLock", &ss.iExIDfcLock);
-	m.Printf("KLCount %d InIDFC %02x EvPend %02x\r\n", ss.iKernLockCount, ss.iInIDFC, ss.iEventHandlersPending);
-	m.Printf("AddrSp  %08x RschdIPIs %08x iNextIPI %08x\r\n", ss.iAddressSpace, ss.iReschedIPIs, ss.iNextIPI);
-	m.DisplaySpinLock("ReadyListLock", &ss.iReadyListLock);
-	m.Printf("EvtHand %08x %08x InitThrd %08x SLOC %08x %08x\r\n", ss.iEventHandlers.iA.iNext, ss.iEventHandlers.iA.iPrev,
-		ss.iInitialThread, I64HIGH(ss.iSpinLockOrderCheck), I64LOW(ss.iSpinLockOrderCheck));
-	m.DisplaySpinLock("EventHandlerLock", &ss.iEventHandlerLock);
-	m.Printf("Extras[ 0] %08x Extras[ 1] %08x Extras[ 2] %08x Extras[ 3] %08x\r\n", ss.iExtras[0], ss.iExtras[1], ss.iExtras[2], ss.iExtras[3]);
-	m.Printf("i_ScuAddr  %08x i_GicDist  %08x i_GicCpuIf %08x i_LocTmrA  %08x\r\n", ss.i_ScuAddr, ss.i_GicDistAddr, ss.i_GicCpuIfcAddr, ss.i_LocalTimerAddr);
-	m.Printf("i_IrqCount %08x i_IrqNest  %08x i_ExcInfo  %08x i_CrashSt  %08x\r\n", ss.i_IrqCount, ss.i_IrqNestCount, ss.i_ExcInfo, ss.i_CrashState);
-	m.Printf("i_AbtStkTp %08x i_UndSktTp %08x i_FiqStkTp %08x i_IrqStkTp %08x\r\n", ss.i_AbtStackTop, ss.i_UndStackTop, ss.i_FiqStackTop, ss.i_IrqStackTop);
-	m.Printf("i_TmrMultF %08x i_TmrMultI %08x i_CpuMult  %08x Extras[13] %08x\r\n", ss.i_TimerMultF, ss.i_TimerMultI, ss.i_CpuMult, ss.iExtras[19]);
-	m.Printf("i_LstTmrSt %08x i_TstmpErr %08x i_MaxCorr  %08x i_TimerGap %08x\r\n", ss.iExtras[20], ss.iExtras[21], ss.iExtras[22], ss.iExtras[23]);
-	m.Printf("iLastTimestamp %08x %08x   iReschedCount %08x %08x\r\n", ss.iLastTimestamp32[1], ss.iLastTimestamp32[0], ss.iReschedCount32[1], ss.iReschedCount32[0]);
-	}
-
-void Monitor::DisplaySchedulerInfo()
-	{
-	TScheduler* pS=TScheduler::Ptr();
-	Printf("SCHEDULER @%08x:\r\n",pS);
-	Printf("ProcessHandler=%08x MonitorExceptionHandler=%08x RescheduleHook=%08x\r\n",pS->iProcessHandler,pS->iMonitorExceptionHandler,pS->iRescheduleHook);
-	Printf("iActiveCpus1=%08x, iActiveCpus2=%08x, iNumCpus=%d\r\n",pS->iActiveCpus1,pS->iActiveCpus2,pS->iNumCpus);
-	Printf("SYSLOCK @ %08x\r\n",&pS->iLock);
-	DisplayNFastMutexInfo(&pS->iLock);
-	DisplaySpinLock("IdleSpinLock", &pS->iIdleSpinLock);
-	Printf("IdleDfcs %08x %08x CpusNotIdle %08x IdleGeneration %02x IdleSpillCpu %02x\r\n",
-		pS->iIdleDfcs.iA.iNext, pS->iIdleDfcs.iA.iPrev, pS->iCpusNotIdle, pS->iIdleGeneration, pS->iIdleSpillCpu);
-	Printf("Extras  0: %08x  1: %08x  2: %08x  3: %08x\r\n",pS->iExtras[0],pS->iExtras[1],pS->iExtras[2],pS->iExtras[3]);
-	Printf("Extras  4: %08x  5: %08x  6: %08x  7: %08x\r\n",pS->iExtras[4],pS->iExtras[5],pS->iExtras[6],pS->iExtras[7]);
-	Printf("Extras  8: %08x  9: %08x  A: %08x  B: %08x\r\n",pS->iExtras[8],pS->iExtras[9],pS->iExtras[10],pS->iExtras[11]);
-	Printf("Extras  C: %08x  D: %08x  E: %08x  F: %08x\r\n",pS->iExtras[12],pS->iExtras[13],pS->iExtras[14],pS->iExtras[15]);
-	Printf("Extras 10: %08x 11: %08x 12: %08x 13: %08x\r\n",pS->iExtras[16],pS->iExtras[17],pS->iExtras[18],pS->iExtras[19]);
-	Printf("Extras 14: %08x 15: %08x 16: %08x 17: %08x\r\n",pS->iExtras[20],pS->iExtras[21],pS->iExtras[22],pS->iExtras[23]);
-
-	TInt i;
-	for (i=0; i<KMaxCpus; ++i)
-		{
-		TSubScheduler& ss = *pS->iSub[i];
-		DisplaySubSchedulerInfo(*this,ss);
-		}
+	volatile TUint32* sx = (volatile TUint32*)&s.iSX;
+	m.Printf("Extras  0: %08x  1: %08x  2: %08x  3: %08x\r\n",sx[0],sx[1],sx[2],sx[3]);
+	m.Printf("Extras  4: %08x  5: %08x  6: %08x  7: %08x\r\n",sx[4],sx[5],sx[6],sx[7]);
+	m.Printf("Extras  8: %08x  9: %08x  A: %08x  B: %08x\r\n",sx[8],sx[9],sx[10],sx[11]);
+	m.Printf("Extras  C: %08x  D: %08x  E: %08x  F: %08x\r\n",sx[12],sx[13],sx[14],sx[15]);
 	}
 
 void DumpRegisters(Monitor& m, SFullArmRegSet& a)
@@ -217,9 +126,9 @@
 		{
 		Printf("CPU %d:\r\n", i);
 		TSubScheduler& ss = *pS->iSub[i];
-		if (!ss.i_Regs)
+		if (!ss.iSSX.iRegs)
 			continue;
-		SFullArmRegSet& r = *(SFullArmRegSet*)ss.i_Regs;
+		SFullArmRegSet& r = *ss.iSSX.iRegs;
 		
 		Printf("Exc %1d Cpsr=%08x FAR=%08x FSR=%08x\r\n",  r.iExcCode, r.iN.iFlags, r.iB[0].iDFAR, r.iB[0].iDFSR);
 		Printf(" R0=%08x  R1=%08x  R2=%08x  R3=%08x\r\n",  r.iN.iR0,  r.iN.iR1,  r.iN.iR2,  r.iN.iR3);
@@ -233,7 +142,6 @@
 
 EXPORT_C void Monitor::GetStackPointers(NThread* aThread, TUint& aSupSP, TUint& aUsrSP)
 	{
-//	TScheduler* pS = TScheduler::Ptr();
 	if (aThread->iCurrent)
 		{
 		TInt i = aThread->iLastCpu;
--- a/kernel/eka/nkernsmp/arm/ncsched.cia	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/nkernsmp/arm/ncsched.cia	Fri Apr 16 16:24:37 2010 +0300
@@ -54,6 +54,7 @@
 
 extern "C" void NewThreadTrace(NThread* a);
 extern "C" void send_accumulated_resched_ipis();
+extern "C" void wake_up_for_ipi(TSubScheduler*, TInt);
 
 
 __NAKED__ void TScheduler::Reschedule()
@@ -71,7 +72,7 @@
 	__ASM_CLI();							// interrupts off
 	asm("ldr	r1, [r0, #%a0]" : : "i" (_FOFF(TSubScheduler,iDfcPendingFlag)&~3));	// check iDfcPendingFlag and iExIDfcPendingFlag
 	asm("mov	r11, r0 ");					// r11->TSubScheduler
-	asm("ldr	r10, [r0, #%a0]" : : "i" _FOFF(TSubScheduler,i_LocalTimerAddr));	// r10->CPU local timer
+	asm("ldr	r10, [r0, #%a0]" : : "i" _FOFF(TSubScheduler,iSSX.iLocalTimerAddr));	// r10->CPU local timer
 
 	asm("start_resched: ");
 	asm("movs	r1, r1, lsr #16 ");			// check if IDFCs or ExIDFCs pending
@@ -829,11 +830,13 @@
 	}
 
 
-extern "C" __NAKED__ void send_irq_ipi(TSubScheduler*)
+extern "C" __NAKED__ void send_irq_ipi(TSubScheduler*, TInt)
 	{
+	asm("tst	r1, #%a0" : : "i" ((TInt)EQueueEvent_WakeUp) );
+	asm("bne "	CSM_CFUNC(wake_up_for_ipi));
 	__DATA_SYNC_BARRIER_Z__(r3);			// need DSB before sending any IPI
 	asm("ldr	r3, [r0, #%a0]" : : "i" _FOFF(TSubScheduler, iCpuMask));
-	asm("ldr	r2, [r0, #%a0]" : : "i" _FOFF(TSubScheduler, i_GicDistAddr));	// we assume i_GicDistAddr is the same for all CPUs
+	asm("ldr	r2, [r0, #%a0]" : : "i" _FOFF(TSubScheduler, iSSX.iGicDistAddr));	// we assume i_GicDistAddr is the same for all CPUs
 	asm("mov	r1, #%a0" : : "i" ((TInt)TRANSFERRED_IRQ_VECTOR));
 	asm("orr	r1, r1, r3, lsl #16 ");
 	asm("str	r1, [r2, #%a0]" : : "i" _FOFF(GicDistributor, iSoftIrq));	// trigger IPIs
@@ -845,7 +848,12 @@
 // Return with R0 unaltered.
 extern "C" __NAKED__ void send_accumulated_resched_ipis()
 	{
-	asm("ldr	r2, [r0, #%a0]" : : "i" _FOFF(TSubScheduler, i_GicDistAddr));
+	asm("ldr	r3, [r0, #%a0]" : : "i" _FOFF(TSubScheduler, iScheduler));
+	asm("ldr	r2, [r0, #%a0]" : : "i" _FOFF(TSubScheduler, iSSX.iGicDistAddr));
+	asm("ldr	r1, [r3, #%a0]" : : "i" _FOFF(TScheduler, iThreadAcceptCpus));
+	asm("bics	r1, r12, r1 ");
+	asm("bne	2f ");
+	asm("1:		");
 	asm("mov	r1, #0 ");
 	asm("str	r1, [r0, #%a0]" : : "i" _FOFF(TSubScheduler,iReschedIPIs));
 	__DATA_SYNC_BARRIER__(r1);				// need DSB before sending any IPI
@@ -853,6 +861,16 @@
 //	asm("orr	r1, r1, #%a0" : : "i" ((TInt)RESCHED_IPI_VECTOR));	RESCHED_IPI_VECTOR=0
 	asm("str	r1, [r2, #%a0]" : : "i" _FOFF(GicDistributor, iSoftIrq));	// trigger IPIs
 	__JUMP(,lr);
+
+	asm("2:		");
+	asm("stmfd	sp!, {r0,lr} ");
+	asm("mov	r0, r3 ");
+	asm("mov	r1, r12 ");
+	asm("bl		ReschedInactiveCpus__10TSchedulerUl ");
+	asm("mov	r12, r0 ");
+	asm("ldmfd	sp!, {r0,lr} ");
+	asm("ldr	r2, [r0, #%a0]" : : "i" _FOFF(TSubScheduler, iSSX.iGicDistAddr));
+	asm("b		1b ");
 	}
 
 // Send a reschedule IPI to the specified CPU
@@ -860,7 +878,7 @@
 	{
 	GET_RWNO_TID(,r3);
 	__DATA_SYNC_BARRIER_Z__(r2);			// need DSB before sending any IPI
-	asm("ldr	r2, [r3, #%a0]" : : "i" _FOFF(TSubScheduler, i_GicDistAddr));	// we assume i_GicDistAddr is the same for all CPUs
+	asm("ldr	r2, [r3, #%a0]" : : "i" _FOFF(TSubScheduler, iSSX.iGicDistAddr));	// we assume i_GicDistAddr is the same for all CPUs
 	ASM_DEBUG1(SendReschedIPI,r0);
 	asm("mov	r1, #0x10000 ");
 	asm("mov	r1, r1, lsl r0 ");	// 0x10000<<aCpu
@@ -875,44 +893,30 @@
 	{
 	GET_RWNO_TID(,r3);
 	__DATA_SYNC_BARRIER_Z__(r2);			// need DSB before sending any IPI
-	asm("ldr	r2, [r3, #%a0]" : : "i" _FOFF(TSubScheduler, i_GicDistAddr));	// we assume i_GicDistAddr is the same for all CPUs
+	asm("ldr	r2, [r3, #%a0]" : : "i" _FOFF(TSubScheduler, iSSX.iGicDistAddr));	// we assume i_GicDistAddr is the same for all CPUs
 	asm("mov	r1, #0x02000000 ");			// target = requesting CPU only
 //	asm("orr	r1, r1, #%a0" : : "i" ((TInt)RESCHED_IPI_VECTOR));	RESCHED_IPI_VECTOR=0
 	asm("str	r1, [r2, #%a0]" : : "i" _FOFF(GicDistributor, iSoftIrq));	// trigger IPI
 	__JUMP(,lr);
 	}
 
-extern "C" __NAKED__ void send_resched_ipis(TUint32 aMask)
-	{
-	ASM_DEBUG1(SendReschedIPIs,r0);
-	__DATA_SYNC_BARRIER_Z__(r2);			// need DSB before sending any IPI
-	asm("cmp	r0, #0 ");		// any bits set in aMask?
-	GET_RWNO_TID(ne,r3);
-	asm("ldrne	r2, [r3, #%a0]" : : "i" _FOFF(TSubScheduler, i_GicDistAddr));	// we assume i_GicDistAddr is the same for all CPUs
-	asm("movne	r0, r0, lsl #16 ");
-//	asm("orrne	r0, r0, #%a0" : : "i" ((TInt)RESCHED_IPI_VECTOR));	RESCHED_IPI_VECTOR=0
-	asm("strne	r0, [r2, #%a0]" : : "i" _FOFF(GicDistributor, iSoftIrq));	// trigger IPIs if any
-	__JUMP(,lr);
-	}
-
-
 extern "C" __NAKED__ void send_resched_ipi_and_wait(TInt /*aCpu*/)
 	{
 	asm("ldr	r1, __TheSubSchedulers ");
 	asm("mov	r2, #0x10000 ");
 	asm("mov	r2, r2, lsl r0 ");	// 0x10000<<aCpu
 	ASM_DEBUG1(SendReschedIPIAndWait,r0);
-	asm("add	r0, r1, r0, lsl #9 ");	// sizeof(TSubScheduler)=512
-	asm("ldr	r3, [r0, #%a0]" : : "i" _FOFF(TSubScheduler, i_GicDistAddr));	// we assume i_GicDistAddr is the same for all CPUs
-	asm("ldr	r12, [r0, #%a0]" : : "i" _FOFF(TSubScheduler, i_IrqCount));
+	asm("add	r0, r1, r0, lsl #%a0 " : : "i" ((TInt)KSubSchedulerShift));
+	asm("ldr	r3, [r0, #%a0]" : : "i" _FOFF(TSubScheduler, iSSX.iGicDistAddr));	// we assume i_GicDistAddr is the same for all CPUs
+	asm("ldr	r12, [r0, #%a0]" : : "i" _FOFF(TSubScheduler, iSSX.iIrqCount));
 	__DATA_SYNC_BARRIER_Z__(r1);		// make sure i_IrqCount is read before IPI is sent
 //	asm("orr	r2, r2, #%a0" : : "i" ((TInt)RESCHED_IPI_VECTOR));	RESCHED_IPI_VECTOR=0
 	asm("str	r2, [r3, #%a0]" : : "i" _FOFF(GicDistributor, iSoftIrq));	// trigger IPIs
 	__DATA_SYNC_BARRIER__(r1);			// make sure IPI has been sent
 	asm("1: ");
 	asm("ldrb	r1, [r0, #%a0]" : : "i" _FOFF(TSubScheduler, iRescheduleNeededFlag));
-	asm("ldr	r2, [r0, #%a0]" : : "i" _FOFF(TSubScheduler, i_IrqNestCount));
-	asm("ldr	r3, [r0, #%a0]" : : "i" _FOFF(TSubScheduler, i_IrqCount));
+	asm("ldr	r2, [r0, #%a0]" : : "i" _FOFF(TSubScheduler, iSSX.iIrqNestCount));
+	asm("ldr	r3, [r0, #%a0]" : : "i" _FOFF(TSubScheduler, iSSX.iIrqCount));
 	asm("cmp	r1, #0 ");
 	asm("beq	0f ");					// iRescheduleNeededFlag not set -> wait
 	asm("cmp	r2, #0 ");
@@ -930,6 +934,7 @@
 	asm(".word TheSubSchedulers ");
 	}
 
+
 /*	If the current thread is subject to timeslicing, update its remaining time
 	from the current CPU's local timer. Don't stop the timer.
 	If the remaining time is negative, save it as zero.
@@ -938,49 +943,57 @@
 	{
 	asm("ldr	r3, [r1, #%a0]" : : "i" _FOFF(NThreadBase,iTime));
 	asm("ldrb	r12, [r1, #%a0]" : : "i" _FOFF(NThreadBase,i_NThread_Initial));
-	asm("ldr	r2, [r0, #%a0]" : : "i" _FOFF(TSubScheduler,i_LocalTimerAddr));
+	asm("ldr	r2, [r0, #%a0]" : : "i" _FOFF(TSubScheduler,iSSX.iLocalTimerAddr));
 	asm("cmp	r3, #0 ");
 	asm("ble	0f ");					// thread isn't timesliced or timeslice already expired so skip
 	asm("cmp	r12, #0 ");
 	asm("bne	0f ");					// initial (i.e. idle) thread, so skip
 	asm("ldr	r3, [r2, #%a0]" : : "i" _FOFF(ArmLocalTimer,iTimerCount));
-	asm("ldr	r12, [r0, #%a0]" : : "i" _FOFF(TSubScheduler,i_TimerMultI));
+	asm("ldr	r12, [r0, #%a0]" : : "i" _FOFF(TSubScheduler,iSSX.iTimerPeriodM));
+	asm("ldr	r2, [r0, #%a0]" : : "i" _FOFF(TSubScheduler,iSSX.iTimerPeriodS));
 	asm("cmp	r3, #0 ");
 	asm("movmi	r0, #0 ");				// if timer count is negative, save zero
 	asm("bmi	1f ");
-	asm("umull	r0, r3, r12, r3 ");		// scale up to max timer clock
-	asm("adds	r0, r0, #0x00800000 ");
-	asm("adcs	r3, r3, #0 ");
-	asm("mov	r0, r0, lsr #24 ");
-	asm("orr	r0, r0, r3, lsl #8 ");
+	asm("umull	r0, r3, r12, r3 ");		// scale up to max timer clock (R3:R0)
+	asm("rsb	r12, r2, #32 ");
+	asm("movs	r0, r0, lsr r2 ");		// r0 >>= iSSX.iTimerPeriodS, C = last bit shifted off (rounding)
+	asm("orr	r0, r0, r3, lsl r12 ");	// bottom bits from r12 into top bits of r0
+	asm("adcs	r0, r0, #0 ");			// round using last bit shifted off
 	asm("1:		");
 	asm("str	r0, [r1, #%a0]" : : "i" _FOFF(NThreadBase,iTime));
 	asm("0:		");
 	__JUMP(,lr);
 	}
 
+
+#if defined(__UTT_MACHINE_CODED__)
+#if defined(__NKERN_TIMESTAMP_USE_LOCAL_TIMER__)
+#error Use of local timer for NKern::Timestamp() no longer supported
+#else
+
 /*	Update aOld's execution time and set up the timer for aNew
 	Update this CPU's timestamp value
 
 	if (!aOld) aOld=iInitialThread
 	if (!aNew) aNew=iInitialThread
-	newcount = aNew->iTime>0 ? Max(aNew->iTime*i_TimerMultF/2^32, 1) : 2^31-1
+	newcount = aNew->iTime>0 ? Max(aNew->iTime*iSSX.iTimerFreqM/2^(32+iTimerFreqS), 1) : 2^31-1
 	cli()
 	oldcount = timer count
 	if (oldcount<=0 || aOld!=aNew)
 		{
 		timer count = newcount
-		elapsed = i_LastTimerSet - oldcount
-		i_LastTimerSet = newcount
-		elapsed = elapsed * i_TimerMultI / 2^24
-		aOld->iTotalCpuTime64 += elapsed
-		correction = i_TimestampError;
-		if (correction > i_MaxCorrection)
-			correction = i_MaxCorrection
-		else if (correction < -i_MaxCorrection)
-			correction = -i_MaxCorrection
-		i_TimestampError -= correction
-		i_LastTimestamp += elapsed + i_TimerGap - correction
+		iSSX.iLastTimerSet = newcount
+		if (aOld!=aNew)
+			{
+			TUint64 now = NKern::Timestamp();
+			elapsed = iLastTimestamp -= now;
+			iLastTimestamp = now;
+			aOld->iTotalCpuTime.i64 += elapsed;
+			if (!aOld->iActiveState)
+				aOld->iTotalActiveTime.i64 += (now - aOld->iLastActivationTime.i64);
+			++iReschedCount.i64;
+			++aNew->iRunCount.i64;
+			}
 		}
 	sti()
  */
@@ -988,77 +1001,73 @@
 	{
 	asm("cmp	r2, #0 ");
 	asm("ldreq	r2, [r0, #%a0]" : : "i" _FOFF(TSubScheduler,iInitialThread));
-	asm("ldr	r12, [r0, #%a0]" : : "i" _FOFF(TSubScheduler,i_TimerMultF));
+	asm("ldr	r12, [r0, #%a0]" : : "i" _FOFF(TSubScheduler,iSSX.iTimerFreqM));
 	asm("cmp	r1, #0 ");
 	asm("ldreq	r1, [r0, #%a0]" : : "i" _FOFF(TSubScheduler,iInitialThread));
 	asm("ldr	r3, [r2, #%a0]" : : "i" _FOFF(NThreadBase,iTime));
 	asm("stmfd	sp!, {r4-r7} ");
-	asm("ldr	r6, [r2, #%a0]" : : "i" _FOFF(NThreadBase,iRunCount64));
-	asm("ldr	r7, [r2, #%a0]" : : "i" (_FOFF(NThreadBase,iRunCount64)+4));
 	asm("cmp	r1, r2 ");
 	asm("beq	2f ");
+	asm("ldr	r6, [r2, #%a0]" : : "i" _FOFF(NThreadBase,iRunCount.i32[0]));
+	asm("ldr	r7, [r2, #%a0]" : : "i" _FOFF(NThreadBase,iRunCount.i32[1]));
 	asm("adds	r6, r6, #1 ");
-	asm("str	r6, [r2, #%a0]" : : "i" _FOFF(NThreadBase,iRunCount64));
-	asm("ldr	r4, [r0, #%a0]" : : "i" _FOFF(TSubScheduler,iReschedCount64));
-	asm("ldr	r6, [r0, #%a0]" : : "i" (_FOFF(TSubScheduler,iReschedCount64)+4));
+	asm("str	r6, [r2, #%a0]" : : "i" _FOFF(NThreadBase,iRunCount.i32[0]));
+	asm("ldr	r4, [r0, #%a0]" : : "i" _FOFF(TSubScheduler,iReschedCount.i32[0]));
+	asm("ldr	r6, [r0, #%a0]" : : "i" _FOFF(TSubScheduler,iReschedCount.i32[1]));
 	asm("adcs	r7, r7, #0 ");
-	asm("str	r7, [r2, #%a0]" : : "i" (_FOFF(NThreadBase,iRunCount64)+4));
+	asm("str	r7, [r2, #%a0]" : : "i" _FOFF(NThreadBase,iRunCount.i32[1]));
 	asm("adds	r4, r4, #1 ");
 	asm("adcs	r6, r6, #0 ");
-	asm("str	r4, [r0, #%a0]" : : "i" _FOFF(TSubScheduler,iReschedCount64));
-	asm("str	r6, [r0, #%a0]" : : "i" (_FOFF(TSubScheduler,iReschedCount64)+4));
+	asm("str	r4, [r0, #%a0]" : : "i" _FOFF(TSubScheduler,iReschedCount.i32[0]));
+	asm("str	r6, [r0, #%a0]" : : "i" _FOFF(TSubScheduler,iReschedCount.i32[1]));
 	asm("2:		");
+	asm("ldr	r6, [r0, #%a0]" : : "i" _FOFF(TSubScheduler,iSSX.iLocalTimerAddr));
 	asm("cmp	r3, #1 ");					// aNew->iTime > 0 ?
-	asm("umullge r4, r3, r12, r3 ");
-	asm("ldr	r5, [r0, #%a0]" : : "i" _FOFF(TSubScheduler,i_LocalTimerAddr));
-	asm("movlt	r3, #0x7fffffff ");
-	asm("addges	r3, r3, r4, lsr #31 ");		// round up top 32 bits if bit 31 set
-	asm("moveq	r3, #1 ");					// if result zero, limit to 1
-	asm("ldr	r12, [r0, #%a0]" : : "i" _FOFF(TSubScheduler,i_LastTimerSet));
-	__ASM_CLI();
-	asm("ldr	r4, [r5, #%a0]" : : "i" _FOFF(ArmLocalTimer,iTimerCount));
-	asm("cmp	r1, r2 ");
-	asm("bne	1f ");
-	asm("cmp	r4, #0 ");
-	asm("bgt	0f ");						// same thread, timeslice not expired -> leave timer alone
-	asm("1:		");
-	asm("str	r3, [r5, #%a0]" : : "i" _FOFF(ArmLocalTimer,iTimerCount));	// set new timeslice value in timer
-	asm("ldr	r5, [r0, #%a0]" : : "i" _FOFF(TSubScheduler,i_TimerMultI));
-	asm("str	r3, [r0, #%a0]" : : "i" _FOFF(TSubScheduler,i_LastTimerSet));
-	asm("sub	r12, r12, r4 ");			// r12 = elapsed (actual timer ticks)
-	asm("umull	r4, r5, r12, r5 ");
-	asm("ldr	r3, [r1, #%a0]!" : : "i" _FOFF(NThreadBase,iTotalCpuTime64));
+	asm("movlt	r3, #0x7fffffff ");			// if not, use 2^31-1
+	asm("blt	3f ");
+	asm("cmp	r1, r2 ");					// different thread?
+	asm("beq	0f ");						// no - finish
+	asm("ldr	r5, [r0, #%a0]" : : "i" _FOFF(TSubScheduler,iSSX.iTimerFreqS));
+	asm("umull	r4, r3, r12, r3 ");			// r3:r4 = aNew->iTime * iTimerFreqM
+	asm("adds	r4, r4, r4 ");				// bit 31 into C
+	asm("teq	r5, #0 ");					// check for iTimerFreqS=0 without changing C
+	asm("movnes	r3, r3, lsr r5 ");			// if not, r3>>=iTimerFreqS, last bit shifted out into C
+	asm("adcs	r3, r3, #0 ");				// round using last bit shifted off
+	asm("3:		");
+	asm("str	r3, [r0, #%a0]" : : "i" _FOFF(TSubScheduler,iSSX.iLastTimerSet));
+	asm("str	r3, [r6, #%a0]" : : "i" _FOFF(ArmLocalTimer,iTimerCount));	// set new timeslice value in timer
+
+	asm("ldr	r6, [r0, #%a0]" : : "i" _FOFF(TSubScheduler,iLastTimestamp.i32[0]));
+	asm("ldr	r7, [r0, #%a0]" : : "i" _FOFF(TSubScheduler,iLastTimestamp.i32[1]));
+	asm("stmfd	sp!, {r0-r2,lr} ");
+	asm("bl		Timestamp__5NKern ");		// R1:R0 = current time
+	asm("mov	r4, r0 ");
+	asm("mov	r5, r1 ");					// R5:R4 = current time
+	asm("ldmfd	sp!, {r0-r2,lr} ");
+	asm("str	r4, [r0, #%a0]" : : "i" _FOFF(TSubScheduler,iLastTimestamp.i32[0]));
+	asm("ldr	r3, [r1, #%a0]!" : : "i" _FOFF(NThreadBase,iTotalCpuTime.i64));
 	asm("ldr	r12, [r1, #4] ");
-	asm("adds	r4, r4, #0x00800000 ");
-	asm("adcs	r5, r5, #0 ");
-	asm("mov	r4, r4, lsr #24 ");
-	asm("orr	r4, r4, r5, lsl #8 ");		// r4 = elapsed
-	asm("adds	r3, r3, r4 ");
-	asm("adcs	r12, r12, #0 ");
-	asm("stmia	r1, {r3,r12} ");			// aOld->iTotalCpuTime64 += elapsed
-	asm("ldr	r3, [r0, #%a0]" : : "i" _FOFF(TSubScheduler,i_TimestampError));
-	asm("ldr	r5, [r0, #%a0]" : : "i" _FOFF(TSubScheduler,i_MaxCorrection));
-	asm("ldr	r1, [r0, #%a0]" : : "i" _FOFF(TSubScheduler,iLastTimestamp64));
-	asm("ldr	r2, [r0, #%a0]" : : "i" (_FOFF(TSubScheduler,iLastTimestamp64)+4));
-	asm("mov	r12, r3 ");
-	asm("cmp	r3, r5 ");
-	asm("movgt	r3, r5 ");					// if (correction>i_MaxCorrection) correction=i_MaxCorrection
-	asm("cmn	r3, r5 ");
-	asm("rsblt	r3, r5, #0 ");				// if (correction+i_MaxCorrection<0) correction=-i_MaxCorrection
-	asm("ldr	r5, [r0, #%a0]" : : "i" _FOFF(TSubScheduler,i_TimerGap));
-	asm("sub	r12, r12, r3 ");
-	asm("str	r12, [r0, #%a0]" : : "i" _FOFF(TSubScheduler,i_TimestampError));
-	asm("add	r4, r4, r5 ");				// r4 = elapsed + i_TimerGap
-	asm("adds	r1, r1, r4 ");
-	asm("adcs	r2, r2, #0 ");				// iLastTimestamp64 + (elapsed + i_TimerGap)
-	asm("subs	r1, r1, r3 ");
-	asm("sbcs	r1, r1, r3, asr #32 ");		// iLastTimestamp64 + (elapsed + i_TimerGap - correction)
-	asm("str	r1, [r0, #%a0]" : : "i" _FOFF(TSubScheduler,iLastTimestamp64));
-	asm("str	r2, [r0, #%a0]" : : "i" (_FOFF(TSubScheduler,iLastTimestamp64)+4));
+	asm("str	r5, [r0, #%a0]" : : "i" _FOFF(TSubScheduler,iLastTimestamp.i32[1]));
+	asm("stmdb	r1, {r4-r5} ");				// aOld->iLastRunTime
+	asm("ldrb	r2, [r1, #%a0]" : : "i" (_FOFF(NSchedulable,iActiveState)-_FOFF(NThreadBase,iTotalCpuTime.i64)));
+	asm("subs	r6, r4, r6 ");
+	asm("sbcs	r7, r5, r7 ");				// R7:R6 = time since last reschedule
+	asm("adds	r3, r3, r6 ");
+	asm("adcs	r12, r12, r7 ");			// total CPU time of old thread
+	asm("stmia	r1!, {r3,r12} ");			// store, r1=&aOld.iLastActivationTime
+	asm("cmp	r2, #0 ");					// old thread still active?
+	asm("bne	0f ");						// yes - done
+	asm("ldmia	r1!, {r2,r3,r6,r7} ");		// R3:R2 = last activation time, R7:R6=total active time
+	asm("subs	r2, r4, r2 ");
+	asm("sbcs	r3, r5, r3 ");				// R3:R2 = time since last activation
+	asm("adds	r6, r6, r2 ");
+	asm("adcs	r7, r7, r3 ");				// R7:R6 = new total active time
+	asm("stmdb	r1, {r6,r7} ");
+
 	asm("0:		");
-	__ASM_STI();
 	asm("ldmfd	sp!, {r4-r7} ");
 	__JUMP(,lr);
 	}
 
-
+#endif
+#endif	// __UTT_MACHINE_CODED__
--- a/kernel/eka/nkernsmp/arm/ncsched.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/nkernsmp/arm/ncsched.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -19,6 +19,7 @@
 #define __INCLUDE_NTHREADBASE_DEFINES__
 
 #include <arm.h>
+#include <arm_tmr.h>
 
 extern "C" void NewThreadTrace(NThread* a)
 	{
@@ -159,3 +160,55 @@
 
 #endif
 
+#if !defined(__UTT_MACHINE_CODED__)
+void TSubScheduler::UpdateThreadTimes(NThreadBase* aOld, NThreadBase* aNew)
+	{
+	if (!aOld)
+		aOld = iInitialThread;
+	if (!aNew)
+		aNew = iInitialThread;
+	if (aNew!=aOld || aNew->iTime<=0)
+		{
+		TUint32 tmrval = 0x7fffffffu;
+		if (aNew->iTime > 0)
+			{
+			TUint64 x = TUint64(aNew->iTime) * TUint64(iSSX.iTimerFreqM);
+			tmrval = I64HIGH(x);
+			if (iSSX.iTimerFreqS)
+				{
+				tmrval += ((1u<<iSSX.iTimerFreqS)-1);
+				tmrval >>= iSSX.iTimerFreqS;
+				}
+			else if (I64LOW(x) & 0x80000000u)
+				++tmrval;
+			}
+		iSSX.iLastTimerSet = tmrval;
+		iSSX.iLocalTimerAddr->iTimerCount = tmrval;
+		}
+	if (aNew!=aOld)
+		{
+		TUint64 now = NKern::Timestamp();
+		TUint64 delta = now - iLastTimestamp.i64;
+		iLastTimestamp.i64 = now;
+		aOld->iLastRunTime.i64 = now;
+		aOld->iTotalCpuTime.i64 += delta;
+		++iReschedCount.i64;
+		++aNew->iRunCount.i64;
+		if (!aOld->iActiveState)
+			aOld->iTotalActiveTime.i64 += (now - aOld->iLastActivationTime.i64);
+		NSchedulable* parent = aOld->iParent;
+		if (parent != aOld)
+			{
+			parent->iLastRunTime.i64 = now;
+			if (!parent->iActiveState)
+				parent->iTotalActiveTime.i64 += (now - parent->iLastActivationTime.i64);
+			if (parent != aNew->iParent)
+				parent->iTotalCpuTime.i64 += (now - parent->iLastStartTime.i64);
+			}
+		NSchedulable* np = aNew->iParent;
+		if (np!=aNew && np!=parent)
+			np->iLastStartTime.i64 = now;
+		}
+	}
+#endif
+
--- a/kernel/eka/nkernsmp/arm/ncthrd.cia	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/nkernsmp/arm/ncthrd.cia	Fri Apr 16 16:24:37 2010 +0300
@@ -966,6 +966,7 @@
 	asm("ldr	r1, [r6, #%a0]" : : "i" (_FOFF(NThreadBase,iPauseCount)-_FOFF(NThreadBase,iWaitState)));
 	asm("sub	r0, r6, #%a0" : : "i" _FOFF(NThreadBase,iWaitState));	// r0 = Thread()
 	asm("movs	r1, r1, lsl #16 ");				// check if iPauseCount=iSuspendCount=0
+	asm("andeq	r1, r4, #%a0" : : "i" ((TInt)EWtStObstructed));
 	asm("bleq	ReadyT__12NSchedulableUi ");	// if so, make thread ready
 	asm("0:		");
 	asm("mov	r0, #0 ");
--- a/kernel/eka/nkernsmp/arm/ncthrd.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/nkernsmp/arm/ncthrd.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -36,7 +36,7 @@
 extern "C" void ExcFault(TAny*);
 
 extern TUint32 __mpid();
-extern void InitAPTimestamp(SNThreadCreateInfo& aInfo);
+extern void InitTimestamp(TSubScheduler* aSS, SNThreadCreateInfo& aInfo);
 
 TInt NThread::Create(SNThreadCreateInfo& aInfo, TBool aInitial)
 	{
@@ -44,19 +44,22 @@
 	__NK_ASSERT_ALWAYS((aInfo.iParameterBlockSize&0x80000007)==0);
 	__NK_ASSERT_ALWAYS(aInfo.iStackBase && aInfo.iStackSize>=aInfo.iParameterBlockSize+KNThreadMinStackSize);
 	TInt cpu = -1;
+	TSubScheduler* ss = 0;
 	new (this) NThread;
 	if (aInitial)
 		{
 		cpu = __e32_atomic_add_ord32(&TheScheduler.iNumCpus, 1);
 		aInfo.iCpuAffinity = cpu;
 		// OK since we can't migrate yet
-		TSubScheduler& ss = TheSubSchedulers[cpu];
-		ss.iCurrentThread = this;
-		iRunCount64 = UI64LIT(1);
-		__KTRACE_OPT(KBOOT,DEBUGPRINT("Init: cpu=%d ss=%08x", cpu, &ss));
+		ss = &TheSubSchedulers[cpu];
+		ss->iCurrentThread = this;
+		ss->iDeferShutdown = 0;
+		iRunCount.i64 = UI64LIT(1);
+		iActiveState = 1;
+		__KTRACE_OPT(KBOOT,DEBUGPRINT("Init: cpu=%d ss=%08x", cpu, ss));
 		if (cpu)
 			{
-			initialiseState(cpu,&ss);
+			initialiseState(cpu,ss);
 
 			ArmLocalTimer& T = LOCAL_TIMER;
 			T.iWatchdogDisable = E_ArmTmrWDD_1;
@@ -69,9 +72,10 @@
 			NIrq::HwInit2AP();
 			T.iTimerCtrl = E_ArmTmrCtrl_IntEn | E_ArmTmrCtrl_Reload | E_ArmTmrCtrl_Enable;
 
-			__e32_atomic_ior_ord32(&TheScheduler.iActiveCpus1, 1<<cpu);
-			__e32_atomic_ior_ord32(&TheScheduler.iActiveCpus2, 1<<cpu);
+			__e32_atomic_ior_ord32(&TheScheduler.iThreadAcceptCpus, 1<<cpu);
+			__e32_atomic_ior_ord32(&TheScheduler.iIpiAcceptCpus, 1<<cpu);
 			__e32_atomic_ior_ord32(&TheScheduler.iCpusNotIdle, 1<<cpu);
+			__e32_atomic_add_ord32(&TheScheduler.iCCRequestLevel, 1);
 			__KTRACE_OPT(KBOOT,DEBUGPRINT("AP MPID=%08x",__mpid()));
 			}
 		else
@@ -132,10 +136,11 @@
 		ArmLocalTimer& T = LOCAL_TIMER;
 		T.iTimerCtrl = E_ArmTmrCtrl_IntEn | E_ArmTmrCtrl_Reload | E_ArmTmrCtrl_Enable;
 
-		// synchronize AP's timestamp with BP's
-		if (cpu>0)
-			InitAPTimestamp(aInfo);
+		// Initialise timestamp
+		InitTimestamp(ss, aInfo);
 		}
+	AddToEnumerateList();
+	InitLbInfo();
 #ifdef BTRACE_THREAD_IDENTIFICATION
 	BTrace4(BTrace::EThreadIdentification,BTrace::ENanoThreadCreate,this);
 #endif
@@ -184,7 +189,7 @@
 	TInt irq = NKern::DisableAllInterrupts();
 	TSubScheduler& ss = SubScheduler();
 	NThreadBase* ct = ss.iCurrentThread;
-	TInt inc = TInt(ss.i_IrqNestCount);
+	TInt inc = TInt(ss.iSSX.iIrqNestCount);
 	TInt cpu = ss.iCpuNum;
 	TInt klc = ss.iKernLockCount;
 	NKern::RestoreInterrupts(irq);
@@ -652,7 +657,7 @@
 	if (pC != this)
 		{
 		AcqSLock();
-		if (iWaitState.ThreadIsDead())
+		if (iWaitState.ThreadIsDead() || i_NThread_Initial)
 			{
 			RelSLock();
 			aAvailRegistersMask = 0;
@@ -840,7 +845,7 @@
 	if (pC != this)
 		{
 		AcqSLock();
-		if (iWaitState.ThreadIsDead())
+		if (iWaitState.ThreadIsDead() || i_NThread_Initial)
 			{
 			RelSLock();
 			aRegMask = 0;
@@ -1057,36 +1062,14 @@
 	return 0;
 	}
 
-/** Return the total CPU time so far used by the specified thread.
-
-	@return The total CPU time in units of 1/NKern::CpuTimeMeasFreq().
-*/
-EXPORT_C TUint64 NKern::ThreadCpuTime(NThread* aThread)
-	{
-	TSubScheduler* ss = 0;
-	NKern::Lock();
-	aThread->AcqSLock();
-	if (aThread->i_NThread_Initial)
-		ss = &TheSubSchedulers[aThread->iLastCpu];
-	else if (aThread->iReady && aThread->iParent->iReady)
-		ss = &TheSubSchedulers[aThread->iParent->iReady & NSchedulable::EReadyCpuMask];
-	if (ss)
-		ss->iReadyListLock.LockOnly();
-	TUint64 t = aThread->iTotalCpuTime64;
-	if (aThread->iCurrent || (aThread->i_NThread_Initial && !ss->iCurrentThread))
-		t += (NKern::Timestamp() - ss->iLastTimestamp64);
-	if (ss)
-		ss->iReadyListLock.UnlockOnly();
-	aThread->RelSLock();
-	NKern::Unlock();
-	return t;
-	}
 
 TInt NKern::QueueUserModeCallback(NThreadBase* aThread, TUserModeCallback* aCallback)
 	{
 	__e32_memory_barrier();
 	if (aCallback->iNext != KUserModeCallbackUnqueued)
 		return KErrInUse;
+	if (aThread->i_NThread_Initial)
+		return KErrArgument;
 	TInt result = KErrDied;
 	NKern::Lock();
 	TUserModeCallback* listHead = aThread->iUserModeCallbacks;
--- a/kernel/eka/nkernsmp/arm/ncutilf.cia	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/nkernsmp/arm/ncutilf.cia	Fri Apr 16 16:24:37 2010 +0300
@@ -20,7 +20,9 @@
 #include <arm_gic.h>
 #include <arm_tmr.h>
 
-
+extern "C" {
+extern SVariantInterfaceBlock* VIB;
+}
 
 __NAKED__ void Arm::GetUserSpAndLr(TAny*) 
 	{
@@ -287,38 +289,72 @@
 #endif
 
 
-
-/** Get the current value of the system timestamp
+#if defined(__NKERN_TIMESTAMP_USE_LOCAL_TIMER__)
+#error Use of local timer for NKern::Timestamp() no longer supported
 
-@publishedPartner
-@prototype
-*/
+#elif defined(__NKERN_TIMESTAMP_USE_SCU_GLOBAL_TIMER__)
+// Code to access global timer in Cortex A9 r1p0
+
+#ifndef	__CPU_ARM_HAS_GLOBAL_TIMER_BLOCK
+#error NKern::Timestamp() wants global timer, but global timer not present.
+#endif
+
 EXPORT_C __NAKED__ TUint64 NKern::Timestamp()
 	{
 	asm("ldr	r3, __TheScheduler ");
 	asm("mrs	r12, cpsr ");				// r12 = saved interrupt mask
-	asm("ldr	r2, [r3, #%a0]" : : "i" _FOFF(TScheduler,i_LocalTimerAddr));	// r2 points to local timer
+	asm("stmfd	sp!, {r4-r7} ");
+	asm("ldr	r5, [r3, #%a0]" : : "i" _FOFF(TScheduler,iSub[0]));						// r5->subscheduler for CPU0
+	asm("ldr	r4, [r3, #%a0]" : : "i" _FOFF(TScheduler,iSX.iGlobalTimerAddr));		// r4 points to global timer
 	__ASM_CLI();							// disable all interrupts
-	GET_RWNO_TID(,r3);						// r3 -> TSubScheduler
-	asm("ldr	r1, [r2, #%a0]" : : "i" _FOFF(ArmLocalTimer,iTimerCount));		// r1 = current timer counter
-	asm("ldr	r0, [r3, #%a0]" : : "i" _FOFF(TSubScheduler,i_LastTimerSet));	// r0 = last value written to timer counter
-	asm("ldr	r2, [r3, #%a0]" : : "i" _FOFF(TSubScheduler,i_TimerMultI));		// r2 = scaling factor
-	asm("sub	r0, r0, r1 ");				// elapsed timer ticks since last timestamp sync
-	asm("umull	r1, r2, r0, r2 ");			// r2:r1 = elapsed ticks * scaling factor
-	asm("ldr	r0, [r3, #%a0]!" : : "i" _FOFF(TSubScheduler,iLastTimestamp64));	// r0 = last timestamp sync point, low word
-	asm("ldr	r3, [r3, #4] ");			// r3 = last timestamp sync point, high word
-	asm("adds	r1, r1, #0x00800000 ");		// add 2^23 (rounding)
-	asm("adcs	r2, r2, #0 ");
-	asm("mov	r1, r1, lsr #24 ");			// divide by 2^24
-	asm("orr	r1, r1, r2, lsl #8 ");		// r1 = elapsed time since last timestamp sync
+	asm("ldr	r6, [r5, #%a0]" : : "i" _FOFF(TSubScheduler,iSSX.iTicksSinceLastSync));	// r6 = count value of last frequency change (low)
+	asm("ldr	r7, [r5, #%a0]" : : "i" _FOFF(TSubScheduler,iSSX.iLastTimerSet));		// r7 = count value of last frequency change (high)
+	asm("ldr	r2, [r4, #%a0]" : : "i" _FOFF(ArmGlobalTimer,iTimerCountHigh));			// r2 = current timer counter high word
+
+	// To read 64 bit timer value, read high, low, high
+	// If two high values match -> OK, else repeat
+	asm("1:		");
+	asm("mov	r1, r2 ");					// r1 = previous value of timer counter high word
+	asm("ldr	r0, [r4, #%a0]" : : "i" _FOFF(ArmGlobalTimer,iTimerCountLow));			// r0 = current timer counter low word
+	asm("ldr	r2, [r4, #%a0]" : : "i" _FOFF(ArmGlobalTimer,iTimerCountHigh));			// r2 = current timer counter high word
+	asm("cmp	r1, r2 ");					// high word changed?
+	asm("bne	1b ");						// if so, retry
+
+	// Now have R1:R0 = 64 bit global timer count
+	asm("ldr	r3, [r5, #%a0]" : : "i" _FOFF(TSubScheduler,iSSX.iNTimerPeriodM));		// r3 = period multiplier
+	asm("ldr	r4, [r5, #%a0]" : : "i" _FOFF(TSubScheduler,iSSX.iNTimerPeriodS));		// r4 = period multiplier shift
+	asm("subs	r6, r0, r6 ");				// r7:r6 = ticks from last frequency change
+	asm("sbcs	r7, r1, r7 ");
+	asm("umull	r0, r1, r6, r3 ");
+	asm("mov	r2, #0 ");
+	asm("umlal	r1, r2, r7, r3 ");			// r2:r1:r0 = delta * period multiplier
+	asm("rsb	r3, r4, #32 ");
+	asm("ldr	r6, [r5, #%a0]!" : : "i" _FOFF(TSubScheduler,iSSX.iLastSyncTime));		// r6 = timestamp at last freq change (low)
+	asm("ldr	r7, [r5, #4] ");														// r7 = timestamp at last freq change (high)
 	asm("msr	cpsr, r12 ");				// restore interrupts
-	asm("adds	r0, r0, r1 ");				// r1:r0 = last timestamp sync point + elapsed time since last timestamp sync
-	asm("adcs	r1, r3, #0 ");
+	asm("movs	r0, r0, lsr r4 ");			// rounding bit into C
+	asm("orr	r0, r0, r1, lsl r3 ");
+	asm("mov	r1, r1, lsr r4 ");
+	asm("orr	r1, r1, r2, lsl r3 ");		// r1:r0 = (delta * period multiplier) >> period multiplier shift
+	asm("adcs	r0, r0, r6 ");				// scaled delta + timestamp at last freq change
+	asm("adcs	r1, r1, r7 ");
+	asm("ldmfd	sp!, {r4-r7} ");
 	__JUMP(,lr);
+
 	asm("__TheScheduler: ");
 	asm(".word	%a0" : : "i" ((TInt)&TheScheduler));
 	}
 
+#elif defined(__NKERN_TIMESTAMP_USE_INLINE_BSP_CODE__)
+#define __DEFINE_NKERN_TIMESTAMP_ASM__
+#include <variant_timestamp.h>
+#undef __DEFINE_NKERN_TIMESTAMP_ASM__
+#elif defined(__NKERN_TIMESTAMP_USE_BSP_CALLOUT__)
+// Code to call function defined in variant
+#else
+#error No definition for NKern::Timestamp()
+#endif
+
 
 extern "C" __NAKED__ TLinAddr get_sp_svc()
 	{
@@ -359,7 +395,7 @@
 
 	asm("1:		");
 	GET_RWNO_TID(,r3);
-	asm("ldr	r2, [r3, #%a0]" : : "i" _FOFF(TSubScheduler,i_FiqStackTop));	// if so, r2->top of FIQ stack
+	asm("ldr	r2, [r3, #%a0]" : : "i" _FOFF(TSubScheduler,iSSX.iFiqStackTop));	// if so, r2->top of FIQ stack
 	asm("ldr	r0, [r2, #-4] ");			// get return address
 	asm("msr	cpsr, r1 ");
 	__JUMP(,	lr);
@@ -594,9 +630,15 @@
 	__JUMP(,lr);
 
 	asm("2: ");
+	asm("ldr	r1, __CrashState ");
 	ARM_WFE;
-	asm("ldrb r1, [r0, #0] ");				/* read out count again */
-	asm("b 3b ");
+	asm("ldr	r1, [r1] ");				/* check for system crash while we were waiting */
+	asm("cmp	r1, #0 ");
+	asm("bne	9f ");
+	asm("ldrb	r1, [r0, #0] ");			/* read out count again */
+	asm("b		3b ");
+	asm("9:		");
+	__ASM_CRASH();							/* system crashed while we were waiting */
 	}
 
 __NAKED__ EXPORT_C void TSpinLock::UnlockIrq()
@@ -615,7 +657,7 @@
 __NAKED__ EXPORT_C TBool TSpinLock::FlashIrq()
 	{
 	GET_RWNO_TID(,r12);						/* r12 -> TSubScheduler */
-	asm("ldr r12, [r12, #%a0]" : : "i" _FOFF(TSubScheduler,i_GicCpuIfcAddr));
+	asm("ldr r12, [r12, #%a0]" : : "i" _FOFF(TSubScheduler,iSSX.iGicCpuIfcAddr));
 	asm("ldrh r1, [r0, #0] ");
 	asm("ldr r3, [r12, #%a0]" : : "i" _FOFF(GicCpuIfc,iHighestPending));
 	asm("sub r1, r1, r1, lsr #8 ");			/* r1 low byte = (out - in) mod 256 */
@@ -655,9 +697,15 @@
 	__JUMP(,lr);
 
 	asm("2: ");
+	asm("ldr	r1, __CrashState ");
 	ARM_WFE;
-	asm("ldrb r1, [r0, #0] ");				/* read out count again */
-	asm("b 3b ");
+	asm("ldr	r1, [r1] ");				/* check for system crash while we were waiting */
+	asm("cmp	r1, #0 ");
+	asm("bne	9f ");
+	asm("ldrb	r1, [r0, #0] ");			/* read out count again */
+	asm("b		3b ");
+	asm("9:		");
+	__ASM_CRASH();							/* system crashed while we were waiting */
 	}
 
 __NAKED__ EXPORT_C void TSpinLock::UnlockOnly()
@@ -713,9 +761,15 @@
 	__JUMP(,lr);
 
 	asm("2: ");
+	asm("ldr	r1, __CrashState ");
 	ARM_WFE;
-	asm("ldrb r1, [r0, #0] ");				/* read out count again */
-	asm("b 3b ");
+	asm("ldr	r1, [r1] ");				/* check for system crash while we were waiting */
+	asm("cmp	r1, #0 ");
+	asm("bne	9f ");
+	asm("ldrb	r1, [r0, #0] ");			/* read out count again */
+	asm("b		3b ");
+	asm("9:		");
+	__ASM_CRASH();							/* system crashed while we were waiting */
 	}
 
 __NAKED__ EXPORT_C void TSpinLock::UnlockIrqRestore(TInt)
@@ -737,7 +791,7 @@
 __NAKED__ EXPORT_C TBool TSpinLock::FlashIrqRestore(TInt)
 	{
 	GET_RWNO_TID(,r12);						/* r12 -> TSubScheduler */
-	asm("ldr r12, [r12, #%a0]" : : "i" _FOFF(TSubScheduler,i_GicCpuIfcAddr));
+	asm("ldr r12, [r12, #%a0]" : : "i" _FOFF(TSubScheduler,iSSX.iGicCpuIfcAddr));
 	asm("ldrh r2, [r0, #0] ");
 	asm("ldr r3, [r12, #%a0]" : : "i" _FOFF(GicCpuIfc,iHighestPending));
 	asm("sub r2, r2, r2, lsr #8 ");			/* r2 low byte = (out - in) mod 256 */
@@ -779,6 +833,9 @@
 	asm("bl " CSM_ZN9TSpinLock8LockOnlyEv);
 	asm("mov r0, #1 ");
 	asm("ldr pc, [sp], #4 ");
+
+	asm("__CrashState: ");
+	asm(".word	%a0" : : "i" ((TInt)&CrashState));
 	}
 
 
@@ -1161,9 +1218,15 @@
 	__JUMP(,lr);
 
 	asm("2: ");
+	asm("ldr	r1, __CrashState ");
 	ARM_WFE;
-	asm("ldr r1, [r0, #0] ");				/* read out.w count again */
-	asm("b 3b ");
+	asm("ldr	r1, [r1] ");				/* check for system crash while we were waiting */
+	asm("cmp	r1, #0 ");
+	asm("bne	9f ");
+	asm("ldr	r1, [r0, #0] ");			/* read out.w count again */
+	asm("b		3b ");
+	asm("9:		");
+	__ASM_CRASH();							/* system crashed while we were waiting */
 	}
 
 __NAKED__ EXPORT_C void TRWSpinLock::UnlockIrqR()
@@ -1185,7 +1248,7 @@
 __NAKED__ EXPORT_C TBool TRWSpinLock::FlashIrqR()
 	{
 	GET_RWNO_TID(,r12);						/* r12 -> TSubScheduler */
-	asm("ldr r12, [r12, #%a0]" : : "i" _FOFF(TSubScheduler,i_GicCpuIfcAddr));
+	asm("ldr r12, [r12, #%a0]" : : "i" _FOFF(TSubScheduler,iSSX.iGicCpuIfcAddr));
 	asm("ldr r2, [r0, #0] ");
 	asm("ldr r3, [r12, #%a0]" : : "i" _FOFF(GicCpuIfc,iHighestPending));
 	asm("eor r2, r2, r2, lsr #16 ");		/* r2 low byte = out.w ^ in.w = 0 if no writers waiting */
@@ -1230,9 +1293,15 @@
 	__JUMP(,lr);
 
 	asm("2: ");
+	asm("ldr	r1, __CrashState ");
 	ARM_WFE;
-	asm("ldr r1, [r0, #0] ");				/* read out count again */
-	asm("b 3b ");
+	asm("ldr	r1, [r1] ");				/* check for system crash while we were waiting */
+	asm("cmp	r1, #0 ");
+	asm("bne	9f ");
+	asm("ldr	r1, [r0, #0] ");			/* read out count again */
+	asm("b		3b ");
+	asm("9:		");
+	__ASM_CRASH();							/* system crashed while we were waiting */
 	}
 
 __NAKED__ EXPORT_C void TRWSpinLock::UnlockIrqW()
@@ -1251,7 +1320,7 @@
 __NAKED__ EXPORT_C TBool TRWSpinLock::FlashIrqW()
 	{
 	GET_RWNO_TID(,r12);						/* r12 -> TSubScheduler */
-	asm("ldr r12, [r12, #%a0]" : : "i" _FOFF(TSubScheduler,i_GicCpuIfcAddr));
+	asm("ldr r12, [r12, #%a0]" : : "i" _FOFF(TSubScheduler,iSSX.iGicCpuIfcAddr));
 	asm("ldr r2, [r0, #0] ");
 	asm("ldr r3, [r12, #%a0]" : : "i" _FOFF(GicCpuIfc,iHighestPending));
 	asm("add r2, r2, #0x00010000 ");		/* increment out.w */
@@ -1300,9 +1369,15 @@
 	__JUMP(,lr);
 
 	asm("2: ");
+	asm("ldr	r1, __CrashState ");
 	ARM_WFE;
-	asm("ldr r1, [r0, #0] ");				/* read out.w count again */
-	asm("b 3b ");
+	asm("ldr	r1, [r1] ");				/* check for system crash while we were waiting */
+	asm("cmp	r1, #0 ");
+	asm("bne	9f ");
+	asm("ldr	r1, [r0, #0] ");			/* read out.w count again */
+	asm("b		3b ");
+	asm("9:		");
+	__ASM_CRASH();							/* system crashed while we were waiting */
 	}
 
 __NAKED__ EXPORT_C void TRWSpinLock::UnlockOnlyR()
@@ -1362,9 +1437,15 @@
 	__JUMP(,lr);
 
 	asm("2: ");
+	asm("ldr	r1, __CrashState ");
 	ARM_WFE;
-	asm("ldr r1, [r0, #0] ");				/* read out count again */
-	asm("b 3b ");
+	asm("ldr	r1, [r1] ");				/* check for system crash while we were waiting */
+	asm("cmp	r1, #0 ");
+	asm("bne	9f ");
+	asm("ldr	r1, [r0, #0] ");			/* read out count again */
+	asm("b		3b ");
+	asm("9:		");
+	__ASM_CRASH();							/* system crashed while we were waiting */
 	}
 
 __NAKED__ EXPORT_C void TRWSpinLock::UnlockOnlyW()
@@ -1428,9 +1509,15 @@
 	__JUMP(,lr);
 
 	asm("2: ");
+	asm("ldr	r1, __CrashState ");
 	ARM_WFE;
-	asm("ldr r1, [r0, #0] ");				/* read out.w count again */
-	asm("b 3b ");
+	asm("ldr	r1, [r1] ");				/* check for system crash while we were waiting */
+	asm("cmp	r1, #0 ");
+	asm("bne	9f ");
+	asm("ldr	r1, [r0, #0] ");			/* read out.w count again */
+	asm("b		3b ");
+	asm("9:		");
+	__ASM_CRASH();							/* system crashed while we were waiting */
 	}
 
 __NAKED__ EXPORT_C void TRWSpinLock::UnlockIrqRestoreR(TInt)
@@ -1455,7 +1542,7 @@
 __NAKED__ EXPORT_C TBool TRWSpinLock::FlashIrqRestoreR(TInt)
 	{
 	GET_RWNO_TID(,r12);						/* r12 -> TSubScheduler */
-	asm("ldr r12, [r12, #%a0]" : : "i" _FOFF(TSubScheduler,i_GicCpuIfcAddr));
+	asm("ldr r12, [r12, #%a0]" : : "i" _FOFF(TSubScheduler,iSSX.iGicCpuIfcAddr));
 	asm("ldr r2, [r0, #0] ");
 	asm("ldr r3, [r12, #%a0]" : : "i" _FOFF(GicCpuIfc,iHighestPending));
 	asm("eor r2, r2, r2, lsr #16 ");		/* r2 low byte = out.w ^ in.w = 0 if no writers waiting */
@@ -1502,9 +1589,15 @@
 	__JUMP(,lr);
 
 	asm("2: ");
+	asm("ldr	r1, __CrashState ");
 	ARM_WFE;
-	asm("ldr r1, [r0, #0] ");				/* read out count again */
-	asm("b 3b ");
+	asm("ldr	r1, [r1] ");				/* check for system crash while we were waiting */
+	asm("cmp	r1, #0 ");
+	asm("bne	9f ");
+	asm("ldr	r1, [r0, #0] ");			/* read out count again */
+	asm("b		3b ");
+	asm("9:		");
+	__ASM_CRASH();							/* system crashed while we were waiting */
 	}
 
 __NAKED__ EXPORT_C void TRWSpinLock::UnlockIrqRestoreW(TInt)
@@ -1526,7 +1619,7 @@
 __NAKED__ EXPORT_C TBool TRWSpinLock::FlashIrqRestoreW(TInt)
 	{
 	GET_RWNO_TID(,r12);						/* r12 -> TSubScheduler */
-	asm("ldr r12, [r12, #%a0]" : : "i" _FOFF(TSubScheduler,i_GicCpuIfcAddr));
+	asm("ldr r12, [r12, #%a0]" : : "i" _FOFF(TSubScheduler,iSSX.iGicCpuIfcAddr));
 	asm("ldr r2, [r0, #0] ");
 	asm("ldr r3, [r12, #%a0]" : : "i" _FOFF(GicCpuIfc,iHighestPending));
 	asm("add r2, r2, #0x00010000 ");		/* increment out.w */
--- a/kernel/eka/nkernsmp/arm/ncutils.cia	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/nkernsmp/arm/ncutils.cia	Fri Apr 16 16:24:37 2010 +0300
@@ -190,26 +190,28 @@
 	{
 	SET_RWNO_TID(,r1);
 	__ASM_CLI_MODE(MODE_ABT);
-	asm("str	sp, [r1, #%a0]" : : "i" _FOFF(TSubScheduler, i_AbtStackTop));
+	asm("str	sp, [r1, #%a0]" : : "i" _FOFF(TSubScheduler, iSSX.iAbtStackTop));
 	asm("mvn	r3, #0 ");
 	asm("str	r3, [sp, #%a0]" : : "i" _FOFF(SFullArmRegSet, iExcCode));
-	asm("str	r3, [r1, #%a0]" : : "i" _FOFF(TSubScheduler, i_IrqNestCount));
+	asm("str	r3, [r1, #%a0]" : : "i" _FOFF(TSubScheduler, iSSX.iIrqNestCount));
 	__ASM_CLI_MODE(MODE_UND);
-	asm("str	sp, [r1, #%a0]" : : "i" _FOFF(TSubScheduler, i_UndStackTop));
+	asm("str	sp, [r1, #%a0]" : : "i" _FOFF(TSubScheduler, iSSX.iUndStackTop));
 	__ASM_CLI_MODE(MODE_FIQ);
-	asm("str	sp, [r1, #%a0]" : : "i" _FOFF(TSubScheduler, i_FiqStackTop));
+	asm("str	sp, [r1, #%a0]" : : "i" _FOFF(TSubScheduler, iSSX.iFiqStackTop));
 	__ASM_CLI_MODE(MODE_IRQ);
-	asm("str	sp, [r1, #%a0]" : : "i" _FOFF(TSubScheduler, i_IrqStackTop));
+	asm("str	sp, [r1, #%a0]" : : "i" _FOFF(TSubScheduler, iSSX.iIrqStackTop));
 	__ASM_CLI_MODE(MODE_SVC);
 	asm("ldr	r2, __TheScheduler ");
-	asm("ldr	r3, [r2, #%a0]" : : "i" _FOFF(TScheduler, i_ScuAddr));
-	asm("str	r3, [r1, #%a0]" : : "i" _FOFF(TSubScheduler, i_ScuAddr));
-	asm("ldr	r3, [r2, #%a0]" : : "i" _FOFF(TScheduler, i_GicDistAddr));
-	asm("str	r3, [r1, #%a0]" : : "i" _FOFF(TSubScheduler, i_GicDistAddr));
-	asm("ldr	r3, [r2, #%a0]" : : "i" _FOFF(TScheduler, i_GicCpuIfcAddr));
-	asm("str	r3, [r1, #%a0]" : : "i" _FOFF(TSubScheduler, i_GicCpuIfcAddr));
-	asm("ldr	r3, [r2, #%a0]" : : "i" _FOFF(TScheduler, i_LocalTimerAddr));
-	asm("str	r3, [r1, #%a0]" : : "i" _FOFF(TSubScheduler, i_LocalTimerAddr));
+	asm("ldr	r3, [r2, #%a0]" : : "i" _FOFF(TScheduler, iSX.iScuAddr));
+	asm("str	r3, [r1, #%a0]" : : "i" _FOFF(TSubScheduler, iSSX.iScuAddr));
+	asm("ldr	r3, [r2, #%a0]" : : "i" _FOFF(TScheduler, iSX.iGicDistAddr));
+	asm("str	r3, [r1, #%a0]" : : "i" _FOFF(TSubScheduler, iSSX.iGicDistAddr));
+	asm("ldr	r3, [r2, #%a0]" : : "i" _FOFF(TScheduler, iSX.iGicCpuIfcAddr));
+	asm("str	r3, [r1, #%a0]" : : "i" _FOFF(TSubScheduler, iSSX.iGicCpuIfcAddr));
+	asm("ldr	r3, [r2, #%a0]" : : "i" _FOFF(TScheduler, iSX.iLocalTimerAddr));
+	asm("str	r3, [r1, #%a0]" : : "i" _FOFF(TSubScheduler, iSSX.iLocalTimerAddr));
+	asm("ldr	r3, [r2, #%a0]" : : "i" _FOFF(TScheduler, iSX.iGlobalTimerAddr));
+	asm("str	r3, [r1, #%a0]" : : "i" _FOFF(TSubScheduler, iSSX.iGlobalTimerAddr));
 	asm("mov	r3, #0 ");
 	SET_RWRO_TID(,r3);
 	SET_RWRW_TID(,r3);
@@ -238,7 +240,7 @@
 	GET_RWNO_TID(,r0);
 	asm("cmp	r0, #0 ");
 	asm("ldreq	r0, __SS0 ");
-	asm("ldr	r0, [r0, #%a0]" : : "i" _FOFF(TSubScheduler,i_Regs));
+	asm("ldr	r0, [r0, #%a0]" : : "i" _FOFF(TSubScheduler, iSSX.iRegs));
 	asm("cmp	r0, #0 ");
 	asm("ldreq	r0, __DefaultRegs ");
 	asm("ldr	r1, [r0, #%a0]" : : "i" _FOFF(SFullArmRegSet, iExcCode));
@@ -275,8 +277,8 @@
 	asm("streq	r2, [r1] ");
 	asm("beq	skip_other_cores ");		// If subscheduler not yet set, don't bother with other cores
 	asm("ldr	r2, [r0, #%a0]" : : "i" _FOFF(TSubScheduler, iCpuMask));
-	asm("ldr	r5, [r0, #%a0]" : : "i" _FOFF(TSubScheduler, i_GicCpuIfcAddr));
-//	asm("ldr	r4, [r0, #%a0]" : : "i" _FOFF(TSubScheduler,i_Regs));
+	asm("ldr	r5, [r0, #%a0]" : : "i" _FOFF(TSubScheduler, iSSX.iGicCpuIfcAddr));
+//	asm("ldr	r4, [r0, #%a0]" : : "i" _FOFF(TSubScheduler, iSSX.iRegs));
 	asm("bic	sp, sp, #4 ");				// align stack to multiple of 8
 
 	__DATA_MEMORY_BARRIER_Z__(r6);
@@ -293,7 +295,7 @@
 	// we weren't first to crash, so wait here for a crash IPI
 	// disable all interrupts except for CRASH_IPI
 	GET_RWNO_TID(,r0);
-	asm("ldr	r0, [r0, #%a0]" : : "i" _FOFF(TSubScheduler, i_GicCpuIfcAddr));
+	asm("ldr	r0, [r0, #%a0]" : : "i" _FOFF(TSubScheduler, iSSX.iGicCpuIfcAddr));
 	asm("mov	r1, #0 ");
 	asm("1: ");
 	asm("add	r1, r1, #1 ");
@@ -312,9 +314,9 @@
 	asm("first_to_crash: ");
 	asm("ldr	r2, [r0, #%a0]" : : "i" _FOFF(TSubScheduler, iScheduler));
 	asm("ldr	r7, __CrashStateOut ");
-	asm("ldr	r3, [r2, #%a0]" : : "i" _FOFF(TScheduler, iActiveCpus1));
+	asm("ldr	r3, [r2, #%a0]" : : "i" _FOFF(TScheduler, iIpiAcceptCpus));
 	asm("str	r3, [r7] ");			// mask of CPUs pending
-	asm("ldr	r5, [r0, #%a0]" : : "i" _FOFF(TSubScheduler, i_GicDistAddr));
+	asm("ldr	r5, [r0, #%a0]" : : "i" _FOFF(TSubScheduler, iSSX.iGicDistAddr));
 	asm("ldr	r1, __CrashIPIWord ");
 	__DATA_SYNC_BARRIER_Z__(r6);
 	asm("str	r1, [r5, #%a0]" : : "i" _FOFF(GicDistributor, iSoftIrq));	// send CRASH_IPI to all other CPUs
@@ -1036,7 +1038,52 @@
 	asm("mov	r0, #0"); //Kernel side not implemented yet
 	}
 
+#ifdef 	__CPU_ARM_HAS_WFE_SEV
+
+extern "C" __NAKED__ void __arm_wfe()
+	{
+	ARM_WFE;
+	__JUMP(,	lr);
+	}
+
+extern "C" __NAKED__ void __arm_sev()
+	{
+	ARM_SEV;
+	__JUMP(,	lr);
+	}
+
+#endif
+
+// Called by a CPU which has completed its detach sequence and should now be powered off
+// Doesn't return - just waits for power to be removed
+// CPU will come back up via the reset vector when it next wakes up.
+// NOTE: On entry the CPU caches are disabled and the CPU does not participate in coherency
+// SO BE VERY CAREFUL
+extern "C" __NAKED__ void DetachComplete()
+	{
+	GET_RWNO_TID(,r0);
+	asm("ldr	r1, [r0, #%a0]" : : "i" _FOFF(TSubScheduler, iUncached));
+	asm("ldr	r2, [r1, #%a0]" : : "i" _FOFF(SPerCpuUncached, iDetachCompleteCpus));
+	asm("ldr	r3, [r0, #%a0]" : : "i" _FOFF(TSubScheduler, iSSX.iGicDistAddr));
+	__DATA_SYNC_BARRIER_Z__(r12);		// need DSB before sending any IPI
+	asm("mov	r2, r2, lsl #16 ");
+	asm("orr	r2, r2, #%a0" : : "i" ((TInt)INDIRECT_POWERDOWN_IPI_VECTOR));
+	asm("str	r2, [r3, #%a0]" : : "i" _FOFF(GicDistributor, iSoftIrq));	// trigger IPIs
+
+	asm("wait_forever: ");
+	__DATA_SYNC_BARRIER__(r12);
+	ARM_WFE;
+	__DATA_SYNC_BARRIER__(r12);
+	asm("ldr	r2, [r1, #%a0]" : : "i" _FOFF(SPerCpuUncached, iPowerOnReq));
+	__DATA_SYNC_BARRIER__(r12);
+	asm("cmp	r2, #0xF000000F ");		// for 'fake' power down
+	asm("bne	wait_forever ");
+
+	asm("0:		");
+	__JUMP(,lr);
+	}
 
 
 
 
+
--- a/kernel/eka/nkernsmp/arm/ncutils.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/nkernsmp/arm/ncutils.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -23,8 +23,16 @@
 
 extern "C" {
 extern SVariantInterfaceBlock* VIB;
+
+extern TUint KernCoreStats_EnterIdle(TUint aCore);
+extern void KernCoreStats_LeaveIdle(TInt aCookie,TUint aCore);
+
+extern void DetachComplete();
+extern void send_irq_ipi(TSubScheduler*, TInt);
 }
 
+
+
 /******************************************************************************
  * Spin lock
  ******************************************************************************/
@@ -90,28 +98,58 @@
 	__KTRACE_OPT(KBOOT,DEBUGPRINT("iGicDistAddr=%08x", VIB->iGicDistAddr));
 	__KTRACE_OPT(KBOOT,DEBUGPRINT("iGicCpuIfcAddr=%08x", VIB->iGicCpuIfcAddr));
 	__KTRACE_OPT(KBOOT,DEBUGPRINT("iLocalTimerAddr=%08x", VIB->iLocalTimerAddr));
+	__KTRACE_OPT(KBOOT,DEBUGPRINT("iGlobalTimerAddr=%08x", VIB->iGlobalTimerAddr));
 
 	TScheduler& s = TheScheduler;
-	s.i_ScuAddr = (TAny*)VIB->iScuAddr;
-	s.i_GicDistAddr = (TAny*)VIB->iGicDistAddr;
-	s.i_GicCpuIfcAddr = (TAny*)VIB->iGicCpuIfcAddr;
-	s.i_LocalTimerAddr = (TAny*)VIB->iLocalTimerAddr;
-	s.i_TimerMax = (TAny*)(VIB->iMaxTimerClock / 1);		// use prescaler value of 1
+	s.iSX.iScuAddr = (ArmScu*)VIB->iScuAddr;
+	s.iSX.iGicDistAddr = (GicDistributor*)VIB->iGicDistAddr;
+	s.iSX.iGicCpuIfcAddr = (GicCpuIfc*)VIB->iGicCpuIfcAddr;
+	s.iSX.iLocalTimerAddr = (ArmLocalTimer*)VIB->iLocalTimerAddr;
+	s.iSX.iTimerMax = (VIB->iMaxTimerClock / 1);		// use prescaler value of 1
+#ifdef	__CPU_ARM_HAS_GLOBAL_TIMER_BLOCK
+	s.iSX.iGlobalTimerAddr = (ArmGlobalTimer*)VIB->iGlobalTimerAddr;
+#endif
 
 	TInt i;
 	for (i=0; i<KMaxCpus; ++i)
 		{
 		TSubScheduler& ss = TheSubSchedulers[i];
-		ss.i_TimerMultF = (TAny*)KMaxTUint32;
-		ss.i_TimerMultI = (TAny*)0x01000000u;
-		ss.i_CpuMult = (TAny*)KMaxTUint32;
-		ss.i_LastTimerSet = (TAny*)KMaxTInt32;
-		ss.i_TimestampError = (TAny*)0;
-		ss.i_TimerGap = (TAny*)16;
-		ss.i_MaxCorrection = (TAny*)64;
-		VIB->iTimerMult[i] = (volatile STimerMult*)&ss.i_TimerMultF;
-		VIB->iCpuMult[i] = (volatile TUint32*)&ss.i_CpuMult;
+		ss.iSSX.iCpuFreqM = KMaxTUint32;
+		ss.iSSX.iCpuFreqS = 0;
+		ss.iSSX.iCpuPeriodM = 0x80000000u;
+		ss.iSSX.iCpuPeriodS = 31;
+		ss.iSSX.iNTimerFreqM = KMaxTUint32;
+		ss.iSSX.iNTimerFreqS = 0;
+		ss.iSSX.iNTimerPeriodM = 0x80000000u;
+		ss.iSSX.iNTimerPeriodS = 31;
+		ss.iSSX.iTimerFreqM = KMaxTUint32;
+		ss.iSSX.iTimerFreqS = 0;
+		ss.iSSX.iTimerPeriodM = 0x80000000u;
+		ss.iSSX.iTimerPeriodS = 31;
+		ss.iSSX.iLastSyncTime = 0;
+		ss.iSSX.iTicksSinceLastSync = 0;
+		ss.iSSX.iLastTimerSet = 0;
+		ss.iSSX.iGapEstimate = 10<<16;
+		ss.iSSX.iGapCount = 0;
+		ss.iSSX.iTotalTicks = 0;
+		ss.iSSX.iDitherer = 1;
+		ss.iSSX.iFreqErrorEstimate = 0;
+		ss.iSSX.iFreqErrorLimit = 0x00100000;
+		ss.iSSX.iErrorIntegrator = 0;
+		ss.iSSX.iRefAtLastCorrection = 0;
+		ss.iSSX.iM = 4;
+		ss.iSSX.iN = 18;
+		ss.iSSX.iD = 3;
+		VIB->iTimerMult[i] = 0;
+		VIB->iCpuMult[i] = 0;
+		UPerCpuUncached* u = VIB->iUncached[i];
+		ss.iUncached = u;
+		u->iU.iDetachCount = 0;
+		u->iU.iAttachCount = 0;
+		u->iU.iPowerOffReq = FALSE;
+		u->iU.iDetachCompleteFn = &DetachComplete;
 		}
+	__e32_io_completion_barrier();
 	InterruptInit0();
 	}
 
@@ -153,6 +191,21 @@
 	ArmInterruptInfo.iFiqHandler=aHandler;
 	}
 
+/** Register the global Idle handler
+	Called by the base port at boot time to register a handler containing a pointer to
+	a function that is called by the Kernel when each core reaches idle.
+	Should not be called at any other time.
+
+	@param	aHandler Pointer to idle handler function
+	@param	aPtr Idle handler function argument
+ */
+EXPORT_C void Arm::SetIdleHandler(TCpuIdleHandlerFn aHandler, TAny* aPtr)
+	{
+	ArmInterruptInfo.iCpuIdleHandler.iHandler = aHandler;
+	ArmInterruptInfo.iCpuIdleHandler.iPtr = aPtr;
+	ArmInterruptInfo.iCpuIdleHandler.iPostambleRequired = EFalse;
+	}
+
 extern void initialiseState(TInt aCpu, TSubScheduler* aSS);
 
 void Arm::Init1Interrupts()
@@ -231,11 +284,15 @@
 	return TheScheduler.iIdleGenerationCount;
 	}
 
-void NKern::Idle()
+void NKern::DoIdle()
 	{
 	TScheduler& s = TheScheduler;
 	TSubScheduler& ss = SubScheduler();	// OK since idle thread locked to CPU
+	SPerCpuUncached* u0 = &((UPerCpuUncached*)ss.iUncached)->iU;
 	TUint32 m = ss.iCpuMask;
+	TUint32 retire = 0;
+	TBool global_defer = FALSE;
+	TBool event_kick = FALSE;
 	s.iIdleSpinLock.LockIrq();
 	TUint32 orig_cpus_not_idle = __e32_atomic_and_acq32(&s.iCpusNotIdle, ~m);
 	if (orig_cpus_not_idle == m)
@@ -255,22 +312,184 @@
 			return;
 			}
 		}
+	TBool shutdown_check = !((s.iThreadAcceptCpus|s.iCCReactivateCpus) & m);
+	if (shutdown_check)
+		{
+		// check whether this CPU is ready to be powered off
+		s.iGenIPILock.LockOnly();
+		ss.iEventHandlerLock.LockOnly();
+		if ( !((s.iThreadAcceptCpus|s.iCCReactivateCpus) & m) && !ss.iDeferShutdown && !ss.iNextIPI && !ss.iEventHandlersPending)
+			{
+			for(;;)
+				{
+				if (s.iCCDeferCount)
+					{
+					global_defer = TRUE;
+					break;
+					}
+				if (s.iPoweringOff)
+					{
+					// another CPU might be in the process of powering off
+					SPerCpuUncached* u = &((UPerCpuUncached*)s.iPoweringOff->iUncached)->iU;
+					if (u->iDetachCount == s.iDetachCount)
+						{
+						// still powering off so we must wait
+						global_defer = TRUE;
+						break;
+						}
+					}
+				TUint32 more = s.CpuShuttingDown(ss);
+				retire = SCpuIdleHandler::ERetire;
+				if (more)
+					retire |= SCpuIdleHandler::EMore;
+				s.iPoweringOff = &ss;
+				s.iDetachCount = u0->iDetachCount;
+				break;
+				}
+			}
+		ss.iEventHandlerLock.UnlockOnly();
+		s.iGenIPILock.UnlockOnly();
+		}
+	if (!retire && ss.iCurrentThread->iSavedSP)
+		{
+		// rescheduled between entry to NKern::Idle() and here
+		// go round again to see if any more threads to pull from other CPUs
+		__e32_atomic_ior_ord32(&s.iCpusNotIdle, m);	// we aren't idle after all
+		s.iIdleSpinLock.UnlockIrq();
+		return;
+		}
+	if (global_defer)
+		{
+		// Don't WFI if we're only waiting for iCCDeferCount to reach zero or for
+		// another CPU to finish powering down since we might not get another IPI.
+		__e32_atomic_ior_ord32(&s.iCpusNotIdle, m);	// we aren't idle after all
+		s.iIdleSpinLock.UnlockIrq();
+		__snooze();
+		return;
+		}
 
 	// postamble happens here - interrupts cannot be reenabled
+	TUint32 arg = orig_cpus_not_idle & ~m;
+	if (arg == 0)
+		s.AllCpusIdle();
 	s.iIdleSpinLock.UnlockOnly();
-	NKIdle(orig_cpus_not_idle & ~m);
+
+	//TUint cookie = KernCoreStats::EnterIdle((TUint8)ss.iCpuNum);
+	TUint cookie = KernCoreStats_EnterIdle((TUint8)ss.iCpuNum);
+
+	arg |= retire;
+	NKIdle(arg);
+
+	//KernCoreStats::LeaveIdle(cookie, (TUint8)ss.iCpuNum);
+	KernCoreStats_LeaveIdle(cookie, (TUint8)ss.iCpuNum);
+
 
 	// interrupts have not been reenabled
 	s.iIdleSpinLock.LockOnly();
-	__e32_atomic_ior_ord32(&s.iCpusNotIdle, m);
+
+	if (retire)
+		{
+		// we just came back from power down
+		SPerCpuUncached* u = &((UPerCpuUncached*)ss.iUncached)->iU;
+		u->iPowerOnReq = 0;
+		__e32_io_completion_barrier();
+		s.iGenIPILock.LockOnly();
+		ss.iEventHandlerLock.LockOnly();
+		s.iIpiAcceptCpus |= m;
+		s.iCCReactivateCpus |= m;
+		s.iCpusGoingDown &= ~m;
+		if (s.iPoweringOff == &ss)
+			s.iPoweringOff = 0;
+		if (ss.iEventHandlersPending)
+			event_kick = TRUE;
+		ss.iEventHandlerLock.UnlockOnly();
+		s.iGenIPILock.UnlockOnly();
+		}
+
+	TUint32 ci = __e32_atomic_ior_ord32(&s.iCpusNotIdle, m);
 	if (ArmInterruptInfo.iCpuIdleHandler.iPostambleRequired)
 		{
 		ArmInterruptInfo.iCpuIdleHandler.iPostambleRequired = FALSE;
-		NKIdle(-1);
+		NKIdle(ci|m|SCpuIdleHandler::EPostamble);
+		}
+	if (ci == 0)
+		s.FirstBackFromIdle();
+
+	if (retire)
+		{
+		s.iCCReactivateDfc.RawAdd();	// kick load balancer to give us some work
+		if (event_kick)
+			send_irq_ipi(&ss, EQueueEvent_Kick);	// so that we will process pending events
 		}
 	s.iIdleSpinLock.UnlockIrq();	// reenables interrupts
 	}
 
+TBool TSubScheduler::Detached()
+	{
+	SPerCpuUncached* u = &((UPerCpuUncached*)iUncached)->iU;
+	return u->iDetachCount != u->iAttachCount;
+	}
+
+TBool TScheduler::CoreControlSupported()
+	{
+	return VIB->iCpuPowerUpFn != 0;
+	}
+
+void TScheduler::CCInitiatePowerUp(TUint32 aCores)
+	{
+	TCpuPowerUpFn pUp = VIB->iCpuPowerUpFn;
+	if (pUp && aCores)
+		{
+		TInt i;
+		for (i=0; i<KMaxCpus; ++i)
+			{
+			if (aCores & (1u<<i))
+				{
+				TSubScheduler& ss = TheSubSchedulers[i];
+				SPerCpuUncached& u = ((UPerCpuUncached*)ss.iUncached)->iU;
+				u.iPowerOnReq = TRUE;
+				__e32_io_completion_barrier();
+				pUp(i, &u);
+
+				// wait for core to reattach
+				while (u.iDetachCount != u.iAttachCount)
+					{
+					__snooze();
+					}
+				}
+			}
+		}
+	}
+
+void TScheduler::CCIndirectPowerDown(TAny*)
+	{
+	TCpuPowerDownFn pDown = VIB->iCpuPowerDownFn;
+	if (pDown)
+		{
+		TInt i;
+		for (i=0; i<KMaxCpus; ++i)
+			{
+			TSubScheduler& ss = TheSubSchedulers[i];
+			SPerCpuUncached& u = ((UPerCpuUncached*)ss.iUncached)->iU;
+			if (u.iPowerOffReq)
+				{
+				pDown(i, &u);
+				__e32_io_completion_barrier();
+				u.iPowerOffReq = FALSE;
+				__e32_io_completion_barrier();
+				}
+			}
+		}
+	}
+
+// Called on any CPU which receives an indirect power down IPI
+extern "C" void handle_indirect_powerdown_ipi()
+	{
+	TScheduler& s = TheScheduler;
+	TSubScheduler& ss = SubScheduler();
+	if (s.iIpiAcceptCpus & ss.iCpuMask)
+		s.iCCPowerDownDfc.Add();
+	}
 
 EXPORT_C TUint32 NKern::CpuTimeMeasFreq()
 	{
@@ -288,7 +507,7 @@
  */
 EXPORT_C TInt NKern::TimesliceTicks(TUint32 aMicroseconds)
 	{
-	TUint32 mf32 = (TUint32)TheScheduler.i_TimerMax;
+	TUint32 mf32 = TheScheduler.iSX.iTimerMax;
 	TUint64 mf(mf32);
 	TUint64 ticks = mf*TUint64(aMicroseconds) + UI64LIT(999999);
 	ticks /= UI64LIT(1000000);
@@ -299,6 +518,20 @@
 	}
 
 
+#if defined(__NKERN_TIMESTAMP_USE_LOCAL_TIMER__)
+	// Assembler
+#elif defined(__NKERN_TIMESTAMP_USE_SCU_GLOBAL_TIMER__)
+	// Assembler
+#elif defined(__NKERN_TIMESTAMP_USE_INLINE_BSP_CODE__)
+#define __DEFINE_NKERN_TIMESTAMP_CPP__
+#include <variant_timestamp.h>
+#undef __DEFINE_NKERN_TIMESTAMP_CPP__
+#elif defined(__NKERN_TIMESTAMP_USE_BSP_CALLOUT__)
+	// Assembler
+#else
+#error No definition for NKern::Timestamp()
+#endif
+
 /** Get the frequency of counter queried by NKern::Timestamp().
 
 @publishedPartner
@@ -306,6 +539,19 @@
 */
 EXPORT_C TUint32 NKern::TimestampFrequency()
 	{
-	return (TUint32)TheScheduler.i_TimerMax;
+#if defined(__NKERN_TIMESTAMP_USE_LOCAL_TIMER__)
+	// Use per-CPU local timer in Cortex A9 or ARM11MP
+	return TheScheduler.iSX.iTimerMax;
+#elif defined(__NKERN_TIMESTAMP_USE_SCU_GLOBAL_TIMER__)
+	// Use global timer in Cortex A9 r1p0
+	return TheScheduler.iSX.iTimerMax;
+#elif defined(__NKERN_TIMESTAMP_USE_INLINE_BSP_CODE__)
+	// Use code in <variant_timestamp.h> supplied by BSP
+	return KTimestampFrequency;
+#elif defined(__NKERN_TIMESTAMP_USE_BSP_CALLOUT__)
+	// Call function defined in variant
+#else
+#error No definition for NKern::TimestampFrequency()
+#endif
 	}
 
--- a/kernel/eka/nkernsmp/arm/vectors.cia	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/nkernsmp/arm/vectors.cia	Fri Apr 16 16:24:37 2010 +0300
@@ -149,11 +149,10 @@
 	asm("beq	wait_for_any_request ");	// special case for Exec::WaitForAnyRequest
 	asm("ldr	r2, [r1, #%a0]" : : "i" _FOFF(NThread,iFastExecTable));
 	asm("ldr	r3, [r2], r12, lsr #7 ");	// r3=limit, r2->dispatch table entry
-	asm("ldr	r2, [r2] ");				// r2->kernel function
 	asm("cmp	r3, r12, lsr #9 ");			// r3-SWI number
-	__JUMP(hi,	r2);						// if SWI number valid, call kernel function
+	asm("ldrhi	pc, [r2] ");				// if SWI number valid, call kernel function
 	asm("mvn	r12, #0 ");					// put invalid SWI number into r12
-	asm("b		slow_swi ");					// go through slow SWI routine to call invalid SWI handler
+	asm("b		slow_swi ");				// go through slow SWI routine to call invalid SWI handler
 
 #ifndef __FAST_SEM_MACHINE_CODED__
 	asm("wait_for_any_request: ");
@@ -291,7 +290,7 @@
 #ifdef BTRACE_CPU_USAGE
 	asm("ldr	r10, __BTraceCpuUsageFilter ");
 #endif
-	asm("ldr	r7, [r4, #%a0]" : : "i" _FOFF(TSubScheduler, i_IrqNestCount));
+	asm("ldr	r7, [r4, #%a0]" : : "i" _FOFF(TSubScheduler, iSSX.iIrqNestCount));
 	asm("ldrb	r0, [r4, #%a0]" : : "i" _FOFF(TSubScheduler, iEventHandlersPending));
 	__DATA_MEMORY_BARRIER_Z__(r2);
 #ifdef BTRACE_CPU_USAGE
@@ -316,7 +315,7 @@
 	asm("cmp	r2, #0x10 ");				// interrupted mode_usr ?
 	asm("cmpne	r2, #0x13 ");				// if not, interrupted mode_svc ?
 	asm("cmpeq	r0, #0 ");					// if mode_usr or mode_svc, is kernel locked?
-	asm("str	r7, [r4, #%a0]" : : "i" _FOFF(TSubScheduler, i_IrqNestCount));
+	asm("str	r7, [r4, #%a0]" : : "i" _FOFF(TSubScheduler, iSSX.iIrqNestCount));
 	asm("bne	irq_kernel_locked_exit ");	// if neither or if kernel locked, exit immediately
 	asm("cmp	r1, #0 ");					// If not, IDFCs/reschedule pending?
 	asm("beq	irq_kernel_locked_exit ");	// if not, exit
@@ -381,7 +380,7 @@
 
 	asm("nested_irq_exit: ");
 	__ASM_CLI1();
-	asm("str	r7, [r4, #%a0]" : : "i" _FOFF(TSubScheduler, i_IrqNestCount));
+	asm("str	r7, [r4, #%a0]" : : "i" _FOFF(TSubScheduler, iSSX.iIrqNestCount));
 #ifdef BTRACE_CPU_USAGE
 	asm("cmp	r10, #0 ");
 	asm("blne	btrace_irq_exit ");
@@ -767,7 +766,7 @@
 	asm("mov	r2, r0 ");
 	asm("cmp	r11, #0 ");
 	asm("ldreq	r11, __SS0 ");
-	asm("ldr	r0, [r11, #%a0]" : : "i" _FOFF(TSubScheduler,i_Regs));	// pass in address of stored registers
+	asm("ldr	r0, [r11, #%a0]" : : "i" _FOFF(TSubScheduler,iSSX.iRegs));	// pass in address of stored registers
 	asm("cmp	r0, #0 ");
 	asm("ldreq	r0, __DefaultRegs ");
 	asm("bl "	CSM_ZN3Arm9SaveStateER14SFullArmRegSet );
@@ -834,7 +833,7 @@
 	{
 	asm("movs	r0, r0, lsl #16 ");		// CPU mask into bits 16-23 - any bits set in aMask?
 	GET_RWNO_TID(ne,r3);
-	asm("ldrne	r2, [r3, #%a0]" : : "i" _FOFF(TSubScheduler, i_GicDistAddr));	// we assume i_GicDistAddr is the same for all CPUs
+	asm("ldrne	r2, [r3, #%a0]" : : "i" _FOFF(TSubScheduler, iSSX.iGicDistAddr));	// we assume i_GicDistAddr is the same for all CPUs
 	__DATA_SYNC_BARRIER_Z__(r1);			// need DSB before sending any IPI
 	asm("orrne	r0, r0, #%a0" : : "i" ((TInt)GENERIC_IPI_VECTOR));
 	asm("strne	r0, [r2, #%a0]" : : "i" _FOFF(GicDistributor, iSoftIrq));	// trigger IPIs if any
@@ -853,12 +852,12 @@
 extern "C" __NAKED__ void handle_crash_ipi()
 	{
 	GET_RWNO_TID(,r0);
-	asm("ldr	r0, [r0, #%a0]" : : "i" _FOFF(TSubScheduler,i_Regs));
+	asm("ldr	r0, [r0, #%a0]" : : "i" _FOFF(TSubScheduler,iSSX.iRegs));
 	asm("ldr	r0, [r0, #%a0]" : : "i" _FOFF(SFullArmRegSet, iExcCode));
 	asm("cmp	r0, #0 ");
 	asm("bge	state_already_saved ");		// skip if this CPU has already saved its state (i.e. already crashed)
 	GET_RWNO_TID(,r0);
-	asm("ldr	r0, [r0, #%a0]" : : "i" _FOFF(TSubScheduler,i_Regs));
+	asm("ldr	r0, [r0, #%a0]" : : "i" _FOFF(TSubScheduler,iSSX.iRegs));
 	asm("bl "	CSM_ZN3Arm9SaveStateER14SFullArmRegSet );	// save machine state (NOTE: R0 trashed)
 	asm("ldr	r1, [r0, #%a0]" : : "i" _FOFF(SFullArmRegSet, iN.iFlags));	// mode on entry
 	asm("and	r1, r1, #0x1f ");
--- a/kernel/eka/nkernsmp/dfcs.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/nkernsmp/dfcs.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -765,6 +765,23 @@
 						}
 					ss->iExIDfcLock.UnlockOnly();
 					if (kick)
+						{
+						TScheduler& s = TheScheduler;
+						TUint32 cpuMask = 1u<<cpu;
+						if (!(s.iThreadAcceptCpus & cpuMask))	// deal with case where target CPU is shutting down or has already shut down
+							{
+							TInt irq = s.iGenIPILock.LockIrqSave();
+							if (!(s.iIpiAcceptCpus & cpuMask))
+								{
+								s.iCCReactivateCpus |= cpuMask;
+								kick = FALSE;
+								}
+							s.iGenIPILock.UnlockIrqRestore(irq);
+							if (!kick)
+								s.iCCReactivateDfc.DoEnque();	// arrange for target CPU to be powered on
+							}
+						}
+					if (kick)
 						send_resched_ipi(cpu);
 					NKern::EnableAllInterrupts();	// let interrupts in
 					if (orig >= 8)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kernel/eka/nkernsmp/nk_bal.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,1538 @@
+// Copyright (c) 2009-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:
+// e32\nkernsmp\nk_bal.cpp
+// 
+//
+
+// NThreadBase member data
+#define __INCLUDE_NTHREADBASE_DEFINES__
+
+// TDfc member data
+#define __INCLUDE_TDFC_DEFINES__
+
+#include "nk_bal.h"
+
+#include "nk_priv.h"
+#include "nk_irq.h"
+
+#include <e32cmn.h>
+
+/******************************************************************************
+ * Load balancing
+ ******************************************************************************/
+
+enum TCCState
+	{
+	ECCReqPending = 0x80000000u,
+	ECCReqDeferred = 0x40000000u,
+	ECCPowerUpInProgress = 0x20000000u,
+	ECCPowerDownInProgress = 0x10000000u,
+	ECCRebalanceRequired = 0x08000000u,
+	ECCRebalanceTimerQueued = 0x04000000u,
+	ECCPeriodicBalancingActive = 0x02000000u,
+	};
+
+const TUint K_CpuMask	= 0x1fu;
+const TUint K_Keep		= 0x20u;
+const TUint K_SameCpu	= 0x40u;
+const TUint K_NewCpu	= 0x80u;
+const TUint K_CpuSticky	= 0x40u;
+const TUint K_CheckCpu	= 0x100u;
+
+#define	PERCENT(fsd, percent)					(((fsd)*(percent)+50)/100)
+
+const TUint K_LB_HeavyThreshold					= PERCENT(4095, 90);
+const TUint K_LB_GravelThreshold_RunAvg			= PERCENT(4095, 1);
+const TUint K_LB_GravelThreshold_RunActAvg		= PERCENT(4095, 50);
+const TInt	K_LB_HeavyCapacityThreshold			= PERCENT(4095, 1);
+const TInt	K_LB_BalanceInterval				= 107;
+const TInt	K_LB_CpuLoadDiffThreshold			= 128;
+
+//const TUint K_LB_HeavyStateThreshold			= 128;
+const TUint K_LB_HeavyPriorityThreshold			= 25;
+
+inline TBool IsHeavy(NSchedulable* a)
+	{
+	TUint x = 0xffu ^ a->iLbInfo.iLbHeavy;
+	return (x&(x-1))==0;
+	}
+
+inline TBool IsNew(NSchedulable* a)
+	{ return a->iLbState & NSchedulable::ELbState_PerCpu; }
+
+struct SPerPri : public SDblQue
+	{
+	inline SPerPri() : iTotalRun(0), iTotalAct(0), iCount(0), iHeavy(0) {}
+
+	TUint32	iTotalRun;
+	TUint32	iTotalAct;
+	TUint16	iCount;
+	TUint16	iHeavy;
+	};
+
+struct SCpuAvailability
+	{
+	enum
+		{
+		EIdle = 4095,
+		EMaxedOut = -268435456,
+		EUnavailable = KMinTInt
+		};
+
+	void	Init(TUint32 aActive);
+	TInt	FindMax() const;
+	TInt	FindMax(NSchedulable* aS) const;
+	TInt	PickCpu(NSchedulable* aS, TBool aDropped) const;
+	TInt	SetMaxed(TInt aCpu);
+	void	AddLoad(TInt aCpu, TInt aLoad);
+	inline	TInt operator[](TInt aCpu) const
+		{	return iRemain[aCpu]; }
+	inline	TInt TotalRemain() const
+		{	return iTotalRemain; }
+
+	TInt	iRemain[KMaxCpus];
+	TInt	iCount;
+	TInt	iTotalRemain;
+	};
+
+TUint32 HotWarmUnit;
+TUint32 LB_DormantThreshold;
+volatile TUint32 LBDelayed = 0;
+
+void CalcHotWarm(TUint8& aOut, TUint64 aTime)
+	{
+	TUint8 out = 0;
+	if (aTime>0)
+		{
+		aTime /= TUint64(HotWarmUnit);
+		if (I64HIGH(aTime))
+			out = 255;
+		else
+			{
+			aTime *= aTime;
+			out = __e32_find_ms1_64(aTime) + 1;
+			}
+		}
+	aOut = (TUint8)out;
+	}
+
+void TScheduler::InitLB()
+	{
+	TScheduler& s = TheScheduler;
+	TDfcQue* rbQ = s.iRebalanceDfcQ;
+	s.iBalanceTimer.SetDfcQ(rbQ);
+	s.iCCReactivateDfc.SetDfcQ(rbQ);
+	s.iCCRequestDfc.SetDfcQ(rbQ);
+	s.iCCPowerDownDfc.SetDfcQ(rbQ);
+	NThreadBase* lbt = rbQ->iThread;
+	lbt->iRebalanceAttr = 1;
+	TUint32 f = NKern::CpuTimeMeasFreq();
+	HotWarmUnit = f / 1000000;
+	TUint8 y = 0;
+	CalcHotWarm(y, f/5);
+	LB_DormantThreshold = y;
+	__KTRACE_OPT(KBOOT,DEBUGPRINT("InitLB()"));
+	__KTRACE_OPT(KBOOT,DEBUGPRINT("LB_DormantThreshold=%d", LB_DormantThreshold));
+	}
+
+void TSubScheduler::GetLbThreads(SDblQue& aQ)
+	{
+	NKern::Lock();
+	iReadyListLock.LockOnly();
+	if (!iLbQ.IsEmpty())
+		{
+		aQ.MoveFrom(&iLbQ);
+		iLbCounter ^= NSchedulable::ELbState_Generation;
+		}
+	iReadyListLock.UnlockOnly();
+	NKern::Unlock();
+	}
+
+void TScheduler::GetLbThreads(SDblQue& aQ)
+	{
+	NKern::Lock();
+	iBalanceListLock.LockOnly();
+	if (!iBalanceList.IsEmpty())
+		{
+		aQ.MoveFrom(&iBalanceList);
+		iLbCounter ^= NSchedulable::ELbState_Generation;
+		}
+	iBalanceListLock.UnlockOnly();
+	NKern::Unlock();
+	}
+
+void NSchedulable::InitLbInfo()
+	{
+	}
+
+void NSchedulable::NominalPriorityChanged()
+	{
+	}
+
+void NSchedulable::LbDone(TUint aFlags)
+	{
+	BTrace8(BTrace::EHSched, BTrace::ELbDone, this, aFlags);
+#ifdef KSCHED3
+	if (IsGroup())
+		{
+		__KTRACE_OPT(KSCHED3,DEBUGPRINT("LbDone %G %x", this, aFlags));
+		}
+	else
+		{
+		__KTRACE_OPT(KSCHED3,DEBUGPRINT("LbDone %T %x", this, aFlags));
+		}
+#endif
+	TBool keep = aFlags & K_Keep;
+	TInt cpu = aFlags & K_CpuMask;
+	TBool setcpu = aFlags & K_NewCpu;
+	TBool keepcpu = aFlags & K_SameCpu;
+	TBool checkcpu = aFlags & K_CheckCpu;
+	LAcqSLock();
+	TBool died = iLbState & ELbState_ExtraRef;
+	if (keep && !died)
+		{
+		TScheduler& s = TheScheduler;
+		s.iBalanceListLock.LockOnly();
+		s.iBalanceList.Add(&iLbLink);
+		iLbState = s.iLbCounter;
+		s.iBalanceListLock.UnlockOnly();
+		if (setcpu)
+			SetCpuAffinityT(cpu | KCpuAffinityPref | (aFlags & K_CpuSticky));
+		else
+			{
+			if (!keepcpu)
+				iPreferredCpu = 0;
+			if (checkcpu)
+				SetCpuAffinityT(NTHREADBASE_CPU_AFFINITY_MASK);	// move it if it's on a core which is shutting down
+			}
+		}
+	else
+		{
+		if (!keepcpu)
+			iPreferredCpu = 0;
+		iLbState = ELbState_Inactive;
+		iLbLink.iNext = 0;
+		iLbInfo.iRecentTime.i64 = 0;
+		iLbInfo.iRecentCpuTime.i64 = 0;
+		iLbInfo.iRecentActiveTime.i64 = 0;
+		iLbInfo.iLbRunAvg = 0;
+		iLbInfo.iLbActAvg = 0;
+		iLbInfo.iLbRunActAvg = 0;
+		if (checkcpu && !died)
+			SetCpuAffinityT(NTHREADBASE_CPU_AFFINITY_MASK);	// move it if it's on a core which is shutting down
+		}
+	RelSLockU();
+	if (died)
+		{
+		NKern::Lock();
+		DropRef();
+		NKern::Unlock();
+		}
+	}
+
+void CalcRatio(TUint16& aRatio, TUint64 aN, TUint64 aD)
+	{
+	TInt ms1 = __e32_find_ms1_64(aD);
+	if (ms1 < 0)
+		{
+		aRatio = 4095;
+		return;
+		}
+	if (ms1 >= 20)
+		{
+		TInt shift = ms1 - 19;
+		aD >>= shift;
+		aN >>= shift;
+		}
+	// aD, aN now < 2^20
+	TUint32 d = I64LOW(aD);
+	TUint32 n = I64LOW(aN);
+	if (n>d) n=d;
+	TUint32 r = (n*4095+(d>>1))/d;
+	if (r>4095) r=4095;	// shouldn't really happen
+	aRatio = (TUint16)r;
+	}
+
+void CalcRatios(TUint16& aRT, TUint16& aAT, TUint16& aRA, TUint64 aDT, TUint64 aDR, TUint64 aDA)
+	{
+	TInt ms1 = __e32_find_ms1_64(aDT);
+	if (ms1 >= 20)
+		{
+		TInt shift = ms1 - 19;
+		aDT >>= shift;
+		aDR >>= shift;
+		aDA >>= shift;
+		}
+	// aDT, aDR, aDA now all < 2^20
+	TUint32 t = I64LOW(aDT);
+	TUint32 rtd = I64LOW(aDR);
+	TUint32 atd = I64LOW(aDA);
+	if (rtd>t) rtd=t;
+	if (atd>t) atd=t;
+	TUint32 rtt = (rtd*4095+(t>>1))/t;
+	TUint32 att = (atd*4095+(t>>1))/t;
+	TUint32 rta = atd ? (rtd*4095+(atd>>1))/atd : 0;
+	if (rta>4095) rta=4095;	// shouldn't really happen
+	aRT = (TUint16)rtt;
+	aAT = (TUint16)att;
+	aRA = (TUint16)rta;
+	}
+
+void NSchedulable::GetLbStats(TUint64 aTime)
+	{
+	SCpuStats stats;
+	LAcqSLock();
+	if (IsGroup())
+		{
+		NThreadGroup* g = (NThreadGroup*)this;
+		if (g->iNThreadList.IsEmpty())
+			iLbInfo.iLbNomPri = 1;
+		else
+			{
+			NThreadBase* t = (NThreadBase*)g->iNThreadList.First();
+			iLbInfo.iLbNomPri = t->iNominalPri;
+			}
+		}
+	else
+		iLbInfo.iLbNomPri = ((NThreadBase*)this)->iNominalPri;
+	GetCpuStatsT(E_AllStats, stats);
+	iLbInfo.iRecentTime.i64 += aTime;
+	iLbInfo.iRecentCpuTime.i64 += stats.iRunTimeDelta;
+	iLbInfo.iRecentActiveTime.i64 += stats.iActiveTimeDelta;
+	TUint32 aff = iCpuAffinity;
+	RelSLockU();
+	CalcRatios(iLbInfo.iLbRunTime, iLbInfo.iLbActTime, iLbInfo.iLbRunAct, aTime, stats.iRunTimeDelta, stats.iActiveTimeDelta);
+	iLbInfo.iLbRunAvg = TUint16((iLbInfo.iLbRunAvg + iLbInfo.iLbRunTime) >> 1);
+	iLbInfo.iLbActAvg = TUint16((iLbInfo.iLbActAvg + iLbInfo.iLbActTime) >> 1);
+	CalcRatio(iLbInfo.iLbRunActAvg, iLbInfo.iRecentCpuTime.i64, iLbInfo.iRecentActiveTime.i64);
+
+	if (aff & NTHREADBASE_CPU_AFFINITY_MASK)
+		iLbInfo.iLbAffinity = (TUint8)(aff & 0xff);
+	else
+		iLbInfo.iLbAffinity = 1u << aff;
+	CalcHotWarm(iLbInfo.iLbHot, stats.iLastRunTime);
+	CalcHotWarm(iLbInfo.iLbWarm, stats.iLastActiveTime);
+	if (IsNew(this))
+		{
+		if (iLbInfo.iLbNomPri <= K_LB_HeavyPriorityThreshold)
+			iLbInfo.iLbHeavy = 0xffu;
+		else
+			iLbInfo.iLbHeavy = 0;
+		}
+	iLbInfo.iLbHeavy >>= 1;
+	if (iLbInfo.iLbActTime > K_LB_HeavyThreshold)
+		iLbInfo.iLbHeavy |= 0x80u;
+/*
+	TUint64 blx = NKern::CpuTimeMeasFreq();
+	blx *= 3;
+	if (i_NSchedulable_Spare3 && iLbInfo.iLbRunActAvg<400 && stats.iActiveTime>blx)
+		{
+		__crash();
+		}
+*/	}
+
+void AddToSortedQueue(SPerPri* aQ, NSchedulable* aS)
+	{
+	TInt k = aS->iLbInfo.iLbNomPri;
+	if (k >= KNumPriorities)
+		k = KNumPriorities;
+	SPerPri* q = aQ + k;
+	TBool h = IsHeavy(aS);
+	SDblQueLink* anchor = &q->iA;
+	SDblQueLink* p = q->First();
+	for (; p!=anchor; p=p->iNext)
+		{
+		NSchedulable* s = _LOFF(p, NSchedulable, iLbLink);
+		if (h)
+			{
+			if (!IsHeavy(s))
+				continue;
+			if (aS->iLbInfo.iLbRunActAvg < s->iLbInfo.iLbRunActAvg)
+				break;
+			}
+		else
+			{
+			if (IsHeavy(s))
+				break;
+			if (aS->iLbInfo.iLbRunAvg > s->iLbInfo.iLbRunAvg)
+				break;
+			}
+		}
+	aS->iLbLink.InsertBefore(p);
+	++q->iCount;
+	if (h)
+		{
+		++q->iHeavy;
+		}
+	else
+		{
+		q->iTotalRun += aS->iLbInfo.iLbRunAvg;
+		if (q->iTotalRun>4095)
+			q->iTotalRun=4095;
+		q->iTotalAct += aS->iLbInfo.iLbActAvg;
+		}
+	}
+
+void SCpuAvailability::Init(TUint32 a)
+	{
+	iCount = __e32_find_ms1_32(a) + 1;
+	iTotalRemain = 0;
+	TInt i;
+	for (i=0; i<KMaxCpus; ++i)
+		{
+		if (a & (1<<i))
+			{
+			iRemain[i] = EIdle;
+			iTotalRemain += EIdle;
+			}
+		else
+			iRemain[i] = EUnavailable;
+		}
+	}
+
+TInt SCpuAvailability::SetMaxed(TInt aCpu)
+	{
+	TInt x = iRemain[aCpu];
+	if (x>0)
+		iTotalRemain -= x;
+	iRemain[aCpu] = EMaxedOut;
+	return x;
+	}
+
+void SCpuAvailability::AddLoad(TInt aCpu, TInt aLoad)
+	{
+	if (TUint32(aLoad) > TUint32(EIdle))
+		__crash();
+	TInt& x = iRemain[aCpu];
+	TInt orig = x;
+	x -= aLoad;
+	if (x < EMaxedOut)
+		x = EMaxedOut;
+	if (orig > 0)
+		iTotalRemain -= ((orig > aLoad) ? aLoad : orig);
+	}
+
+TInt SCpuAvailability::FindMax() const
+	{
+	TInt maxv = KMinTInt;
+	TInt maxi = -1;
+	TInt i;
+	for (i=0; i<iCount; ++i)
+		{
+		if (iRemain[i] > maxv)
+			{
+			maxv = iRemain[i];
+			maxi = i;
+			}
+		}
+	return maxi;
+	}
+
+TInt SCpuAvailability::FindMax(NSchedulable* aS) const
+	{
+	TUint32 s = aS->iLbInfo.iLbAffinity;
+	s &= TheScheduler.iThreadAcceptCpus;
+	if ( (s&(s-1)) == 0 )
+		return __e32_find_ms1_32(s);
+	TInt maxv = KMinTInt;
+	TInt maxi = -1;
+	TInt i = 0;
+	for (; s; s>>=1, ++i)
+		{
+		if ((s&1) && iRemain[i] > maxv)
+			{
+			maxv = iRemain[i];
+			maxi = i;
+			}
+		}
+	return maxi;
+	}
+
+TInt SCpuAvailability::PickCpu(NSchedulable* aS, TBool aDropped) const
+	{
+	TUint32 s0 = aS->iLbInfo.iLbAffinity & TheScheduler.iThreadAcceptCpus;
+	TUint32 s = s0;
+//	BTrace12(BTrace::EHSched, 0x90u, aS, s, aPtr);
+	if ( (s&(s-1)) == 0 )
+		return __e32_find_ms1_32(s);
+	TInt maxv = KMinTInt;
+	TInt maxi = -1;
+	TInt i = 0;
+	for (; s; s>>=1, ++i)
+		{
+//		BTrace12(BTrace::EHSched, 0x91u, s, maxv, aPtr[i]);
+		if ((s&1) && iRemain[i] > maxv)
+			{
+			maxv = iRemain[i];
+			maxi = i;
+			}
+		}
+	if (IsNew(aS))
+		{
+		// this thread hasn't run for a while
+		// pick the highest numbered CPU with a near-maximum availability
+		i = __e32_find_ms1_32(s0);
+		for (; i>maxi; --i)
+			{
+			if ( (s0&(1u<<i)) && maxv-iRemain[i]<K_LB_CpuLoadDiffThreshold)
+				return i;
+			}
+		}
+	else
+		{
+		// this thread has run recently - see if we can keep it on the same CPU
+		TInt threshold = aDropped ? 1 : (TInt)K_LB_CpuLoadDiffThreshold;
+		TInt lcpu = aS->iLastCpu;
+		if ( (s0&(1u<<lcpu)) && maxv-iRemain[lcpu]<threshold)
+			return lcpu;
+		}
+	// use highest availability CPU
+	return maxi;
+	}
+
+void TScheduler::BalanceTimerExpired(TAny* aPtr)
+	{
+	((TScheduler*)aPtr)->PeriodicBalance();
+	}
+
+TBool TScheduler::ReBalance(SDblQue& aQ, TBool aCC)
+	{
+	ModifyCCState(~ECCRebalanceRequired, 0);
+
+	SPerPri sbq[KNumPriorities+1];
+	NSchedulable* s = 0;
+	TInt i;
+	TUint64 now = NKern::Timestamp();
+	TUint64 lbt = iLastBalanceTime;
+	iLastBalanceTime = now;
+	TUint64 bpl = now - lbt;		// balance period length
+	TUint cc = aCC ? K_CheckCpu : 0;
+
+	TInt nact = __e32_bit_count_32(iThreadAcceptCpus);	// number of CPUs available
+
+	// aQ holds list of threads/groups to be considered
+	TInt ns = 0;	// number for further consideration
+	TInt nd = 0;	// number dropped this time round
+	SCpuAvailability avail;
+	avail.Init(iThreadAcceptCpus);
+	TUint32 gravel = 0;
+	TInt totalN = 0;
+	TInt checked = 0;
+	while (!aQ.IsEmpty())
+		{
+		NThread* t = 0;
+		++totalN;
+		s = _LOFF(aQ.First()->Deque(), NSchedulable, iLbLink);
+		if (!s->IsGroup())
+			{
+			t = (NThread*)s;
+			if (t->iRebalanceAttr & 1)
+				++checked;
+			}
+		s->GetLbStats(bpl);
+		if (
+			(s->iLbInfo.iLbWarm >= LB_DormantThreshold)	// hasn't run for a while
+		||	(s->iLbInfo.iLbWarm>0 && s->iLbInfo.iLbRunAvg<K_LB_GravelThreshold_RunAvg && s->iLbInfo.iLbRunActAvg>K_LB_GravelThreshold_RunActAvg)	// gravel
+		)
+			{
+			TUint32 a = s->iLbInfo.iLbAffinity;
+			if ( (a&(a-1)) == 0)
+				avail.AddLoad(__e32_find_ms1_32(a), s->iLbInfo.iLbRunAvg);
+			else
+				gravel += s->iLbInfo.iLbRunAvg;
+			if (!IsNew(s))
+				++nd;
+			s->LbDone(cc);		// drop it
+			}
+		else if (nact==1)
+			{
+			s->LbDone(cc|K_Keep);	// keep it but only 1 CPU so don't balance
+			}
+		else if (t && t->iCoreCycling)
+			{
+			s->LbDone(cc|K_Keep);	// keep it but don't balance
+			}
+		else
+			{
+			++ns;
+			AddToSortedQueue(&sbq[0], s);
+			}
+		}
+
+	gravel /= TUint(nact);
+	for (i=0; i<KMaxCpus; ++i)
+		{
+		if (iThreadAcceptCpus & (1<<i))
+			avail.AddLoad(i, gravel);
+		}
+	if (ns>0)
+		{
+		TInt k;
+		for (k=KNumPriorities; k>=0; --k)
+			{
+			SPerPri& q = sbq[k];
+			if (q.iCount==0)
+				{
+				__NK_ASSERT_ALWAYS(q.IsEmpty());
+				continue;
+				}
+			if (nact==0)
+				goto dump_remaining;
+			while (!q.IsEmpty())
+				{
+				s = _LOFF(q.First(), NSchedulable, iLbLink);
+//				BTrace12(BTrace::EHSched, 0x80u, s, s->iLbInfo.iLbRunAvg, s->iLbInfo.iLbRunActAvg);
+				if (IsHeavy(s))
+					break;
+				s->iLbLink.Deque();
+				TInt cpu = avail.PickCpu(s, nd);
+//				BTrace12(BTrace::EHSched, 0x81u, cpu, remain[cpu], totalremain);
+				avail.AddLoad(cpu, s->iLbInfo.iLbRunAvg);
+//				BTrace8(BTrace::EHSched, 0x82u, remain[cpu], totalremain);
+				s->LbDone(cc|K_Keep|K_NewCpu|cpu);
+				}
+			if (q.iHeavy > nact)
+				{
+				TInt hr = avail.TotalRemain() / q.iHeavy;
+				TInt n = q.iHeavy;
+				TInt j;
+				for (j=0; j<nact; ++j)
+					{
+					// don't bother about keeping same CPU since we must rotate
+					// threads between CPUs to even out the run times.
+					TInt cpu = avail.FindMax();
+//					BTrace12(BTrace::EHSched, 0x83u, cpu, remain[cpu], totalremain);
+					TInt capacity = avail.SetMaxed(cpu);
+//					BTrace8(BTrace::EHSched, 0x84u, remain[cpu], totalremain);
+					TInt nh = 0;
+					if (hr > K_LB_HeavyCapacityThreshold)
+						{
+						if (j == nact-1)
+							nh = n;
+						else
+							nh = capacity / hr;
+						}
+					else
+						nh = n / (nact-j);
+					n -= nh;
+					for (; nh>0; --nh)
+						{
+						if (q.IsEmpty())
+							__crash();
+						s = _LOFF(q.First()->Deque(), NSchedulable, iLbLink);
+						s->LbDone(cc|K_Keep|K_NewCpu|cpu);
+						}
+					}
+				nact = 0;
+				}
+			else
+				{
+				while (!q.IsEmpty())
+					{
+					s = _LOFF(q.First()->Deque(), NSchedulable, iLbLink);
+					TInt cpu = avail.PickCpu(s, nd);
+//					BTrace12(BTrace::EHSched, 0x85u, cpu, remain[cpu], totalremain);
+					avail.SetMaxed(cpu);
+//					BTrace8(BTrace::EHSched, 0x86u, remain[cpu], totalremain);
+					s->LbDone(cc|K_Keep|K_NewCpu|cpu);
+					--nact;
+					}
+				}
+			__NK_ASSERT_ALWAYS(q.IsEmpty());
+			if (nact==0)
+				{
+dump_remaining:
+				while (!q.IsEmpty())
+					{
+//					BTrace4(BTrace::EHSched, 0x87u, s);
+					s = _LOFF(q.First()->Deque(), NSchedulable, iLbLink);
+					s->LbDone(cc|K_Keep);	// keep it but lose preferred CPU
+					}
+				continue;
+				}
+			}
+		}
+
+	// return TRUE if the only threads which ran were this one and the NTimer thread
+	return (totalN==2 && checked==2);
+	}
+
+void TScheduler::PeriodicBalance()
+	{
+	iNeedBal = 0;
+	ModifyCCState( ~ECCRebalanceTimerQueued, 0 );
+	SDblQue rbq;	// raw balance queue
+	GetLbThreads(rbq);
+	TInt i;
+	for (i=0; i<iNumCpus; ++i)
+		iSub[i]->GetLbThreads(rbq);
+	TBool bored = ReBalance(rbq, FALSE);
+	if (!bored || iNeedBal)
+		StartRebalanceTimer(FALSE);
+	}
+
+
+void TScheduler::StartPeriodicBalancing()
+	{
+#ifdef KBOOT
+	__KTRACE_OPT(KBOOT,DEBUGPRINT("StartPeriodicBalancing()"));
+	TInt i;
+	for (i=0; i<KMaxCpus; ++i)
+		{
+		TSubScheduler& ss = TheSubSchedulers[i];
+		volatile TUint32* p = (volatile TUint32*)ss.iUncached;
+		__KTRACE_OPT(KBOOT,DEBUGPRINT("CPU %1d: iUncached=%08x -> %08x %08x %08x %08x", i, p, p[0], p[1], p[2], p[3]));
+		}
+#endif
+	TheScheduler.StartRebalanceTimer(TRUE);
+	}
+
+void TScheduler::StartRebalanceTimer(TBool aRestart)
+	{
+	TInt interval = K_LB_BalanceInterval;
+	TUint32 mask = aRestart ? (ECCRebalanceTimerQueued|ECCPeriodicBalancingActive) : (ECCRebalanceTimerQueued);
+	TUint32 orig = ModifyCCState(~mask, mask);
+	TUint32 ns = (orig &~ mask) ^ mask;
+	__KTRACE_OPT(KSCHED3,DEBUGPRINT("StrtRbTmr %08x %08x %08x", mask, orig, ns));
+	if ((ns & ECCPeriodicBalancingActive) && !(orig & ECCRebalanceTimerQueued))
+		{
+		TInt r = KErrArgument;
+		if (orig & ECCPeriodicBalancingActive)
+			{
+			r = iBalanceTimer.Again(interval);
+			if (r == KErrArgument)
+				{
+				++LBDelayed;	// so we can see if this happened
+				}
+			}
+		if (r == KErrArgument)
+			{
+			r = iBalanceTimer.OneShot(interval);
+			}
+		if (r != KErrNone)
+			__crash();
+		}
+	}
+
+void TScheduler::StopRebalanceTimer(TBool aTemp)
+	{
+	TUint32 mask = aTemp ? ECCRebalanceTimerQueued : (ECCRebalanceTimerQueued|ECCPeriodicBalancingActive);
+	TUint32 orig = ModifyCCState(~mask, 0);
+	__KTRACE_OPT(KSCHED3,DEBUGPRINT("StopRbTmr %08x %08x", mask, orig));
+	if (orig & ECCRebalanceTimerQueued)
+		iBalanceTimer.Cancel();
+	}
+
+
+
+/******************************************************************************
+ * Core Control
+ ******************************************************************************/
+
+/*
+
+TScheduler fields used for core control:
+
+iThreadAcceptCpus
+	Bit n = 1 iff CPU n is available to threads with no specific affinity.
+	Bits corresponding to existing CPUs are set at boot time.
+	Subsequently this word is only modified by load balancer thread.
+	Bit n is cleared when a decision is made to shut down core n.
+
+
+iIpiAcceptCpus
+	Bit n = 1 iff CPU n is accepting generic IPIs
+	Bits corresponding to existing CPUs are set at boot time.
+	Bit n is cleared when CPU n makes the decision to ask the idle handler to power down
+		At the same time, bit n of iCpusGoingDown is set.
+	Bit n is set when CPU n returns from the idle handler after waking up.
+	Protected by iGenIPILock
+
+iCpusComingUp
+	Bit n = 1 iff CPU n is in the process of powering up
+	All bits zero at boot
+	Bit n set when the load balancer decides to initiate power up of CPU n, provided iCCDeferCount==0
+	Bit n cleared when the load balancer sets iThreadAcceptCpus bit n
+	Protected by iGenIPILock
+
+iCpusGoingDown
+	Bit n = 1 iff CPU n is in the process of powering down and is no longer accepting IPIs
+	All bits zero at boot
+	Bit n is set when CPU n makes the decision to ask the idle handler to power down
+	?Bit n is cleared when?
+		- when TCoreCycler observes the CPU has detached
+		- when the load balancer observes the CPU has detached
+		- when the load balancer decides to reactivate the CPU
+	Protected by iGenIPILock
+
+iCCDeferCount
+	If this is positive CPUs being shut down will not proceed to clear iIpiAcceptCpus
+	In this case bits can be set in iIpiAcceptCpus but cannot be cleared.
+	Also (iIpiAcceptCpus|iCpusComingUp) remains constant
+	Protected by iGenIPILock
+
+iCCSyncCpus
+	Bit n = 1 iff a change has been made to iThreadAcceptCpus which CPU n should observe
+	but it has not yet observed it.
+	Bit n set by the load balancer after a change is made to iThreadAcceptCpus, provided bit n
+	is also set in iIpiAcceptCpus.
+	Bit n cleared when CPU n services the core control sync IPI if iKernCSLocked==0 or the
+	next time iKernCSLocked becomes zero otherwise.
+
+iCCReactivateCpus
+	Bit n = 1 if CPU n is being reactivated after being removed from iThreadAcceptCpus
+	Bit n is set if a thread is made ready, cannot be assigned to any active CPU on
+		account of affinity restrictions and is assigned to CPU n.
+	Bit n is also set when CPU n wakes up from being retired.
+	Protected by iGenIPILock
+
+iCCState
+	Bit 31 (ECCReqPending)	Set when an external request to change the number of cores is in progress
+
+iCCRequestLevel
+	The number of CPUs last requested to be active.
+
+iGenIPILock
+
+iCCSyncIDFC
+	Runs when all CPUs have observed a change to iThreadAcceptCpus
+
+iCCReactivateDfc
+	Runs whenever one or more bits have been set in iCCReactivateCpus
+
+iCCRequestDfc
+	Runs whenever a request is received to change the number of active cores
+
+TSubScheduler fields used for core control:
+
+
+*/
+
+void TScheduler::CCUnDefer()
+	{
+	TUint32 powerOn = 0;
+	TBool doDeferredReq = FALSE;
+	TInt irq = iGenIPILock.LockIrqSave();
+	if (--iCCDeferCount == 0)
+		{
+		// Kick cores waiting to power off
+		__holler();
+
+		// See if any cores are waiting to power on
+		powerOn = iCCReactivateCpus &~ iCpusComingUp;
+
+		// See if a core control request has been deferred
+		if (iCCState & ECCReqDeferred)
+			{
+			if (iCpusComingUp==0 && iCCReactivateCpus==0)
+				doDeferredReq = TRUE;
+			}
+		}
+	iGenIPILock.UnlockIrqRestore(irq);
+	if (powerOn)
+		iCCReactivateDfc.Enque();
+	if (doDeferredReq)
+		iCCRequestDfc.Enque();
+	}
+
+void TScheduler::CCSyncDone(TAny* aPtr)
+	{
+	NFastSemaphore* s = (NFastSemaphore*)aPtr;
+	s->Signal();
+	}
+
+void CCSyncIPI(TGenericIPI*)
+	{
+	TScheduler& s = TheScheduler;
+	TSubScheduler& ss = SubScheduler();
+	if (ss.iKernLockCount)
+		{
+		ss.iCCSyncPending = 1;
+		ss.iRescheduleNeededFlag = 1;
+		return;
+		}
+	TUint32 m = ss.iCpuMask;
+	if (__e32_atomic_and_ord32(&s.iCCSyncCpus, ~m)==m)
+		{
+		s.iCCSyncIDFC.Add();
+		}
+	}
+
+void TScheduler::ChangeThreadAcceptCpus(TUint32 aNewMask)
+	{
+	NThread* lbt = LBThread();
+	if (NKern::CurrentThread() != lbt)
+		__crash();
+	TInt irq = iGenIPILock.LockIrqSave();
+	++iCCDeferCount;
+	iThreadAcceptCpus = aNewMask;
+	TUint32 cpus = iIpiAcceptCpus;
+	iCCSyncCpus = cpus;
+	iCpusComingUp &= ~aNewMask;
+	iGenIPILock.UnlockIrqRestore(irq);
+
+	NFastSemaphore sem(0);
+	iCCSyncIDFC.iPtr = &sem;
+	TGenericIPI ipi;
+	ipi.Queue(&CCSyncIPI, cpus);
+
+	NKern::FSWait(&sem);
+	CCUnDefer();
+	}
+
+template<int N> struct Log2 {};
+
+TEMPLATE_SPECIALIZATION struct Log2<1> { enum {Log=0u}; };
+TEMPLATE_SPECIALIZATION struct Log2<2> { enum {Log=1u}; };
+TEMPLATE_SPECIALIZATION struct Log2<4> { enum {Log=2u}; };
+TEMPLATE_SPECIALIZATION struct Log2<8> { enum {Log=3u}; };
+TEMPLATE_SPECIALIZATION struct Log2<16> { enum {Log=4u}; };
+TEMPLATE_SPECIALIZATION struct Log2<32> { enum {Log=5u}; };
+
+
+class TCpuSet
+	{
+public:
+	enum {
+		EBitsPerTUint8Shift=3u,
+		EBitsPerTUint32Shift=EBitsPerTUint8Shift+Log2<sizeof(TUint32)>::Log,
+		EBitsPerTUint8=1u<<EBitsPerTUint8Shift,
+		EBitsPerTUint32=1u<<EBitsPerTUint32Shift,
+		EWords=1u<<(KMaxCpus-EBitsPerTUint32Shift),
+		EBytes=1u<<(KMaxCpus-EBitsPerTUint8Shift),
+		EBits=1u<<KMaxCpus,
+		};
+public:
+	TCpuSet(TUint32 aMask);
+	void Consider(TUint32 aAffinity);
+	TCpuSet& operator&=(const TCpuSet&);
+	TCpuSet& operator|=(const TCpuSet&);
+	TCpuSet& Not();
+	TBool IsEmpty() const;
+	TInt Profile(TInt* aOut) const;
+	TUint32 Select(TInt aDesiredNumber, TUint32 aCurrent, TUint32 aIgnore) const;
+private:
+	/**
+	Bitfield: Bit n	= bit (n%8) of byte INT(n/8)
+					= bit (n%32) of word INT(n/32)
+	Bit n is set if the subset S of CPUs represented by the bits of n in the
+	canonical way (i.e. x \in S <=> bit x of n = 1) is acceptable.
+	*/
+	TUint32	iMask[EWords];
+	};
+
+TCpuSet::TCpuSet(TUint32 aM)
+	{
+	memset(iMask, 0, sizeof(iMask));
+	TInt i;
+	TUint32 m=1;	// empty set only
+	for (i=0; i<EBitsPerTUint32Shift; ++i)
+		{
+		TUint32 ibit = 1u<<i;
+		if (aM & ibit)
+			m |= (m<<ibit);
+		}
+	iMask[0] = m;
+	for (; i<KMaxCpus; ++i)
+		{
+		TUint32 ibit = 1u<<i;
+		if (aM & ibit)
+			{
+			TInt ws = 1<<(i-EBitsPerTUint32Shift);
+			TInt j;
+			for (j=0; j<ws; ++j)
+				iMask[ws+j] = iMask[j];
+			}
+		}
+	}
+
+TCpuSet& TCpuSet::operator&=(const TCpuSet& aS)
+	{
+	TInt i;
+	for (i=0; i<EWords; ++i)
+		iMask[i] &= aS.iMask[i];
+	return *this;
+	}
+
+TCpuSet& TCpuSet::operator|=(const TCpuSet& aS)
+	{
+	TInt i;
+	for (i=0; i<EWords; ++i)
+		iMask[i] |= aS.iMask[i];
+	return *this;
+	}
+
+TCpuSet& TCpuSet::Not()
+	{
+	TInt i;
+	for (i=0; i<EWords; ++i)
+		iMask[i] = ~iMask[i];
+	return *this;
+	}
+
+TBool TCpuSet::IsEmpty() const
+	{
+	TInt i;
+	TUint32 x = 0;
+	for (i=0; i<EWords; ++i)
+		x |= iMask[i];
+	return !x;
+	}
+
+void TCpuSet::Consider(TUint32 aAffinity)
+	{
+	TUint32 am = AffinityToMask(aAffinity);
+	am &= EBits-1;
+	if (am == EBits-1 || am==0)
+		return;	// no restrictions
+
+	TCpuSet bad(am ^ (EBits-1));	// sets incompatible with aAffinity
+	TInt i;
+	for (i=0; i<EWords; ++i)
+		iMask[i] &= ~bad.iMask[i];	// knock out sets incompatible with aAffinity
+	}
+
+const TUint32 Pmask[6] =
+	{
+	0x00000001,			// no bits set
+	0x00010116,			// 1 bit set (10000, 01000, 00100, 00010, 00001 -> 16,8,4,2,1)
+	0x01161668,			// 2 bits set (11000, 10100, 10010, 10001, 01100, 01010, 01001, 00110, 00101, 00011 -> 24,20,18,17,12,10,9,6,5,3)
+	0x16686880,			// 3 bits set (11100, 11010, 11001, 10110, 10101, 10011, 01110, 01101, 01011, 00111 -> 28,26,25,22,21,19,14,13,11,7)
+	0x68808000,			// 4 bits set (11110, 11101, 11011, 10111, 01111 -> 30,29,27,23,15)
+	0x80000000			// 5 bits set
+	};
+
+/**
+	Sets aOut[n] = number of entries with n CPUs present (0<=n<=KMaxCpus)
+	Returns total number of entries
+*/
+TInt TCpuSet::Profile(TInt* aOut) const
+	{
+	TInt i,j;
+	TInt r = 0;
+	memset(aOut, 0, (KMaxCpus+1)*sizeof(TInt));
+	for (i=0; i<EWords; ++i)
+		{
+		TUint32 m = iMask[i];
+		if (!m)
+			continue;
+		TInt n1 = __e32_bit_count_32(i);
+		for (j=0; j<=EBitsPerTUint32Shift; ++j)
+			{
+			TInt dr = __e32_bit_count_32(m & Pmask[j]);
+			r += dr;
+			aOut[n1+j] += dr;
+			}
+		}
+	return r;
+	}
+
+/**
+	Given a desired number of active cores and the mask of currently
+	running cores, returns the new mask of active cores.
+*/
+TUint32 TCpuSet::Select(TInt aDesiredNumber, TUint32 aCurrent, TUint32 aIgnore) const
+	{
+	TInt max = __e32_bit_count_32(aCurrent);
+	if (aDesiredNumber > max)
+		return 0;
+	TInt profile[KMaxCpus+1] = {0};
+	Profile(profile);
+	TInt dn;
+	for (dn=aDesiredNumber; dn<=max && profile[dn]==0; ++dn)
+		{}
+	if (dn > max)
+		return 0;
+	TInt wix;
+	TUint32 bestMask = 0;
+	TInt bestDiff = KMaxTInt;
+	TInt stop = max - dn;
+	for (wix=0; wix<EWords; ++wix)
+		{
+		TUint32 candidate = wix << EBitsPerTUint32Shift;
+		TUint32 m = iMask[wix];
+		if (!m)
+			continue;
+		TInt n1 = __e32_bit_count_32(wix);
+		if (n1 > dn)
+			continue;
+		m &= Pmask[dn-n1];
+		for (; m; m>>=1, ++candidate)
+			{
+			if (!(m&1))
+				continue;
+			TUint32 diff = (candidate&~aIgnore) ^ aCurrent;
+			TInt wt = __e32_bit_count_32(diff);
+			if (wt < bestDiff)
+				{
+				bestDiff = wt;
+				bestMask = candidate;
+				if (bestDiff == stop)
+					{
+					wix = EWords;
+					break;
+					}
+				}
+			}
+		}
+	return bestMask;
+	}
+
+void NSchedulable::LbTransfer(SDblQue& aDestQ)
+	{
+	if (iLbState & ELbState_PerCpu)
+		{
+		TSubScheduler* ss = &TheSubSchedulers[iLbState & ELbState_CpuMask];
+		ss->iReadyListLock.LockOnly();
+		if (iLbState == ss->iLbCounter)
+			{
+			iLbLink.Deque();
+			}
+		ss->iReadyListLock.UnlockOnly();
+		}
+	else if ((iLbState & ELbState_CpuMask) == ELbState_Global)
+		{
+		TScheduler& s = TheScheduler;
+		s.iBalanceListLock.LockOnly();
+		if (iLbState == s.iLbCounter)
+			{
+			iLbLink.Deque();
+			}
+		s.iBalanceListLock.UnlockOnly();
+		}
+	else if (iLbState != ELbState_Inactive)
+		{
+		// shouldn't happen
+		__crash();
+		}
+	iLbState = ELbState_Temp;
+	aDestQ.Add(&iLbLink);
+	}
+
+void GetAll(SDblQue& aOutQ, SIterDQ* aInQ)
+	{
+	TScheduler& s = TheScheduler;
+	SIterDQIterator iter;
+	TInt maxSteps = NKern::NumberOfCpus() + 2;
+	TInt r;
+	NKern::Lock();
+	s.iEnumerateLock.LockOnly();
+	iter.Attach(aInQ);
+	FOREVER
+		{
+		SIterDQLink* link = 0;
+		r = iter.Step(link, maxSteps);
+		if (r == KErrEof)
+			break;
+		if (r == KErrNone)
+			{
+			NSchedulable* sch = _LOFF(link, NSchedulable, iEnumerateLink);
+			sch->AcqSLock();
+			sch->LbTransfer(aOutQ);
+			sch->RelSLock();
+			}
+		s.iEnumerateLock.FlashPreempt();
+		}
+	iter.Detach();
+	s.iEnumerateLock.UnlockOnly();
+	NKern::Unlock();
+	}
+
+void GetAll(SDblQue& aOutQ)
+	{
+	TScheduler& s = TheScheduler;
+	GetAll(aOutQ, &s.iAllGroups);
+	GetAll(aOutQ, &s.iAllThreads);
+/*
+	SDblQueLink* l0 = aOutQ.Last();
+	SDblQueLink* anchor = &aOutQ.iA;
+	GetLbThreads(aOutQ);
+	TInt i;
+	for (i=0; i<s.iNumCpus; ++i)
+		s.iSub[i]->GetLbThreads(aOutQ);
+	SDblQueLink* l = l0->iNext;
+	for (; l!=anchor; l=l->iNext)
+		{
+		NSchedulable* sch = _LOFF(l, NSchedulable, iLbLink);
+		sch->LAcqSLock();
+		sch->iLbState = (sch->iLbState & ELbState_ExtraRef) | ELbState_Temp;
+		sch->RelSLockU();
+		}
+*/
+	}
+
+void GetCpuSet(TCpuSet& aSet, SDblQue& aQ)
+	{
+	SDblQueLink* anchor = &aQ.iA;
+	SDblQueLink* l = aQ.First();
+	for (; l!=anchor; l=l->iNext)
+		{
+		NSchedulable* sch = _LOFF(l, NSchedulable, iLbLink);
+		if (!sch->IsGroup() && ((NThreadBase*)sch)->i_NThread_Initial )
+			continue;	// skip idle threads since they are locked to their respective CPU
+		TUint32 aff = sch->iCpuAffinity;
+		aSet.Consider(aff);
+		}
+	}
+
+
+void TScheduler::CCReactivateDfcFn(TAny* a)
+	{
+	((TScheduler*)a)->CCReactivate(0);
+	}
+
+void TScheduler::CCRequestDfcFn(TAny* a)
+	{
+	((TScheduler*)a)->CCRequest();
+	}
+
+void TScheduler::CCIpiReactivateFn(TAny* a)
+	{
+	((TScheduler*)a)->CCIpiReactivate();
+	}
+
+TUint32 TScheduler::ModifyCCState(TUint32 aAnd, TUint32 aXor)
+	{
+	TInt irq = iGenIPILock.LockIrqSave();
+	TUint32 orig = iCCState;
+	iCCState = (orig & aAnd) ^ aXor;
+	iGenIPILock.UnlockIrqRestore(irq);
+	return orig;
+	}
+
+
+/**
+Runs if a thread is made ready on a CPU marked for shutdown (apart from on
+account of core cycling) or if a core wakes up from shutdown.
+*/
+void TScheduler::CCReactivate(TUint32 aMore)
+	{
+	TUint32 startPowerUp = 0;		// cores which need to be powered up
+	TUint32 finishPowerUp = 0;		// cores which have just powered up
+	TInt irq = iGenIPILock.LockIrqSave();
+	iCCReactivateCpus |= aMore;
+	TUint32 cu = iCpusComingUp | iIpiAcceptCpus;
+	finishPowerUp = iCCReactivateCpus & cu;
+	iCCReactivateCpus &= ~finishPowerUp;
+	if (iCCDeferCount == 0)
+		{
+		startPowerUp = iCCReactivateCpus &~ cu;
+		iCCReactivateCpus = 0;
+		iCpusComingUp |= startPowerUp;
+		}
+	TUint32 ccs = iCCState;
+	iGenIPILock.UnlockIrqRestore(irq);
+	if (startPowerUp)
+		{
+		// Begin powering up cores
+		CCInitiatePowerUp(startPowerUp);
+		}
+	if (finishPowerUp)
+		{
+		// ?Rebalance load to new cores now or wait till next periodic?
+		ChangeThreadAcceptCpus(iThreadAcceptCpus | finishPowerUp);
+		if ((iThreadAcceptCpus & (iThreadAcceptCpus-1)) && !(ccs & ECCPeriodicBalancingActive))
+			{
+			// more than 1 core so restart periodic balancing
+			StartRebalanceTimer(TRUE);
+			}
+		if (startPowerUp == 0)
+			ModifyCCState(~ECCPowerUpInProgress, 0);
+		}
+	if (iNeedBal)
+		{
+		if ( (ccs & (ECCPeriodicBalancingActive|ECCRebalanceTimerQueued)) == ECCPeriodicBalancingActive)
+			{
+			StartRebalanceTimer(FALSE);
+			}
+		}
+	}
+
+extern "C" void wake_up_for_ipi(TSubScheduler* aSS, TInt)
+	{
+	TScheduler& s = *aSS->iScheduler;
+	if (__e32_atomic_ior_ord32(&s.iCCIpiReactivate, aSS->iCpuMask)==0)
+		{
+		s.iCCIpiReactIDFC.RawAdd();
+		}
+	}
+
+/**
+Runs if a core needs to wake up on account of a transferred tied IRQ or IDFC
+*/
+void TScheduler::CCIpiReactivate()
+	{
+	TUint32 cores = __e32_atomic_swp_ord32(&iCCIpiReactivate, 0);
+	TInt irq = iGenIPILock.LockIrqSave();
+	iCCReactivateCpus |= cores;
+	iGenIPILock.UnlockIrqRestore(irq);
+	iCCReactivateDfc.DoEnque();
+	}
+
+TUint32 TScheduler::ReschedInactiveCpus(TUint32 aMask)
+	{
+	TUint32 rm = aMask & 0x7FFFFFFFu;
+	if (aMask & 0x80000000u)
+		{
+		TSubScheduler& ss = SubScheduler();
+		TUint32 me = ss.iCpuMask;
+		if (__e32_atomic_and_ord32(&iCCSyncCpus, ~me) == me)
+			{
+			rm |= me;
+			iCCSyncIDFC.RawAdd();
+			}
+		}
+	return rm;
+	}
+
+TUint32 TScheduler::CpuShuttingDown(TSubScheduler& aSS)
+	{
+	TUint32 m = aSS.iCpuMask;
+	iIpiAcceptCpus &= ~m;		// no more IPIs for us
+	iCpusGoingDown |= m;		// we are now past the 'point of no return'
+	TUint32 more = iIpiAcceptCpus &~ (iThreadAcceptCpus | iCpusComingUp | iCCReactivateCpus);
+	if (more)
+		return more;
+	if (iCCState & ECCPowerDownInProgress)
+		return KMaxTUint32;
+	return 0;
+	}
+
+// Called just before last CPU goes idle
+void TScheduler::AllCpusIdle()
+	{
+	}
+
+// Called just after first CPU wakes up from idle
+void TScheduler::FirstBackFromIdle()
+	{
+	}
+
+
+struct SCoreControlAction
+	{
+	SCoreControlAction();
+
+	TInt	iPowerUpCount;			// number of cores to power on ...
+	TUint32	iPowerUpCandidates;		// ... out of these
+	TUint32 iPowerUpChoice;			// chosen to power on
+	TInt	iPowerDownCount;		// number of cores to power off ...
+	TUint32	iPowerDownCandidates;	// ... out of these
+	TUint32 iPowerDownChoice;		// chosen to power off
+
+	// snapshot of core control state
+	TInt	iCCRequestLevel;
+	TUint32	iThreadAcceptCpus;
+	TUint32	iIpiAcceptCpus;
+	TUint32	iCpusComingUp;
+	TUint32 iCCReactivateCpus;
+
+	TBool	iCCDefer;
+	SDblQue	iBalanceQ;
+	};
+
+SCoreControlAction::SCoreControlAction()
+	:	iPowerUpCount(0),
+		iPowerUpCandidates(0),
+		iPowerUpChoice(0),
+		iPowerDownCount(0),
+		iPowerDownCandidates(0),
+		iPowerDownChoice(0),
+		iCCRequestLevel(0),
+		iThreadAcceptCpus(0),
+		iIpiAcceptCpus(0),
+		iCpusComingUp(0),
+		iCCReactivateCpus(0),
+		iCCDefer(0)
+	{
+	}
+
+void TScheduler::InitCCAction(SCoreControlAction& aA)
+	{
+	aA.iPowerUpCount = 0;
+	aA.iPowerUpCandidates = 0;
+	aA.iPowerUpChoice = 0;
+	aA.iPowerDownCount = 0;
+	aA.iPowerDownCandidates = 0;
+	aA.iPowerDownChoice = 0;
+	aA.iCCDefer = FALSE;
+
+	TUint32 all = (1u<<iNumCpus)-1;
+
+	TInt irq = iGenIPILock.LockIrqSave();
+
+	// cores fully operative and not being powered off
+	TUint32 c1 = iThreadAcceptCpus;
+
+	// cores in the process of being retired
+	TUint32 c0 = iIpiAcceptCpus &~ (iThreadAcceptCpus | iCpusComingUp | iCCReactivateCpus);
+
+	// cores on (including those being retired) or coming up
+	TUint32 c2 = (iIpiAcceptCpus | iCpusComingUp | iCCReactivateCpus);
+	TInt n2 = __e32_bit_count_32(c2);
+
+	// cores on and not being retired, plus cores being reactivated
+	TUint32 c3 = c2 &~ c0;
+	TInt n3 = __e32_bit_count_32(c3);
+
+	TInt req = iCCRequestLevel;
+
+	// take snapshot of state
+	aA.iCCRequestLevel = req;
+	aA.iThreadAcceptCpus = c1;
+	aA.iIpiAcceptCpus = iIpiAcceptCpus;
+	aA.iCpusComingUp = iCpusComingUp;
+	aA.iCCReactivateCpus = iCCReactivateCpus;
+
+	if (req > n2)
+		{
+		// need to activate some more cores
+		aA.iPowerUpCount = req - n2;
+		aA.iPowerUpCandidates = all &~ c2;
+		iCCReactivateCpus |= c0;	// revive cores currently in the process of powering down
+		iCCState &= ~ECCReqPending;
+		iCCState |= ECCPowerUpInProgress;
+		}
+	else if (req > n3)
+		{
+		// need to reactivate some cores which are currently powering down
+		aA.iPowerUpCount = req - n3;
+		aA.iPowerUpCandidates = c0;
+		iCCState &= ~ECCReqPending;
+		iCCState |= ECCPowerUpInProgress;
+		aA.iCCDefer = TRUE;
+		++iCCDeferCount;	// stop cores going down past recovery
+		}
+	else if (req == n3)
+		{
+		// don't need to do anything
+		iCCState &= ~ECCReqPending;
+		}
+	else if (iCpusComingUp | iCCReactivateCpus)
+		{
+		// defer this request until reactivations in progress have happened
+		iCCState |= ECCReqDeferred;
+		}
+	else
+		{
+		// need to retire some more cores
+		aA.iPowerDownCount = n3 - req;
+		aA.iPowerDownCandidates = c3;
+		iCCState &= ~ECCReqPending;
+		iCCState |= ECCPowerDownInProgress;
+		}
+	iGenIPILock.UnlockIrqRestore(irq);
+	}
+
+
+/**
+Runs when a request is made to change the number of active cores
+*/
+void TScheduler::CCRequest()
+	{
+	SCoreControlAction action;
+	InitCCAction(action);
+	if (action.iPowerDownCount > 0)
+		{
+		TCpuSet cpuSet(action.iIpiAcceptCpus);
+		GetAll(action.iBalanceQ);
+		GetCpuSet(cpuSet, action.iBalanceQ);
+
+		TUint32 leaveOn = cpuSet.Select(action.iCCRequestLevel, action.iIpiAcceptCpus, action.iIpiAcceptCpus&~action.iPowerDownCandidates);
+		if (leaveOn)
+			{
+			action.iPowerDownChoice = action.iPowerDownCandidates &~ leaveOn;
+
+			// remove CPUs to be shut down from iThreadAcceptCpus
+			ChangeThreadAcceptCpus(iThreadAcceptCpus &~ action.iPowerDownChoice);
+			}
+
+		// rebalance to remaining cores
+		StopRebalanceTimer(TRUE);
+		ReBalance(action.iBalanceQ, TRUE);
+		if (iThreadAcceptCpus & (iThreadAcceptCpus - 1))
+			{
+			// more than 1 CPU on
+			ModifyCCState(~ECCPowerDownInProgress, 0);
+			StartRebalanceTimer(FALSE);
+			}
+		else
+			ModifyCCState(~(ECCPowerDownInProgress|ECCPeriodicBalancingActive), 0);	// stop periodic balancing
+		}
+	if (action.iPowerUpCount > 0)
+		{
+		TUint32 ch = 0;
+		TUint32 ca = action.iPowerUpCandidates;
+		TInt n = action.iPowerUpCount;
+		while(n)
+			{
+			TInt b = __e32_find_ls1_32(ca);
+			ch |= (1u<<b);
+			ca &= ~(1u<<b);
+			--n;
+			}
+		action.iPowerUpChoice = ch;
+		CCReactivate(action.iPowerUpChoice);
+		if (action.iCCDefer)
+			CCUnDefer();
+		}
+	}
+
+/**
+Initiates a change to the number of active cores
+*/
+EXPORT_C void NKern::SetNumberOfActiveCpus(TInt aNumber)
+	{
+	__NK_ASSERT_ALWAYS(aNumber>0 && aNumber<=NKern::NumberOfCpus());
+	TScheduler& s = TheScheduler;
+	if (!s.CoreControlSupported())
+		return;
+	TBool chrl = FALSE;
+	TBool kick = FALSE;
+	NKern::Lock();
+	TInt irq = s.iGenIPILock.LockIrqSave();
+	if (s.iCCRequestLevel != (TUint32)aNumber)
+		{
+		s.iCCRequestLevel = aNumber;
+		chrl = TRUE;
+		}
+
+	// cores in the process of being retired
+	TUint32 c0 = s.iIpiAcceptCpus &~ (s.iThreadAcceptCpus | s.iCpusComingUp | s.iCCReactivateCpus);
+
+	// cores on (including those being retired) or coming up
+	TUint32 c2 = (s.iIpiAcceptCpus | s.iCpusComingUp | s.iCCReactivateCpus);
+
+	// cores on and not being retired, plus cores being reactivated
+	TUint32 c3 = c2 &~ c0;
+	TUint32 cc_active = __e32_bit_count_32(c3);
+
+	if (s.iCCRequestLevel != cc_active)
+		{
+		if (chrl || !(s.iCCState & (ECCReqPending|ECCPowerDownInProgress|ECCPowerUpInProgress) ))
+			{
+			kick = TRUE;
+			}
+		s.iCCState |= ECCReqPending;
+		}
+	s.iGenIPILock.UnlockIrqRestore(irq);
+	if (kick)
+		s.iCCRequestDfc.Add();
+	NKern::Unlock();
+	}
+
+
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kernel/eka/nkernsmp/nk_bal.h	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,63 @@
+// Copyright (c) 2009-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:
+// e32\nkernsmp\nk_bal.h
+// 
+//
+
+/**
+ @file
+ @internalComponent
+*/
+
+#ifndef __NK_BAL_H__
+#define __NK_BAL_H__
+#include <cpudefs.h>
+#include <nkern.h>
+
+#define __LOAD_BALANCE_INFO_DEFINED__
+
+struct SLbInfo
+	{
+	TUint64HL			iRecentTime;
+	TUint64HL			iRecentCpuTime;
+	TUint64HL			iRecentActiveTime;
+	TUint16				iLbRunTime;
+	TUint16				iLbActTime;
+	TUint16				iLbRunAct;
+	TUint16				iLbRunAvg;
+	TUint16				iLbActAvg;
+	TUint16				iLbRunActAvg;
+	TUint8				iLbNomPri;
+	TUint8				iLbHot;
+	TUint8				iLbWarm;
+	TUint8				iLbAffinity;
+	TUint8				iLbHeavy;
+	TUint8				iLbSpare1;
+	TUint8				iLbSpare2;
+	TUint8				iLbSpare3;
+	TUint8				iLbSpare4;
+	TUint8				iLbSpare5;
+	TUint8				iLbSpare6;
+	TUint8				iLbSpare7;
+	};
+
+#define	DUMP_LOAD_BALANCE_INFO(s)	\
+	Printf("RecentTime      %08x %08x\r\n", (s)->iLbInfo.iRecentTime.i32[1], (s)->iLbInfo.iRecentTime.i32[0]),	\
+	Printf("RecentCpuTime   %08x %08x  RecentActivTime %08x %08x\r\n", (s)->iLbInfo.iRecentCpuTime.i32[1], (s)->iLbInfo.iRecentCpuTime.i32[0], (s)->iLbInfo.iRecentActiveTime.i32[1], (s)->iLbInfo.iRecentActiveTime.i32[0]),	\
+	Printf("LbRunTime %03x  LbActTime %03x     LbRunAct %03x\r\n", (s)->iLbInfo.iLbRunTime, (s)->iLbInfo.iLbActTime, (s)->iLbInfo.iLbRunAct),	\
+	Printf("LbRunAvg  %03x   LbActAvg %03x  LbRunActAvg %03x\r\n", (s)->iLbInfo.iLbRunAvg, (s)->iLbInfo.iLbActAvg, (s)->iLbInfo.iLbRunActAvg),	\
+	Printf("LbNomPri  %02x       LbHot %02x        LbWarm %02x   LbAffinity %02x\r\n", (s)->iLbInfo.iLbNomPri, (s)->iLbInfo.iLbHot, (s)->iLbInfo.iLbWarm, (s)->iLbInfo.iLbAffinity),	\
+	Printf("LbHeavy   %02x", (s)->iLbInfo.iLbHeavy)
+
+#endif
--- a/kernel/eka/nkernsmp/nk_irq.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/nkernsmp/nk_irq.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -29,7 +29,7 @@
 NIrqHandler	Handlers[NK_MAX_IRQ_HANDLERS];
 NIrqHandler* NIrqHandler::FirstFree;
 
-extern "C" void send_irq_ipi(TSubScheduler*);
+extern "C" void send_irq_ipi(TSubScheduler*, TInt);
 
 void StepCookie(volatile TUint16& p, TInt n)
 	{
@@ -252,7 +252,8 @@
 	TRACE_IRQ12(17, this, orig, aCount);
 	if (orig & (EDisable|EUnbind|EActive))
 		return;	// disabled or already active
-	if (iTied)
+	NSchedulable* tied = iTied;
+	if (tied)
 		{
 		// we need to enforce mutual exclusion between the event handler
 		// and the tied thread or thread group, so the event handler must
@@ -261,7 +262,7 @@
 		// can't be migrated until the event handler completes.
 		// need a pending event count for the tied thread/group
 		// so we know when the thread/group can be migrated
-		TInt tied_cpu = iTied->BeginTiedEvent();
+		TInt tied_cpu = tied->BeginTiedEvent();
 		TInt this_cpu = NKern::CurrentCpu();
 		if (tied_cpu != this_cpu)
 			{
@@ -282,8 +283,8 @@
 		TRACE_IRQ8(19, this, orig);
 		if (!(orig & EActive))
 			{
-			if (iTied)
-				iTied->EndTiedEvent();
+			if (tied)
+				tied->EndTiedEvent();
 			return;	// that was last occurrence or event now disabled
 			}
 		}
@@ -456,22 +457,27 @@
 	pI->Done();
 	}
 
-TBool TSubScheduler::QueueEvent(NEventHandler* aEvent)
+TInt TSubScheduler::QueueEvent(NEventHandler* aEvent)
 	{
+	TInt r = 0;
 	TInt irq = __SPIN_LOCK_IRQSAVE(iEventHandlerLock);
-	TBool pending = iEventHandlersPending;
+	if (!(iScheduler->iIpiAcceptCpus & iCpuMask))
+		r = EQueueEvent_WakeUp;
+	else if (!iEventHandlersPending)
+		r = EQueueEvent_Kick;
 	iEventHandlersPending = TRUE;
 	iEventHandlers.Add(aEvent);
 	__SPIN_UNLOCK_IRQRESTORE(iEventHandlerLock,irq);
-	return !pending;
+	return r;
 	}
 
 void TSubScheduler::QueueEventAndKick(NEventHandler* aEvent)
 	{
-	if (QueueEvent(aEvent))
+	TInt kick = QueueEvent(aEvent);
+	if (kick)
 		{
 		// extra barrier ?
-		send_irq_ipi(this);
+		send_irq_ipi(this, kick);
 		}
 	}
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kernel/eka/nkernsmp/nk_mon.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,180 @@
+// Copyright (c) 2009-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:
+// e32\nkernsmp\nk_mon.cpp
+// Kernel crash debugger - NKERNSMP platform-independent portion
+// 
+//
+
+#define __INCLUDE_NTHREADBASE_DEFINES__
+
+#include "nk_bal.h"
+#include <kernel/monitor.h>
+#include "nk_priv.h"
+
+void Monitor::DisplaySpinLock(const char* aTitle, TSpinLock* aLock)
+	{
+	volatile TUint32* p = (volatile TUint32*)aLock;
+	Printf("%s %08x %08x\r\n", aTitle, p[0], p[1]);
+	}
+
+EXPORT_C void Monitor::DisplayNThreadInfo(NThread* aT)
+	{
+	DisplayNSchedulableInfo(aT);
+	}
+
+extern void DisplayNThreadStackedRegs(Monitor&, SThreadReschedStack&);
+extern void DisplaySubSchedulerExt(Monitor& m, TSubScheduler& ss);
+extern void DisplaySchedulerExt(Monitor& m, TScheduler& s);
+
+void Monitor::DisplayNSchedulableInfo(NSchedulable* aS)
+	{
+	NThread* t = aS->iParent ? (NThread*)aS : 0;
+	NThreadGroup* g = aS->iParent ? 0 : (NThreadGroup*)aS;
+
+	if (t && aS->iParent==aS)
+		Printf("NThread @%08x Pri %d\r\n",aS,aS->iPriority);
+	else if (t)
+		Printf("NThread @%08x (G:%08x) Pri %d\r\n",aS,aS->iParent,aS->iPriority);
+	else
+		Printf("NThreadGroup @%08x Pri %d\r\n",aS,aS->iPriority);
+	Printf("Rdy=%02x Curr=%02x LastCpu=%d CpuChg=%02x FrzCpu=%d\r\n", aS->iReady, aS->iCurrent, aS->iLastCpu, aS->iCpuChange, aS->iFreezeCpu);
+	Printf("Next=%08x Prev=%08x Parent=%08x\r\n", aS->iNext, aS->iPrev, aS->iParent);
+	Printf("CPUaff=%08x PrefCpu=%02x TCpu=%02x FCpu=%02x\r\n", aS->iCpuAffinity, aS->iPreferredCpu, aS->iTransientCpu, aS->iForcedCpu);
+	Printf("PauseCount %02x Susp %1x ACount %02x ActiveState %d\r\n", aS->iPauseCount, aS->iSuspended, aS->iACount, aS->iActiveState);
+	DisplaySpinLock("SpinLock", &aS->iSSpinLock);
+	Printf("Stopping %02x Events %08x %08x EventState %08x\r\n", aS->iStopping, aS->iEvents.iA.iNext, aS->iEvents.iA.iPrev, aS->iEventState);
+	Printf("TotalCpuTime    %08x %08x  RunCount        %08x %08x\r\n", aS->iTotalCpuTime.i32[1], aS->iTotalCpuTime.i32[0], aS->iRunCount.i32[1], aS->iRunCount.i32[0]);
+	Printf("TotalActiveTime %08x %08x  LastActivation  %08x %08x\r\n", aS->iTotalActiveTime.i32[1], aS->iTotalActiveTime.i32[0], aS->iLastActivationTime.i32[1], aS->iLastActivationTime.i32[0]);
+	Printf("SavedCpuTime    %08x %08x  SavedActiveTime %08x %08x\r\n", aS->iSavedCpuTime.i32[1], aS->iSavedCpuTime.i32[0], aS->iSavedActiveTime.i32[1], aS->iSavedActiveTime.i32[0]);
+	Printf("LastRunTime     %08x %08x  LbLink          %08x %08x    LbState %02x\r\n", aS->iLastRunTime.i32[1], aS->iLastRunTime.i32[0], aS->iLbLink.iNext, aS->iLbLink.iPrev, aS->iLbState);
+
+	DUMP_LOAD_BALANCE_INFO(aS);
+	volatile TUint32* el = (volatile TUint32*)&aS->iEnumerateLink;
+	Printf("EnumLink  %08x %08x\r\n", el[0], el[1]);
+
+	if (g)
+		{
+		// Thread group
+		return;
+		}
+
+	Printf("WaitState %02x %02x [%02x %02x] (%08x)\r\n", t->iWaitState.iWtC.iWtStFlags, t->iWaitState.iWtC.iWtObjType,
+											t->iWaitState.iWtC.iWtStSpare1, t->iWaitState.iWtC.iWtStSpare2, t->iWaitState.iWtC.iWtObj);
+	Printf("BasePri %d MutexPri %d NomPri %d Att=%02x\r\n", t->iBasePri, t->iMutexPri, t->iNominalPri, t->i_ThrdAttr);
+	Printf("HeldFM=%08x FMDef=%02x AddrSp=%08x Initial=%d\r\n", t->iHeldFastMutex, t->iFastMutexDefer, t->iAddressSpace, t->iInitial);
+	Printf("Time=%d Timeslice=%d ReqCount=%08x\r\n", t->iTime, t->iTimeslice, t->iRequestSemaphore.iCount);
+	Printf("SuspendCount=%d CsCount=%d CsFunction=%08x\r\n", t->iSuspendCount, t->iCsCount, t->iCsFunction);
+	Printf("LinkedObjType %02x LinkedObj %08x CoreCyc %02x RebalAttr %02x\r\n", t->iLinkedObjType, t->iLinkedObj, t->iCoreCycling, t->iRebalanceAttr);
+	Printf("SavedSP=%08x WaitLink:%08x %08x %d\r\n", t->iSavedSP, t->iWaitLink.iNext, t->iWaitLink.iPrev, t->iWaitLink.iPriority);
+	Printf("iNewParent=%08x iExtraContext=%08x, iExtraContextSize=%08x\r\n", t->iNewParent, t->iExtraContext, t->iExtraContextSize);
+	Printf("iUserModeCallbacks=%08x iNThreadBaseSpare6=%08x\r\n", t->iUserModeCallbacks, t->iNThreadBaseSpare6);
+	Printf("iNThreadBaseSpare7=%08x iNThreadBaseSpare8=%08x iNThreadBaseSpare9=%08x\r\n", t->iNThreadBaseSpare7, t->iNThreadBaseSpare8, t->iNThreadBaseSpare9);
+	if (!aS->iCurrent)
+		{
+		TUint32* pS=(TUint32*)t->iSavedSP;
+		SThreadReschedStack reg;
+		MTRAPD(r,wordmove(&reg,pS,sizeof(SThreadReschedStack)));
+		if (r==KErrNone)
+			DisplayNThreadStackedRegs(*this, reg);
+		}
+	NewLine();
+	}
+
+void Monitor::DisplayNFastSemInfo(NFastSemaphore* pS)
+	{
+	if (pS->iCount >= 0)
+		Printf("NFastSemaphore @ %08x Count %d OwningThread %08x\r\n",pS,pS->iCount,pS->iOwningThread);
+	else
+		Printf("NFastSemaphore @ %08x Count %08x (%08x) OwningThread %08x\r\n",pS,pS->iCount,pS->iCount<<2,pS->iOwningThread);
+	}
+
+void Monitor::DisplayNFastMutexInfo(NFastMutex* aM)
+	{
+	Printf("NFastMutex @ %08x HoldingThread %08x iWaitQ Pri Mask %08x %08x\r\n", aM, aM->iHoldingThread, aM->iWaitQ.iPresent[1], aM->iWaitQ.iPresent[0]);
+	DisplaySpinLock("SpinLock", &aM->iMutexLock);
+	}
+
+void DisplaySubSchedulerInfo(Monitor& m, TSubScheduler& ss)
+	{
+	m.Printf("\r\nSUBSCHEDULER %d @%08x:\r\n", ss.iCpuNum, &ss);
+	m.Printf("CurrentThread=%08x\r\n", ss.iCurrentThread);
+	m.Printf("IDFCs   %08x %08x    CPU# %08x CPUmask %08x\r\n", ss.iDfcs.iA.iNext, ss.iDfcs.iA.iPrev, ss.iCpuNum, ss.iCpuMask);
+	m.Printf("ExIDFCs %08x %08x CurIDFC %08x PendFlg %08x\r\n", ss.iExIDfcs.iA.iNext, ss.iExIDfcs.iA.iPrev, ss.iCurrentIDFC, *(TUint32*)&ss.iRescheduleNeededFlag);
+	m.DisplaySpinLock("ExIDfcLock", &ss.iExIDfcLock);
+	m.Printf("KLCount %d InIDFC %02x EvPend %02x\r\n", ss.iKernLockCount, ss.iInIDFC, ss.iEventHandlersPending);
+	m.Printf("LbQ     %08x %08x   LbCtr %02x\r\n", ss.iLbQ.iA.iNext, ss.iLbQ.iA.iPrev, ss.iLbCounter);
+	m.Printf("AddrSp  %08x RschdIPIs %08x iNextIPI %08x\r\n", ss.iAddressSpace, ss.iReschedIPIs, ss.iNextIPI);
+	m.DisplaySpinLock("ReadyListLock", &ss.iReadyListLock);
+	m.Printf("EvtHand %08x %08x InitThrd %08x SLOC %08x %08x\r\n", ss.iEventHandlers.iA.iNext, ss.iEventHandlers.iA.iPrev,
+		ss.iInitialThread, I64HIGH(ss.iSpinLockOrderCheck), I64LOW(ss.iSpinLockOrderCheck));
+	m.DisplaySpinLock("EventHandlerLock", &ss.iEventHandlerLock);
+	m.Printf("LastTmstmp %08x %08x            RschdCount %08x %08x\r\n", ss.iLastTimestamp.i32[1], ss.iLastTimestamp.i32[0], ss.iReschedCount.i32[1], ss.iReschedCount.i32[0]);
+
+	m.Printf("DeferShutdown %4d RdyThrdC %d Uncached %08x\r\n", ss.iDeferShutdown, ss.iRdyThreadCount, ss.iUncached);
+	DisplaySubSchedulerExt(m, ss);
+	TPriListBase* b = (TPriListBase*)&ss;
+	m.Printf("PriClassThrdC %4d %4d %4d %4d\r\n", ss.iPriClassThreadCount[0], ss.iPriClassThreadCount[1], ss.iPriClassThreadCount[2], ss.iPriClassThreadCount[3]);
+	m.Printf("Present %08x %08x\r\n", b->iPresent[1], b->iPresent[0]);
+	TInt k;
+	TUint64 p64 = b->iPresent64;
+	for (k=KNumPriorities-1; k>=0; --k, p64+=p64)
+		{
+		if (p64>>63)
+			{
+			m.Printf("Priority %2d -> %08x\r\n", k, ss.EntryAtPriority(k));
+			}
+		}
+	}
+
+void Monitor::DisplaySchedulerInfo()
+	{
+	TScheduler* pS=TScheduler::Ptr();
+	Printf("SCHEDULER @%08x:\r\n",pS);
+	Printf("ProcessHandler    %08x MonitorExcHndlr %08x ReschedHook %08x\r\n",pS->iProcessHandler,pS->iMonitorExceptionHandler,pS->iRescheduleHook);
+	Printf("iThreadAcceptCpus %08x  iIpiAcceptCpus %08x    iNumCpus %d\r\n",pS->iThreadAcceptCpus,pS->iIpiAcceptCpus,pS->iNumCpus);
+	Printf("iCpusComingUp     %08x  iCpusGoingDown %08x  CCDeferCnt %d\r\n",pS->iCpusComingUp,pS->iCpusGoingDown,pS->iCCDeferCount);
+	Printf("iCCSyncCpus       %08x  CCReactiv8Cpus %08x  CCState    %08x\r\n",pS->iCCSyncCpus,pS->iCCReactivateCpus,pS->iCCState);
+	Printf("IdleDfcs %08x %08x     CpusNotIdle %08x     IdleGen %02x IdleSpillCpu %02x\r\n",
+		pS->iIdleDfcs.iA.iNext, pS->iIdleDfcs.iA.iPrev, pS->iCpusNotIdle, pS->iIdleGeneration, pS->iIdleSpillCpu);
+	DisplaySpinLock("IdleSpinLock", &pS->iIdleSpinLock);
+	Printf("SYSLOCK @ %08x\r\n",&pS->iLock);
+	DisplayNFastMutexInfo(&pS->iLock);
+
+	DisplaySpinLock("EnumerateLock", &pS->iEnumerateLock);
+	volatile TUint32* at = (volatile TUint32*)&pS->iAllThreads;
+	volatile TUint32* ag = (volatile TUint32*)&pS->iAllGroups;
+	Printf("AllThrds %08x %08x       AllGroups %08x %08x\r\n", at[0], at[1], ag[0], ag[1]);
+	DisplaySpinLock("IdleBalanceLock", &pS->iIdleBalanceLock);
+	DisplaySpinLock("BalanceListLock", &pS->iBalanceListLock);
+	Printf("BalList  %08x %08x LastBalanceTime %08x %08x\r\n", pS->iBalanceList.iA.iNext, pS->iBalanceList.iA.iPrev,
+									I64HIGH(pS->iLastBalanceTime), I64LOW(pS->iLastBalanceTime));
+	Printf("LbCntr   %02x RebalanceDfcQ %08x NeedBal %02x\r\n", pS->iLbCounter, pS->iRebalanceDfcQ, pS->iNeedBal);
+	Printf("iCCRequestLevel   %08x  iPoweringOff   %08x  DetachCnt  %08x\r\n",pS->iCCRequestLevel,pS->iPoweringOff,pS->iDetachCount);
+
+	DisplaySchedulerExt(*this, *pS);
+	volatile TUint32* sc = (volatile TUint32*)&pS->iSchedScratch[0];
+	Printf("Scratch 0: %08x  1: %08x  2: %08x  3: %08x\r\n",sc[0],sc[1],sc[2],sc[3]);
+	Printf("Scratch 4: %08x  5: %08x  6: %08x  7: %08x\r\n",sc[4],sc[5],sc[6],sc[7]);
+	Printf("Scratch 8: %08x  9: %08x  A: %08x  B: %08x\r\n",sc[8],sc[9],sc[10],sc[11]);
+	Printf("Scratch C: %08x  D: %08x  E: %08x  F: %08x\r\n",sc[12],sc[13],sc[14],sc[15]);
+
+	TInt i;
+	for (i=0; i<KMaxCpus; ++i)
+		{
+		TSubScheduler& ss = *pS->iSub[i];
+		DisplaySubSchedulerInfo(*this, ss);
+		}
+	NewLine();
+	}
+
--- a/kernel/eka/nkernsmp/nk_timer.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/nkernsmp/nk_timer.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -26,7 +26,7 @@
 
 GLDEF_D NTimerQ TheTimerQ;
 
-extern "C" void send_irq_ipi(TSubScheduler*);
+extern "C" void send_irq_ipi(TSubScheduler*, TInt);
 
 #ifndef __MSTIM_MACHINE_CODED__
 #ifdef _DEBUG
@@ -345,7 +345,6 @@
 // Wait aTime from last trigger time - used for periodic timers
 //
 	{
-	__NK_ASSERT_DEBUG(aTime>0);
 	TInt irq = TheTimerQ.iTimerSpinLock.LockIrqSave();
 	if (!IsValid())
 		{
@@ -586,6 +585,8 @@
 	{
 	__KTRACE_OPT(KBOOT,DEBUGPRINT("NTimerQ::Init3 DFCQ at %08x",aDfcQ));
 	TheTimerQ.iDfc.SetDfcQ(aDfcQ);
+	NThreadBase* t = aDfcQ->iThread;
+	t->iRebalanceAttr = 1;
 	}
 
 #ifndef __MSTIM_MACHINE_CODED__
@@ -742,8 +743,7 @@
 EXPORT_C void NTimerQ::Tick()
 	{
 	TInt irq = iTimerSpinLock.LockIrqSave();
-	TInt i=iMsCount & ETimerQMask;
-	iMsCount++;
+	TInt i = TInt(__e32_atomic_add_rlx64(&iMsCount64, 1)) & ETimerQMask;
 	STimerQ* pQ=iTickQ+i;
 	iPresent &= ~(1<<i);
 	TBool doDfc=FALSE;
@@ -802,10 +802,10 @@
 					{
 					pC->i_NTimer_iState = TUint8(NTimer::EEventQ + cpu);
 					TSubScheduler* ss = TheSubSchedulers + cpu;
-					TBool kick = ss->QueueEvent(pC);
+					TInt kick = ss->QueueEvent(pC);
 					iTimerSpinLock.UnlockIrqRestore(irq);
 					if (kick)
-						send_irq_ipi(ss);
+						send_irq_ipi(ss, kick);
 					continue;
 					}
 				}
@@ -921,8 +921,8 @@
  */
 EXPORT_C void NTimerQ::Advance(TInt aTicks)
 	{
-	CHECK_PRECONDITIONS(MASK_INTERRUPTS_DISABLED,"NTimerQ::Advance");	
-	TheTimerQ.iMsCount+=(TUint32)aTicks;
+	CHECK_PRECONDITIONS(MASK_INTERRUPTS_DISABLED,"NTimerQ::Advance");
+	__e32_atomic_add_rlx64(&TheTimerQ.iMsCount64, TUint64(TUint32(aTicks)));
 	}
 
 
--- a/kernel/eka/nkernsmp/nkern.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/nkernsmp/nkern.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -98,7 +98,10 @@
 			pC->iLinkedObj = this;
 			pC->iWaitState.SetUpWait(NThreadBase::EWaitFastMutex, NThreadWaitState::EWtStObstructed, this);
 			pC->iWaitLink.iPriority = pC->iPriority;
-			iWaitQ.Add(&pC->iWaitLink);
+			if (waited)
+				iWaitQ.AddHead(&pC->iWaitLink);	// we were next at this priority
+			else
+				iWaitQ.Add(&pC->iWaitLink);
 			pC->RelSLock();
 			if (pH)
 				pH->SetMutexPriority(this);
@@ -880,6 +883,9 @@
 		iCsFunction = ECSDivertPending;
 		iSuspendCount = 0;
 		iSuspended = 0;
+
+		// If thread is killed before first resumption, set iACount=1
+		__e32_atomic_tau_ord8(&iACount, 1, 0, 1);
 		if (aS)
 			aS->iReadyListLock.UnlockOnly();
 		DoReleaseT(KErrDied,0);
@@ -894,7 +900,7 @@
 TBool NThreadBase::SuspendOrKill(TInt aCount)
 	{
 	__KTRACE_OPT(KNKERN,DEBUGPRINT("%T nSuspendOrKill %d", this, aCount));
-	if (aCount==0)
+	if (aCount==0 || i_NThread_Initial)
 		return FALSE;
 	TBool result = FALSE;
 	TBool concurrent = FALSE;
@@ -1047,6 +1053,10 @@
 			{
 			result = TRUE;
 			iSuspended = 0;
+
+			// On first resumption set iACount=1
+			// From then on the thread must be killed before being deleted
+			__e32_atomic_tau_ord8(&iACount, 1, 0, 1);
 			if (!iPauseCount && !iReady && !iWaitState.iWtC.iWtStFlags)
 				ReadyT(0);
 			}
@@ -1212,6 +1222,9 @@
 	if (xh)
 		pD = (*xh)((NThread*)this);		// call exit handler
 
+	// if CPU freeze still active, remove it
+	NKern::EndFreezeCpu(0);
+
 	// detach any tied events
 	DetachTiedEvents();
 
@@ -1283,34 +1296,65 @@
 			KCpuAny if it should be able to run on any CPU.
 	@return The previous affinity mask.
 */
-TUint32 NThreadBase::SetCpuAffinity(TUint32 aAffinity)
+TUint32 NSchedulable::SetCpuAffinityT(TUint32 aAffinity)
 	{
 	// check aAffinity is valid
-	AcqSLock();
-	TUint32 old_aff = iParent->iCpuAffinity;
-	TBool migrate = FALSE;
+	NThreadBase* t = 0;
+	NThreadGroup* g = 0;
+	NSchedulable* p = iParent;
+	if (!p)
+		g = (NThreadGroup*)this, p=g;
+	else
+		t = (NThreadBase*)this;
+	if (iParent && iParent!=this)
+		g = (NThreadGroup*)iParent;
+	TUint32 old_aff = p->iCpuAffinity;
 	TBool make_ready = FALSE;
 	TSubScheduler* ss0 = &SubScheduler();
 	TSubScheduler* ss = 0;
-	__KTRACE_OPT(KNKERN,DEBUGPRINT("%T nSetCpu %08x->%08x, F:%d R:%02x PR:%02x",this,iParent->iCpuAffinity,aAffinity,iParent->iFreezeCpu,iReady,iParent->iReady));
-	if (i_NThread_Initial)
+#ifdef KNKERN
+	if (iParent)
+		{
+		__KTRACE_OPT(KNKERN,DEBUGPRINT("%T nSetCpu %08x->%08x, F:%d R:%02x PR:%02x",this,iParent->iCpuAffinity,aAffinity,iParent->iFreezeCpu,iReady,iParent->iReady));
+		}
+	else
+		{
+		__KTRACE_OPT(KNKERN,DEBUGPRINT("%G nSetCpu %08x->%08x, F:%d R:%02x",this,iCpuAffinity,aAffinity,iFreezeCpu,iReady));
+		}
+#endif
+	if (t && t->i_NThread_Initial)
 		goto done;	// can't change affinity of initial thread
-	iParent->iCpuAffinity = aAffinity;		// set new affinity, might not take effect yet
-	if (!iParent->iReady)
+	if (aAffinity == NTHREADBASE_CPU_AFFINITY_MASK)
+		{
+		p->iTransientCpu = 0;
+		}
+	else if ( (aAffinity & (KCpuAffinityPref|NTHREADBASE_CPU_AFFINITY_MASK)) == KCpuAffinityPref)
+		{
+		p->iTransientCpu = 0;
+		p->iPreferredCpu = TUint8((aAffinity & (EReadyCpuMask|EReadyCpuSticky)) | EReadyOffset);
+		}
+	else if ( (aAffinity & (KCpuAffinityTransient|KCpuAffinityPref|NTHREADBASE_CPU_AFFINITY_MASK)) == KCpuAffinityTransient)
+		{
+		p->iTransientCpu = TUint8(aAffinity & EReadyCpuMask) | EReadyOffset;
+		}
+	else
+		p->iCpuAffinity = NSchedulable::PreprocessCpuAffinity(aAffinity);		// set new affinity, might not take effect yet
+	if (!p->iReady)
 		goto done;	// thread/group not currently on a ready list so can just change affinity
-	migrate = !CheckCpuAgainstAffinity(iParent->iReady & EReadyCpuMask, aAffinity);	// TRUE if thread's current CPU is incompatible with the new affinity
-	if (!migrate)
+
+	// Check if the thread needs to migrate or can stay where it is
+	if (!p->ShouldMigrate(p->iReady & EReadyCpuMask))
 		goto done;	// don't need to move thread, so just change affinity
-	ss = TheSubSchedulers + (iParent->iReady & EReadyCpuMask);
+	ss = TheSubSchedulers + (p->iReady & EReadyCpuMask);
 	ss->iReadyListLock.LockOnly();
-	if (iParent->iCurrent)
+	if (p->iCurrent)
 		{
-		iParent->iCpuChange = TRUE;			// mark CPU change pending
+		p->iCpuChange = TRUE;			// mark CPU change pending
 		if (ss == ss0)
 			RescheduleNeeded();
 		else
 			// kick other CPU now so migration happens before acquisition of fast mutex
-			send_resched_ipi_and_wait(iParent->iReady & EReadyCpuMask);
+			send_resched_ipi_and_wait(p->iReady & EReadyCpuMask);
 		}
 	else
 		{
@@ -1318,23 +1362,81 @@
 		// This is handled by the scheduler - when a thread belonging to a group is context switched
 		// out while holding a fast mutex its iFastMutexDefer is set to 1 and the group's iFreezeCpu
 		// is incremented.
-		if (iParent->iFreezeCpu || (iParent==this && CheckFastMutexDefer()))
-			iParent->iCpuChange = TRUE;	// CPU frozen or fast mutex held so just mark deferred CPU migration
+		if (p->iFreezeCpu || (iParent==this && t->CheckFastMutexDefer()))
+			p->iCpuChange = TRUE;	// CPU frozen or fast mutex held so just mark deferred CPU migration
 		else
 			{
-			ss->Remove(iParent);
-			iParent->iReady = 0;
+			ss->SSRemoveEntry(p);
+			p->iReady = 0;
 			make_ready = TRUE;
 			}
 		}
 	ss->iReadyListLock.UnlockOnly();
 	if (make_ready)
-		iParent->ReadyT(0);
+		p->ReadyT(0);
 done:
-	RelSLock();
 	return old_aff;
 	}
 
+/** Force the current thread onto a particular CPU
+
+	@pre	Kernel must not be locked.
+	@pre	Call in a thread context.
+	@pre	Current thread must not be in a group
+	@pre	Current thread must not hold a fast mutex
+	@pre	Current thread must have an active CPU freeze
+	@pre	Current thread must not be an initial thread
+
+	@param	The number of the CPU to which this thread should be moved
+*/
+void NKern::JumpTo(TInt aCpu)
+	{
+	// check aAffinity is valid
+	NThreadBase* t = NKern::CurrentThread();
+	__KTRACE_OPT(KNKERN,DEBUGPRINT("%T NJumpTo %d", t, aCpu));
+	if (NKern::HeldFastMutex())
+		__crash();
+	t->LAcqSLock();
+	if (t->iParent!=t)
+		__crash();
+	if (!t->iFreezeCpu)
+		__crash();
+	if (t->i_NThread_Initial)
+		__crash();
+	if (TUint(aCpu) >= (TUint)NKern::NumberOfCpus())
+		__crash();
+	TUint8 fc = (TUint8)(aCpu | NSchedulable::EReadyOffset);
+	if (t->iCurrent != fc)
+		{
+		t->iForcedCpu = fc;
+		t->iCpuChange = TRUE;
+		RescheduleNeeded();
+		}
+	t->RelSLockU();		// reschedules and jumps to new CPU
+	}
+
+TBool NSchedulable::ShouldMigrate(TInt aCpu)
+	{
+	// Check if the thread's current CPU is compatible with the new affinity
+	TUint32 active = TheScheduler.iThreadAcceptCpus;
+
+	// If it can't stay where it is, migrate
+	if (!CheckCpuAgainstAffinity(aCpu, iCpuAffinity, active))
+		return TRUE;
+
+	TInt cpu = iTransientCpu ? iTransientCpu : iPreferredCpu;
+
+	// No preferred or transient CPU, so can stay where it is
+	if (!cpu)
+		return FALSE;
+
+	// If thread isn't on preferred CPU but could be, migrate
+	cpu &= EReadyCpuMask;
+	if (cpu!=aCpu && CheckCpuAgainstAffinity(cpu, iCpuAffinity, active))
+		return TRUE;
+	return FALSE;
+	}
+
 
 /******************************************************************************
  * Thread wait state
@@ -1412,7 +1514,7 @@
 		{
 		NThreadBase* t = Thread();
 		if (!t->iPauseCount && !t->iSuspended)
-			t->ReadyT(0);
+			t->ReadyT(oldws64 & EWtStObstructed);
 		}
 	return KErrNone;
 	}
@@ -1756,6 +1858,24 @@
 	}
 
 
+/** Changes the nominal priority of a thread.
+
+	This function is intended to be used by the EPOC layer and personality layers.
+	Do not use this function directly on a Symbian OS thread - use Kern::ThreadSetPriority().
+
+    @param aThread Thread to receive the new priority.
+    @param aPriority New inherited priority for aThread.
+    
+	@see Kern::SetThreadPriority()
+*/
+void NKern::ThreadSetNominalPriority(NThread* aThread, TInt aPriority)
+	{
+	NKern::Lock();
+	aThread->SetNominalPriority(aPriority);
+	NKern::Unlock();
+	}
+
+
 /** Atomically signals the request semaphore of a nanothread and a fast mutex.
 
 	This function is intended to be used by the EPOC layer and personality
@@ -1947,6 +2067,7 @@
 		return 1;
 		}
 	pC->iFreezeCpu = 1;
+	__e32_atomic_add_rlx32(&ss.iDeferShutdown, 1);
 	if (pC->iParent != pC)
 		{
 		pC->AcqSLock();
@@ -1986,6 +2107,7 @@
 			}
 		else if (pC->iCpuChange)		// deferred CPU change?
 			RescheduleNeeded();
+		__e32_atomic_add_rlx32(&ss.iDeferShutdown, TUint32(-1));
 		}
 	NKern::Unlock();
 	}
@@ -2000,9 +2122,9 @@
  */
 EXPORT_C TUint32 NKern::ThreadSetCpuAffinity(NThread* aThread, TUint32 aAffinity)
 	{
-	NKern::Lock();
-	TUint32 r = aThread->SetCpuAffinity(aAffinity);
-	NKern::Unlock();
+	aThread->LAcqSLock();
+	TUint32 r = aThread->SetCpuAffinityT(aAffinity);
+	aThread->RelSLockU();
 	return r;
 	}
 
@@ -2327,7 +2449,15 @@
 		pC->UnReadyT();
 		pC->iParent = pC;
 		g->iCurrent = 0;	// since current thread is no longer in g
-		ss.AddHead(pC);
+		TUint64 now = NKern::Timestamp();
+		g->iLastRunTime.i64 = now;
+		g->iTotalCpuTime.i64 += (now - g->iLastStartTime.i64);
+		if (--g->iActiveState == 0)
+			{
+			// group no longer active
+			g->iTotalActiveTime.i64 += (now - g->iLastActivationTime.i64);
+			}
+		ss.SSAddEntryHead(pC);
 		pC->iReady = TUint8(ss.iCpuNum | NSchedulable::EReadyOffset);
 		pC->iCpuAffinity = g->iCpuAffinity;	// keep same CPU affinity
 		// if we're frozen, the group's freeze count was incremented
@@ -2351,7 +2481,7 @@
 				g->iCpuChange = FALSE;
 				if (g->iReady)
 					{
-					ss.Remove(g);
+					ss.SSRemoveEntry(g);
 					g->iReady = 0;
 					make_group_ready = TRUE;
 					}
@@ -2393,7 +2523,9 @@
 	__KTRACE_OPT(KNKERN,DEBUGPRINT("NJoinGroup %T->%G",pC,aGroup));
 	pC->AcqSLock();
 	aGroup->AcqSLock();
-	TBool migrate = !CheckCpuAgainstAffinity(ss.iCpuNum, aGroup->iCpuAffinity);	// TRUE if thread's current CPU is incompatible with the group's affinity
+
+	// Check if current CPU is compatible with group's affinity
+	TBool migrate = !CheckCpuAgainstAffinity(ss.iCpuNum, aGroup->iCpuAffinity);
 	if (!aGroup->iReady || aGroup->iReady==pC->iReady)
 		{
 		// group not ready or ready on this CPU
@@ -2406,17 +2538,19 @@
 			if (!aGroup->iReady)
 				{
 				aGroup->iPriority = pC->iPriority;
-				ss.AddHead(aGroup);
+				ss.SSAddEntryHead(aGroup);
 				aGroup->iReady = TUint8(ss.iCpuNum | NSchedulable::EReadyOffset);
 				}
 			else if (pC->iPriority > aGroup->iPriority)
-				{
-				ss.ChangePriority(aGroup, pC->iPriority);
-				}
+				ss.SSChgEntryP(aGroup, pC->iPriority);
 			pC->iReady = NSchedulable::EReadyGroup;
 			aGroup->iCurrent = aGroup->iReady;
 			ss.iReadyListLock.UnlockOnly();
 			++aGroup->iThreadCount;
+			TUint64 now = NKern::Timestamp();
+			aGroup->iLastStartTime.i64 = now;
+			if (++aGroup->iActiveState == 1)
+				aGroup->iLastActivationTime.i64 = now;
 			goto done;
 			}
 		}
@@ -2444,6 +2578,45 @@
 
 
 /******************************************************************************
+ * Iterable Doubly Linked List
+ ******************************************************************************/
+TInt SIterDQIterator::Step(SIterDQLink*& aObj, TInt aMaxSteps)
+	{
+	if (aMaxSteps <= 0)
+		aMaxSteps = KMaxCpus + 3;
+	SIterDQLink* p = Next();
+	SIterDQLink* q = p;
+	__NK_ASSERT_DEBUG(p!=0);
+	for(; p->IsIterator() && --aMaxSteps>0; p=p->Next())
+		{}
+	if (p->IsObject())
+		{
+		// found object
+		Deque();
+		InsertAfter(p);
+		aObj = p;
+		return KErrNone;
+		}
+	if (p->IsAnchor())
+		{
+		// reached end of list
+		if (p != q)
+			{
+			Deque();
+			InsertBefore(p);	// put at the end
+			}
+		aObj = 0;
+		return KErrEof;
+		}
+	// Maximum allowed number of other iterators skipped
+	Deque();
+	InsertAfter(p);
+	aObj = 0;
+	return KErrGeneral;
+	}
+
+
+/******************************************************************************
  * Priority Lists
  ******************************************************************************/
 
@@ -2454,8 +2627,6 @@
  */
 EXPORT_C TInt TPriListBase::HighestPriority()
 	{
-//	TUint64 present = MAKE_TUINT64(iPresent[1], iPresent[0]);
-//	return __e32_find_ms1_64(present);
 	return __e32_find_ms1_64(iPresent64);
 	}
 
@@ -2564,28 +2735,22 @@
  * Generic IPIs
  ******************************************************************************/
 
-TGenIPIList::TGenIPIList()
-	:	iGenIPILock(TSpinLock::EOrderGenericIPIList)
-	{
-	}
-
-TGenIPIList GenIPIList;
-
 extern "C" {
 extern void send_generic_ipis(TUint32);
 
 void generic_ipi_isr(TSubScheduler* aS)
 	{
+	TScheduler& s = TheScheduler;
 	TGenericIPI* ipi = aS->iNextIPI;
 	if (!ipi)
 		return;
 	TUint32 m = aS->iCpuMask;
-	SDblQueLink* anchor = &GenIPIList.iA;
+	SDblQueLink* anchor = &s.iGenIPIList.iA;
 	while (ipi != anchor)
 		{
 		__e32_atomic_and_acq32(&ipi->iCpusIn, ~m);
 		(*ipi->iFunc)(ipi);
-		TInt irq = GenIPIList.iGenIPILock.LockIrqSave();
+		TInt irq = s.iGenIPILock.LockIrqSave();
 		TGenericIPI* n = (TGenericIPI*)ipi->iNext;
 		ipi->iCpusOut &= ~m;
 		if (ipi->iCpusOut == 0)
@@ -2599,7 +2764,7 @@
 			ipi = (TGenericIPI*)ipi->iNext;
 		if (ipi == anchor)
 			aS->iNextIPI = 0;
-		GenIPIList.iGenIPILock.UnlockIrqRestore(irq);
+		s.iGenIPILock.UnlockIrqRestore(irq);
 		}
 	}
 }
@@ -2611,13 +2776,13 @@
 	TScheduler& s = TheScheduler;
 	TInt i;
 	TUint32 ipis = 0;
-	TInt irq = GenIPIList.iGenIPILock.LockIrqSave();
+	TInt irq = s.iGenIPILock.LockIrqSave();
 	if (aCpuMask & 0x80000000u)
 		{
 		if (aCpuMask==0xffffffffu)
-			aCpuMask = s.iActiveCpus2;
+			aCpuMask = s.iIpiAcceptCpus;
 		else if (aCpuMask==0xfffffffeu)
-			aCpuMask = s.iActiveCpus2 &~ SubScheduler().iCpuMask;
+			aCpuMask = s.iIpiAcceptCpus &~ SubScheduler().iCpuMask;
 		else
 			aCpuMask = 0;
 		}
@@ -2625,11 +2790,11 @@
 	iCpusOut = aCpuMask;
 	if (!aCpuMask)
 		{
-		GenIPIList.iGenIPILock.UnlockIrqRestore(irq);
+		s.iGenIPILock.UnlockIrqRestore(irq);
 		iNext = 0;
 		return;
 		}
-	GenIPIList.Add(this);
+	s.iGenIPIList.Add(this);
 	for (i=0; i<s.iNumCpus; ++i)
 		{
 		if (!(aCpuMask & (1<<i)))
@@ -2642,7 +2807,7 @@
 			}
 		}
 	send_generic_ipis(ipis);
-	GenIPIList.iGenIPILock.UnlockIrqRestore(irq);
+	s.iGenIPILock.UnlockIrqRestore(irq);
 	__KTRACE_OPT(KSCHED2,DEBUGPRINT("GenIPI ipis=%08x", ipis));
 	}
 
@@ -2706,3 +2871,109 @@
 	}
 
 
+/******************************************************************************
+ * TCoreCycler - general method to execute something on all active cores
+ ******************************************************************************/
+TCoreCycler::TCoreCycler()
+	{
+	iCores = 0;
+	iG = 0;
+	}
+
+void TCoreCycler::Init()
+	{
+	CHECK_PRECONDITIONS(MASK_THREAD_STANDARD,"TCoreCycler::Init()");
+	TScheduler& s = TheScheduler;
+	NKern::ThreadEnterCS();
+	iG = NKern::LeaveGroup();
+	NThread* t = NKern::CurrentThread();
+	if (t->iCoreCycling)
+		{
+		__crash();
+		}
+	t->iCoreCycling = TRUE;
+
+	// Stop any cores powering up or down for now
+	// A core already on the way down will stop just before the transition to SHUTDOWN_FINAL
+	// A core already on the way up will carry on powering up
+	TInt irq = s.iGenIPILock.LockIrqSave();
+	++s.iCCDeferCount;	// stops bits in iIpiAcceptCpus being cleared, but doesn't stop them being set
+						// but iIpiAcceptCpus | s.iCpusComingUp is constant
+	TUint32 act2 = s.iIpiAcceptCpus;		// CPUs still accepting IPIs
+	TUint32 cu = s.iCpusComingUp;			// CPUs powering up
+	TUint32 gd = s.iCpusGoingDown;			// CPUs no longer accepting IPIs on the way down
+	s.iGenIPILock.UnlockIrqRestore(irq);
+	if (gd)
+		{
+		// wait for CPUs going down to reach INACTIVE state
+		TUint32 remain = gd;
+		FOREVER
+			{
+			TInt i;
+			for (i=0; i<KMaxCpus; ++i)
+				{
+				if (remain & (1u<<i))
+					{
+					// platform specific function returns TRUE when core has detached from SMP cluster
+					if (s.iSub[i]->Detached())
+						remain &= ~(1u<<i);	// core is now down
+					}
+				}
+			if (!remain)
+				break;		// all done
+			else
+				{
+				__snooze();	// snooze until cores have gone down
+				}
+			}
+		}
+	iCores = act2 | cu;
+	if (cu)
+		{
+		// wait for CPUs coming up to start accepting IPIs
+		while (iCores & ~s.iIpiAcceptCpus)
+			{
+			__snooze();	// snooze until cores have come up
+			}
+		}
+	iFrz = NKern::FreezeCpu();
+	if (iFrz)
+		__crash();	// already frozen so won't be able to migrate :-(
+	iInitialCpu = NKern::CurrentCpu();
+	iCurrentCpu = iInitialCpu;
+	iRemain = iCores;
+	}
+
+TInt TCoreCycler::Next()
+	{
+	NThread* t = NKern::CurrentThread();
+	if (iCores == 0)
+		{
+		Init();
+		return KErrNone;
+		}
+	if (NKern::CurrentCpu() != iCurrentCpu)
+		__crash();
+	iRemain &= ~(1u<<iCurrentCpu);
+	TInt nextCpu = iRemain ? __e32_find_ms1_32(iRemain) : iInitialCpu;
+	if (nextCpu != iCurrentCpu)
+		{
+		NKern::JumpTo(nextCpu);
+		iCurrentCpu = nextCpu;
+		if (NKern::CurrentCpu() != iCurrentCpu)
+			__crash();
+		}
+	if (iRemain)
+		{
+		return KErrNone;
+		}
+	NKern::EndFreezeCpu(iFrz);
+	iCores = 0;
+	TScheduler& s = TheScheduler;
+	s.CCUnDefer();
+	t->iCoreCycling = FALSE;
+	if (iG)
+		NKern::JoinGroup(iG);
+	NKern::ThreadLeaveCS();
+	return KErrEof;
+	}
--- a/kernel/eka/nkernsmp/nkern.mmp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/nkernsmp/nkern.mmp	Fri Apr 16 16:24:37 2010 +0300
@@ -16,7 +16,7 @@
 //
 
 sourcepath				../nkernsmp
-source					nkern.cpp nkerns.cpp sched.cpp dfcs.cpp nk_timer.cpp nk_irq.cpp
+source					nkern.cpp nkerns.cpp sched.cpp dfcs.cpp nk_timer.cpp nk_irq.cpp nk_bal.cpp
 
 #ifdef MARM
 sourcepath				../common/arm
--- a/kernel/eka/nkernsmp/nkerns.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/nkernsmp/nkerns.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -47,10 +47,15 @@
 	iReady = 0;
 	iCurrent = 0;
 	iLastCpu = 0;
-	iNSchedulableSpare1 = 0;
 	iPauseCount = 0;
 	iSuspended = 0;
-	iNSchedulableSpare2 = 0;
+	iACount = 0;
+	iPreferredCpu = 0;
+	iActiveState = 0;
+	i_NSchedulable_Spare2 = 0;
+	iTransientCpu = 0;
+	iForcedCpu = 0;
+	iLbState = ELbState_Inactive;
 	iCpuChange = 0;
 	iStopping = 0;
 	iFreezeCpu = 0;
@@ -58,14 +63,41 @@
 	iCpuAffinity = 0;
 	new (i_IDfcMem) TDfc(&DeferredReadyIDfcFn, this);
 	iEventState = 0;
-	iTotalCpuTime64 = 0;
+	iRunCount.i64 = 0;
+	iLastRunTime.i64 = 0;
+	iTotalCpuTime.i64 = 0;
+	iLastActivationTime.i64 = 0;
+	iTotalActiveTime.i64 = 0;
+	iSavedCpuTime.i64 = 0;
+	iSavedActiveTime.i64 = 0;
+	iLbLink.iNext = 0;
+	memclr(&iLbInfo, EMaxLbInfoSize);
 	}
 
+void NSchedulable::AddToEnumerateList()
+	{
+	TScheduler& s = TheScheduler;
+	SIterDQ& dq = iParent ? s.iAllThreads : s.iAllGroups;
+	NKern::Lock();
+	s.iEnumerateLock.LockOnly();
+	dq.Add(&iEnumerateLink);
+	TUint32 active = s.iThreadAcceptCpus;
+	TUint32 cpus = active & iCpuAffinity;
+	if (!cpus)
+		cpus = active;	// can't run on any currently active CPU, just pick an active one until it becomes ready
+	TInt ecpu = __e32_find_ls1_32(cpus);
+	iEventState = (ecpu<<EEventCpuShift) | (ecpu<<EThreadCpuShift);
+	s.iEnumerateLock.UnlockOnly();
+	NKern::Unlock();
+	}
+
+
 /******************************************************************************
  * NThreadGroup
  ******************************************************************************/
 NThreadGroup::NThreadGroup()
 	{
+	iACount = 1;
 	iParent = 0;
 	iThreadCount = 0;
 	new (&iSSpinLock) TSpinLock(TSpinLock::EOrderThreadGroup);
@@ -79,7 +111,10 @@
 EXPORT_C TInt NKern::GroupCreate(NThreadGroup* aGroup, SNThreadGroupCreateInfo& aInfo)
 	{
 	new (aGroup) NThreadGroup();
-	aGroup->iCpuAffinity = aInfo.iCpuAffinity;
+	aGroup->iDestructionDfc = aInfo.iDestructionDfc;
+	aGroup->iCpuAffinity = NSchedulable::PreprocessCpuAffinity(aInfo.iCpuAffinity);
+	aGroup->AddToEnumerateList();
+	aGroup->InitLbInfo();
 	return KErrNone;
 	}
 
@@ -98,6 +133,13 @@
 	{
 	NKern::ThreadEnterCS();
 	aGroup->DetachTiedEvents();
+	NKern::Lock();
+	aGroup->AcqSLock();
+	if (aGroup->iLbLink.iNext)
+		aGroup->LbUnlink();
+	aGroup->RelSLock();
+	aGroup->DropRef();
+	NKern::Unlock();
 	NKern::ThreadLeaveCS();
 	}
 
@@ -136,10 +178,10 @@
 	iWaitLink.iPriority = 0;
 	iBasePri = 0;
 	iMutexPri = 0;
-	i_NThread_Initial = 0;
+	iNominalPri = 0;
 	iLinkedObjType = EWaitNone;
 	i_ThrdAttr = 0;
-	iNThreadBaseSpare10 = 0;
+	i_NThread_Initial = 0;
 	iFastMutexDefer = 0;
 	iRequestSemaphore.iOwningThread = (NThreadBase*)this;
 	iTime = 0;
@@ -160,14 +202,15 @@
 	iStackSize = 0;
 	iExtraContext = 0;
 	iExtraContextSize = 0;
+	iCoreCycling = 0;
+	iRebalanceAttr = 0;
+	iNThreadBaseSpare4c = 0;
+	iNThreadBaseSpare4d = 0;
+	iNThreadBaseSpare5 = 0;
 	iNThreadBaseSpare6 = 0;
 	iNThreadBaseSpare7 = 0;
 	iNThreadBaseSpare8 = 0;
 	iNThreadBaseSpare9 = 0;
-
-	// KILL
-	iTag = 0;
-	iVemsData = 0;
 	}
 
 TInt NThreadBase::Create(SNThreadCreateInfo& aInfo, TBool aInitial)
@@ -185,7 +228,8 @@
 	iTime=iTimeslice;
 	iPriority=TUint8(aInfo.iPriority);
 	iBasePri=TUint8(aInfo.iPriority);
-	iCpuAffinity = aInfo.iCpuAffinity;
+	iNominalPri=TUint8(aInfo.iPriority);
+	iCpuAffinity = NSchedulable::PreprocessCpuAffinity(aInfo.iCpuAffinity);
 	iHandlers = aInfo.iHandlers ? aInfo.iHandlers : &NThread_Default_Handlers;
 	iFastExecTable=aInfo.iFastExecTable?aInfo.iFastExecTable:&DefaultFastExecTable;
 	iSlowExecTable=(aInfo.iSlowExecTable?aInfo.iSlowExecTable:&DefaultSlowExecTable)->iEntries;
@@ -198,8 +242,9 @@
 		iCurrent = iReady;
 		iCpuAffinity = iLastCpu;
 		iEventState = (iLastCpu<<EEventCpuShift) | (iLastCpu<<EThreadCpuShift);
-		ss.Add(this);
+		ss.SSAddEntry(this);
 		i_NThread_Initial = TRUE;
+		iACount = 1;
 		ss.iInitialThread = (NThread*)this;
 		NKern::Unlock();		// now that current thread is defined
 		}
@@ -207,16 +252,7 @@
 		{
 		iSuspendCount = 1;
 		iSuspended = 1;
-		TInt ecpu;
-		if (iCpuAffinity & NTHREADBASE_CPU_AFFINITY_MASK)
-			{
-			ecpu = __e32_find_ls1_32(iCpuAffinity);
-			if (ecpu >= TheScheduler.iNumCpus)
-				ecpu = 0;	// FIXME: Inactive CPU?
-			}
-		else
-			ecpu = iCpuAffinity;
-		iEventState = (ecpu<<EEventCpuShift) | (ecpu<<EThreadCpuShift);
+		iEventState = 0;
 		if (aInfo.iGroup)
 			{
 			NKern::Lock();
@@ -247,6 +283,19 @@
 	ExcFault(aContext);
 	}
 
+//
+// Destroy a thread before it has ever run
+// Must be called before first resumption of thread
+//
+void NThread::Stillborn()
+	{
+	__NK_ASSERT_ALWAYS(iACount==0);	// ensure thread has never been resumed
+	NKern::Lock();
+	RemoveFromEnumerateList();
+	NKern::Unlock();
+	}
+
+
 
 /** Create a nanothread.
 
@@ -270,8 +319,10 @@
 	return aThread->Create(aInfo,FALSE);
 	}
 
-// User-mode callbacks
 
+/******************************************************************************
+ * User-mode callbacks
+ ******************************************************************************/
 TUserModeCallback::TUserModeCallback(TUserModeCallbackFunc aFunc)
 	:	iNext(KUserModeCallbackUnqueued),
 		iFunc(aFunc)
@@ -329,6 +380,7 @@
 	NKern::Unlock();
 	}
 
+
 /** Initialise the null thread
 	@internalComponent
 */
@@ -478,3 +530,14 @@
 	return 0;
 #endif
 	}
+
+TDfcQue* TScheduler::RebalanceDfcQ()
+	{
+	return TheScheduler.iRebalanceDfcQ;
+	}
+
+NThread* TScheduler::LBThread()
+	{
+	return (NThread*)(TheScheduler.iRebalanceDfcQ->iThread);
+	}
+
--- a/kernel/eka/nkernsmp/sched.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/nkernsmp/sched.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -26,16 +26,41 @@
 
 TSpinLock	NEventHandler::TiedLock(TSpinLock::EOrderEventHandlerTied);
 
+
+const TUint8 KClassFromPriority[KNumPriorities] =
+	{
+	0,	0,	0,	0,	0,	0,	0,	0,				// priorities 0-7
+	0,	0,	0,	0,	1,	1,	1,	1,				// priorities 8-15
+	2,	2,	2,	2,	2,	2,	2,	2,				// priorities 16-23
+	2,	2,	2,	3,	3,	3,	3,	3,				// priorities 24-31
+	3,	3,	3,	3,	3,	3,	3,	3,				// priorities 32-39
+	3,	3,	3,	3,	3,	3,	3,	3,				// priorities 40-47
+	3,	3,	3,	3,	3,	3,	3,	3,				// priorities 48-55
+	3,	3,	3,	3,	3,	3,	3,	3				// priorities 56-63
+	};
+
+
 /******************************************************************************
  * TScheduler
  ******************************************************************************/
 
 // TScheduler resides in .bss so other fields are zero-initialised
 TScheduler::TScheduler()
-	:	iActiveCpus1(1),	// only boot CPU for now
-		iActiveCpus2(1),	// only boot CPU for now
+	:	iThreadAcceptCpus(1),	// only boot CPU for now
+		iIpiAcceptCpus(1),		// only boot CPU for now
+		iGenIPILock(TSpinLock::EOrderGenericIPIList),
+		iIdleBalanceLock(TSpinLock::EOrderEnumerate),
 		iIdleSpinLock(TSpinLock::EOrderIdleDFCList),
-		iCpusNotIdle(1)		// only boot CPU for now
+		iCpusNotIdle(1),	// only boot CPU for now
+		iEnumerateLock(TSpinLock::EOrderEnumerate),
+		iBalanceListLock(TSpinLock::EOrderReadyList),
+		iBalanceTimer(&BalanceTimerExpired, this, 1),
+		iCCSyncIDFC(&CCSyncDone, 0),
+		iCCReactivateDfc(&CCReactivateDfcFn, this, 3),
+		iCCRequestLevel(1),		// only boot CPU for now
+		iCCRequestDfc(&CCRequestDfcFn, this, 2),
+		iCCPowerDownDfc(&CCIndirectPowerDown, this, 0),
+		iCCIpiReactIDFC(&CCIpiReactivateFn, this)
 	{
 	TInt i;
 	for (i=0; i<KMaxCpus; ++i)
@@ -45,7 +70,10 @@
 		s->iScheduler = this;
 		s->iCpuNum = TUint32(i);
 		s->iCpuMask = 1u<<i;
+		s->iLbCounter = TUint8(NSchedulable::ELbState_PerCpu + i);
 		}
+	iLbCounter = (TUint8)NSchedulable::ELbState_Global;
+	iNeedBal = 1;	// stop anyone trying to kick rebalancer before it has been created
 	}
 
 
@@ -67,18 +95,75 @@
 
 // TSubScheduler resides in .bss so other fields are zero-initialised
 TSubScheduler::TSubScheduler()
-	:	TPriListBase(KNumPriorities),
-		iExIDfcLock(TSpinLock::EOrderExIDfcQ),
+	:	iExIDfcLock(TSpinLock::EOrderExIDfcQ),
 		iReadyListLock(TSpinLock::EOrderReadyList),
 		iKernLockCount(1),
 		iEventHandlerLock(TSpinLock::EOrderEventHandlerList)
 	{
 	}
 
+void TSubScheduler::SSAddEntry(NSchedulable* aEntry)
+	{
+	if (aEntry->iParent!=aEntry || !((NThreadBase*)aEntry)->i_NThread_Initial)
+		{
+		TInt c = KClassFromPriority[aEntry->iPriority];
+		++iPriClassThreadCount[c];
+		++iRdyThreadCount;
+		}
+	iSSList.Add(aEntry);
+	}
+
+void TSubScheduler::SSAddEntryHead(NSchedulable* aEntry)
+	{
+	if (aEntry->iParent!=aEntry || !((NThreadBase*)aEntry)->i_NThread_Initial)
+		{
+		TInt c = KClassFromPriority[aEntry->iPriority];
+		++iPriClassThreadCount[c];
+		++iRdyThreadCount;
+		}
+	iSSList.AddHead(aEntry);
+	}
+
+void TSubScheduler::SSRemoveEntry(NSchedulable* aEntry)
+	{
+	if (aEntry->iParent!=aEntry || !((NThreadBase*)aEntry)->i_NThread_Initial)
+		{
+		TInt c = KClassFromPriority[aEntry->iPriority];
+		--iPriClassThreadCount[c];
+		--iRdyThreadCount;
+		}
+	iSSList.Remove(aEntry);
+	}
+
+void TSubScheduler::SSChgEntryP(NSchedulable* aEntry, TInt aNewPriority)
+	{
+	if (aEntry->iParent!=aEntry || !((NThreadBase*)aEntry)->i_NThread_Initial)
+		{
+		TInt c0 = KClassFromPriority[aEntry->iPriority];
+		TInt c1 = KClassFromPriority[aNewPriority];
+		if (c0 != c1)
+			{
+			--iPriClassThreadCount[c0];
+			++iPriClassThreadCount[c1];
+			}
+		}
+	iSSList.ChangePriority(aEntry, aNewPriority);
+	}
+
 
 /******************************************************************************
  * NSchedulable
  ******************************************************************************/
+TUint32 NSchedulable::PreprocessCpuAffinity(TUint32 aAffinity)
+	{
+	if (!(aAffinity & NTHREADBASE_CPU_AFFINITY_MASK))
+		return aAffinity;
+	TUint32 x = aAffinity & ~NTHREADBASE_CPU_AFFINITY_MASK;
+	if (x & (x-1))
+		return aAffinity;
+	return __e32_find_ls1_32(x);
+	}
+
 void NSchedulable::AcqSLock()
 	{
 	iSSpinLock.LockOnly();
@@ -257,6 +342,87 @@
 		}
 	}
 
+
+/** Return the total CPU time so far used by the specified thread.
+
+	@return The total CPU time in units of 1/NKern::CpuTimeMeasFreq().
+*/
+EXPORT_C TUint64 NKern::ThreadCpuTime(NThread* aThread)
+	{
+	NSchedulable::SCpuStats stats;
+	NKern::Lock();
+	aThread->GetCpuStats(NSchedulable::E_RunTime, stats);
+	NKern::Unlock();
+	return stats.iRunTime;
+	}
+
+void NSchedulable::GetCpuStats(TUint aMask, NSchedulable::SCpuStats& aOut)
+	{
+	AcqSLock();
+	GetCpuStatsT(aMask, aOut);
+	RelSLock();
+	}
+
+void NSchedulable::GetCpuStatsT(TUint aMask, NSchedulable::SCpuStats& aOut)
+	{
+	TSubScheduler* ss = 0;
+	NThread* t = 0;
+	TBool initial = FALSE;
+	if (!IsGroup())
+		t = (NThread*)this;
+	if (t && t->i_NThread_Initial)
+		ss = &TheSubSchedulers[iLastCpu], initial = TRUE;
+	else if (iReady)
+		{
+		if (IsGroup())
+			ss = &TheSubSchedulers[iReady & NSchedulable::EReadyCpuMask];
+		else if (iParent->iReady)
+			ss = &TheSubSchedulers[iParent->iReady & NSchedulable::EReadyCpuMask];
+		}
+	if (ss)
+		ss->iReadyListLock.LockOnly();
+	TUint64 now = NKern::Timestamp();
+	if (aMask & (E_RunTime|E_RunTimeDelta))
+		{
+		aOut.iRunTime = iTotalCpuTime.i64;
+		if (iCurrent || (initial && !ss->iCurrentThread))
+			aOut.iRunTime += (now - ss->iLastTimestamp.i64);
+		if (aMask & E_RunTimeDelta)
+			{
+			aOut.iRunTimeDelta = aOut.iRunTime - iSavedCpuTime.i64;
+			iSavedCpuTime.i64 = aOut.iRunTime;
+			}
+		}
+	if (aMask & (E_ActiveTime|E_ActiveTimeDelta))
+		{
+		aOut.iActiveTime = iTotalActiveTime.i64;
+		if (iActiveState)
+			aOut.iActiveTime += (now - iLastActivationTime.i64);
+		if (aMask & E_ActiveTimeDelta)
+			{
+			aOut.iActiveTimeDelta = aOut.iActiveTime - iSavedActiveTime.i64;
+			iSavedActiveTime.i64 = aOut.iActiveTime;
+			}
+		}
+	if (aMask & E_LastRunTime)
+		{
+		if (iCurrent)
+			aOut.iLastRunTime = 0;
+		else
+			aOut.iLastRunTime = now - iLastRunTime.i64;
+		}
+	if (aMask & E_LastActiveTime)
+		{
+		if (iActiveState)
+			aOut.iLastActiveTime = 0;
+		else
+			aOut.iLastActiveTime = now - iLastRunTime.i64;
+		}
+	if (ss)
+		ss->iReadyListLock.UnlockOnly();
+	}
+
+
 /******************************************************************************
  * NThreadGroup
  ******************************************************************************/
@@ -281,12 +447,22 @@
 	CHECK_PRECONDITIONS(MASK_KERNEL_LOCKED|MASK_NOT_ISR,"NSchedulable::ReadyT");
 	__KTRACE_OPT(KNKERN,DEBUGPRINT("%T nReadyT(%x)",this,aMode));
 	NThreadBase* t = (NThreadBase*)this;
+	if (iParent && !iActiveState)
+		{
+		iActiveState=1;
+		iLastActivationTime.i64 = NKern::Timestamp();
+		if (iParent!=this && ++iParent->iActiveState==1)
+			iParent->iLastActivationTime.i64 = iLastActivationTime.i64;
+		}
 #ifdef _DEBUG
 	if (!iParent)
 		t = (NThreadBase*)0xface0fff;
 #endif
-	__NK_ASSERT_DEBUG(!iReady && (!iParent || (!t->iWaitState.iWtC.iWtStFlags && !t->iPauseCount && !t->iSuspended)));
+	__NK_ASSERT_DEBUG(!iReady && (!iParent || (!t->iWaitState.iWtC.iWtStFlags && !t->iSuspended)));
 	TSubScheduler& ss0 = SubScheduler();
+	TScheduler& s = TheScheduler;
+	TBool reactivate = FALSE;
+	TBool no_ipi = FALSE;
 	NSchedulable* g = this;
 	if (iParent != this && iParent)
 		{
@@ -301,7 +477,9 @@
 			ss.iReadyListLock.LockOnly();
 			TInt hp = ss.HighestPriority();
 			if (iPriority>gp)
-				ss.ChangePriority(tg, iPriority);
+				{
+				ss.SSChgEntryP(tg, iPriority);
+				}
 			if (iPriority>hp || (iPriority==hp && ss.iCurrentThread && ss.iCurrentThread->iTime==0))
 				{
 				if (&ss == &ss0)
@@ -309,84 +487,178 @@
 				else
 					ss0.iReschedIPIs |= ss.iCpuMask;	// will kick the other CPU when this CPU reenables preemption
 				}
-			if ((aMode & ENewTimeslice) && t->iTime==0 && (iNext!=this || ss.iQueue[iPriority]))
+			if ((aMode & ENewTimeslice) && t->iTime==0 && (iNext!=this || ss.EntryAtPriority(iPriority)) )
 				t->iTime = t->iTimeslice;
 			ss.iReadyListLock.UnlockOnly();
+
+			ss0.iMadeReadyCounter++;
 			return;
 			}
 		tg->iNThreadList.Add(this);
 		tg->iPriority = iPriority;	// first in group
 		g = tg;						// fall through to add group to subscheduler
 		}
+	TInt priClass = -1;
 	TInt cpu = -1;
+	TUint32 active = TheScheduler.iThreadAcceptCpus;
+	if (g!=t || !t->i_NThread_Initial)
+		priClass = KClassFromPriority[g->iPriority];
+	if (g->iForcedCpu)
+		{
+		cpu = iForcedCpu & EReadyCpuMask;	// handles core cycling case (No.1 below)
+		if (active & (1u<<cpu))
+			goto cpu_ok;
+		else
+			goto single_cpu_reactivate;
+		}
 	if (aMode & EUnPause)
 		{
 		cpu = (g->iEventState & EThreadCpuMask)>>EThreadCpuShift;
 		if (CheckCpuAgainstAffinity(cpu, g->iCpuAffinity))
 			goto cpu_ok;
+		cpu = -1;
 		}
-	else if (g->iFreezeCpu)
+	if (g->iFreezeCpu)
 		{
 		cpu = g->iLastCpu;
-		if (!CheckCpuAgainstAffinity(cpu, g->iCpuAffinity))
-			g->iCpuChange = TRUE;
+		goto cpu_ok;
 		}
-	else if (!(g->iCpuAffinity & NTHREADBASE_CPU_AFFINITY_MASK))
+	if (!(g->iCpuAffinity & NTHREADBASE_CPU_AFFINITY_MASK))
+		{
 		cpu = g->iCpuAffinity;
-	else if ((aMode & EPreferSameCpu) && (g->iCpuAffinity & ss0.iCpuMask))
+		if (!(active & (1u<<cpu)))
+			goto single_cpu_reactivate;
+		goto cpu_ok;
+		}
+	if ((aMode & EPreferSameCpu) && CheckCpuAgainstAffinity(ss0.iCpuNum, g->iCpuAffinity, active))
 		cpu = ss0.iCpuNum;
+	else if (iTransientCpu && CheckCpuAgainstAffinity(iTransientCpu & EReadyCpuMask, g->iCpuAffinity))
+		cpu = iTransientCpu & EReadyCpuMask;
+	else if (iPreferredCpu && CheckCpuAgainstAffinity(iPreferredCpu & EReadyCpuMask, g->iCpuAffinity, active))
+		cpu = iPreferredCpu & EReadyCpuMask;
 	if (cpu < 0)
 		{
 		// pick a cpu
-		TScheduler& s = TheScheduler;
-		TUint32 m = g->iCpuAffinity & s.iActiveCpus1;
-		TInt i;
-		TInt lowest_p = KMaxTInt;
-		for (i=0; i<s.iNumCpus; ++i)
-			{
-			TSubScheduler& ss = *s.iSub[i];
-			if (!(m & ss.iCpuMask))
-				continue;
-			TInt hp = ss.HighestPriority();
-			if (hp < lowest_p)
+		TUint32 m = g->iCpuAffinity & active;
+		TInt lastCpu = g->iLastCpu;
+		TInt i = lastCpu;
+		TInt lcp = KMaxTInt;
+		TInt lco = KMaxTInt;
+		TInt cpunp = -1;
+		TInt idle_cpu = -1;
+		do	{
+			if (m & (1u<<i))
 				{
-				lowest_p = hp;
-				cpu = i;
-				continue;
+				TSubScheduler& ss = *s.iSub[i];
+				TInt nInC = ss.iPriClassThreadCount[priClass];
+				if (nInC < lco)
+					lco=nInC, cpunp=i;
+				TInt hp = ss.HighestPriority();
+				if (idle_cpu<0 && hp<=0)
+					idle_cpu = i;
+				if (hp < iPriority)
+					{
+					if (i == lastCpu)
+						{
+						cpu = i;
+						if (hp <= 0)
+							break;
+						lcp = -1;
+						}
+					if (nInC < lcp)
+						lcp=nInC, cpu=i;
+					}
 				}
-			if (hp > lowest_p)
-				continue;
-			if (cpu>=0 && g->iLastCpu!=i)
-				continue;
-			lowest_p = hp;
-			cpu = i;
+			if (++i == s.iNumCpus)
+				i = 0;
+			} while (i != lastCpu);
+		if (idle_cpu>=0 && cpu!=idle_cpu)
+			cpu = idle_cpu;
+		else if (cpu<0)
+			cpu = cpunp;
+		}
+	if (cpu<0)
+		{
+single_cpu_reactivate:
+		/*	CORE_CONTROL
+			Might have no CPU at this point due to all CPUs specified by
+			iCpuAffinity being off or in the process of shutting down.
+			There are three possibilities:
+			1.	This thread is 'core cycling'. In that case it will be
+				allowed to move to a 'shutting down' CPU. The CPU will
+				not be permitted to shut down entirely until all core cycling
+				has completed. This is already handled above.
+			2.	There are one or more CPUs which this thread could run on which
+				are shutting down. In that case, pick one, abort the shutdown
+				process and put this thread on it.
+			3.	All CPUs which this thread can run on are off. In that case,
+				assign the thread to one of them and initiate power up of that core.
+		*/
+		TUint32 affm = AffinityToMask(g->iCpuAffinity);
+		TInt irq = s.iGenIPILock.LockIrqSave();
+		if (cpu < 0)
+			{
+			if (affm & s.iCCReactivateCpus)
+				cpu = __e32_find_ls1_32(affm & s.iCCReactivateCpus);
+			else if (affm & s.iIpiAcceptCpus)
+				cpu = __e32_find_ls1_32(affm & s.iIpiAcceptCpus);
+			else
+				cpu = __e32_find_ls1_32(affm), no_ipi = TRUE;
 			}
+		TUint32 cm = 1u<<cpu;
+		if (!((s.iCCReactivateCpus|s.iThreadAcceptCpus) & cm))
+			{
+			s.iCCReactivateCpus |= (1u<<cpu);
+			reactivate = TRUE;
+			}
+		s.iGenIPILock.UnlockIrqRestore(irq);
 		}
 cpu_ok:
 	__NK_ASSERT_ALWAYS(cpu>=0);
+	if (g->iFreezeCpu && !CheckCpuAgainstAffinity(cpu, g->iCpuAffinity))
+		g->iCpuChange = TRUE;
 	if (g->TiedEventReadyInterlock(cpu))
 		{
 		__KTRACE_OPT(KSCHED2,DEBUGPRINT("ReadyT->CPU %dD",cpu));
 		++g->iPauseCount;
-//		((TDfc*)g->i_IDfcMem)->Add();
-		return;
 		}
-	__KTRACE_OPT(KSCHED2,DEBUGPRINT("ReadyT->CPU %d",cpu));
-	TSubScheduler& ss = TheSubSchedulers[cpu];
-	ss.iReadyListLock.LockOnly();
-	TInt hp = ss.HighestPriority();
-	if (g->iPriority>hp || (g->iPriority==hp && ss.iCurrentThread && ss.iCurrentThread->iTime==0))
+	else
 		{
-		if (&ss == &ss0)
-			RescheduleNeeded();					// reschedule on this processor
-		else
-			ss0.iReschedIPIs |= ss.iCpuMask;	// will kick the other CPU when this CPU reenables preemption
+		__KTRACE_OPT(KSCHED2,DEBUGPRINT("ReadyT->CPU %d",cpu));
+		TSubScheduler& ss = TheSubSchedulers[cpu];
+		ss.iReadyListLock.LockOnly();
+		TInt hp = ss.HighestPriority();
+		if (g->iPriority>hp || (g->iPriority==hp && ss.iCurrentThread && ss.iCurrentThread->iTime==0))
+			{
+			if (&ss == &ss0)
+				RescheduleNeeded();					// reschedule on this processor
+			else if (!no_ipi)
+				ss0.iReschedIPIs |= ss.iCpuMask;	// will kick the other CPU when this CPU reenables preemption
+			}
+		ss.SSAddEntry(g);
+		g->iReady = TUint8(cpu | EReadyOffset);
+		if ((aMode & ENewTimeslice) && iParent && t->iTime==0 && g->iNext!=g)
+			t->iTime = t->iTimeslice;
+		if (!g->iLbLink.iNext && !(g->iParent && t->i_NThread_Initial))
+			{
+			ss.iLbQ.Add(&g->iLbLink);
+			g->iLbState = ss.iLbCounter;
+			if (!s.iNeedBal && (!g->iParent || !(t->iRebalanceAttr & 1)))
+				{
+				s.iNeedBal = 1;
+				reactivate = TRUE;
+				}
+			}
+		if (g->iForcedCpu == g->iReady)
+			{
+			g->iLastCpu = (TUint8)cpu;
+			g->iForcedCpu = 0;	// iForcedCpu has done its job - iFreezeCpu will keep the thread on the right CPU
+			}
+		ss.iReadyListLock.UnlockOnly();
+		ss0.iMadeReadyCounter++;
 		}
-	ss.Add(g);
-	g->iReady = TUint8(cpu | EReadyOffset);
-	if ((aMode & ENewTimeslice) && iParent && t->iTime==0 && g->iNext!=g)
-		t->iTime = t->iTimeslice;
-	ss.iReadyListLock.UnlockOnly();
+	if (reactivate)
+		s.iCCReactivateDfc.Add();
 	}
 
 
@@ -420,6 +692,7 @@
 		if (ot->iTime==0 || pfmd)
 			{
 			// ot's timeslice has expired
+			ot->iParent->iTransientCpu = 0;
 			fmd_res = ot->CheckFastMutexDefer();
 			fmd_done = TRUE;
 			if (fmd_res)
@@ -448,12 +721,21 @@
 		TInt wtst = ot->iWaitState.DoWait();
 		if (wtst>=0 && wtst!=NThread::EWaitFastMutex)
 			ot->iTime = ot->iTimeslice;
+		if (wtst==KErrDied || ot->iSuspended || (!(ot->iWaitState.iWtC.iWtStFlags & NThreadWaitState::EWtStObstructed) && wtst>=0) )
+			{
+			ot->iActiveState = 0;
+			ot->iParent->iTransientCpu = 0;
+			if (ot->iParent != ot)
+				--ot->iParent->iActiveState;
+			}
 		ot->UnReadyT();
 		if (ot->iNewParent)
 			{
 			ot->iParent = ot->iNewParent, ++((NThreadGroup*)ot->iParent)->iThreadCount;
 			wmb();	// must make sure iParent is updated before iNewParent is cleared
 			ot->iNewParent = 0;
+			if (ot->iActiveState && ++ot->iParent->iActiveState==1)
+				ot->iParent->iLastActivationTime.i64 = NKern::Timestamp();
 			}
 		ot->iCpuChange = FALSE;
 		}
@@ -467,41 +749,53 @@
 		++((NThreadGroup*)ot->iParent)->iThreadCount;
 		wmb();	// must make sure iParent is updated before iNewParent is cleared
 		ot->iNewParent = 0;
+		TUint64 now = NKern::Timestamp();
+		if (!ot->iParent->iCurrent)
+			ot->iParent->iLastStartTime.i64 = now;
+		if (++ot->iParent->iActiveState==1)
+			ot->iParent->iLastActivationTime.i64 = now;
 		}
-	else if (ot->iParent->iCpuChange && !ot->iParent->iFreezeCpu)
+	else if (ot->iParent->iCpuChange)
 		{
-		if (!CheckCpuAgainstAffinity(iCpuNum, ot->iParent->iCpuAffinity))
+		if (ot->iForcedCpu)
+			migrate = TRUE;
+		else if (!ot->iParent->iFreezeCpu)
 			{
-			if (ot->iParent==ot)
+			if (ot->iParent->ShouldMigrate(iCpuNum))
 				{
-				if (!fmd_done)
-					fmd_res = ot->CheckFastMutexDefer(), fmd_done = TRUE;
-				if (!fmd_res)
+				if (ot->iParent==ot)
 					{
-					__KTRACE_OPT(KSCHED2,DEBUGPRINT("Rschd<-%T A:%08x",ot,ot->iParent->iCpuAffinity));
-					ot->UnReadyT();
-					migrate = TRUE;
-					ot->iCpuChange = FALSE;
+					if (!fmd_done)
+						fmd_res = ot->CheckFastMutexDefer(), fmd_done = TRUE;
+					if (!fmd_res)
+						migrate = TRUE;
 					}
+				else
+					gmigrate = TRUE;
 				}
 			else
 				{
-				__KTRACE_OPT(KSCHED2,DEBUGPRINT("Rschd<-%T GA:%08x",ot,ot->iParent->iCpuAffinity));
-				Remove(ot->iParent);
-				ot->iParent->iReady = 0;
-				gmigrate = TRUE;
 				ot->iCpuChange = FALSE;
 				ot->iParent->iCpuChange = FALSE;
 				}
 			}
-		else
+		if (migrate)
 			{
+			__KTRACE_OPT(KSCHED2,DEBUGPRINT("Rschd<-%T A:%08x",ot,ot->iParent->iCpuAffinity));
+			ot->UnReadyT();
+			ot->iCpuChange = FALSE;
+			}
+		else if (gmigrate)
+			{
+			__KTRACE_OPT(KSCHED2,DEBUGPRINT("Rschd<-%T GA:%08x",ot,ot->iParent->iCpuAffinity));
+			SSRemoveEntry(ot->iParent);
+			ot->iParent->iReady = 0;
 			ot->iCpuChange = FALSE;
 			ot->iParent->iCpuChange = FALSE;
 			}
 		}
 no_ot:
-	NSchedulable* g = (NSchedulable*)First();
+	NSchedulable* g = (NSchedulable*)iSSList.First();
 	TBool rrcg = FALSE;
 	if (g && g->IsGroup())
 		{
@@ -515,17 +809,20 @@
 	if (t && t->iTime==0 && (rrcg || rrct))
 		{
 		// candidate thread's timeslice has expired and there is another at the same priority
+
+		iTimeSliceExpireCounter++; // update metric
+		
 		if (t==ot)
 			{
 			if (ot->iParent!=ot)
 				{
 				((NThreadGroup*)ot->iParent)->iNThreadList.iQueue[ot->iPriority] = ot->iNext;
-				iQueue[ot->iParent->iPriority] = ot->iParent->iNext;
+				iSSList.iQueue[ot->iParent->iPriority] = ot->iParent->iNext;
 				}
 			else
-				iQueue[ot->iPriority] = ot->iNext;
+				iSSList.iQueue[ot->iPriority] = ot->iNext;
 			ot->iTime = ot->iTimeslice;
-			NSchedulable* g2 = (NSchedulable*)First();
+			NSchedulable* g2 = (NSchedulable*)iSSList.First();
 			if (g2->IsGroup())
 				t = (NThread*)((NThreadGroup*)g2)->iNThreadList.First();
 			else
@@ -540,14 +837,6 @@
 				{
 				__KTRACE_OPT(KSCHED2,DEBUGPRINT("Rschd<-%T RR",ot));
 				}
-/*			if (ot->iCpuAffinity & NTHREADBASE_CPU_AFFINITY_MASK)
-				{
-				ot->UnReadyT();
-				migrate = TRUE;
-				}
-			else
-				ot->iTime = ot->iTimeslice;
-*/
 			}
 		else	// loop again since we need to lock t before round robining it
 			{
@@ -580,17 +869,105 @@
 		ot->iParent->ReadyT(0);	// new timeslice if it's queued behind another thread at same priority
 	if (ot)
 		{
+		TBool dead = ot->iWaitState.ThreadIsDead();
+		if (dead && ot->iLbLink.iNext)
+			ot->LbUnlink();
 		ot->RelSLock();
 
 		// DFC to signal thread is now dead
-		if (ot->iWaitState.ThreadIsDead() && ot->iWaitState.iWtC.iKillDfc)
+		if (dead && ot->iWaitState.iWtC.iKillDfc && __e32_atomic_tau_ord8(&ot->iACount, 1, 0xff, 0)==1)
+			{
+			ot->RemoveFromEnumerateList();
 			ot->iWaitState.iWtC.iKillDfc->DoEnque();
+			}
+		}
+	if (iCCSyncPending)
+		{
+		iCCSyncPending = 0;
+		iReschedIPIs |= 0x80000000u;		// update iCCSyncCpus when kernel is finally unlocked
 		}
 	__KTRACE_OPT(KSCHED,DEBUGPRINT("Rschd->%T",t));
 	__NK_ASSERT_ALWAYS(!t || t->iParent);	// must be a thread not a group
 	return t;	// could return NULL
 	}
 
+void NSchedulable::LbUnlink()
+	{
+	if (iLbState & ELbState_PerCpu)
+		{
+		TSubScheduler* ss = &TheSubSchedulers[iLbState & ELbState_CpuMask];
+		ss->iReadyListLock.LockOnly();
+		if (iLbState == ss->iLbCounter)
+			{
+			iLbLink.Deque();
+			iLbLink.iNext = 0;
+			iLbState = ELbState_Inactive;
+			}
+		ss->iReadyListLock.UnlockOnly();
+		}
+	else if ((iLbState & ELbState_CpuMask) == ELbState_Global)
+		{
+		TScheduler& s = TheScheduler;
+		s.iBalanceListLock.LockOnly();
+		if (iLbState == s.iLbCounter)
+			{
+			iLbLink.Deque();
+			iLbLink.iNext = 0;
+			iLbState = ELbState_Inactive;
+			}
+		s.iBalanceListLock.UnlockOnly();
+		}
+	if (iLbState != ELbState_Inactive)
+		{
+		// load balancer is running so we can't dequeue the thread
+		iLbState |= ELbState_ExtraRef;				// indicates extra ref has been taken
+		__e32_atomic_tau_ord8(&iACount, 1, 1, 0);	// extra ref will be removed by load balancer
+		}
+	}
+
+TBool NSchedulable::TakeRef()
+	{
+	return __e32_atomic_tau_ord8(&iACount, 1, 1, 0);
+	}
+
+TBool NSchedulable::DropRef()
+	{
+	if (__e32_atomic_tau_ord8(&iACount, 1, 0xff, 0)!=1)
+		return EFalse;
+	TDfc* d = 0;
+	AcqSLock();
+	if (iParent)
+		{
+		// it's a thread
+		NThreadBase* t = (NThreadBase*)this;
+		if (t->iWaitState.ThreadIsDead() && t->iWaitState.iWtC.iKillDfc)
+			d = t->iWaitState.iWtC.iKillDfc;
+		RelSLock();
+		t->RemoveFromEnumerateList();
+		}
+	else
+		{
+		NThreadGroup* g = (NThreadGroup*)this;
+		d = g->iDestructionDfc;
+		RelSLock();
+		g->RemoveFromEnumerateList();
+		}
+	if (d)
+		d->DoEnque();
+	return ETrue;
+	}
+
+void NSchedulable::RemoveFromEnumerateList()
+	{
+	TScheduler& s = TheScheduler;
+	s.iEnumerateLock.LockOnly();
+	if (iEnumerateLink.Next())
+		{
+		iEnumerateLink.Deque();
+		iEnumerateLink.SetNext(0);
+		}
+	s.iEnumerateLock.UnlockOnly();
+	}
 
 void NThreadBase::UnReadyT()
 	{
@@ -604,24 +981,25 @@
 			TSubScheduler& ss = TheSubSchedulers[g.iReady & EReadyCpuMask];
 			if (l.IsEmpty())
 				{
-//				__KTRACE_OPT(KNKERN,DEBUGPRINT("%T UnReadyT (G=%G-)",this,&g));
-				ss.Remove(&g);
+				ss.SSRemoveEntry(&g);
 				g.iReady = 0;
 				g.iPriority = 0;
 				}
 			else
 				{
-//				__KTRACE_OPT(KNKERN,DEBUGPRINT("%T UnReadyT (G=%G)",this,&g));
-				ss.ChangePriority(&g, l.HighestPriority());
+				TInt np = l.HighestPriority();
+				ss.SSChgEntryP(&g, np);
 				}
 			}
 		}
 	else
 		{
-//		__KTRACE_OPT(KNKERN,DEBUGPRINT("%T UnReadyT",this));
-		TheSubSchedulers[iReady & EReadyCpuMask].Remove(this);
+		TSubScheduler& ss = TheSubSchedulers[iReady & EReadyCpuMask];
+		ss.SSRemoveEntry(this);
 		}
 	iReady = 0;
+
+	SubScheduler().iMadeUnReadyCounter++;
 	}
 
 
@@ -646,11 +1024,11 @@
 			{
 			TInt ngp = tg->iNThreadList.HighestPriority();
 			if (ngp!=tg->iPriority)
-				ss->ChangePriority(tg, ngp);
+				ss->SSChgEntryP(tg, ngp);
 			}
 		}
 	else
-		ss->ChangePriority(this, newp);
+		ss->SSChgEntryP(this, newp);
 	if (iCurrent)	// can't be current if parent not ready
 		{
 		TInt nhp = ss->HighestPriority();
@@ -696,9 +1074,9 @@
 	{
 	CHECK_PRECONDITIONS(MASK_KERNEL_LOCKED|MASK_NOT_IDFC|MASK_NOT_ISR,"NThreadBase::SetPriority");
 	AcqSLock();
-	__KTRACE_OPT(KNKERN,DEBUGPRINT("%T nSetPri %d(%d)->%d(%d)",this,iPriority,iBasePri,newp,iMutexPri));
+	__KTRACE_OPT(KNKERN,DEBUGPRINT("%T nSetPri(%d) PBNM[%d,%d,%d,%d]",this,newp,iPriority,iBasePri,iNominalPri,iMutexPri));
 	iBasePri = TUint8(newp);
-	if (iMutexPri > iBasePri)
+	if (iMutexPri > newp)
 		newp = iMutexPri;
 	TInt oldp = iPriority;
 	if (newp == oldp)
@@ -759,6 +1137,17 @@
 		}
 	}
 
+void NThreadBase::SetNominalPriority(TInt newp)
+	{
+	CHECK_PRECONDITIONS(MASK_KERNEL_LOCKED|MASK_NOT_IDFC|MASK_NOT_ISR,"NThreadBase::SetNominalPriority");
+	AcqSLock();
+	__KTRACE_OPT(KNKERN,DEBUGPRINT("%T nSetNPr(%d) PBNM[%d,%d,%d,%d]",this,newp,iPriority,iBasePri,iNominalPri,iMutexPri));
+	iNominalPri = TUint8(newp);
+	NominalPriorityChanged();
+	RelSLock();
+	}
+
+
 
 /** Set the inherited priority of a nanokernel thread.
 
@@ -815,9 +1204,160 @@
 		}
 	if (newp <= ss->HighestPriority())
 		RescheduleNeeded();
-	ss->ChangePriority(g, newp);
+	ss->SSChgEntryP(g, newp);
 out:
 	ss->iReadyListLock.UnlockOnly();
 	}
 
 
+/******************************************************************************
+ * Pull threads on idle
+ ******************************************************************************/
+
+const TInt KMaxTries = 4;
+
+struct SIdlePullThread
+	{
+	SIdlePullThread();
+	void Finish(TBool aDone);
+
+	NSchedulable*	iS;
+	TInt			iPri;
+	NSchedulable*	iOld[KMaxCpus];
+	};
+
+SIdlePullThread::SIdlePullThread()
+	{
+	iS = 0;
+	iPri = 0;
+	TInt i;
+	for (i=0; i<KMaxCpus; ++i)
+		iOld[i] = 0;
+	}
+
+void SIdlePullThread::Finish(TBool aComplete)
+	{
+	if (aComplete && iS)
+		{
+		iS->AcqSLock();
+		iS->SetCpuAffinityT(NKern::CurrentCpu() | KCpuAffinityTransient);
+		iS->RelSLock();
+		}
+	if (iS)
+		iS->DropRef();
+	TInt i;
+	for (i=0; i<KMaxCpus; ++i)
+		if (iOld[i])
+			iOld[i]->DropRef();
+	}
+
+void TSubScheduler::IdlePullSearch(SIdlePullThread& a, TSubScheduler* aDest)
+	{
+	NSchedulable* orig = a.iS;
+	TInt dcpu = aDest->iCpuNum;
+	volatile TUint32& flags = *(volatile TUint32*)&aDest->iRescheduleNeededFlag;
+	iReadyListLock.LockOnly();
+	if (iRdyThreadCount>1)	// if there's only 1 it'll be running so leave it alone
+		{
+		TUint64 pres = iSSList.iPresent64;
+		TInt tries = iRdyThreadCount;
+		if (tries > KMaxTries)
+			tries = KMaxTries;
+		NSchedulable* q = 0;
+		NSchedulable* p = 0;
+		TInt pri = -1;
+		for (; tries>0 && !flags; --tries)
+			{
+			if (p)
+				{
+				p = (NSchedulable*)(p->iNext);
+				if (p == q)
+					pri = -1;
+				}
+			if (pri<0)
+				{
+				pri = __e32_find_ms1_64(pres);
+				if (pri < 0)
+					break;
+				pres &= ~(TUint64(1)<<pri);
+				q = (NSchedulable*)iSSList.iQueue[pri];
+				p = q;
+				}
+			NThreadBase* t = 0;
+			if (p->iParent)
+				t = (NThreadBase*)p;
+			if (p->iCurrent)
+				continue;	// running on other CPU so leave it alone
+			if (p->iFreezeCpu)
+				continue;	// can't run on this CPU - frozen to current CPU
+			if (t && t->iCoreCycling)
+				continue;	// currently cycling through cores so leave alone
+			if (t && t->iHeldFastMutex && t->iLinkedObjType==NThreadBase::EWaitNone)
+				continue;	// can't run on this CPU - fast mutex held
+			if (p->iCpuChange)
+				continue;	// already being migrated so leave it alone
+			if (!CheckCpuAgainstAffinity(dcpu, p->iCpuAffinity))
+				continue;	// can't run on this CPU - hard affinity
+			if (p->iPreferredCpu & NSchedulable::EReadyCpuSticky)
+				continue;	// don't want to move it on idle, only on periodic balance
+			if (pri > a.iPri)
+				{
+				if (p->TakeRef())
+					{
+					a.iS = p;
+					a.iPri = pri;
+					break;
+					}
+				}
+			}
+		}
+	iReadyListLock.UnlockOnly();
+	if (orig && orig!=a.iS)
+		a.iOld[iCpuNum] = orig;
+	}
+
+void NKern::Idle()
+	{
+	TScheduler& s = TheScheduler;
+	TSubScheduler& ss0 = SubScheduler();	// OK since idle thread locked to CPU
+	ss0.iCurrentThread->iSavedSP = 0;		// will become nonzero if a reschedule occurs
+	TUint32 m0 = ss0.iCpuMask;
+	volatile TUint32& flags = *(volatile TUint32*)&ss0.iRescheduleNeededFlag;
+	if (s.iThreadAcceptCpus & m0)			// if this CPU is shutting down, don't try to pull threads
+		{
+		SIdlePullThread ipt;
+		NKern::Lock();
+		s.iIdleBalanceLock.LockOnly();
+		TUint32 active = s.iThreadAcceptCpus;
+		TUint32 srchm = active &~ m0;
+		if (srchm && srchm!=active)
+			{
+			TUint32 randomizer = *(volatile TUint32*)&s.iIdleBalanceLock;
+			TInt nact = __e32_bit_count_32(srchm);
+			while (srchm)
+				{
+				TUint32 srchm2 = srchm;
+				if (nact > 1)
+					{
+					randomizer = 69069*randomizer+41;
+					TUint32 lose = randomizer % TUint32(nact);
+					for (; lose; --lose)
+						srchm2 = srchm2 & (srchm2-1);
+					}
+				TInt cpu = __e32_find_ls1_32(srchm2);
+				TSubScheduler* ss = &TheSubSchedulers[cpu];
+				ss->IdlePullSearch(ipt, &ss0);
+				if (flags)
+					break;
+				srchm &= ~(1u<<cpu);
+				--nact;
+				}
+			}
+		s.iIdleBalanceLock.UnlockOnly();
+		ipt.Finish(!srchm);
+		NKern::Unlock();
+		}
+	DoIdle();
+	}
+
+
--- a/kernel/eka/nkernsmp/x86/nccpu.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/nkernsmp/x86/nccpu.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -191,7 +191,9 @@
 	__e32_io_completion_barrier();
 	a.iBPTimestamp = X86::Timestamp();
 	__e32_io_completion_barrier();
-	while (a.iBootFlag2==2)
+	a.iBootFlag2 = 3;
+	__e32_io_completion_barrier();
+	while (a.iBootFlag2==3)
 		{}
 	__e32_io_completion_barrier();
 	NKern::EnableAllInterrupts();
@@ -199,8 +201,16 @@
 	return KErrNone;
 	}
 
-void InitAPTimestamp(SNThreadCreateInfo&)
+void InitTimestamp(TSubScheduler* aSS, SNThreadCreateInfo& aInfo)
 	{
+	NThread* t = (NThread*)aSS->iCurrentThread;
+	t->iActiveState = 1;
+	if (aSS->iCpuNum == 0)
+		{
+		aSS->iLastTimestamp.i64 = 0;
+		t->iLastActivationTime.i64 = 0;
+		return;
+		}
 	volatile SApInitInfo& a = *(volatile SApInitInfo*)KApBootPage;
 	NKern::DisableAllInterrupts();
 	a.iBootFlag2 = 1;
@@ -210,16 +220,20 @@
 	__e32_io_completion_barrier();
 	a.iAPTimestamp = X86::Timestamp();
 	__e32_io_completion_barrier();
+	while (a.iBootFlag2!=3)
+		{}
+	__e32_io_completion_barrier();
 	TUint64 bpt = a.iBPTimestamp;
 	TUint64 apt = a.iAPTimestamp;
 	TUint64 delta = bpt - apt;
-	TSubScheduler& ss = SubScheduler();
-	ss.iLastTimestamp64 += delta;
-	*(TUint64*)&ss.i_TimestampOffset = delta;
+	aSS->iSSX.iTimestampOffset.i64 = delta;
+	TUint64 now = NKern::Timestamp();
 	__KTRACE_OPT(KBOOT,DEBUGPRINT("APT=0x%lx BPT=0x%lx Delta=0x%lx", apt, bpt, delta));
 	__e32_io_completion_barrier();
-	a.iBootFlag2 = 3;
+	a.iBootFlag2 = 4;
 	NKern::EnableAllInterrupts();
+	t->iLastActivationTime.i64 = now;
+	aSS->iLastTimestamp.i64 = now;
 	}
 
 
--- a/kernel/eka/nkernsmp/x86/ncmonitor.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/nkernsmp/x86/ncmonitor.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -12,7 +12,7 @@
 //
 // Description:
 // e32\nkernsmp\x86\ncmonitor.cpp
-// Kernel crash debugger - NKERN X86 specific portion
+// Kernel crash debugger - NKERNSMP X86 specific portion
 // 
 //
 
@@ -23,128 +23,38 @@
 #include <kernel/monitor.h>
 
 
-void Monitor::DisplaySpinLock(const char* aTitle, TSpinLock* aLock)
+void DisplayNThreadStackedRegs(Monitor& m, SThreadReschedStack& reg)
 	{
-	volatile TUint32* p = (volatile TUint32*)aLock;
-	Printf("%s %08x %08x\r\n", aTitle, p[0], p[1]);
-	}
-
-EXPORT_C void Monitor::DisplayNThreadInfo(NThread* aT)
-	{
-	DisplayNSchedulableInfo(aT);
+	m.Printf("CR0 %08x  RsF %08x  EIP %08x  RSN %08x\r\n", reg.iCR0, reg.iReschedFlag, reg.iEip, reg.iReason);
 	}
 
-void Monitor::DisplayNSchedulableInfo(NSchedulable* aS)
+void DisplaySubSchedulerExt(Monitor& m, TSubScheduler& ss)
 	{
-	NThread* t = aS->iParent ? (NThread*)aS : 0;
-	NThreadGroup* g = aS->iParent ? 0 : (NThreadGroup*)aS;
-
-	if (t && aS->iParent==aS)
-		Printf("NThread @%08x Pri %d\r\n",aS,aS->iPriority);
-	else if (t)
-		Printf("NThread @%08x (G:%08x) Pri %d\r\n",aS,aS->iParent,aS->iPriority);
-	else
-		Printf("NThreadGroup @%08x Pri %d\r\n",aS,aS->iPriority);
-	Printf("Rdy=%02x Curr=%02x LastCpu=%d CpuChg=%02x FrzCpu=%d\r\n", aS->iReady, aS->iCurrent, aS->iLastCpu, aS->iCpuChange, aS->iFreezeCpu);
-	Printf("Next=%08x Prev=%08x Parent=%08x CPUaff=%08x\r\n", aS->iNext, aS->iPrev, aS->iParent, aS->iCpuAffinity);
-	Printf("PauseCount %02x Susp %1x\r\n", aS->iPauseCount, aS->iSuspended);
-	DisplaySpinLock("SpinLock", &aS->iSSpinLock);
-	Printf("Stopping %02x Events %08x %08x EventState %08x\r\n", aS->iStopping, aS->iEvents.iA.iNext, aS->iEvents.iA.iPrev, aS->iEventState);
-	Printf("TotalCpuTime %08x %08x RunCount %08x %08x\r\n", aS->iTotalCpuTime32[1], aS->iTotalCpuTime32[0], aS->iRunCount32[1], aS->iRunCount32[0]);
-
-	if (g)
-		{
-		// Thread group
-		return;
-		}
-
-	Printf("WaitState %02x %02x [%02x %02x] (%08x)\r\n", t->iWaitState.iWtC.iWtStFlags, t->iWaitState.iWtC.iWtObjType,
-											t->iWaitState.iWtC.iWtStSpare1, t->iWaitState.iWtC.iWtStSpare2, t->iWaitState.iWtC.iWtObj);
-	Printf("BasePri %d MutexPri %d Att=%02x\r\n", t->iBasePri, t->iMutexPri, t->i_ThrdAttr);
-	Printf("HeldFM=%08x FMDef=%02x AddrSp=%08x\r\n", t->iHeldFastMutex, t->iFastMutexDefer, t->iAddressSpace);
-	Printf("Time=%d Timeslice=%d ReqCount=%08x\r\n", t->iTime, t->iTimeslice, t->iRequestSemaphore.iCount);
-	Printf("SuspendCount=%d CsCount=%d CsFunction=%08x\r\n", t->iSuspendCount, t->iCsCount, t->iCsFunction);
-	Printf("LinkedObjType %02x LinkedObj %08x\r\n", t->iLinkedObjType, t->iLinkedObj);
-	Printf("SavedSP=%08x WaitLink:%08x %08x %d\r\n", t->iSavedSP, t->iWaitLink.iNext, t->iWaitLink.iPrev, t->iWaitLink.iPriority);
-	Printf("iNewParent=%08x iExtraContext=%08x, iExtraContextSize=%08x\r\n", t->iNewParent, t->iExtraContext, t->iExtraContextSize);
-	Printf("iUserModeCallbacks=%08x iNThreadBaseSpare6=%08x\r\n", t->iUserModeCallbacks, t->iNThreadBaseSpare6);
-	Printf("iNThreadBaseSpare7=%08x iNThreadBaseSpare8=%08x iNThreadBaseSpare9=%08x\r\n", t->iNThreadBaseSpare7, t->iNThreadBaseSpare8, t->iNThreadBaseSpare9);
-	if (!aS->iCurrent)
-		{
-		TUint32* pS=(TUint32*)t->iSavedSP;
-		SThreadReschedStack reg;
-		MTRAPD(r,wordmove(&reg,pS,sizeof(SThreadReschedStack)));
-		if (r==KErrNone)
-			{
-			Printf("CR0 %08x  RsF %08x  EIP %08x  RSN %08x\r\n", reg.iCR0, reg.iReschedFlag, reg.iEip, reg.iReason);
-			}
-		}
-	NewLine();
+	TSubSchedulerX& x = ss.iSSX;
+	m.Printf("Extras[ 0] %08x Extras[ 1] %08x Extras[ 2] %08x Extras[ 3] %08x\r\n", x.iSSXP[0], x.iSSXP[1], x.iSSXP[2], x.iSSXP[3]);
+	m.Printf("Extras[ 4] %08x Extras[ 5] %08x Extras[ 6] %08x Extras[ 7] %08x\r\n", x.iSSXP[4], x.iSSXP[5], x.iSSXP[6], x.iSSXP[7]);
+	m.Printf("Extras[ 8] %08x i_IrqCount %08x i_ExcInfo  %08x i_CrashSt  %08x\r\n", x.iSSXP[8], x.iIrqCount, x.iExcInfo, x.iCrashState);
+	m.Printf("i_APICID   %08x i_IrqNestC %08x i_IrqStkTp %08x i_Tss      %08x\r\n", x.iAPICID, x.iIrqNestCount, x.iIrqStackTop, x.iTss);
+	m.Printf("CpuFreqM   %08x CpuFreqS   %08x CpuPeriodM %08x CpuPeriodS %08x\r\n", x.iCpuFreqM, x.iCpuFreqS, x.iCpuPeriodM, x.iCpuPeriodS);
+	m.Printf("NTmrFreqM  %08x NTmrFreqS  %08x NTmPeriodM %08x NTmPeriodS %08x\r\n", x.iNTimerFreqM, x.iNTimerFreqS, x.iNTimerPeriodM, x.iNTimerPeriodS);
+	m.Printf("TmrFreqM   %08x TmrFreqS   %08x TmrPeriodM %08x TmrPeriodS %08x\r\n", x.iTimerFreqM, x.iTimerFreqS, x.iTimerPeriodM, x.iTimerPeriodS);
+	m.Printf("TmstampOff %08x %08x            iSSXP2[0]  %08x iSSXP2[1]  %08x\r\n", I64HIGH(x.iTimestampOffset.i64), I64LOW(x.iTimestampOffset.i64), x.iSSXP2[0], x.iSSXP2[1]);
 	}
 
-void Monitor::DisplayNFastSemInfo(NFastSemaphore* pS)
-	{
-	if (pS->iCount >= 0)
-		Printf("NFastSemaphore @ %08x Count %d OwningThread %08x\r\n",pS,pS->iCount,pS->iOwningThread);
-	else
-		Printf("NFastSemaphore @ %08x Count %08x (%08x) OwningThread %08x\r\n",pS,pS->iCount,pS->iCount<<2,pS->iOwningThread);
-	}
-
-void Monitor::DisplayNFastMutexInfo(NFastMutex* aM)
-	{
-	Printf("NFastMutex @ %08x HoldingThread %08x iWaitQ Pri Mask %08x %08x\r\n", aM, aM->iHoldingThread, aM->iWaitQ.iPresent[1], aM->iWaitQ.iPresent[0]);
-	DisplaySpinLock("SpinLock", &aM->iMutexLock);
-	}
-
-void DisplaySubSchedulerInfo(Monitor& m, TSubScheduler& ss)
+void DisplaySchedulerExt(Monitor& m, TScheduler& s)
 	{
-	m.Printf("\r\nSUBSCHEDULER %d @%08x:\r\n",ss.iCpuNum,&ss);
-	m.Printf("CurrentThread=%08x\r\n", ss.iCurrentThread);
-	m.Printf("DFCS %08x %08x CPU# %08x CPUmask %08x\r\n", ss.iDfcs.iA.iNext, ss.iDfcs.iA.iPrev, ss.iCpuNum, ss.iCpuMask);
-	m.Printf("KLCount %d DFCPending %02x ReschedNeeded %02x InIDFC %02x\r\n", ss.iKernLockCount, ss.iDfcPendingFlag, ss.iRescheduleNeededFlag, ss.iInIDFC);
-	m.Printf("AddressSpace=%08x ReschedIPIs=%08x iNextIPI %08x\r\n", ss.iAddressSpace, ss.iReschedIPIs, ss.iNextIPI);
-	volatile TUint32* pL = (volatile TUint32*)&ss.iReadyListLock;
-	m.Printf("SpinLock %08x %08x %08x %08x\r\n", pL[0], pL[1], pL[2], pL[3]);
-	m.Printf("Extras[ 0] %08x Extras[ 1] %08x Extras[ 2] %08x Extras[ 3] %08x\r\n", ss.iExtras[0], ss.iExtras[1], ss.iExtras[2], ss.iExtras[3]);
-	m.Printf("Extras[ 4] %08x Extras[ 5] %08x Extras[ 6] %08x Extras[ 7] %08x\r\n", ss.iExtras[4], ss.iExtras[5], ss.iExtras[6], ss.iExtras[7]);
-	m.Printf("Extras[ 8] %08x i_IrqCount %08x i_ExcInfo  %08x i_CrashSt  %08x\r\n", ss.iExtras[8], ss.i_IrqCount, ss.i_ExcInfo, ss.i_CrashState);
-	m.Printf("i_APICID   %08x i_IrqNestC %08x i_IrqStkTp %08x i_Tss      %08x\r\n", ss.i_APICID, ss.i_IrqNestCount, ss.i_IrqStackTop, ss.i_Tss);
-	m.Printf("i_TmrMultF %08x i_TmrMultI %08x i_CpuMult  %08x Extras[13] %08x\r\n", ss.i_TimerMultF, ss.i_TimerMultI, ss.i_CpuMult, ss.iExtras[19]);
-	m.Printf("i_TmOffL   %08x i_TmOffH   %08x Extras[16] %08x Extras[17] %08x\r\n", ss.iExtras[20], ss.iExtras[21], ss.iExtras[22], ss.iExtras[23]);
-	m.Printf("iLastTimestamp %08x %08x   iReschedCount %08x %08x\r\n", ss.iLastTimestamp32[1], ss.iLastTimestamp32[0], ss.iReschedCount32[1], ss.iReschedCount32[0]);
-	}
-
-void Monitor::DisplaySchedulerInfo()
-	{
-	TScheduler* pS=TScheduler::Ptr();
-	Printf("SCHEDULER @%08x:\r\n",pS);
-	Printf("ProcessHandler=%08x MonitorExceptionHandler=%08x RescheduleHook=%08x\r\n",pS->iProcessHandler,pS->iMonitorExceptionHandler,pS->iRescheduleHook);
-	Printf("iActiveCpus1=%08x, iActiveCpus2=%08x, iNumCpus=%d\r\n",pS->iActiveCpus1,pS->iActiveCpus2,pS->iNumCpus);
-	Printf("SYSLOCK @ %08x\r\n",&pS->iLock);
-	DisplayNFastMutexInfo(&pS->iLock);
-	DisplaySpinLock("IdleSpinLock", &pS->iIdleSpinLock);
-	Printf("IdleDfcs %08x %08x CpusNotIdle %08x IdleGeneration %02x IdleSpillCpu %02x\r\n",
-		pS->iIdleDfcs.iA.iNext, pS->iIdleDfcs.iA.iPrev, pS->iCpusNotIdle, pS->iIdleGeneration, pS->iIdleSpillCpu);
-	Printf("Extras  0: %08x  1: %08x  2: %08x  3: %08x\r\n",pS->iExtras[0],pS->iExtras[1],pS->iExtras[2],pS->iExtras[3]);
-	Printf("Extras  4: %08x  5: %08x  6: %08x  7: %08x\r\n",pS->iExtras[4],pS->iExtras[5],pS->iExtras[6],pS->iExtras[7]);
-	Printf("Extras  8: %08x  9: %08x  A: %08x  B: %08x\r\n",pS->iExtras[8],pS->iExtras[9],pS->iExtras[10],pS->iExtras[11]);
-	Printf("Extras  C: %08x  D: %08x  E: %08x  F: %08x\r\n",pS->iExtras[12],pS->iExtras[13],pS->iExtras[14],pS->iExtras[15]);
-	Printf("Extras 10: %08x 11: %08x 12: %08x 13: %08x\r\n",pS->iExtras[16],pS->iExtras[17],pS->iExtras[18],pS->iExtras[19]);
-	Printf("Extras 14: %08x 15: %08x 16: %08x 17: %08x\r\n",pS->iExtras[20],pS->iExtras[21],pS->iExtras[22],pS->iExtras[23]);
-
-	TInt i;
-	for (i=0; i<KMaxCpus; ++i)
-		{
-		TSubScheduler& ss = *pS->iSub[i];
-		DisplaySubSchedulerInfo(*this,ss);
-		}
+	volatile TUint32* sx = (volatile TUint32*)&s.iSX;
+	m.Printf("Extras  0: %08x  1: %08x  2: %08x  3: %08x\r\n",sx[0],sx[1],sx[2],sx[3]);
+	m.Printf("Extras  4: %08x  5: %08x  6: %08x  7: %08x\r\n",sx[4],sx[5],sx[6],sx[7]);
+	m.Printf("Extras  8: %08x  9: %08x  A: %08x  B: %08x\r\n",sx[8],sx[9],sx[10],sx[11]);
+	m.Printf("Extras  C: %08x  D: %08x  E: %08x  F: %08x\r\n",sx[12],sx[13],sx[14],sx[15]);
 	}
 
 SFullX86RegSet& RegSet(TInt aCpu)
 	{
 	TScheduler* pS=TScheduler::Ptr();
 	TSubScheduler& ss = *pS->iSub[aCpu];
-	SCpuData* cpudata = (SCpuData*)ss.i_Tss;
+	SCpuData* cpudata = (SCpuData*)ss.iSSX.iTss;
 	return cpudata->iRegs;
 	}
 
@@ -152,7 +62,7 @@
 	{
 	TScheduler* pS=TScheduler::Ptr();
 	TSubScheduler& ss = *pS->iSub[aCpu];
-	return *(TX86Tss*)ss.i_Tss;
+	return *ss.iSSX.iTss;
 	}
 
 void Monitor::DumpCpuRegisters()
@@ -179,9 +89,9 @@
 		{
 		Printf("CPU %d:\r\n", i);
 		TSubScheduler& ss = *pS->iSub[i];
-		if (!ss.i_ExcInfo)
+		if (!ss.iSSX.iExcInfo)
 			continue;
-		TX86ExcInfo& a = *(TX86ExcInfo*)ss.i_ExcInfo;
+		TX86ExcInfo& a = *(TX86ExcInfo*)ss.iSSX.iExcInfo;
 		Printf("Exc %02x EFLAGS=%08x FAR=%08x ErrCode=%08x\r\n",a.iExcId,a.iEflags,a.iFaultAddress,a.iExcErrorCode);
 		Printf("EAX=%08x EBX=%08x ECX=%08x EDX=%08x\r\n",a.iEax,a.iEbx,a.iEcx,a.iEdx);
 		Printf("ESP=%08x EBP=%08x ESI=%08x EDI=%08x\r\n",a.iEsp,a.iEbp,a.iEsi,a.iEdi);
--- a/kernel/eka/nkernsmp/x86/ncsched.cia	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/nkernsmp/x86/ncsched.cia	Fri Apr 16 16:24:37 2010 +0300
@@ -100,7 +100,7 @@
 	asm("je same_thread ");
 	asm("mov eax, [ebx+%0]" : : "i" _FOFF(NThreadBase, iStackBase));
 	asm("add eax, [ebx+%0]" : : "i" _FOFF(NThreadBase, iStackSize));
-	asm("mov ecx, [esi+60+%0]" : : "i" _FOFF(TSubScheduler, iExtras));		// iExtras[15] points to TSS
+	asm("mov ecx, [esi+%0]" : : "i" _FOFF(TSubScheduler, iSSX.iTss));		// iExtras[15] points to TSS
 	asm("mov [ecx+%0], eax" : : "i" _FOFF(TX86Tss, iEsp0));					// set ESP0 to top of new thread supervisor stack
 
 	asm("test byte ptr [ebx+%0], 2" : : "i" _FOFF(NThreadBase,i_ThrdAttr));	// test for address space switch
@@ -551,7 +551,7 @@
 	asm("jz bad_cc");
 	asm("test dl, 3");
 	asm("jnz bad_cc");
-	asm("cmp eax, [edx+52+%0]": : "i"_FOFF(TSubScheduler,iExtras)); // i_IrqNestCount
+	asm("cmp eax, [edx+%0]": : "i"_FOFF(TSubScheduler,iSSX.iIrqNestCount)); // i_IrqNestCount
 	asm("jle irq");
 	asm("cmp al, [edx+%0]": : "i"_FOFF(TSubScheduler, iInIDFC));
 	asm("jz thread");
@@ -609,16 +609,22 @@
 	asm("ret ");
 	}
 
-extern "C" __NAKED__ void send_irq_ipi(TSubScheduler*)
+extern "C" __NAKED__ void send_irq_ipi(TSubScheduler*, TInt)
 	{
+	/* check that EQueueEvent_WakeUp isn't set since we don't support that on x86 yet */
+	asm("test dword ptr [esp+8], 2 ");
+	asm("jnz wake_up_requested ");
 	asm("mov ecx, [esp+4] ");
 	asm("pushfd ");
-	asm("mov edx, [ecx+%0]" : : "i" _FOFF(TSubScheduler, i_APICID));
+	asm("mov edx, [ecx+%0]" : : "i" _FOFF(TSubScheduler, iSSX.iAPICID));
 	asm("cli ");
 	asm("mov ds:[%0], edx" : : "i" (X86_LOCAL_APIC_BASE + X86_LOCAL_APIC_OFFSET_ICRH));
 	asm("mov eax, %0" : : "i" (TRANSFERRED_IRQ_VECTOR | 0x4000));
 	asm("mov ds:[%0], eax" : : "i" (X86_LOCAL_APIC_BASE + X86_LOCAL_APIC_OFFSET_ICRL));
 	asm("popfd ");
 	asm("ret ");
+
+	asm("wake_up_requested: ");
+	asm("int 0xff ");
 	}
 
--- a/kernel/eka/nkernsmp/x86/ncsched.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/nkernsmp/x86/ncsched.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -55,35 +55,38 @@
 	{
 	TSubScheduler& ss = TheSubSchedulers[aCpu];
 	__KTRACE_OPT(KSCHED2,DEBUGPRINT("@%d",aCpu));
-	send_ipi((TUint32)ss.i_APICID);
+	send_ipi(ss.iSSX.iAPICID);
 	}
 
+#ifndef __USE_LOGICAL_DEST_MODE__
+extern "C" void __fastcall do_send_resched_ipis(TUint32 aMask)
+	{
+	TInt i=0;
+	for (; aMask; aMask>>=1, ++i)
+		if (aMask&1)
+			send_resched_ipi(i);
+	}
+#endif
+
 extern "C" void send_resched_ipis(TUint32 aMask)
 	{
 	__KTRACE_OPT(KSCHED2,DEBUGPRINT("@%02x",aMask));
-#ifdef __USE_LOGICAL_DEST_MODE__
-	do_send_resched_ipis(aMask);
-#else
-	TInt i=0;
-	while (aMask)
-		{
-		if (aMask&1)
-			send_resched_ipi(i);
-		aMask>>=1;
-		++i;
-		}
-#endif
+	TScheduler& s = TheScheduler;
+	if (aMask &~ s.iThreadAcceptCpus)
+		aMask = s.ReschedInactiveCpus(aMask);
+	if (aMask)
+		do_send_resched_ipis(aMask);
 	}
 
 extern "C" void send_resched_ipi_and_wait(TInt aCpu)
 	{
 	TSubScheduler& ss = TheSubSchedulers[aCpu];
 	__KTRACE_OPT(KSCHED2,DEBUGPRINT("@@%d",aCpu));
-	volatile TUint32& irqc = (volatile TUint32&)ss.i_IrqCount;
-	volatile TInt& irqn = (volatile TInt&)ss.i_IrqNestCount;
+	volatile TUint32& irqc = ss.iSSX.iIrqCount;
+	volatile TInt& irqn = ss.iSSX.iIrqNestCount;
 	TUint32 irqc0 = irqc;
 	mb();
-	send_ipi((TUint32)ss.i_APICID);
+	send_ipi(ss.iSSX.iAPICID);
 	mb();
 	while (!ss.iRescheduleNeededFlag || (irqn<0 && irqc==irqc0))
 		{
@@ -98,9 +101,9 @@
 		{
 		TUint32 remain32 = read_apic_reg(CURRCNT);
 		TUint64 x(remain32);
-		x *= TUint32(i_TimerMultI);
-		x += 0x00800000u;
-		x >>= 24;
+		x *= TUint32(iSSX.iTimerPeriodM);
+		x += 1u<<(iSSX.iTimerPeriodS-1);
+		x >>= iSSX.iTimerPeriodS;
 		aT->iTime = (TInt)x;
 		}
 	write_apic_reg(INITCNT, 0);
@@ -127,19 +130,35 @@
 		{
 		TUint32 remain32 = (TUint32)aNew->iTime;
 		TUint64 x(remain32);
-		x *= TUint32(i_TimerMultF);
-		x += 0x80000000u;
-		x >>= 32;
+		x *= TUint32(iSSX.iTimerFreqM);
+		x += TUint64(0x80000000u)<<iSSX.iTimerFreqS;
+		x >>= (32+iSSX.iTimerFreqS);
 		write_apic_reg(LVTTMR, TIMESLICE_VECTOR);
 		write_apic_reg(INITCNT, (TUint32)x);
 		}
 	if (aNew!=aOld)
 		{
 		TUint64 now = NKern::Timestamp();
-		aOld->iTotalCpuTime64 += (now - iLastTimestamp64);
-		iLastTimestamp64 = now;
-		++iReschedCount64;
-		++aNew->iRunCount64;
+		TUint64 delta = now - iLastTimestamp.i64;
+		iLastTimestamp.i64 = now;
+		aOld->iLastRunTime.i64 = now;
+		aOld->iTotalCpuTime.i64 += delta;
+		++iReschedCount.i64;
+		++aNew->iRunCount.i64;
+		if (!aOld->iActiveState)
+			aOld->iTotalActiveTime.i64 += (now - aOld->iLastActivationTime.i64);
+		NSchedulable* parent = aOld->iParent;
+		if (parent != aOld)
+			{
+			parent->iLastRunTime.i64 = now;
+			if (!parent->iActiveState)
+				parent->iTotalActiveTime.i64 += (now - parent->iLastActivationTime.i64);
+			if (parent != aNew->iParent)
+				parent->iTotalCpuTime.i64 += (now - parent->iLastStartTime.i64);
+			}
+		NSchedulable* np = aNew->iParent;
+		if (np!=aNew && np!=parent)
+			np->iLastStartTime.i64 = now;
 		}
 	}
 
--- a/kernel/eka/nkernsmp/x86/ncthrd.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/nkernsmp/x86/ncthrd.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -36,7 +36,7 @@
 extern void __ltr(TInt /*aSelector*/);
 
 extern "C" TUint __tr();
-extern void InitAPTimestamp(SNThreadCreateInfo& aInfo);
+extern void InitTimestamp(TSubScheduler* aSS, SNThreadCreateInfo& aInfo);
 
 TInt NThread::Create(SNThreadCreateInfo& aInfo, TBool aInitial)
 	{
@@ -44,6 +44,7 @@
 		return KErrArgument;
 	new (this) NThread;
 	TInt cpu = -1;
+	TSubScheduler* ss = 0;
 	if (aInitial)
 		{
 		cpu = __e32_atomic_add_ord32(&TheScheduler.iNumCpus, 1);
@@ -52,20 +53,22 @@
 		aInfo.iCpuAffinity = cpu;
 		// OK since we can't migrate yet
 		TUint32 apicid = *(volatile TUint32*)(X86_LOCAL_APIC_BASE + X86_LOCAL_APIC_OFFSET_ID) >> 24;
-		TSubScheduler& ss = TheSubSchedulers[cpu];
-		ss.i_APICID = (TAny*)(apicid<<24);
-		ss.iCurrentThread = this;
-		SubSchedulerLookupTable[apicid] = &ss;
-		ss.iLastTimestamp64 = NKern::Timestamp();
-		iRunCount64 = UI64LIT(1);
-		__KTRACE_OPT(KBOOT,DEBUGPRINT("Init: cpu=%d APICID=%08x ss=%08x", cpu, apicid, &ss));
+		ss = &TheSubSchedulers[cpu];
+		ss->iSSX.iAPICID = apicid << 24;
+		ss->iCurrentThread = this;
+		ss->iDeferShutdown = 0;
+		SubSchedulerLookupTable[apicid] = ss;
+		iRunCount.i64 = UI64LIT(1);
+		iActiveState = 1;
+		__KTRACE_OPT(KBOOT,DEBUGPRINT("Init: cpu=%d APICID=%08x ss=%08x", cpu, apicid, ss));
 		if (cpu)
 			{
 			__ltr(TSS_SELECTOR(cpu));
 			NIrq::HwInit2AP();
-			__e32_atomic_ior_ord32(&TheScheduler.iActiveCpus1, 1<<cpu);
-			__e32_atomic_ior_ord32(&TheScheduler.iActiveCpus2, 1<<cpu);
+			__e32_atomic_ior_ord32(&TheScheduler.iThreadAcceptCpus, 1<<cpu);
+			__e32_atomic_ior_ord32(&TheScheduler.iIpiAcceptCpus, 1<<cpu);
 			__e32_atomic_ior_ord32(&TheScheduler.iCpusNotIdle, 1<<cpu);
+			__e32_atomic_add_ord32(&TheScheduler.iCCRequestLevel, 1);
 			__KTRACE_OPT(KBOOT,DEBUGPRINT("AP TR=%x",__tr()));
 			}
 		}
@@ -124,10 +127,11 @@
 		{
 		NKern::EnableAllInterrupts();
 
-		// synchronize AP's timestamp with BP's
-		if (cpu>0)
-			InitAPTimestamp(aInfo);
+		// Initialise timestamp
+		InitTimestamp(ss, aInfo);
 		}
+	AddToEnumerateList();
+	InitLbInfo();
 #ifdef BTRACE_THREAD_IDENTIFICATION
 	BTrace4(BTrace::EThreadIdentification,BTrace::ENanoThreadCreate,this);
 #endif
@@ -149,7 +153,7 @@
 	TInt irq = NKern::DisableAllInterrupts();
 	TSubScheduler& ss = SubScheduler();
 	NThreadBase* ct = ss.iCurrentThread;
-	TInt inc = TInt(ss.i_IrqNestCount);
+	TInt inc = TInt(ss.iSSX.iIrqNestCount);
 	TInt cpu = ss.iCpuNum;
 	NKern::RestoreInterrupts(irq);
 	DEBUGPRINT("Thread %T, CPU %d, KLCount=%08x, IrqNest=%d",ct,cpu,ss.iKernLockCount,inc);
@@ -228,7 +232,7 @@
 	if (pC != this)
 		{
 		AcqSLock();
-		if (iWaitState.ThreadIsDead())
+		if (iWaitState.ThreadIsDead() || i_NThread_Initial)
 			{
 			RelSLock();
 			aAvailRegistersMask = 0;
@@ -279,7 +283,7 @@
 	TGetContextIPI& ipi = *(TGetContextIPI*)aPtr;
 	TX86RegSet& a = *ipi.iContext;
 	TSubScheduler& ss = SubScheduler();
-	TUint32* irqstack = (TUint32*)ss.i_IrqStackTop;
+	TUint32* irqstack = (TUint32*)ss.iSSX.iIrqStackTop;
 	SThreadExcStack* txs = (SThreadExcStack*)irqstack[-1];	// first word pushed on IRQ stack points to thread supervisor stack
 	GetContextAfterExc(a, txs, *ipi.iAvailRegsMask, TRUE);
 	}
@@ -390,7 +394,7 @@
 	if (pC != this)
 		{
 		AcqSLock();
-		if (iWaitState.ThreadIsDead())
+		if (iWaitState.ThreadIsDead() || i_NThread_Initial)
 			{
 			RelSLock();
 			aRegMask = 0;
@@ -567,31 +571,6 @@
 	}
 
 
-/** Return the total CPU time so far used by the specified thread.
-
-	@return The total CPU time in units of 1/NKern::CpuTimeMeasFreq().
-*/
-EXPORT_C TUint64 NKern::ThreadCpuTime(NThread* aThread)
-	{
-	TSubScheduler* ss = 0;
-	NKern::Lock();
-	aThread->AcqSLock();
-	if (aThread->i_NThread_Initial)
-		ss = &TheSubSchedulers[aThread->iLastCpu];
-	else if (aThread->iReady && aThread->iParent->iReady)
-		ss = &TheSubSchedulers[aThread->iParent->iReady & NSchedulable::EReadyCpuMask];
-	if (ss)
-		ss->iReadyListLock.LockOnly();
-	TUint64 t = aThread->iTotalCpuTime64;
-	if (aThread->iCurrent || (aThread->i_NThread_Initial && !ss->iCurrentThread))
-		t += (NKern::Timestamp() - ss->iLastTimestamp64);
-	if (ss)
-		ss->iReadyListLock.UnlockOnly();
-	aThread->RelSLock();
-	NKern::Unlock();
-	return t;
-	}
-
 extern "C" void __fastcall add_dfc(TDfc* aDfc)
 	{
 	aDfc->Add();
@@ -603,6 +582,8 @@
 	__e32_memory_barrier();
 	if (aCallback->iNext != KUserModeCallbackUnqueued)
 		return KErrInUse;
+	if (aThread->i_NThread_Initial)
+		return KErrArgument;
 	TInt result = KErrDied;
 	NKern::Lock();
 	TUserModeCallback* listHead = aThread->iUserModeCallbacks;
--- a/kernel/eka/nkernsmp/x86/ncutilf.cia	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/nkernsmp/x86/ncutilf.cia	Fri Apr 16 16:24:37 2010 +0300
@@ -74,8 +74,9 @@
 	asm("test cl, 3 ");
 	asm("jnz short use_tsc_only ");
 	asm("rdtsc ");
-	asm("add eax, [ecx+80+%0]" : : "i" _FOFF(TSubScheduler, iExtras));
-	asm("adc edx, [ecx+84+%0]" : : "i" _FOFF(TSubScheduler, iExtras));
+	asm("lea ecx, [ecx+%0]" : : "i" _FOFF(TSubScheduler, iSSX.iTimestampOffset));
+	asm("add eax, [ecx] ");
+	asm("adc edx, [ecx+4] ");
 	asm("popfd ");
 	asm("ret ");
 
@@ -133,7 +134,7 @@
 	asm("slec_preemption: ");
 	asm("cmp cl, 0xff ");
 	asm("je short slec_1 ");			/* EOrderNone - don't check interrupts or preemption */
-	asm("cmp dword ptr [edx+52+%0], 0" : : "i"_FOFF(TSubScheduler, iExtras));
+	asm("cmp dword ptr [edx+%0], 0" : : "i"_FOFF(TSubScheduler, iSSX.iIrqNestCount));
 	asm("jge short slec_preemption_die ");	/* If called from ISR, die */
 	asm("cmp dword ptr [edx+%0], 0" : : "i" _FOFF(TSubScheduler, iKernLockCount));
 	asm("jnz short slec_1 ");			/* Preemption disabled - OK */
@@ -484,7 +485,7 @@
 	asm("rwrlec_preemption: ");
 	asm("cmp cl, 0xff ");
 	asm("je short rwrlec_1 ");			/* EOrderNone - don't check interrupts or preemption */
-	asm("cmp dword ptr [edx+52+%0], 0" : : "i"_FOFF(TSubScheduler, iExtras));
+	asm("cmp dword ptr [edx+%0], 0" : : "i"_FOFF(TSubScheduler, iSSX.iIrqNestCount));
 	asm("jge short rwrlec_preemption_die ");	/* If called from ISR, die */
 	asm("cmp dword ptr [edx+%0], 0" : : "i" _FOFF(TSubScheduler, iKernLockCount));
 	asm("jnz short rwrlec_1 ");			/* Preemption disabled - OK */
@@ -641,7 +642,7 @@
 	asm("rwwlec_preemption: ");
 	asm("cmp cl, 0xff ");
 	asm("je short rwwlec_1 ");			/* EOrderNone - don't check interrupts or preemption */
-	asm("cmp dword ptr [edx+52+%0], 0" : : "i"_FOFF(TSubScheduler, iExtras));
+	asm("cmp dword ptr [edx+%0], 0" : : "i"_FOFF(TSubScheduler, iSSX.iIrqNestCount));
 	asm("jge short rwwlec_preemption_die ");	/* If called from ISR, die */
 	asm("cmp dword ptr [edx+%0], 0" : : "i" _FOFF(TSubScheduler, iKernLockCount));
 	asm("jnz short rwwlec_1 ");			/* Preemption disabled - OK */
--- a/kernel/eka/nkernsmp/x86/ncutils.cia	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/nkernsmp/x86/ncutils.cia	Fri Apr 16 16:24:37 2010 +0300
@@ -18,7 +18,7 @@
 #include <x86.h>
 #include <apic.h>
 
-extern "C" __NAKED__ void NKIdle(TInt)
+extern "C" __NAKED__ void NKIdle(TUint32)
 	{
 	asm("sti");
 	asm("hlt");
@@ -68,7 +68,7 @@
 	asm("mov edx, eax ");
 	asm("cmp eax, 0 ");
 	asm("jnz short atomic_set_1 ");
-	asm("mov edx, [%a0]" : : "i" (&TheScheduler.iActiveCpus1));
+	asm("mov edx, [%a0]" : : "i" (&TheScheduler.iIpiAcceptCpus));
 	asm("shl edx, 16 ");
 	asm("atomic_set_1: ");
 	asm("or edx, [esi+%0]" : : "i" _FOFF(TSubScheduler,iCpuMask));
@@ -90,7 +90,7 @@
 	asm("jmp short crash_halt ");
 
 	asm("first_to_crash: ");
-	asm("mov ebp, [esi+60+%0]" : : "i" _FOFF(TSubScheduler,iExtras));	// points to SCpuData
+	asm("mov ebp, [esi+%0]" : : "i" _FOFF(TSubScheduler,iSSX.iTss));	// points to SCpuData
 	asm("lea ebp, [ebp+%0]" : : "i" _FOFF(SCpuData,iRegs));
 	asm("pop dword ptr [ebp+%0]" : : "i" _FOFF(SFullX86RegSet,iEsi));
 	asm("pop dword ptr [ebp+%0]" : : "i" _FOFF(SFullX86RegSet,iEbp));
@@ -111,7 +111,7 @@
 	asm("mov [eax+12], fs ");
 	asm("mov [eax+16], gs ");
 	asm("mov [eax+20], ss ");
-	asm("lea ebx, [esi+52+%0]" : : "i" _FOFF(TSubScheduler,iExtras));	// points to i_IrqNestCount
+	asm("lea ebx, [esi+%0]" : : "i" _FOFF(TSubScheduler,iSSX.iIrqNestCount));
 	asm("mov eax, 0x80000000 ");
 	asm("lock xchg eax, [ebx] ");
 	asm("mov [ebp+%0], eax" : : "i" _FOFF(SFullX86RegSet,iIrqNestCount));
@@ -137,7 +137,7 @@
 	asm("not eax ");
 	asm("mov edx, %0": :"i" (addressof_CrashState)); 
 	asm("lock and [edx+2], ax ");
-	asm("mov dword ptr [esi+44+%0], 1" : : "i" _FOFF(TSubScheduler, iExtras));	// flag that this CPU is done
+	asm("mov dword ptr [esi+%0], 1" : : "i" _FOFF(TSubScheduler, iSSX.iCrashState));	// flag that this CPU is done
 	asm("xor ecx, ecx ");
 	asm("wait_other_cpus: ");
 	asm("mov ax, [edx+2] ");
--- a/kernel/eka/nkernsmp/x86/ncutils.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/nkernsmp/x86/ncutils.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -32,7 +32,7 @@
 	return TheScheduler.iIdleGenerationCount;
 	}
 
-void NKern::Idle()
+void NKern::DoIdle()
 	{
 	TScheduler& s = TheScheduler;
 	TSubScheduler& ss = SubScheduler();	// OK since idle thread is locked to CPU
@@ -57,8 +57,19 @@
 			return;
 			}
 		}
+	if (ss.iCurrentThread->iSavedSP)
+		{
+		// rescheduled between entry to NKern::Idle() and here
+		// go round again to see if any more threads to pull from other CPUs
+		__e32_atomic_ior_ord32(&s.iCpusNotIdle, m);	// we aren't idle after all
+		s.iIdleSpinLock.UnlockIrq();
+		return;
+		}
+
 	s.iIdleSpinLock.UnlockOnly();	// leave interrupts disabled
+
 	NKIdle(0);
+	
 	}
 
 TUint32 ContextId()
@@ -324,13 +335,23 @@
 	for (i=0; i<KMaxCpus; ++i)
 		{
 		TSubScheduler& ss = TheSubSchedulers[i];
-		ss.i_TimerMultF = (TAny*)KMaxTUint32;
-		ss.i_TimerMultI = (TAny*)0x01000000u;
-		ss.i_CpuMult = (TAny*)KMaxTUint32;
-		VIB->iTimerMult[i] = (volatile STimerMult*)&ss.i_TimerMultF;
-		VIB->iCpuMult[i] = (volatile TUint32*)&ss.i_CpuMult;
+		ss.iSSX.iCpuFreqM = KMaxTUint32;
+		ss.iSSX.iCpuFreqS = 0;
+		ss.iSSX.iCpuPeriodM = 0x80000000u;
+		ss.iSSX.iCpuPeriodS = 31;
+		ss.iSSX.iNTimerFreqM = KMaxTUint32;
+		ss.iSSX.iNTimerFreqS = 0;
+		ss.iSSX.iNTimerPeriodM = 0x80000000u;
+		ss.iSSX.iNTimerPeriodS = 31;
+		ss.iSSX.iTimerFreqM = KMaxTUint32;
+		ss.iSSX.iTimerFreqS = 0;
+		ss.iSSX.iTimerPeriodM = 0x80000000u;
+		ss.iSSX.iTimerPeriodS = 31;
+		ss.iSSX.iTimestampOffset.i64 = 0;
+		VIB->iTimerMult[i] = 0;
+		VIB->iCpuMult[i] = 0;
 		}
-	TheScheduler.i_TimerMax = (TAny*)(VIB->iMaxTimerClock / 128);
+	TheScheduler.iSX.iTimerMax = (VIB->iMaxTimerClock / 128);
 	InitFpu();
 	InterruptInit0();
 	}
@@ -351,7 +372,7 @@
  */
 EXPORT_C TInt NKern::TimesliceTicks(TUint32 aMicroseconds)
 	{
-	TUint32 mf32 = (TUint32)TheScheduler.i_TimerMax;
+	TUint32 mf32 = (TUint32)TheScheduler.iSX.iTimerMax;
 	TUint64 mf(mf32);
 	TUint64 ticks = mf*TUint64(aMicroseconds) + UI64LIT(999999);
 	ticks /= UI64LIT(1000000);
@@ -361,3 +382,21 @@
 		return (TInt)ticks;
 	}
 
+TBool TSubScheduler::Detached()
+	{
+	return FALSE;
+	}
+
+TBool TScheduler::CoreControlSupported()
+	{
+	return FALSE;
+	}
+
+void TScheduler::CCInitiatePowerUp(TUint32 /*aCores*/)
+	{
+	}
+
+void TScheduler::CCIndirectPowerDown(TAny*)
+	{
+	}
+
--- a/kernel/eka/nkernsmp/x86/vectors.cia	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/nkernsmp/x86/vectors.cia	Fri Apr 16 16:24:37 2010 +0300
@@ -338,10 +338,10 @@
 	asm("shr eax, 24 ");
 	asm("mov esi, [eax*4+%0]" : : "i" (&SubSchedulerLookupTable));
 	asm("mov edi, esp ");								// edi points to saved stuff
-	asm("inc dword ptr [esi+36+%0]" : : "i" _FOFF(TSubScheduler, iExtras));	// increment i_IrqCount
-	asm("inc dword ptr [esi+52+%0]" : : "i" _FOFF(TSubScheduler, iExtras));	// nest count starts at -1, iExtras[13]
+	asm("inc dword ptr [esi+%0]" : : "i" _FOFF(TSubScheduler, iSSX.iIrqCount));	// increment i_IrqCount
+	asm("inc dword ptr [esi+%0]" : : "i" _FOFF(TSubScheduler, iSSX.iIrqNestCount));	// nest count starts at -1, iExtras[13]
 	asm("jnz short nested_irq_entry ");
-	asm("mov esp, [esi+56+%0]" : : "i" _FOFF(TSubScheduler, iExtras));			// iExtras[14] = irq stack top
+	asm("mov esp, [esi+%0]" : : "i" _FOFF(TSubScheduler, iSSX.iIrqStackTop));			// iExtras[14] = irq stack top
 	asm("push edi ");
 	asm("nested_irq_entry: ");
 	asm("mov edx, [esi+%0]" : : "i" _FOFF(TSubScheduler, iCpuMask));
@@ -393,7 +393,7 @@
 	// Postamble. Interrupts disabled here.
 	asm("postamble: ");
 	asm("cli ");
-	asm("dec dword ptr [esi+52+%0]" : : "i" _FOFF(TSubScheduler, iExtras));
+	asm("dec dword ptr [esi+%0]" : : "i" _FOFF(TSubScheduler, iSSX.iIrqNestCount));
 	asm("jns short nested_irq_exit ");
 
 	// Check for deferred/transferred IRQs
@@ -401,11 +401,11 @@
 	asm("je short no_event_handlers ");
 
 	// increment i_IrqNestCount again since we are going to run more ISRs
-	asm("inc dword ptr [esi+52+%0]" : : "i" _FOFF(TSubScheduler, iExtras));
+	asm("inc dword ptr [esi+%0]" : : "i" _FOFF(TSubScheduler, iSSX.iIrqNestCount));
 	asm("push esi ");
 	asm("call %a0" : : "i" (run_event_handlers));
 	asm("add esp, 4 ");
-	asm("dec dword ptr [esi+52+%0]" : : "i" _FOFF(TSubScheduler, iExtras));
+	asm("dec dword ptr [esi+%0]" : : "i" _FOFF(TSubScheduler, iSSX.iIrqNestCount));
 
 	asm("no_event_handlers: ");
 	asm("pop eax ");
@@ -517,7 +517,7 @@
 	asm("ring0_exception: ");
 	asm("mov [ebp], eax ");
 
-	asm("cmp dword ptr [esi+52+%0], -1 " : : "i" _FOFF(TSubScheduler, iExtras));
+	asm("cmp dword ptr [esi+%0], -1 " : : "i" _FOFF(TSubScheduler, iSSX.iIrqNestCount));
 	asm("jnz short fatal_exception_irq ");
 	asm("cmp dword ptr [esi+%0], 0 " : : "i" _FOFF(TSubScheduler, iKernLockCount));
 	asm("jnz short fatal_exception_locked ");
@@ -602,10 +602,10 @@
 	asm("mov esi, ds:[%0]" : : "i" (X86_LOCAL_APIC_BASE + X86_LOCAL_APIC_OFFSET_ID));
 	asm("shr esi, 24 ");
 	asm("mov esi, [esi*4+%0]" : : "i" (&SubSchedulerLookupTable));			// esi -> subscheduler
-	asm("mov ebp, [esi+44+%0]" : : "i" _FOFF(TSubScheduler, iExtras));
+	asm("mov ebp, [esi+%0]" : : "i" _FOFF(TSubScheduler, iSSX.iCrashState));
 	asm("cmp ebp, 16 ");
 	asm("jae nmihook ");
-	asm("mov ebp, [esi+60+%0]" : : "i" _FOFF(TSubScheduler, iExtras));		// points to SCpuData
+	asm("mov ebp, [esi+%0]" : : "i" _FOFF(TSubScheduler, iSSX.iTss));		// points to SCpuData
 	asm("mov edi, %0" : : "i" (addressof_TheScheduler)); 
 	asm("lea ebp, [ebp+%0]" : : "i" _FOFF(SCpuData, iRegs));
 	asm("mov [ebp+%0], eax" : : "i" _FOFF(SFullX86RegSet, iEax));
@@ -627,7 +627,7 @@
 	asm("mov [ebp+%0], eax" : : "i" _FOFF(SFullX86RegSet, iFs));
 	asm("mov ax, gs ");
 	asm("mov [ebp+%0], eax" : : "i" _FOFF(SFullX86RegSet, iGs));
-	asm("lea ebx, [esi+52+%0]" : : "i" _FOFF(TSubScheduler, iExtras));		// points to i_IrqNestCount
+	asm("lea ebx, [esi+%0]" : : "i" _FOFF(TSubScheduler, iSSX.iIrqNestCount));		// points to i_IrqNestCount
 	asm("mov eax, 0x80000000 ");
 	asm("lock xchg eax, [ebx] ");
 	asm("mov [ebp+%0], eax" : : "i" _FOFF(SFullX86RegSet, iIrqNestCount));
@@ -641,7 +641,7 @@
 	asm("pop dword ptr [ebp+%0]" : : "i" _FOFF(SFullX86RegSet, iEsp));
 	asm("pop dword ptr [ebp+%0]" : : "i" _FOFF(SFullX86RegSet, iSs));
 	asm("got_regs: ");
-	asm("mov dword ptr [esi+44+%0], 2" : : "i" _FOFF(TSubScheduler, iExtras));	// flag that this CPU is done
+	asm("mov dword ptr [esi+%0], 2" : : "i" _FOFF(TSubScheduler, iSSX.iCrashState));	// flag that this CPU is done
 	asm("nmi_halt: ");
 	asm("cli ");
 	asm("xor eax, eax ");
@@ -794,10 +794,10 @@
 	{
 	asm("mov eax, ds:[%0]" : : "i" (X86_LOCAL_APIC_BASE + X86_LOCAL_APIC_OFFSET_ID));
 	asm("shr eax, 24 ");
-	asm("mov eax, [eax*4+%0]" : : "i" (&SubSchedulerLookupTable));			// esi -> subscheduler
-	asm("mov eax, [eax+56+%0]" : : "i" _FOFF(TSubScheduler, iExtras));		// eax = i_IrqStackTop
-	asm("mov eax, [eax-4] ");												// saved supervisor stack pointer
-	asm("mov eax, [eax+%0]" : : "i" _FOFF(SThreadExcStack, iEip));			// saved return address from original interrupt
+	asm("mov eax, [eax*4+%0]" : : "i" (&SubSchedulerLookupTable));				// esi -> subscheduler
+	asm("mov eax, [eax+%0]" : : "i" _FOFF(TSubScheduler, iSSX.iIrqStackTop));	// eax = i_IrqStackTop
+	asm("mov eax, [eax-4] ");													// saved supervisor stack pointer
+	asm("mov eax, [eax+%0]" : : "i" _FOFF(SThreadExcStack, iEip));				// saved return address from original interrupt
 	asm("ret ");
 	}
 
@@ -863,7 +863,7 @@
 	asm("shr eax, 1 ");
 	asm("jnc short sgi1 ");
 	asm("sgi2: ");
-	asm("mov ecx, [esi+48+%0]" : : "i" _FOFF(TSubScheduler, iExtras));	// ss.i_APICID
+	asm("mov ecx, [esi+%0]" : : "i" _FOFF(TSubScheduler, iSSX.iAPICID));
 	asm("mov ds:[%0], ecx" : : "i" (X86_LOCAL_APIC_BASE + X86_LOCAL_APIC_OFFSET_ICRH));
 	asm("mov ds:[%0], edx" : : "i" (X86_LOCAL_APIC_BASE + X86_LOCAL_APIC_OFFSET_ICRL));
 	asm("sgi1: ");
--- a/kernel/eka/nkernsmp/x86/vectors.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/nkernsmp/x86/vectors.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -86,11 +86,11 @@
 	{
 	TLinAddr a = 0;
 	if (aCpu>=0 && aCpu<KMaxCpus)
-		a = TLinAddr(TheSubSchedulers[aCpu].i_IrqStackTop);
+		a = TLinAddr(TheSubSchedulers[aCpu].iSSX.iIrqStackTop);
 	else
 		{
 		TInt irq = NKern::DisableAllInterrupts();
-		a = TLinAddr(SubScheduler().i_IrqStackTop);
+		a = TLinAddr(SubScheduler().iSSX.iIrqStackTop);
 		NKern::RestoreInterrupts(irq);
 		}
 	return a;
@@ -150,9 +150,9 @@
 		SetTssDescriptor(&cp.iGdt[5+i], &cd.iTss);
 
 		TSubScheduler& ss = TheSubSchedulers[i];
-		ss.i_IrqNestCount = (TAny*)(-1);
-		ss.i_IrqStackTop = (TAny*)esp;
-		ss.i_Tss = &cd.iTss;
+		ss.iSSX.iIrqNestCount = (TLinAddr)(-1);
+		ss.iSSX.iIrqStackTop = (TLinAddr)esp;
+		ss.iSSX.iTss = &cd.iTss;
 		}
 
 	X86::DefaultCR0 = get_cr0();
--- a/kernel/eka/release.txt	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/release.txt	Fri Apr 16 16:24:37 2010 +0300
@@ -1,12 +1,531 @@
-Version 2.00.2066
+Version 2.00.3040
+=================
+(Made by vfebvre 09/03/2010)
+
+1.	lforynsk
+	1.	DEF144742: T_Cputime failing on winscw and HREF
+
+2.	lanerobe
+	1.	DEF144710 bootloader component not built in KHS package
+
+
+Version 2.00.3039
+=================
+(Made by vfebvre 08/03/2010)
+
+1.	jimmzhou
+	1.	PDEF144619: ARAN-82PGM3: Connecting empty cable causes error, after connecting/disconnecting
+
+2.	y153liu
+	1.	PDEF144726: Extra KErrUsbOtgPeriphNotSupported Event for Peripheral Requires More power
+
+3.	davegord
+	1.	DEF144818 Moving Model version of ReadAndParseDesHeader() can reference uninitialised data 
+
+
+Version 2.00.3038
+=================
+(Made by vfebvre 04/03/2010)
+
+1.	ahiron
+	1.	DEF144450 DIicBusChannel timeouts are handled incorrectly
+		Relates to Break Request in Polonium:
+		#455 - IIC: access to iTimeoutTimer and macros GET_TRANS_SPEED, SET_TRANS_SPEED
+	2.	DEF144748 iic_transaction.h, .inl should be exported with the appropriate macros
+	3.	DEF144488 IIC interface for setting up transaction speed is confusing
+		Relates to Break Request in Polonium:
+		#455 - IIC: access to iTimeoutTimer and macros GET_TRANS_SPEED, SET_TRANS_SPEED
+
+2.	martai
+	1.	PDEF144757 ArmMmu::ReleasePagesFromDMA() may hold system lock for unbounded time periods
+	2.	PDEF144572: DBase Reference counting contains incorrect debug assertions 
+
+3.	jessiezh
+	1.	DEF144709:T_IIC should not be limited to execution on the Emulator
+		iic build warnings and errors fix
+
+4.	genwei
+	1.	PDEF144770 USB PIL Crash after MTP server panic
+
+
+Version 2.00.3037
+=================
+(Made by vfebvre 03/03/2010)
+
+1.	cnotton
+	1.	REQ 417-52765 SMP: Product Quality SMP Kernel for Bridge
+		PackageReleaseID=451110 FeatureReleaseID=440027
+
+
+Version 2.00.3036
+=================
+(Made by vfebvre 03/03/2010)
+
+1.	mipetzol
+	1.	DEF144291 DMA: Apply fix for DEF143310 (PRM) also to DMAv2
+
+2.	marisood
+	1.	DEF144635 Coverity defect in eka/ewsrv/ky_tran.cpp (UNINIT)
+
+3.	ferporta
+	1.	DEF143491 Breakpoints in looping code can be missed when inserting/deleting and stepping
+	2.	DEF142018 Debug Sec Srv crashes if asked for an incompat srv version
+	3.	DEF143991 E32TEST T_RMDEBUG2_OEM fails on Navi-Engine with WDP enabled
+
+4.	paconway
+	1.	DEF144633 Coverity defect in onbl2.cpp (UNINIT) 
+
+
+Version 2.00.3035
+=================
+(Made by vfebvre 02/03/2010)
+
+1.	seolney
+	1.	PDEF144695 Assertion failure in DMA PIL
+		Improved t_dma. Missed interrupt cleanup is cofigurable (with macro
+		DISABLE_MISSED_IRQ_RECOVERY) in DMA PIL v1 and is removed from PIL v2
+
+2.	jimhofe
+	1.	MINOR_CHANGE: Changing policy Id to 7 for os\kernelhwsrv\kernel\eka\drivers\pbus\mmc\sdcard\XXXX\sdcard3c
+
+
+Version 2.00.3034
+=================
+(Made by vfebvre 01/03/2010)
+
+1.	vfebvre
+	1.	DEF144564 E32TEST T_PIN test failures on x86gcc.fmm (t_pin.cpp:688)
+	2.	DEF144687 OSTv2 doesn't provide a standarised way for instrumentors to add UDEB only trace
+
+2.	jimmzhou
+	1.	PDEF144575 for submission: TSW defect TSW TRLM-82BCNG: t_usb_device test fails
+	2.	PDEF144581 - for base submission: fix defect YXIO-824BQL RUsb::DeviceStateNotification doesn'
+
+
+Version 2.00.3033
+=================
+(Made by vfebvre 26/02/2010)
+
+1.	frhofman
+	1.	DEF142944: T_IDRV - fails with test drive count is more than the supportedsrives on gekko77
+
+2.	marisood
+	1.	DEF144627:Coverity defects in btrace_analyse.cpp 
+
+
+Version 2.00.3032
+=================
+(Made by vfebvre 25/02/2010)
+
+1.	davegord
+	1.	REQ417-62614 Data exports across DLL boundaries
+		PackageReleaseID=450554 FeatureReleaseID=450540
+		PNUN-7T4E35 efile/loader: Writable DLL data across DLL boundary does not work
+
+
+Version 2.00.3031
+=================
+(Made by vfebvre 25/02/2010)
+
+1.	mipetzol
+	1.	PDEF144567: Rapu Base Port DMA tests failing
+
+2.	jcoppear
+	1.	DEF144597 WDP: WDP only writes one page to swap at a time
+
+3.	gcochran
+	1.	DEF144355 - t_context locks up on Vasco/HW79 
+
+4.	hengrant
+	1.	PDEF144605 Incorrect trace metadata included in medsd.mmp
+
+
+Version 2.00.3030
+=================
+(Made by vfebvre 25/02/2010)
+
+1.	martai
+	1.	REQ 417-68452 Provide a WDP configuration for Atlantis
+		PackageReleaseID=463461 FeatureReleaseID=463452
+
+
+Version 2.00.3029
+=================
+(Made by vfebvre 23/02/2010)
+
+1.	lforynsk
+	1.	DEF144416: Occasional T_CHNOT failures on SMP configurations
+		There is a potential race condition, if the calling thread runs on a different
+		CPU than the Supervisor thread, which can result this thread being signalled
+		before the RHandleBase is fully closed.
+
+		Used EKernelHalSupervisorBarrier to wait until the Supervisor thread gets to
+		idle which is the indication that the DChangeNotifier::Complete() function has
+		returned and the Kernel memory was released (DThread object was closed)
+
+2.	vfebvre
+	1.	PDEF144553 T_SHBUF failures on X86GCC/FMM (t_shbuf:2835)
+
+3.	jcoppear
+	1.	PDEF144518 Emulator crashes when run under Carbide debugger on Windows 7
+
+
+Version 2.00.3028
+=================
+(Made by vfebvre 19/02/2010)
+
+1.	jimhofe
+	1.	MINOR_CHANGE: Removing obsolete files
+
+2.	cnotton
+	1.	DEF144396 h2.arm4.udeb.f32test.page ROMs are not built on devcedar builds
+
+
+Version 2.00.3027
+=================
+(Made by vfebvre 18/02/2010)
+
+1.	shamaden
+	1.	MINOR_CHANGE: SFL to EPL copyrights
+
+2.	vfebvre
+	1.	DEF144065 boostrap.flm is broken
+
+3.	amironen
+	1.	MINOR_CHANGE Adding GPIO Extenders support has been added
+		This project target is introducing support for GPIO Extender by introducing
+		new 32-bit pin id which consists of two parts highest 16-bit defines the GPIO
+		device(SOC or 0-15 GPIO extenders) and the lowest 16-bit defines the 65K of
+		SOC or GPIO extender pins. 
+
+4.	paconway
+	1.	PDEF144501 SD mounting issue due to postponed door-open media change
+
+
+Version 2.00.3026
+=================
+(Made by vfebvre 17/02/2010)
+
+1.	sakhghos
+	1.	PDEF144158 IMPORT_C missing from declaration of StopModeDebug::ExitPoint() RVCT4.0
+
+
+Version 2.00.3025
+=================
+(Made by vfebvre 15/02/2010)
+
+1.	tommarti
+	1.	MINOR_CHANGE Remove outdated comments from mpager.cpp
+
+
+Version 2.00.3024
+=================
+(Made by vfebvre 11/02/2010)
+
+1.	tommarti
+	1.	DEF144393 SMP: Minimum page cache size not set correctly on SMP systems
+
+
+Version 2.00.3023
+=================
+(Made by vfebvre 10/02/2010)
+
+1.	mmoate
+	1.	PackageReleaseID=446093 FeatureReleaseID=445992
+		Cryptographically-Strong Random Number Generator
+
+
+Version 2.00.3022
+=================
+(Made by vfebvre 09/02/2010)
+
+1.	cnotton
+	1.	PDEF144259: HAL header files can now been returned to platform...
+	2.	MINOR_CHANGE Fixed T_RMDEBUG_MULTI_AGENT compile issue with SYMBIAN_ENABLE_PUBLIC_PLATFORM_HEADER_SPLIT.
+
+
+Version 2.00.3021
+=================
+(Made by vfebvre 08/02/2010)
+
+1.	cnotton
+	1.	MINOR_CHANGE Fixed RM_DEBUG test code issue for SYMBIAN_ENABLE_PUBLIC_PLATFORM_HEADER_SPLIT.
+	2.	PDEF144300 eslm-82cags locmedia_ost.h is missing in wk05 NCP79 build
+
+2.	martai
+	1.	PDEF144330: FMM handles IPC aliasing inefficiently
+
+
+Version 2.00.3020
+=================
+(Made by vfebvre 05/02/2010)
+
+1.	cnotton
+	1.	MINOR_CHANGE Fixed RM_DEBUG test code issue for SYMBIAN_ENABLE_PUBLIC_PLATFORM_HEADER_SPLIT.
+
+2.	tocosgro
+	1.	DEFECT FIX: DEF144243 JHWG-822NAG FOUR_TUINT8 macro in e32cmn.h caused compiling warning in RVCT4
+		Cast to TUint32 before shift to avoid RVCT4 compiler warning.
+
+3.	coliward
+	1.	PDEF144269 WSD data is allocated incorrectly on the kernel heap
+		WSD was being allocated on the kernel heap, which was causing large Qt programs
+		to fail to start up, given that the kernel heap is limited to 16 MB.
+
+
+Version 2.00.3019
+=================
+(Made by vfebvre 05/02/2010)
+
+1.	lforynsk
+	1.	DEF144007 New Platform Independent Coverity Defect
+
+2.	djkovace
+	1.	PDEF144260:  [SymTB10.1] PL310 maintenance by IndexWay misses some ways
+
+3.	mipetzol
+	1.	PDEF144193 DMA: PIL detection of missed interrupts can fail
+		The method whereby the DMA PIL tried to detect missed PSL DMA interrupts could
+		yield false positives resulting in spurious missed interrupts which ultimately
+		led to the DMA driver crashing. The detection condition has been reworked to
+		rule out those false positives.
+
+4.	tocosgro
+	1.	MINOR_CHANGE: Use blhi rather than bhi to a panic, for call stack
+		Change bhi to blhi and blo to bllo so that LR is set for stack trace
+
+5.	gcochran
+	1.	DEF144239: t_perflogger tests fails at kern perf logger tests on production hw79/vasco
+
+
+Version 2.00.3018
+=================
+(Made by vfebvre 03/02/2010)
+
+1.	migubarr
+	1.	PDEF143960: MMC stack initialisation enables DMA when ESupportsDoubleBuffering specified 
+
+
+Version 2.00.3017
+=================
+(Made by vfebvre 02/02/2010)
+
+1.	martai
+	1.	DEF144198 FMM: The RAM zone callback function ERamZoneOp_Init isn't invoked in the FMM 
+
+
+Version 2.00.3016
+=================
+(Made by vfebvre 29/01/2010)
+
+1.	vfebvre
+	1.	PDEF144097 BTracex_ldd causing missing file warning in CTS77 image creation - TSW Defect
+
+
+Version 2.00.3015
+=================
+(Made by vfebvre 28/01/2010)
+
+1.	necliffo
+	1.	DEF144094: BGAHSMMCPTN does not check for partition table version
+		Modified BGAHSMMCPTN to check version of table is supported.
+
+
+Version 2.00.3014
+=================
+(Made by vfebvre 27/01/2010)
+
+1.	famustaf
+	1.	MINOR_CHANGE Add documentation to 'Copy' in Text Shell
+		Added documentation to state that ShellFunction::Copy will overwrite existing file(s)
+
+2.	stmansfi
+	1.	MINOR_CHANGE Improved HCR HAI in-source documentation
+
+3.	amironen
+	1.	DEF144028 HCR Get large settings API does not check for invalid arguments
+	2.	MINOR_CHANGE HCR: Add test scenarios from User Guide and improve robustness
+
+
+Version 2.00.3013
+=================
+(Made by vfebvre 27/01/2010)
+
+1.	cnotton
+	1.	MINOR_CHANGE Fixed test code for File Header Relocation
+
+
+Version 2.00.3012
+=================
+(Made by vfebvre 25/01/2010)
+
+1.	djkovace
+	1.	PDEF144004 Fix PL310 erratum 727915
+
+2.	x120li
+	1.	DEF143955 Submit UTF-16 descriptor APIs to TB101
+		Submit remaining part of PREQ2471
+
+
+Version 2.00.3011
+=================
+(Made by vfebvre 25/01/2010)
+
+1.	vfebvre
+	1.	MINOR_CHANGE Update required to base_e32.mrp for Header Relocation
+
+
+Version 2.00.3010
+=================
+(Made by vfebvre 19/01/2010)
+
+1.	gcochran
+	1.	DEF143458 E32 T_CODEPAGING test is not support large page cache TSW: EYGL-7T38TL
+
+2.	vfebvre
+	1.	MINOR_CHANGE Fix copyright notices in newly submitted files
+
+
+Version 2.00.3009
+=================
+(Made by vfebvre 18/01/2010)
+
+1.	shamaden
+	1.	DEF143830:  Memory model information missing from overnight test logs
+
+2.	necliffo
+	1.	PDEF143883: SALM-7ZQN53 WDP: EMMC drive not mountable as Mass Storage 
+
+
+Version 2.00.3008
+=================
+(Made by vfebvre 15/01/2010)
+
+1.	martai
+	1.	PDEF143818:  t_fuzzldr crashes/hangs on FMM and Datapaged ROMs
+
+2.	tommarti
+	1.	DEF140936: T_WDPSTRESS fails on NaviEngine SMPPAGE/SMPKERNEL
+
+
+Version 2.00.3007
+=================
+(Made by vfebvre 15/01/2010)
+
+1.	shamaden
+	1.	PDEF143831 t_heap fails when KHeapMinCellSize = 16 for IVAL (WDP)
+
+2.	djkovace
+	1.	DEF143786 Support platform specific mappings on 1136
+
+
+Version 2.00.3006
+=================
+(Made by vfebvre 13/01/2010)
+
+1.	vfebvre
+	1.	DEF142854 Bootstrap.flm and related bld.inf changes not submitted to the MCL
+		Update the Base Port Template so the bootstrap is built using the new
+		bootstrap FLM with Raptor.
+
+
+Version 2.00.3005
+=================
+(Made by vfebvre 12/01/2010)
+
+1.	ryharkin
+	1.	DEF143738 TConsoleKey missing iPointerNumber
+		Integrating changes from Kernel Extentions team to add iPointerNumber to TConsoleKey
+
+2.	ange
+	1.	DEF143703 Precondition is not met when USB OTG driver use Kernel API
+
+
+Version 2.00.3004
 =================
 (Made by vfebvre 11/01/2010)
 
+1.	prbetage
+	1.	DEF142990 Change to Make Files - Causing OS Base Build Failure
+
+2.	djkovace
+	1.	DEF143620 OOM defect in DVirtualPinMapping::New
+
+3.	jimmzhou
+	1.	DEF142812 SMP-Panic in the TDfcQue::ThreadFunction when USB channel is closing
+	2.	DEF142888 SMP-t_usbdi test case 1231 failed
+
+4.	cnotton
+	1.	MINOR_CHANGE Fixed test export locations for Header Relocation
+
+
+Version 2.00.3003
+=================
+(Made by vfebvre 07/01/2010)
+
+1.	necliffo
+	1.	DEF143593 WDP: Phone does not boot if SWAP drive is corrupted
+
+
+Version 2.00.3002
+=================
+(Made by vfebvre 06/01/2010)
+
+1.	kingzhan
+	1.	DEF143562 ForBaseSubmission(TSW JHAA-7YAEKV): No error note about connected USB HUB shown
+		TSW defect: JHAA-7YAEKV No error note about connected USB HUB shown.
+
+2.	wuda
+	1.	DEF143561 open for submission:EDHO-7Y3AAD, USB connection:
+		TSW Defect EDHO-7Y3AAD: USB connection: USB connection state changes after connecting the USB charger.
+
+3.	dogunjum
+	1.	DEF137221 NE1 PCI driver not confirmed SMPSAFE automatic test case missing
+
+4.	marisood
+	1.	DEF143212 Missing M&FS files from Symbian Foundation due to IP classifications
+
+5.	martai
+	1.	DEF143441 FMM: Minimise size of live list when demand paging disabled
+
+6.	shenzhou
+	1.	DEF143568 open for submission - USB using an obsoleted API to allocate endpoint resource
+
+
+Version 2.00.3001
+=================
+(Made by vfebvre 05/01/2010)
+
 1.	necliffo
 	1.	PackageReleaseID=439017 FeatureReleaseID=439013
 		eMMC Partition Plugin compatibility with Nokia flashing tools
 
 
+Version 2.00.3000
+=================
+(Made by vfebvre 29/12/2009)
+
+1.	vfebvre
+	1.	DEF142026 Core Dump Server not getting events after attaching to more than one executable
+	2.	MINOR_CHANGE Copyright header correction
+
+2.	djkovace
+	1.	MINOR_CHANGE Fix Kernel builds with  __FLUSH_PT_INTO_RAM__
+		Kerrnel doesn't build if __FLUSH_PT_INTO_RAM__ is defined in variant.mmh. The fix is quite trivial.
+
+3.	cnotton
+	1.	MINOR_CHANGE Fixed some smaller compile issues with split and relocation header changes.		
+
+4.	necliffo
+	1.	DEF143340 JPLS-7XXEAC: eMMC initialisation fails with Samsung 32GB
+
+5.	marisood
+	1.	DEF142934 Bridge: t_rescontrolcli and t_extendedrescontrolcli fail on 8500 board.
+
+6.	martai
+	1.	DEF142714 Frequent T_RAMDEFRAG failures observed on the H4
+
+
 Version 2.00.2065
 =================
 (Made by vfebvre 17/12/2009)
--- a/kernel/eka/rombuild/alltests.oby	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/rombuild/alltests.oby	Fri Apr 16 16:24:37 2010 +0300
@@ -21,7 +21,7 @@
 files=
 
 #ifdef PAGED_ROM
-data=gentestpaged.txt			Test\test_paged.cpp
+data=##BASEPATH##kernelhwsrv\kernel\eka\rombuild\gentestpaged.txt					Test\test_paged.cpp
 #endif
 
 #include <rom\##VARIANT##\kernel.iby>
@@ -53,18 +53,18 @@
 // !!! Disable platform security tests until we get the new APIs
 // #include "##BASEPATH##f32test\loader\security\ldrtest.iby"
 
-data=EPOCROOT##epoc32\release\##MAIN##\##BUILD##\t_ldrtst.exe		\sys\bin\t_ldrtst.exe
-data=EPOCROOT##epoc32\Release\##MAIN##\##BUILD##\d_exc.exe			\sys\bin\d_exc.exe
-data=EPOCROOT##epoc32\Release\##KMAIN##\##BUILD##\minkda.ldd			\sys\bin\minkda.ldd
+data=EPOCROOT##epoc32\release\##MAIN##\##BUILD##\t_ldrtst.exe						\sys\bin\t_ldrtst.exe
+data=EPOCROOT##epoc32\Release\##MAIN##\##BUILD##\d_exc.exe							\sys\bin\d_exc.exe
+data=EPOCROOT##epoc32\Release\##KMAIN##\##BUILD##\minkda.ldd						\sys\bin\minkda.ldd
 
 #ifdef PAGED_ROM
-data=gentestnonpaged.txt			Test\test_unpaged.cpp	unpaged
+data=##BASEPATH##kernelhwsrv\kernel\eka\rombuild\gentestnonpaged.txt				Test\test_unpaged.cpp	unpaged
 #endif
 
 #if defined(SMPSOAK)
-data=autoexec_smpsoak.bat			\autoexec.bat
+data=##BASEPATH##kernelhwsrv\kernel\eka\rombuild\autoexec_smpsoak.bat				\autoexec.bat
 #else
-data=autoexec_smpsoak.bat			Test\smpsoak.bat
+data=##BASEPATH##kernelhwsrv\kernel\eka\rombuild\autoexec_smpsoak.bat				Test\smpsoak.bat
 #endif
 
 data=##BASEPATH##kernelhwsrv\kerneltest\e32test\smp_demo\war_and_peace_ch1.txt		test\war_and_peace_ch1.txt
--- a/kernel/eka/rombuild/autotest.oby	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/rombuild/autotest.oby	Fri Apr 16 16:24:37 2010 +0300
@@ -21,7 +21,7 @@
 files=
 
 #ifdef PAGED_ROM
-data=gentestpaged.txt			Test\test_paged.cpp
+data=##BASEPATH##kernelhwsrv\kernel\eka\rombuild\gentestpaged.txt			Test\test_paged.cpp
 #endif
 
 #include <rom\##VARIANT##\kernel.iby>
@@ -59,5 +59,5 @@
 data=EPOCROOT##Epoc32\Release\##KMAIN##\##BUILD##\minkda.ldd			\sys\bin\minkda.ldd
 
 #ifdef PAGED_ROM
-data=gentestnonpaged.txt			Test\test_unpaged.cpp	unpaged
+data=##BASEPATH##kernelhwsrv\kernel\eka\rombuild\gentestnonpaged.txt			Test\test_unpaged.cpp	unpaged
 #endif
--- a/kernel/eka/rombuild/autotest_e32tests.oby	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/rombuild/autotest_e32tests.oby	Fri Apr 16 16:24:37 2010 +0300
@@ -21,7 +21,7 @@
 files=
 
 #ifdef PAGED_ROM
-data=gentestpaged.txt			Test\test_paged.cpp
+data=##BASEPATH##kernelhwsrv\kernel\eka\rombuild\gentestpaged.txt			Test\test_paged.cpp
 #endif
 
 #include <rom\##VARIANT##\kernel.iby>
@@ -43,5 +43,5 @@
 data=EPOCROOT##epoc32\rom\##VARIANT##\autoexec_e32test.bat				\autoexec.bat
 
 #ifdef PAGED_ROM
-data=gentestnonpaged.txt			Test\test_unpaged.cpp	unpaged
+data=##BASEPATH##kernelhwsrv\kernel\eka\rombuild\gentestnonpaged.txt			Test\test_unpaged.cpp	unpaged
 #endif
--- a/kernel/eka/rombuild/autotest_f32tests.oby	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/rombuild/autotest_f32tests.oby	Fri Apr 16 16:24:37 2010 +0300
@@ -20,7 +20,7 @@
 files=
 
 #ifdef PAGED_ROM
-data=gentestpaged.txt			Test\test_paged.cpp
+data=##BASEPATH##kernelhwsrv\kernel\eka\rombuild\gentestpaged.txt			Test\test_paged.cpp
 #endif
 
 #include <rom\##VARIANT##\kernel.iby>
@@ -56,5 +56,5 @@
 data=EPOCROOT##epoc32\rom\##VARIANT##\autoexec_f32test.bat				\autoexec.bat
 
 #ifdef PAGED_ROM
-data=gentestnonpaged.txt			Test\test_unpaged.cpp	unpaged
+data=##BASEPATH##kernelhwsrv\kernel\eka\rombuild\gentestnonpaged.txt			Test\test_unpaged.cpp	unpaged
 #endif
--- a/kernel/eka/rombuild/f32_perf_tests.oby	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/rombuild/f32_perf_tests.oby	Fri Apr 16 16:24:37 2010 +0300
@@ -34,7 +34,7 @@
 files=
 
 #ifdef PAGED_ROM
-data=gentestpaged.txt           Test\test_paged.cpp
+data=##BASEPATH##kernelhwsrv\kernel\eka\rombuild\gentestpaged.txt           Test\test_paged.cpp
 #endif
 
 #include <rom\##VARIANT##\kernel.iby>
@@ -60,7 +60,7 @@
 #endif
 
 #ifdef PAGED_ROM
-data=gentestnonpaged.txt            Test\test_unpaged.cpp   unpaged
+data=##BASEPATH##kernelhwsrv\kernel\eka\rombuild\gentestnonpaged.txt            Test\test_unpaged.cpp   unpaged
 #endif
 
 //-------------------------------------------------------------------------------------------------
--- a/kernel/eka/rombuild/f32_perf_tests_fat_exfat.oby	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/rombuild/f32_perf_tests_fat_exfat.oby	Fri Apr 16 16:24:37 2010 +0300
@@ -36,7 +36,7 @@
 files=
 
 #ifdef PAGED_ROM
-data=gentestpaged.txt           Test\test_paged.cpp
+data=##BASEPATH##kernelhwsrv\kernel\eka\rombuild\gentestpaged.txt           Test\test_paged.cpp
 #endif
 
 #include <rom\##VARIANT##\kernel.iby>
@@ -58,7 +58,7 @@
 #include <rom##E32PATH##\kernelhwsrv\kerneltest\f32test\rofs\##MAIN##test.iby>
 
 #ifdef PAGED_ROM
-data=gentestnonpaged.txt            Test\test_unpaged.cpp   unpaged
+data=##BASEPATH##kernelhwsrv\kernel\eka\rombuild\gentestnonpaged.txt            Test\test_unpaged.cpp   unpaged
 #endif
 
 //-------------------------------------------------------------------------------------------------
--- a/kernel/eka/rombuild/f32tests.oby	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/rombuild/f32tests.oby	Fri Apr 16 16:24:37 2010 +0300
@@ -22,7 +22,7 @@
 files=
 
 #ifdef PAGED_ROM
-data=gentestpaged.txt			Test\test_paged.cpp
+data=##BASEPATH##kernelhwsrv\kernel\eka\rombuild\gentestpaged.txt			Test\test_paged.cpp
 #endif
 
 #include <rom\##VARIANT##\kernel.iby>
@@ -48,7 +48,7 @@
 data=EPOCROOT##Epoc32\Release\##KMAIN##\##BUILD##\minkda.ldd			\sys\bin\minkda.ldd
 
 #ifdef PAGED_ROM
-data=gentestnonpaged.txt			Test\test_unpaged.cpp	unpaged
+data=##BASEPATH##kernelhwsrv\kernel\eka\rombuild\gentestnonpaged.txt			Test\test_unpaged.cpp	unpaged
 #endif
 
 #if defined(SYMBIAN_INCLUDE_USB_OTG_HOST) && defined(WITH_MASS_STORAGE)
--- a/kernel/eka/rombuild/h4usbmmctest_load.oby	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/rombuild/h4usbmmctest_load.oby	Fri Apr 16 16:24:37 2010 +0300
@@ -57,13 +57,13 @@
 
 #if defined(MULTIPLEROFS)
 // Built by rom.pl with type=nandtest_test
-data=tests.rofs								\rofs1.img
-data=dir.rofs								\rofs2.img
-data=extension.rofs							\rofsextension3.img
-data=dir1.rofs								\rofs4.img
-data=dir2.rofs								\rofs5.img
-data=dir3.rofs								\rofs6.img
+data=##BASEPATH##kernelhwsrv\kernel\eka\rombuild\tests.rofs								\rofs1.img
+data=##BASEPATH##kernelhwsrv\kernel\eka\rombuild\dir.rofs								\rofs2.img
+data=##BASEPATH##kernelhwsrv\kernel\eka\rombuild\extension.rofs							\rofsextension3.img
+data=##BASEPATH##kernelhwsrv\kernel\eka\rombuild\dir1.rofs								\rofs4.img
+data=##BASEPATH##kernelhwsrv\kernel\eka\rombuild\dir2.rofs								\rofs5.img
+data=##BASEPATH##kernelhwsrv\kernel\eka\rombuild\dir3.rofs								\rofs6.img
 data=\epoc32\rom\rofstest\fatimage.bin					\user3.img
 #else
-data=dir.rofs								\rofs1.img
+data=##BASEPATH##kernelhwsrv\kernel\eka\rombuild\dir.rofs								\rofs1.img
 #endif
--- a/kernel/eka/rombuild/h4usbmmctest_test.oby	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/rombuild/h4usbmmctest_test.oby	Fri Apr 16 16:24:37 2010 +0300
@@ -29,7 +29,7 @@
 files=
 
 #ifdef PAGED_ROM
-data=gentestpaged.txt			Test\test_paged.cpp paging_unmovable
+data=##BASEPATH##kernelhwsrv\kernel\eka\rombuild\gentestpaged.txt			Test\test_paged.cpp paging_unmovable
 #endif
 
 #include <rom\##VARIANT##\kernel.iby>
@@ -37,7 +37,7 @@
 #include <rom\hal\hal.iby>
 #include <rom\f32\f32.iby>
 
-data=gentestpaged.txt			Test\test_paged1.cpp paging_unmovable
+data=##BASEPATH##kernelhwsrv\kernel\eka\rombuild\gentestpaged.txt			Test\test_paged1.cpp paging_unmovable
 
 // scripts
 #if !defined(MANUALROM)
@@ -46,7 +46,7 @@
 
 #ifdef WITH_COMP
 #ifdef PAGED_ROM
-data=gentestnonpaged.txt			Test\test_unpaged.cpp	unpaged paging_unmovable
+data=##BASEPATH##kernelhwsrv\kernel\eka\rombuild\gentestnonpaged.txt			Test\test_unpaged.cpp	unpaged paging_unmovable
 #endif
 
 #ifdef MULTIPLEROFS
@@ -71,7 +71,7 @@
 
 #ifndef WITH_COMP
 #ifdef PAGED_ROM
-data=gentestnonpaged.txt			Test\test_unpaged.cpp	unpaged paging_unmovable
+data=##BASEPATH##kernelhwsrv\kernel\eka\rombuild\gentestnonpaged.txt			Test\test_unpaged.cpp	unpaged paging_unmovable
 #endif
 #endif
 
--- a/kernel/eka/rombuild/h4usbstress.oby	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/rombuild/h4usbstress.oby	Fri Apr 16 16:24:37 2010 +0300
@@ -21,7 +21,7 @@
 files=
 
 #ifdef PAGED_ROM
-data=gentestpaged.txt			Test\test_paged.cpp
+data=##BASEPATH##kernelhwsrv\kernel\eka\rombuild\gentestpaged.txt			Test\test_paged.cpp
 #endif
 
 #include <rom\##VARIANT##\kernel.iby>
@@ -46,9 +46,9 @@
 // USB Config file
 data=##BASEPATH##e32test\usb\t_usb_device\configs\h4if0a3.xml       test\h4if0a3.xml
 
-data=usbstress_autoexec.bat                                 \autoexec.bat
+data=##BASEPATH##kernelhwsrv\kernel\eka\rombuild\usbstress_autoexec.bat                                 \autoexec.bat
 data=EPOCROOT##epoc32\rom\##VARIANT##\autoexec.bat				\alltests.bat
 
 #ifdef PAGED_ROM
-data=gentestnonpaged.txt			Test\test_unpaged.cpp	unpaged
+data=##BASEPATH##kernelhwsrv\kernel\eka\rombuild\gentestnonpaged.txt			Test\test_unpaged.cpp	unpaged
 #endif
--- a/kernel/eka/rombuild/mmctest_load.oby	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/rombuild/mmctest_load.oby	Fri Apr 16 16:24:37 2010 +0300
@@ -57,13 +57,13 @@
 
 #if defined(MULTIPLEROFS)
 // Built by rom.pl with type=nandtest_test
-data=tests.rofs								\rofs1.img
-data=dir.rofs								\rofs2.img
-data=extension.rofs							\rofsextension3.img
-data=dir1.rofs								\rofs4.img
-data=dir2.rofs								\rofs5.img
-data=dir3.rofs								\rofs6.img
+data=##BASEPATH##kernelhwsrv\kernel\eka\rombuild\tests.rofs								\rofs1.img
+data=##BASEPATH##kernelhwsrv\kernel\eka\rombuild\dir.rofs								\rofs2.img
+data=##BASEPATH##kernelhwsrv\kernel\eka\rombuild\extension.rofs							\rofsextension3.img
+data=##BASEPATH##kernelhwsrv\kernel\eka\rombuild\dir1.rofs								\rofs4.img
+data=##BASEPATH##kernelhwsrv\kernel\eka\rombuild\dir2.rofs								\rofs5.img
+data=##BASEPATH##kernelhwsrv\kernel\eka\rombuild\dir3.rofs								\rofs6.img
 data=\epoc32\rom\rofstest\fatimage.bin					\user3.img
 #else
-data=dir.rofs								\rofs1.img
+data=##BASEPATH##kernelhwsrv\kernel\eka\rombuild\dir.rofs								\rofs1.img
 #endif
--- a/kernel/eka/rombuild/mmctest_test.oby	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/rombuild/mmctest_test.oby	Fri Apr 16 16:24:37 2010 +0300
@@ -31,7 +31,7 @@
 files=
 
 #ifdef PAGED_ROM
-data=gentestpaged.txt			Test\test_paged.cpp paging_unmovable
+data=##BASEPATH##kernelhwsrv\kernel\eka\rombuild\gentestpaged.txt			Test\test_paged.cpp paging_unmovable
 #endif
 
 #include <rom\##VARIANT##\kernel.iby>
@@ -62,13 +62,13 @@
 
 #endif // #ifndef EXCLUDE_TESTS
 
-data=gentestpaged.txt			Test\test_paged1.cpp paging_unmovable
+data=##BASEPATH##kernelhwsrv\kernel\eka\rombuild\gentestpaged.txt			Test\test_paged1.cpp paging_unmovable
 
 // scripts
 #if !defined(MANUALROM)
 
 #if defined(RAMSTRESS)
-data=ramstress_autoexec.bat	\autoexec.bat
+data=##BASEPATH##kernelhwsrv\kernel\eka\rombuild\ramstress_autoexec.bat	\autoexec.bat
 #define RAMSTRESS_SUFFFIX	_ramstress
 #else
 #define RAMSTRESS_SUFFFIX	
@@ -95,7 +95,7 @@
 
 #ifdef WITH_COMP
 #ifdef PAGED_ROM
-data=gentestnonpaged.txt			Test\test_unpaged.cpp	unpaged paging_unmovable
+data=##BASEPATH##kernelhwsrv\kernel\eka\rombuild\gentestnonpaged.txt			Test\test_unpaged.cpp	unpaged paging_unmovable
 #endif
 
 #ifdef MULTIPLEROFS
@@ -126,7 +126,7 @@
 
 #ifndef WITH_COMP
 #ifdef PAGED_ROM
-data=gentestnonpaged.txt			Test\test_unpaged.cpp	unpaged paging_unmovable
+data=##BASEPATH##kernelhwsrv\kernel\eka\rombuild\gentestnonpaged.txt			Test\test_unpaged.cpp	unpaged paging_unmovable
 #endif
 #endif
 
--- a/kernel/eka/rombuild/mmctest_test_e32tests.oby	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/rombuild/mmctest_test_e32tests.oby	Fri Apr 16 16:24:37 2010 +0300
@@ -36,7 +36,7 @@
 files=
 
 #ifdef PAGED_ROM
-data=gentestpaged.txt			Test\test_paged.cpp paging_unmovable
+data=##BASEPATH##kernelhwsrv\kernel\eka\rombuild\gentestpaged.txt			Test\test_paged.cpp paging_unmovable
 #endif
 
 #include <rom\##VARIANT##\kernel.iby>
@@ -56,7 +56,7 @@
 data=EPOCROOT##epoc32\release\##MAIN##\##BUILD##\t_ldrtst.exe			sys\bin\t_ldrtst.exe
 
 
-data=gentestpaged.txt			Test\test_paged1.cpp paging_unmovable
+data=##BASEPATH##kernelhwsrv\kernel\eka\rombuild\gentestpaged.txt			Test\test_paged1.cpp paging_unmovable
 
 // scripts
 #if !defined(MANUALROM)
@@ -73,7 +73,7 @@
 
 #ifdef WITH_COMP
 #ifdef PAGED_ROM
-data=gentestnonpaged.txt			Test\test_unpaged.cpp	unpaged paging_unmovable
+data=##BASEPATH##kernelhwsrv\kernel\eka\rombuild\gentestnonpaged.txt			Test\test_unpaged.cpp	unpaged paging_unmovable
 #endif
 
 rofsname = dir.rofs
@@ -100,7 +100,7 @@
 
 #ifndef WITH_COMP
 #ifdef PAGED_ROM
-data=gentestnonpaged.txt			Test\test_unpaged.cpp	unpaged paging_unmovable
+data=##BASEPATH##kernelhwsrv\kernel\eka\rombuild\gentestnonpaged.txt			Test\test_unpaged.cpp	unpaged paging_unmovable
 #endif
 #endif
 
--- a/kernel/eka/rombuild/mmctest_test_f32tests.oby	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/rombuild/mmctest_test_f32tests.oby	Fri Apr 16 16:24:37 2010 +0300
@@ -36,7 +36,7 @@
 files=
 
 #ifdef PAGED_ROM
-data=gentestpaged.txt			Test\test_paged.cpp paging_unmovable
+data=##BASEPATH##kernelhwsrv\kernel\eka\rombuild\gentestpaged.txt			Test\test_paged.cpp paging_unmovable
 #endif
 
 #include <rom\##VARIANT##\kernel.iby>
@@ -59,7 +59,7 @@
 #include <rom##E32PATH##\kernelhwsrv\kerneltest\f32test\shostmassstorage\##MAIN##test.iby>
 #endif
 
-data=gentestpaged.txt			Test\test_paged1.cpp paging_unmovable
+data=##BASEPATH##kernelhwsrv\kernel\eka\rombuild\gentestpaged.txt			Test\test_paged1.cpp paging_unmovable
 
 // scripts
 #if !defined(MANUALROM)
@@ -76,7 +76,7 @@
 
 #ifdef WITH_COMP
 #ifdef PAGED_ROM
-data=gentestnonpaged.txt			Test\test_unpaged.cpp	unpaged paging_unmovable
+data=##BASEPATH##kernelhwsrv\kernel\eka\rombuild\gentestnonpaged.txt			Test\test_unpaged.cpp	unpaged paging_unmovable
 #endif
 
 rofsname = dir.rofs
@@ -106,7 +106,7 @@
 
 #ifndef WITH_COMP
 #ifdef PAGED_ROM
-data=gentestnonpaged.txt			Test\test_unpaged.cpp	unpaged paging_unmovable
+data=##BASEPATH##kernelhwsrv\kernel\eka\rombuild\gentestnonpaged.txt			Test\test_unpaged.cpp	unpaged paging_unmovable
 #endif
 #endif
 
--- a/kernel/eka/rombuild/nandtest_erase.oby	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/rombuild/nandtest_erase.oby	Fri Apr 16 16:24:37 2010 +0300
@@ -39,7 +39,7 @@
 #include <rom\hal\hal.iby>
 #include <rom\f32\f32.iby>
 
-data=nand_test_erase_autoexec.bat				\autoexec.bat
+data=##BASEPATH##kernelhwsrv\kernel\eka\rombuild\nand_test_erase_autoexec.bat				\autoexec.bat
 
 #if defined(LMNAND2)
 data=\epoc32\rom\LMNAND2\nandtest_erase_autoexec.bat			\test\nandtest_erase_autoexec.bat
--- a/kernel/eka/rombuild/nandtest_load.oby	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/rombuild/nandtest_load.oby	Fri Apr 16 16:24:37 2010 +0300
@@ -70,18 +70,18 @@
 
 #if defined(MULTIPLEROFS)
 // Built by rom.pl with type=nandtest_test
-data=tests.rofs								\rofs1.img
-data=dir.rofs								\rofs2.img
-data=extension.rofs							\rofsextension3.img
-data=dir1.rofs								\rofs4.img
-data=dir2.rofs								\rofs5.img
-data=dir3.rofs								\rofs6.img
+data=##BASEPATH##kernelhwsrv\kernel\eka\rombuild\tests.rofs								\rofs1.img
+data=##BASEPATH##kernelhwsrv\kernel\eka\rombuild\dir.rofs								\rofs2.img
+data=##BASEPATH##kernelhwsrv\kernel\eka\rombuild\extension.rofs							\rofsextension3.img
+data=##BASEPATH##kernelhwsrv\kernel\eka\rombuild\dir1.rofs								\rofs4.img
+data=##BASEPATH##kernelhwsrv\kernel\eka\rombuild\dir2.rofs								\rofs5.img
+data=##BASEPATH##kernelhwsrv\kernel\eka\rombuild\dir3.rofs								\rofs6.img
 data=\epoc32\rom\rofstest\fatimage.bin		\user3.img
 #else
-data=dir.rofs								\rofs1.img
-data=extension.rofs							\rofsextension2.img
+data=##BASEPATH##kernelhwsrv\kernel\eka\rombuild\dir.rofs								\rofs1.img
+data=##BASEPATH##kernelhwsrv\kernel\eka\rombuild\extension.rofs							\rofsextension2.img
 #endif
 
-data=smr1.img								\smr1.img
+data=##BASEPATH##kernelhwsrv\kernel\eka\rombuild\smr1.img								\smr1.img
 data=\epoc32\data\smr_part_102400.img		\smr2.img
 
--- a/kernel/eka/rombuild/nandtest_test.oby	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/rombuild/nandtest_test.oby	Fri Apr 16 16:24:37 2010 +0300
@@ -40,7 +40,7 @@
 files=
 
 #ifdef PAGED_ROM
-data=gentestpaged.txt			Test\test_paged.cpp paging_unmovable
+data=##BASEPATH##kernelhwsrv\kernel\eka\rombuild\gentestpaged.txt			Test\test_paged.cpp paging_unmovable
 #endif
 
 #include <rom\##VARIANT##\kernel.iby>
@@ -70,7 +70,7 @@
 data=EPOCROOT##epoc32\release\##MAIN##\##BUILD##\t_ldrtst.exe			sys\bin\t_ldrtst.exe
 
 #ifdef PAGED_ROM
-data=gentestpaged.txt			Test\test_paged1.cpp paging_unmovable
+data=##BASEPATH##kernelhwsrv\kernel\eka\rombuild\gentestpaged.txt			Test\test_paged1.cpp paging_unmovable
 #endif
 
 #endif // #ifndef EXCLUDE_TESTS
@@ -78,7 +78,7 @@
 // scripts
 #if !defined(MANUALROM)
 #if defined(RAMSTRESS)
-data=ramstress_autoexec.bat			\autoexec.bat
+data=##BASEPATH##kernelhwsrv\kernel\eka\rombuild\ramstress_autoexec.bat			\autoexec.bat
 #define RAMSTRESS_SUFFFIX	_ramstress
 #else
 #define RAMSTRESS_SUFFFIX	
@@ -109,7 +109,7 @@
 
 #ifdef WITH_COMP
 #ifdef PAGED_ROM
-data=gentestnonpaged.txt			Test\test_unpaged.cpp	unpaged paging_unmovable
+data=##BASEPATH##kernelhwsrv\kernel\eka\rombuild\gentestnonpaged.txt			Test\test_unpaged.cpp	unpaged paging_unmovable
 #endif
 
 #ifdef MULTIPLEROFS
@@ -149,7 +149,7 @@
 
 #ifndef WITH_COMP
 #ifdef PAGED_ROM
-data=gentestnonpaged.txt			Test\test_unpaged.cpp	unpaged paging_unmovable
+data=##BASEPATH##kernelhwsrv\kernel\eka\rombuild\gentestnonpaged.txt			Test\test_unpaged.cpp	unpaged paging_unmovable
 #endif
 #endif
 
--- a/kernel/eka/rombuild/nandtest_test_e32tests.oby	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/rombuild/nandtest_test_e32tests.oby	Fri Apr 16 16:24:37 2010 +0300
@@ -35,7 +35,7 @@
 files=
 
 #ifdef PAGED_ROM
-data=gentestpaged.txt			Test\test_paged.cpp paging_unmovable
+data=##BASEPATH##kernelhwsrv\kernel\eka\rombuild\gentestpaged.txt			Test\test_paged.cpp paging_unmovable
 #endif
 
 #include <rom\##VARIANT##\kernel.iby>
@@ -63,13 +63,13 @@
 data=EPOCROOT##epoc32\release\##MAIN##\##BUILD##\t_ldrtst.exe			sys\bin\t_ldrtst.exe
 
 #ifdef PAGED_ROM
-data=gentestpaged.txt			Test\test_paged1.cpp paging_unmovable
+data=##BASEPATH##kernelhwsrv\kernel\eka\rombuild\gentestpaged.txt			Test\test_paged1.cpp paging_unmovable
 #endif
 
 // scripts
 #if !defined(MANUALROM)
 #if defined(RAMSTRESS)
-data=ramstress_autoexec.bat			\autoexec.bat
+data=##BASEPATH##kernelhwsrv\kernel\eka\rombuild\ramstress_autoexec.bat			\autoexec.bat
 #define RAMSTRESS_SUFFFIX	_ramstress
 #else
 #define RAMSTRESS_SUFFFIX	
@@ -87,7 +87,7 @@
 
 #ifdef WITH_COMP
 #ifdef PAGED_ROM
-data=gentestnonpaged.txt			Test\test_unpaged.cpp	unpaged paging_unmovable
+data=##BASEPATH##kernelhwsrv\kernel\eka\rombuild\gentestnonpaged.txt			Test\test_unpaged.cpp	unpaged paging_unmovable
 #endif
 
 #ifdef MULTIPLEROFS
@@ -123,7 +123,7 @@
 
 #ifndef WITH_COMP
 #ifdef PAGED_ROM
-data=gentestnonpaged.txt			Test\test_unpaged.cpp	unpaged paging_unmovable
+data=##BASEPATH##kernelhwsrv\kernel\eka\rombuild\gentestnonpaged.txt			Test\test_unpaged.cpp	unpaged paging_unmovable
 #endif
 #endif
 
--- a/kernel/eka/rombuild/nandtest_test_f32tests.oby	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/rombuild/nandtest_test_f32tests.oby	Fri Apr 16 16:24:37 2010 +0300
@@ -34,7 +34,7 @@
 files=
 
 #ifdef PAGED_ROM
-data=gentestpaged.txt			Test\test_paged.cpp paging_unmovable
+data=##BASEPATH##kernelhwsrv\kernel\eka\rombuild\gentestpaged.txt			Test\test_paged.cpp paging_unmovable
 #endif
 
 #include <rom\##VARIANT##\kernel.iby>
@@ -68,13 +68,13 @@
 #endif
 
 #ifdef PAGED_ROM
-data=gentestpaged.txt			Test\test_paged1.cpp paging_unmovable
+data=##BASEPATH##kernelhwsrv\kernel\eka\rombuild\gentestpaged.txt			Test\test_paged1.cpp paging_unmovable
 #endif
 
 // scripts
 #if !defined(MANUALROM)
 #if defined(RAMSTRESS)
-data=ramstress_autoexec.bat			\autoexec.bat
+data=##BASEPATH##kernelhwsrv\kernel\eka\rombuild\ramstress_autoexec.bat			\autoexec.bat
 #define RAMSTRESS_SUFFFIX	_ramstress
 #else
 #define RAMSTRESS_SUFFFIX	
@@ -92,7 +92,7 @@
 
 #ifdef WITH_COMP
 #ifdef PAGED_ROM
-data=gentestnonpaged.txt			Test\test_unpaged.cpp	unpaged paging_unmovable
+data=##BASEPATH##kernelhwsrv\kernel\eka\rombuild\gentestnonpaged.txt			Test\test_unpaged.cpp	unpaged paging_unmovable
 #endif
 
 #ifdef MULTIPLEROFS
@@ -100,7 +100,7 @@
 #else
 rofsname = dir.rofs
 #endif	//MULTIPLEROFS
-rofssize = 0x500000
+rofssize = 0x520000
 
 #ifdef PAGED_ROM
 PAGINGOVERRIDE DEFAULTPAGED
@@ -129,7 +129,7 @@
 
 #ifndef WITH_COMP
 #ifdef PAGED_ROM
-data=gentestnonpaged.txt			Test\test_unpaged.cpp	unpaged paging_unmovable
+data=##BASEPATH##kernelhwsrv\kernel\eka\rombuild\gentestnonpaged.txt			Test\test_unpaged.cpp	unpaged paging_unmovable
 #endif
 #endif
 
--- a/kernel/eka/rombuild/ost.iby	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/rombuild/ost.iby	Fri Apr 16 16:24:37 2010 +0300
@@ -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.
--- a/kernel/eka/rombuild/t_soak.oby	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/rombuild/t_soak.oby	Fri Apr 16 16:24:37 2010 +0300
@@ -26,7 +26,7 @@
 
 file=\EPOC32\RELEASE\##MAIN##\##BUILD##\T_SOAK.EXE          sys\bin\T_SOAK.EXE
 
-data=t_soak_autoexec.bat \autoexec.bat
+data=##BASEPATH##kernelhwsrv\kernel\eka\rombuild\t_soak_autoexec.bat \autoexec.bat
 
 
 
--- a/kernel/eka/rombuild/ubootldr.oby	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/rombuild/ubootldr.oby	Fri Apr 16 16:24:37 2010 +0300
@@ -29,4 +29,4 @@
 
 file=\Epoc32\Release\##MAIN##\##BUILD##\_##VARIANT##_bootldr.exe			Sys\Bin\bootldr.exe
 device[VARID]=\epoc32\release\##KMAIN##\##BUILD##\_##VARIANT##_ubootldr.ldd	Sys\Bin\ubootldr.ldd
-data=ubootldr.autoexec.bat												autoexec.bat
+data=##BASEPATH##kernelhwsrv\kernel\eka\rombuild\ubootldr.autoexec.bat												autoexec.bat
--- a/kernel/eka/rombuild/user.iby	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/rombuild/user.iby	Fri Apr 16 16:24:37 2010 +0300
@@ -67,7 +67,7 @@
 #endif
 
 
-#ifndef USE_CUSTOM_MMC_PARTITION
+#if !(defined(INST_X86) || defined(INST_X86GCC)) && !defined(USE_CUSTOM_MMC_PARTITION)
 extension[VARID]=\Epoc32\Release\##KMAIN##\##BUILD##\EMMCPTN.DLL                   \Sys\Bin\EMMCPTN.DLL
 #endif
 
--- a/kernel/eka/rombuild/utrace.iby	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernel/eka/rombuild/utrace.iby	Fri Apr 16 16:24:37 2010 +0300
@@ -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/kernelhwsrv_info/kernelhwsrv_metadata/kernelhwsrv_metadata.mrp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kernelhwsrv_info/kernelhwsrv_metadata/kernelhwsrv_metadata.mrp	Fri Apr 16 16:24:37 2010 +0300
@@ -1,3 +1,19 @@
+#
+# 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 "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: 
+#
+
 component           kernelhwsrv_metadata
 source   \sf\os\kernelhwsrv\kernelhwsrv_info\kernelhwsrv_metadata 
 source   \sf\os\kernelhwsrv\package_definition.xml
--- a/kerneltest/e32test/active/t_timerduration.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kerneltest/e32test/active/t_timerduration.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -52,6 +52,48 @@
 TInt* TimeValue;
 TInt TimeMin[KMaxTimeValues];
 TInt TimeMax[KMaxTimeValues];
+
+RTimer TheTimer;
+
+void After(TInt aTime)
+	{
+	TRequestStatus s;
+	TheTimer.HighRes(s, aTime);
+	User::WaitForRequest(s);
+	}
+
+TInt Again(TInt aTime)
+	{
+	TRequestStatus s;
+	TheTimer.AgainHighRes(s, aTime);
+	User::WaitForRequest(s);
+	return s.Int();
+	}
+
+void WaitInSteps(TUint aWait, TUint aPeriod, TUint aSteps)
+	{
+	TUint total_ticks = aWait / aPeriod;
+	TUint remain = total_ticks;
+	TUint steps = aSteps > remain ? remain : aSteps;
+	TUint carry = 0;
+	TUint step = 0;
+	while (remain)
+		{
+		TUint stepLength = remain / steps;
+		carry += stepLength;
+		TUint us = carry * aPeriod;
+		TInt r = KErrNone;
+		if (step==0)
+			After(us);
+		else
+			r = Again(us);
+		if (r==KErrNone)
+			carry = 0;
+		++step;
+		--steps;
+		remain -= stepLength;
+		}
+	}
 	
 void calcStats(TInt i)
 	{
@@ -66,20 +108,20 @@
 
 void printStats()
 	{
-	test.Printf(_L("Value\tMin\tMax"));
+	test.Printf(_L("  Value     Min      Max\n"));
 	for (TInt i=0;i<KMaxTimeValues;++i)
 		{
 		if (TimeValue[i]<0) break;
-		test.Printf(_L("%d\t%d\t%d"),TimeValue[i],TimeMin[i],TimeMax[i]);
+		test.Printf(_L("%8d %8d %8d\n"),TimeValue[i],TimeMin[i],TimeMax[i]);
 		}
 	}
 
 #define __BEFORE_WAIT__ \
-	test.Printf(_L("Measuring value(%d measurements at each value):"), MaxTimeMeasurements);\
+	test.Printf(_L("Measuring value(%d measurements at each value):\n"), MaxTimeMeasurements);\
 	for (i=0;i<KMaxTimeValues;++i)\
 		{\
 		if (TimeValue[i]<0) break;\
-		test.Printf(_L("%d microseconds ..."),TimeValue[i]);\
+		test.Printf(_L("%8d microseconds ...\n"),TimeValue[i]);\
 		value = TimeValue[i];\
 		for (j=0; j<MaxTimeMeasurements; ++j)\
 			{\
@@ -102,12 +144,13 @@
 	test.Title();
 	test.Start(_L("Timer resolution test"));
 	test.SetLogged(ETrue);
+	test(TheTimer.CreateLocal()==KErrNone);
 	RThread This;
 	This.SetPriority(EPriorityRealTime);
 	TUint tick1,tick2;
 	TInt value, tickPeriod;
 	HAL::Get(HAL::ENanoTickPeriod, tickPeriod);
-	test.Printf(_L("tickPeriod=%d"),tickPeriod);
+	test.Printf(_L("tickPeriod=%d\n"),tickPeriod);
 ///////////////////////////////////////////
 	test.Next(_L("Calibrate"));
 	MaxTimeMeasurements = KMaxTimeMeasurements;
@@ -172,6 +215,45 @@
 		}
 #endif
 ///////////////////////////////////////////
+	test.Next(_L("RTimer::AgainHighRes (2 steps)"));
+	MaxTimeMeasurements = KMaxTimeMeasurements;
+	TInt TimeValues5[KMaxTimeValues]={2000,4000,8000,16000,32000,64000,128000,-1};
+	TimeValue = &TimeValues5[0];
+	__BEFORE_WAIT__
+	__MEASURE1__
+			WaitInSteps(value, tickPeriod, 2);
+	__MEASURE2__
+	__AFTER_WAIT__
+#if defined(__EPOC32__)
+	//Check that RTimer::AgainHighRes() calls completed within boundaries
+	for (k = 0; k<KMaxTimeValues; k++)
+		{
+		if (TimeValue[k] == -1) break;
+		test(TimeValue[k] <= TimeMin[k]);
+		test((TimeValue[k] + 2*tickPeriod) >= TimeMax[k]);
+		}
+#endif
+///////////////////////////////////////////
+	test.Next(_L("RTimer::AgainHighRes (5 steps)"));
+	MaxTimeMeasurements = KMaxTimeMeasurements;
+	TInt TimeValues6[KMaxTimeValues]={4000,8000,16000,32000,64000,128000,-1};
+	TimeValue = &TimeValues6[0];
+	__BEFORE_WAIT__
+	__MEASURE1__
+			WaitInSteps(value, tickPeriod, 5);
+	__MEASURE2__
+	__AFTER_WAIT__
+#if defined(__EPOC32__)
+	//Check that RTimer::AgainHighRes() calls completed within boundaries
+	for (k = 0; k<KMaxTimeValues; k++)
+		{
+		if (TimeValue[k] == -1) break;
+		test(TimeValue[k] <= TimeMin[k]);
+		test((TimeValue[k] + 2*tickPeriod) >= TimeMax[k]);
+		}
+#endif
+///////////////////////////////////////////
+	TheTimer.Close();
 	test.End();
 	return(KErrNone);
 	}
--- a/kerneltest/e32test/bench/t_r64bm.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kerneltest/e32test/bench/t_r64bm.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -26,7 +26,7 @@
 const TInt KAverageOverInSeconds=10;
 const TInt KNumberOfCalculationsPerLoop=10;
 
-volatile TUint count;
+volatile TUint Count;
 #ifdef T_R64BM_WITH_VFP
 RTest test(_L("T_VFPBM"));
 #else
@@ -58,9 +58,10 @@
 		}
     thread.Resume();
     User::After(1000000);
-    count=0;
+    TUint initial = Count;
     User::After(KAverageOverInSeconds*1000000);
-    TUint64 result = count;
+	TUint final = Count;
+    TUint64 result = TUint64(final - initial);
 	result *= TUint64(KNumberOfCalculationsPerLoop);
 	result /= TUint64(KAverageOverInSeconds);
 	TUint r32 = (TUint)result;
--- a/kerneltest/e32test/bench/t_r64fnc.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kerneltest/e32test/bench/t_r64fnc.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -33,15 +33,24 @@
 								76.1,	9,	56.1,	1/9,
 								1/3,	22,	99.7,	42};
 
-GLREF_D volatile TUint count;
+GLREF_D volatile TUint Count;
+
+#include <e32btrace.h>
+
+void Step()
+	{
+	if (++Count & 0xffff)
+		return;
+	BTrace4(BTrace::ETest1, 0, Count);
+	}
 
 TInt TReal64Addition(TAny*)
     {
-	count=0;
+	Count=0;
 
     FOREVER
         {
-		r=AntiOptimization[count & 0xf];
+		r=AntiOptimization[Count & 0xf];
 		r+=One;
 		r+=One;
 		r+=One;
@@ -52,17 +61,17 @@
 		r+=One;
 		r+=One;
 		r+=One;
-        count++;
+        Step();
         }
     }
 
 TInt TReal64Subtraction(TAny*)
     {
-	count=0;
+	Count=0;
 
     FOREVER
         {
-		r=AntiOptimization[count & 0xf];
+		r=AntiOptimization[Count & 0xf];
 		r-=Ten;
 		r-=Ten;
 		r-=Ten;
@@ -73,16 +82,16 @@
 		r-=Ten;
 		r-=Ten;
 		r-=Ten;
-        count++;
+        Step();
         }
     }
 
 TInt TReal64Multiplication(TAny*)
     {
-	count=0;
+	Count=0;
     FOREVER
         {
-		r=AntiOptimization[count & 0xf];
+		r=AntiOptimization[Count & 0xf];
 		r*=Pi;
 		r*=Pi;
 		r*=Pi;
@@ -93,17 +102,17 @@
 		r*=Pi;
 		r*=Pi;
 		r*=Pi;
-        count++;
+        Step();
         }
     }
 
 TInt TReal64Division(TAny*)
     {
-	count=0;
+	Count=0;
 	
     FOREVER
         {
-		r=AntiOptimization[count & 0xf];
+		r=AntiOptimization[Count & 0xf];
 		r/=Ten;
 		r/=Ten;
 		r/=Ten;
@@ -114,12 +123,13 @@
 		r/=Ten;
 		r/=Ten;
 		r/=Ten;
-        count++;
+        Step();
         }
     }
 
 TInt TRealSqrt(TAny*)
     {
+	Count=0;
 
 	TReal r;
 
@@ -135,12 +145,13 @@
 		Math::Sqrt(r,1.414213562373);
 		Math::Sqrt(r,1.7320508078);
 		Math::Sqrt(r,299792458.0);
-        count++;
+        Step();
         }
     }
 
 TInt TRealSin(TAny*)
     {
+	Count=0;
 
 	TReal r=7;
 
@@ -156,12 +167,13 @@
 		Math::Sin(r,8.0);
 		Math::Sin(r,9.0);
 		Math::Sin(r,-1.0);
-        count++;
+        Step();
         }
     }
 
 TInt TRealLn(TAny*)
     {
+	Count=0;
 
 	TReal r=7;
 
@@ -177,12 +189,13 @@
 		Math::Ln(r,11.0);
 		Math::Ln(r,13.0);
 		Math::Ln(r,17.0);
-        count++;
+        Step();
         }
     }
 
 TInt TRealExp(TAny*)
     {
+	Count=0;
 
 	TReal r=7;
 
@@ -198,12 +211,13 @@
 		Math::Exp(r,-2.0);
 		Math::Exp(r,11.0);
 		Math::Exp(r,-11.0);
-        count++;
+        Step();
         }
     }
 
 TInt TRealAsin(TAny*)
     {
+	Count=0;
 
 	TReal r=7;
 
@@ -219,12 +233,13 @@
 		Math::ASin(r,0.8);
 		Math::ASin(r,0.9);
 		Math::ASin(r,-0.9);
-        count++;
+        Step();
         }
     }
 
 TInt TRealAtan(TAny*)
     {
+	Count=0;
 
 	TReal r=7;
 
@@ -240,12 +255,13 @@
 		Math::ATan(r,1.5);
 		Math::ATan(r,1.7);
 		Math::ATan(r,2.9);
-        count++;
+        Step();
         }
     }
 
 TInt TRealTan(TAny*)
     {
+	Count=0;
 
 	TReal r=7;
 
@@ -261,12 +277,13 @@
 		Math::Tan(r,8.0);
 		Math::Tan(r,9.0);
 		Math::Tan(r,-1.0);
-        count++;
+        Step();
         }
     }
 
 TInt TRealPower(TAny*)
     {
+	Count=0;
 
 	TReal r=7;
 
@@ -282,7 +299,7 @@
 		Math::Pow(r,95.4,1.57079);
 		Math::Pow(r,317.9,0.3333333333333333);
 		Math::Pow(r,299792458,-2.718281828459045235);
-        count++;
+        Step();
         }
     }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/bmarm/i2c_ctrlessu.def	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,8 @@
+EXPORTS
+	CreatePhysicalDevice__Fv @ 1 NONAME R3UNUSED ; CreatePhysicalDevice(void)
+	DfcFunc__20TIicBusSlaveCallbackPv @ 2 NONAME R3UNUSED ; TIicBusSlaveCallback::DfcFunc(void *)
+	__25DIicBusChannelMasterSlaveQ214DIicBusChannel8TBusTypeQ214DIicBusChannel14TChannelDuplexP20DIicBusChannelMasterP19DIicBusChannelSlave @ 3 NONAME ; DIicBusChannelMasterSlave::DIicBusChannelMasterSlave(DIicBusChannel::TBusType, DIicBusChannel::TChannelDuplex, DIicBusChannelMaster *, DIicBusChannelSlave *)
+	__31DSimulatedIicBusChannelSlaveI2cQ214DIicBusChannel8TBusTypeQ214DIicBusChannel14TChannelDuplex @ 4 NONAME R3UNUSED ; DSimulatedIicBusChannelSlaveI2c::DSimulatedIicBusChannelSlaveI2c(DIicBusChannel::TBusType, DIicBusChannel::TChannelDuplex)
+	__32DSimulatedIicBusChannelMasterI2cQ214DIicBusChannel8TBusTypeQ214DIicBusChannel14TChannelDuplex @ 5 NONAME R3UNUSED ; DSimulatedIicBusChannelMasterI2c::DSimulatedIicBusChannelMasterI2c(DIicBusChannel::TBusType, DIicBusChannel::TChannelDuplex)
+	__37DSimulatedIicBusChannelMasterSlaveI2cQ214DIicBusChannel8TBusTypeQ214DIicBusChannel14TChannelDuplexP32DSimulatedIicBusChannelMasterI2cP31DSimulatedIicBusChannelSlaveI2c @ 6 NONAME ; DSimulatedIicBusChannelMasterSlaveI2c::DSimulatedIicBusChannelMasterSlaveI2c(DIicBusChannel::TBusType, DIicBusChannel::TChannelDuplex, DSimulatedIicBusChannelMasterI2c *, DSimulatedIicBusChannelSlaveI2c *)
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/bmarm/spi_ctrlessu.def	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,7 @@
+EXPORTS
+	CreatePhysicalDevice__Fv @ 1 NONAME R3UNUSED ; CreatePhysicalDevice(void)
+	DfcFunc__20TIicBusSlaveCallbackPv @ 2 NONAME R3UNUSED ; TIicBusSlaveCallback::DfcFunc(void *)
+	__25DIicBusChannelMasterSlaveQ214DIicBusChannel8TBusTypeQ214DIicBusChannel14TChannelDuplexP20DIicBusChannelMasterP19DIicBusChannelSlave @ 3 NONAME ; DIicBusChannelMasterSlave::DIicBusChannelMasterSlave(DIicBusChannel::TBusType, DIicBusChannel::TChannelDuplex, DIicBusChannelMaster *, DIicBusChannelSlave *)
+	__31DSimulatedIicBusChannelSlaveSpiQ214DIicBusChannel8TBusTypeQ214DIicBusChannel14TChannelDuplex @ 4 NONAME R3UNUSED ; DSimulatedIicBusChannelSlaveSpi::DSimulatedIicBusChannelSlaveSpi(DIicBusChannel::TBusType, DIicBusChannel::TChannelDuplex)
+	__32DSimulatedIicBusChannelMasterSpiQ214DIicBusChannel8TBusTypeQ214DIicBusChannel14TChannelDuplex @ 5 NONAME R3UNUSED ; DSimulatedIicBusChannelMasterSpi::DSimulatedIicBusChannelMasterSpi(DIicBusChannel::TBusType, DIicBusChannel::TChannelDuplex)
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/bmarm/t_wsd_dl1.def	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,4 @@
+EXPORTS
+	ExportedData @ 1 NONAME ; TInt32 ExportedData
+	CheckExportedDataAddress__FPv @ 2 NONAME ; void CheckExportedDataAddress(void* aDataAddr)
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/bmarm/t_wsd_dl2.def	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,4 @@
+EXPORTS
+	GetAddressOfDataProxy__FRiRPvT1 @ 1 NONAME R3UNUSED ; GetAddressOfDataProxy(int &, void *&, void *&)
+	CheckWritableStaticData__Fv @ 2 NONAME ; CheckWritablStaticData(void)
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/bmarm/t_wsd_dl3.def	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,7 @@
+EXPORTS
+	GetAddressOfData__FRiRPvT1 @ 1 NONAME R3UNUSED ; GetAddressOfData(int &, void *&, void *&)
+	TestDataSize @ 2 NONAME ; (null)
+	WritableTestData @ 3 NONAME ; (null)
+	PointerToStaticData @ 4 NONAME ; (null)
+	PointerToWritableData @ 5 NONAME ; (null)
+
--- a/kerneltest/e32test/buffer/Unicode, Inc License Agreement - Data Files and Software.txt	Tue Feb 02 01:24:03 2010 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,21 +0,0 @@
-                          EXHIBIT 1
-UNICODE, INC. LICENSE AGREEMENT - DATA FILES AND SOFTWARE
-
-Unicode Data Files include all data files under the directories http://www.unicode.org/Public/, http://www.unicode.org/reports/, and http://www.unicode.org/cldr/data/ . Unicode Software includes any source code published in the Unicode Standard or under the directories http://www.unicode.org/Public/, http://www.unicode.org/reports/, and http://www.unicode.org/cldr/data/.
-
-NOTICE TO USER: Carefully read the following legal agreement. BY DOWNLOADING, INSTALLING, COPYING OR OTHERWISE USING UNICODE INC.'S DATA FILES ("DATA FILES"), AND/OR SOFTWARE ("SOFTWARE"), YOU UNEQUIVOCALLY ACCEPT, AND AGREE TO BE BOUND BY, ALL OF THE TERMS AND CONDITIONS OF THIS AGREEMENT. IF YOU DO NOT AGREE, DO NOT DOWNLOAD, INSTALL, COPY, DISTRIBUTE OR USE THE DATA FILES OR SOFTWARE.
-
-COPYRIGHT AND PERMISSION NOTICE
-
-Copyright © 1991-2009 Unicode, Inc. All rights reserved. Distributed under the Terms of Use in http://www.unicode.org/copyright.html.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of the Unicode data files and any associated documentation (the "Data Files") or Unicode software and any associated documentation (the "Software") to deal in the Data Files or Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, and/or sell copies of the Data Files or Software, and to permit persons to whom the Data Files or Software are furnished to do so, provided that (a) the above copyright notice(s) and this permission notice appear with all copies of the Data Files or Software, (b) both the above copyright notice(s) and this permission notice appear in associated documentation, and (c) there is clear notice in each modified Data File or in the Software as well as in the documentation associated with the Data File(s) or Software that the data or software has been modified.
-
-THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THE DATA FILES OR SOFTWARE.
-
-Except as contained in this notice, the name of a copyright holder shall not be used in advertising or otherwise to promote the sale, use or other dealings in these Data Files or Software without prior written authorization of the copyright holder.
-
-
---------------------------------------------------------------------------------
-
-Unicode and the Unicode logo are trademarks of Unicode, Inc., and may be registered in some jurisdictions. All other trademarks and registered trademarks mentioned herein are the property of their respective owners.
--- a/kerneltest/e32test/buffer/t_char.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kerneltest/e32test/buffer/t_char.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -1,7 +1,7 @@
 // Copyright (c) 2008-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"
+// under the terms of "Eclipse Public License v1.0"
 // which accompanies this distribution, and is available
 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
 //
@@ -370,9 +370,9 @@
 	}
 
 
-//////////////////////////////////////////////
+//
 // Test Fold, Fold(TChar::EFoldAccents), Collate, LowerCase, UpperCase
-////////////////////////////////////////////
+//
 template<class TCharType>
 GLDEF_C void TestTChar<TCharType>::Test4(TCharTypes CharType)
 	{
--- a/kerneltest/e32test/buffer/t_des.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kerneltest/e32test/buffer/t_des.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -1353,6 +1353,52 @@
 LOCAL_C void testSurrogateAwareInterfaces()
 	{
 	test.Next(_L("new TDesC interfaces"));
+	TInt count;
+	
+	// string 1: all BMP characters
+	_LIT(KBmpString1,			"abcdcf");
+	TBuf16<128> s01(KBmpString1);
+	test(s01.FindCorruptSurrogate() == KErrNotFound);
+	test(s01.Locate2('f') == 5);
+	test(s01.LocateReverse2('c') == 4);
+	test(s01.Match(_L("*cdc*")) == 2);
+	test(s01.Match2(_L("*bcdc*")) == 1);
+	test(s01.Match2(_L("*c?c*")) == 2);
+	
+	// string 2: all non-BMP characters
+	_LIT(KSurrogateString1,		"\xD840\xDDAA\xD840\xDDAB\xD840\xDDAC\xD840\xDDAD\xD840\xDDAE\xD840\xDDAF");
+	TBuf16<128> s02(KSurrogateString1);
+	for (count=0; count<=11; count++)
+	test(s02.FindCorruptSurrogate() == KErrNotFound);
+	test(s02.Locate2(0x201AE) == 8);
+	test(s02.LocateReverse2(0x201AC) == 4);
+	test(s02.Match2(_L("*\xD840\xDDAB\xD840\xDDAC*")) == 2);
+	test(s02.Match2(_L("*\xD840\xDDBB*")) == KErrNotFound);
+	test(s02.Match2(_L("*\xD840\xDDAD*")) == 6);
+
+	// string 3: mixed
+	_LIT(KMixedString1,			"ab\xD840\xDDAD e\xD801\xDC27");
+	TBuf16<128> s03(KMixedString1);
+	test(s03.FindCorruptSurrogate() == KErrNotFound);
+	test(s03.Locate2(0x10427) == 6);
+	test(s03.Locate2('e') == 5);
+	test(s03.LocateF2(0x1044F) == 6);	// lower case=U+1044F(D801, DC4F), upper case=U+10427(D801, DC27), title case=U+10427
+	TBuf16<128> s03a;
+	s03a.CopyLC2(s03);
+	s03a.Append2(0x21000);
+	TBuf16<128> s03b;
+	s03b.Copy(s03);
+	
+	s03b.AppendFill2(0x21000, 2);
+	test(s03a != s03b);
+	test(s03.Match2(_L("*b\xD840\xDDAD*")) == 1);
+	test(s03.Match2(_L("* e*")) == 4);
+	test(s03.Match2(_L("*\xD840\xDDAD?*")) == 2);
+	
+	// string 4: mixed, with corrupt surrogate
+	_LIT(KCorruptString1,		"ab\xD840\xDDAD e\xDDAD\xD840");
+	TBuf16<128> s04(KCorruptString1);
+	test(s04.FindCorruptSurrogate() == 6);
 	}
 
 
--- a/kerneltest/e32test/buffer/t_match.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kerneltest/e32test/buffer/t_match.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -76,47 +76,6 @@
 #include "CompareImp.h"
 #include "u32std.h"
 
-static inline TBool IsSupplementary(TUint aChar)
-/**
-@param aChar The 32-bit code point value of a Unicode character.
-
-@return True, if aChar is supplementary character; false, otherwise.
-*/
-        {
-        return (aChar > 0xFFFF);
-        }
-
-static inline TText16 GetHighSurrogate(TUint aChar)
-/**
-Retrieve the high surrogate of a supplementary character.
-
-@param aChar The 32-bit code point value of a Unicode character.
-
-@return High surrogate of aChar, if aChar is a supplementary character;
-        aChar itself, if aChar is not a supplementary character.
-
-@see TChar::GetLowSurrogate
-*/
-        {
-        return STATIC_CAST(TText16, 0xD7C0 + (aChar >> 10));
-        }
-
-static inline TText16 GetLowSurrogate(TUint aChar)
-/**
-Retrieve the low surrogate of a supplementary character.
-
-@param aChar The 32-bit code point value of a Unicode character.
-
-@return Low surrogate of aChar, if aChar is a supplementary character;
-        zero, if aChar is not a supplementary character.
-
-@see TChar::GetHighSurrogate
-*/
-        {
-        return STATIC_CAST(TText16, 0xDC00 | (aChar & 0x3FF));
-        }
-
-
 ///***************** copied from locale euser source code ***********************
 static const TCollationMethod TheCollationMethod[] =
 	{
@@ -1637,15 +1596,15 @@
         TUint32 code;
         User::LeaveIfError(lex.Val(code, EHex));
         lex.Assign(lex.NextToken());
-        if (!IsSupplementary(code))
+        if (!TChar::IsSupplementary(code))
         	{
         	aStr[1+len] = (TUint16)code;
         	}
         else
         	{
-        	aStr[1+len] = GetHighSurrogate(code);
+        	aStr[1+len] = TChar::GetHighSurrogate(code);
         	++len;
-        	aStr[1+len] = GetLowSurrogate(code);
+        	aStr[1+len] = TChar::GetLowSurrogate(code);
         	}
         }
     __ASSERT_ALWAYS(len > 0, User::Invariant());
@@ -1708,14 +1667,14 @@
             {
             continue;
             }
-        if (!IsSupplementary(chCode))
+        if (!TChar::IsSupplementary(chCode))
         	{
         	candidate[KChPos] = (TUint16)chCode;
         	}
         else
         	{
-            candidate[KChPos] = GetHighSurrogate(chCode);
-            candidate[KChPos+1] = GetLowSurrogate(chCode);
+            candidate[KChPos] = TChar::GetHighSurrogate(chCode);
+            candidate[KChPos+1] = TChar::GetLowSurrogate(chCode);
         	}
         //"Character decomposition mapping" is the 5th field, starting from 0.
         TPtrC8 decomp(GetUnicodeDataField(stmt, 5));
@@ -1762,16 +1721,16 @@
             {
             continue;
             }
-        if (!IsSupplementary(chCode))
+        if (!TChar::IsSupplementary(chCode))
         	{
         	candidate[KChPos] = (TUint16)chCode;
         	candidate.SetLength(2);
         	}
         else
         	{
-            candidate[KChPos] = GetHighSurrogate(chCode);
+            candidate[KChPos] = TChar::GetHighSurrogate(chCode);
             candidate.SetLength(3);
-            candidate[KChPos+1] = GetLowSurrogate(chCode);
+            candidate[KChPos+1] = TChar::GetLowSurrogate(chCode);
         	}
         //"Character decomposition mapping" is the 5th field, starting from 0.
         TPtrC8 decomp(GetUnicodeDataField(stmt, 5));
@@ -2554,7 +2513,10 @@
 	test.Next(_L("MatchSurrogate"));
 	for (ii=0;ii<KTestsSurrogate;++ii)
 		{
-		TInt r=TPtrC16(TestsSurrogate[ii].iLeft).MatchF(TPtrC16(TestsSurrogate[ii].iRight));
+		TInt r=TPtrC16(TestsSurrogate[ii].iLeft).Match2(TPtrC16(TestsSurrogate[ii].iRight));
+		RDebug::Printf("    ii=%d, expect=%d, result=%d", ii, TestsSurrogate[ii].iResult, r);
+		test (r==TestsSurrogate[ii].iResult);
+		r=TPtrC16(TestsSurrogate[ii].iLeft).MatchF(TPtrC16(TestsSurrogate[ii].iRight));
 		test (r==TestsSurrogate[ii].iResult);
 		}
 	
@@ -2562,6 +2524,10 @@
 	_LIT( KQuestion, "?" );
 	_LIT( KDC00, "\xdc00" );
 	_LIT( KDFFF, "\xdfff" );
+	test( KErrCorruptSurrogateFound == TPtrC16( KD800() ).Match2( TPtrC16( KQuestion() ) ) );
+	test( KErrCorruptSurrogateFound == TPtrC16( KD800() ).Match2( TPtrC16( KD800() ) ) );
+	test( KErrCorruptSurrogateFound == TPtrC16( KDC00() ).Match2( TPtrC16( KQuestion() ) ) );
+	test( KErrCorruptSurrogateFound == TPtrC16( KDFFF() ).Match2( TPtrC16( KQuestion() ) ) );
 
     test( KErrNotFound == TPtrC16( KD800() ).MatchF( TPtrC16( KQuestion() ) ) );
     test( 0 == TPtrC16( KD800() ).MatchF( TPtrC16( KD800() ) ) );
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/bwins/t_wsd_dl1.def	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,4 @@
+EXPORTS
+	?ExportedData@@3JA @ 1 NONAME ; TInt32 ExportedData
+	?CheckExportedDataAddress@@YAHPAX@Z @2 NONAME ; void CheckExportedDataAddress(void* aDataAddr)
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/bwins/t_wsd_dl2.def	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,4 @@
+EXPORTS
+	?GetAddressOfDataProxy@@YAPAPAXAAHAAPAX1@Z @ 1 NONAME ; void * * GetAddressOfDataProxy(int &, void * &, void * &)
+	?CheckWritableStaticData@@YAHXZ @ 2 NONAME ; void CheckWritablStaticData(void)
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/bwins/t_wsd_dl3.def	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,7 @@
+EXPORTS
+	?GetAddressOfData@@YAPAPAXAAHAAPAX1@Z @ 1 NONAME ; void * * GetAddressOfData(int &, void * &, void * &)
+	?TestDataSize@@3JA @ 2 NONAME ; long TestDataSize
+	?WritableTestData@@3PAPAXA @ 3 NONAME ; void * * WritableTestData
+	?PointerToStaticData@@3PBQBXB @ 4 NONAME ; void const * * PointerToStaticData
+	?PointerToWritableData@@3PAPAXA @ 5 NONAME ; void * * PointerToWritableData
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/bx86/t_wsd_dl1.def	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,4 @@
+EXPORTS
+	?ExportedData@@3JA @ 1 NONAME ; TInt32 ExportedData
+	?CheckExportedDataAddress@@YAHPAX@Z @2 NONAME ; void CheckExportedDataAddress(void* aDataAddr)
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/bx86/t_wsd_dl2.def	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,4 @@
+EXPORTS
+	?GetAddressOfDataProxy@@YAPAPAXAAHAAPAX1@Z @ 1 NONAME ; void * * GetAddressOfDataProxy(int &, void * &, void * &)
+	?CheckWritableStaticData@@YAHXZ @ 2 NONAME ; void CheckWritablStaticData(void)
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/bx86/t_wsd_dl3.def	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,7 @@
+EXPORTS
+	?GetAddressOfData@@YAPAPAXAAHAAPAX1@Z @ 1 NONAME ; void * * GetAddressOfData(int &, void * &, void * &)
+	?TestDataSize@@3JA @ 2 NONAME ; long TestDataSize
+	?WritableTestData@@3PAPAXA @ 3 NONAME ; void * * WritableTestData
+	?PointerToStaticData@@3PBQBXB @ 4 NONAME ; void const * * PointerToStaticData
+	?PointerToWritableData@@3PAPAXA @ 5 NONAME ; void * * PointerToWritableData
+
--- a/kerneltest/e32test/debug/context.cia	Tue Feb 02 01:24:03 2010 +0200
+++ b/kerneltest/e32test/debug/context.cia	Fri Apr 16 16:24:37 2010 +0300
@@ -72,9 +72,9 @@
 __NAKED__ TInt ThreadContextHwExc(TAny*)
 	{
 	asm("stmdb sp!, {r4-r11,lr} ");
-	asm("mov r1, #0x80000000");
+	asm("mov r1, #0x00000000");
 	asm("bl SetRegs");
-	asm("ldr r0,[r13, #1]");   // Cause alignment fault
+	asm("ldr r0,[r0]");        // Cause data abort with null access, SetRegs will have set r0=0	
 	asm("ThreadContextHwExc_pc:");
 	asm("mov r0, #0 ");
 	asm("ldmia sp!, {r4-r11,pc} ");
--- a/kerneltest/e32test/debug/t_perflogger.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kerneltest/e32test/debug/t_perflogger.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -105,6 +105,7 @@
 	{
     TUint8*         record;
     TTraceLayout    traceLayout;
+	TInt    		nRecords = 0;
 	
 	for(TInt i=0; ;++i)
 		{
@@ -134,7 +135,6 @@
 		
         TUint8* end = record+dataSize;
         TUint8* currPos = record;
-        TInt    nRecords = 0;
 		TUint nBytes = 0;
 		
         //-- parser the record, print out fields and optionally check the correspondence to the fields of the control structure.
@@ -168,16 +168,17 @@
 				}
             
 			}
+				
+		//-- release data buffer.
+		aTrace.DataUsed();
+		}
 		
-        //-- check number of trace records obtained
-        if(apControlStruct)
-			{
-            test(nRecords == apControlStruct->iLogsNum);
-			}
-		
-        //-- release data buffer.
-        aTrace.DataUsed();
+	//-- check number of trace records obtained
+	if(apControlStruct)
+		{
+		test(nRecords == apControlStruct->iLogsNum);
 		}
+
 	}
 
 
--- a/kerneltest/e32test/defrag/t_ramdefrag.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kerneltest/e32test/defrag/t_ramdefrag.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -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/demandpaging/t_datapaging.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kerneltest/e32test/demandpaging/t_datapaging.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -44,9 +44,10 @@
 #include "../mmu/d_memorytest.h"
 #include "../mmu/paging_info.h"
 
-RTest test(_L("T_DATAPAGING"));
+_LIT(KChunkName, "t_datapaging chunk");
 
-_LIT(KChunkName, "t_datapaging chunk");
+RTest test(_L("T_DATAPAGING"));
+SVMSwapInfo InitialSwapInfo;
 
 class TRandom
 	{
@@ -330,8 +331,8 @@
 	if (aActual != aExpected)
 		{
 		StopSoakTest(aMsgQueue);
-		RDebug::Printf("  thread %d failure reading page %d at iteration %d address %08x: expected %08x but got %08x",
-					   aThread, aPage, aIteration, aPtr, aExpected, aActual);
+		RDebug::Printf("  thread %d failure reading page %d at iteration %d address %08x line %d: expected %08x but got %08x",
+					   aThread, aPage, aIteration, aPtr, aLine, aExpected, aActual);
 		return EFalse;
 		}
 	return ETrue;
@@ -341,7 +342,6 @@
 	{
 	SSoakTestArgs* args = (SSoakTestArgs*)aArg;
 
-	
 	RMsgQueue<TInt> msgQueue;
 	TInt r = msgQueue.OpenGlobal(KMsgQueueName, EOwnerThread);
 	if (r != KErrNone)
@@ -595,41 +595,35 @@
 	test(swapInfo.iSwapFree <= swapInfo.iSwapSize);
 	test.Printf(_L("  Swap size == 0x%x bytes\n"), swapInfo.iSwapSize);
 	test.Printf(_L("  Swap free == 0x%x bytes\n"), swapInfo.iSwapFree);
-	if (!gDataPagingSupported)
-		{
-		test_Equal(0, swapInfo.iSwapSize);
-		}
-	else
-		{
-		test(swapInfo.iSwapSize != 0);
+	test(swapInfo.iSwapSize != 0);
+	InitialSwapInfo = swapInfo;
 		
-		CommitPage(chunk, 0);
-		SVMSwapInfo swapInfo2;
-		test_KErrNone(UserSvr::HalFunction(EHalGroupVM, EVMHalGetSwapInfo, &swapInfo2, 0));
-		test_Equal(swapInfo.iSwapSize, swapInfo2.iSwapSize);
-		test_Equal(swapInfo.iSwapFree - gPageSize, swapInfo2.iSwapFree);
+	CommitPage(chunk, 0);
+	SVMSwapInfo swapInfo2;
+	test_KErrNone(UserSvr::HalFunction(EHalGroupVM, EVMHalGetSwapInfo, &swapInfo2, 0));
+	test_Equal(swapInfo.iSwapSize, swapInfo2.iSwapSize);
+	test_Equal(swapInfo.iSwapFree - gPageSize, swapInfo2.iSwapFree);
 		
-		DecommitPage(chunk, 0);
-		test_KErrNone(UserSvr::HalFunction(EHalGroupVM, EVMHalGetSwapInfo, &swapInfo2, 0));
-		test_Equal(swapInfo.iSwapSize, swapInfo2.iSwapSize);
-		test_Equal(swapInfo.iSwapFree, swapInfo2.iSwapFree);
+	DecommitPage(chunk, 0);
+	test_KErrNone(UserSvr::HalFunction(EHalGroupVM, EVMHalGetSwapInfo, &swapInfo2, 0));
+	test_Equal(swapInfo.iSwapSize, swapInfo2.iSwapSize);
+	test_Equal(swapInfo.iSwapFree, swapInfo2.iSwapFree);
 
-		// Test that closing the chunk releases the swap page.
-		CommitPage(chunk, 0);
-		test_KErrNone(UserSvr::HalFunction(EHalGroupVM, EVMHalGetSwapInfo, &swapInfo2, 0));
-		test_Equal(swapInfo.iSwapSize, swapInfo2.iSwapSize);
-		test_Equal(swapInfo.iSwapFree - gPageSize, swapInfo2.iSwapFree);
+	// Test that closing the chunk releases the swap page.
+	CommitPage(chunk, 0);
+	test_KErrNone(UserSvr::HalFunction(EHalGroupVM, EVMHalGetSwapInfo, &swapInfo2, 0));
+	test_Equal(swapInfo.iSwapSize, swapInfo2.iSwapSize);
+	test_Equal(swapInfo.iSwapFree - gPageSize, swapInfo2.iSwapFree);
 		
-		chunk.Close();
-		test_KErrNone(UserSvr::HalFunction(EHalGroupVM, EVMHalGetSwapInfo, &swapInfo2, 0));
-		test_Equal(swapInfo.iSwapSize, swapInfo2.iSwapSize);
-		test_Equal(swapInfo.iSwapFree, swapInfo2.iSwapFree);
+	chunk.Close();
+	test_KErrNone(UserSvr::HalFunction(EHalGroupVM, EVMHalGetSwapInfo, &swapInfo2, 0));
+	test_Equal(swapInfo.iSwapSize, swapInfo2.iSwapSize);
+	test_Equal(swapInfo.iSwapFree, swapInfo2.iSwapFree);
 
-		// Chunk must be created for rest of testing.
-		test_KErrNone(chunk.Create(createInfo));
-		if (gDataPagingSupported)
-			test(chunk.IsPaged());
-		}
+	// Chunk must be created for rest of testing.
+	test_KErrNone(chunk.Create(createInfo));
+	if (gDataPagingSupported)
+		test(chunk.IsPaged());
 	
 	//	EVMHalSetSwapThresholds,
 	test.Next(_L("Test EVMHalSetSwapThresholds"));
@@ -690,6 +684,16 @@
 	CLOSE_AND_WAIT(chunk);
 	}
 
+void TestSwapInfoUnchanged()
+	{
+	SVMSwapInfo swapInfo;
+	test_KErrNone(UserSvr::HalFunction(EHalGroupVM, EVMHalGetSwapInfo, &swapInfo, 0));
+	test.Printf(_L("  Swap size == 0x%x bytes\n"), swapInfo.iSwapSize);
+	test.Printf(_L("  Swap free == 0x%x bytes\n"), swapInfo.iSwapFree);
+	test_Equal(InitialSwapInfo.iSwapSize, swapInfo.iSwapSize);
+	test_Equal(InitialSwapInfo.iSwapFree, swapInfo.iSwapFree);
+	}
+
 void TestSwapHalNotSupported()
 	{
 	test_Equal(KErrNotSupported, UserSvr::HalFunction(EHalGroupVM, EVMHalGetSwapInfo, 0, 0));
@@ -1241,15 +1245,18 @@
 					for (TUint pin = 0 ; pin <= 1 ; ++pin)
 						{
 						test.Printf(_L("processes=%d threads=%d pages=%d maxcachesize=%d pin=%d\r\n"),processes, threads, pages, gMaxCacheSize,pin);
-						SoakTest(processes, threads, pages, pin, 3);
+						SoakTest(processes, threads, pages, pin, 5);
 						}
 					}
 				}
 			}
 
-			//Reset the cache size to normal
-			test.Next(_L("Soak test: Reset cache size to normal"));
-			test_KErrNone(DPTest::SetCacheSize(cacheOriginalMin, cacheOriginalMax)); 
+		//Reset the cache size to normal
+		test.Next(_L("Soak test: Reset cache size to normal"));
+		test_KErrNone(DPTest::SetCacheSize(cacheOriginalMin, cacheOriginalMax)); 
+
+		test.Next(_L("Check we haven't leaked any swap in the course of the test"));
+		TestSwapInfoUnchanged();
 		}
 
 	test.End();
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/demandpaging/t_printsysinfo.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,93 @@
+// Copyright (c) 2010 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\demandpaging\t_printsysinfo.cpp
+// 
+//
+
+
+#include <e32std.h>
+#include <e32test.h>
+#include <e32cmn.h>
+#include <dptest.h>
+#include "..\mmu\mmudetect.h"
+
+
+RTest test(_L("T_PRINTSYSINFO"));
+
+
+void PrintOutTheKernelVersion()
+{
+	TVersion version = User::Version();	
+	TInt8 major = version.iMajor;
+	TInt8 minor = version.iMinor;
+	TInt16 build = version.iBuild;
+
+	test.Printf(_L("e32 version : %d.%d.%d\n"), major, minor, build);
+}
+
+
+
+void PrintOutTheMemoryModelInUse()
+{	
+	TUint32 memmodtype = MemModelType();
+
+	switch (memmodtype)
+	{
+	case EMemModelTypeDirect:
+		test.Printf(_L("Memory model enabled is :  Direct Memory Model\n"));
+		break;
+	case EMemModelTypeMoving:
+		test.Printf(_L("Memory model enabled is :  Moving Memory Model\n"));
+		break;
+	case EMemModelTypeMultiple:
+		test.Printf(_L("Memory model enabled is :  Multiple Memory Model\n"));
+		break;
+	case EMemModelTypeEmul:
+		test.Printf(_L("Memory model enabled is :  Emulator Memory Model\n"));
+		break;
+	case EMemModelTypeFlexible:
+		test.Printf(_L("Memory model enabled is :  Flexible Memory Model\n"));
+		break;
+	default:
+		test(EFalse);		
+	}
+}
+
+void PrintOutTheEnabledPagingTypes()
+{
+	if (DPTest::Attributes() & DPTest::ERomPaging)
+		test.Printf(_L("Rom paging enabled\n"));
+	if (DPTest::Attributes() & DPTest::ECodePaging)
+		test.Printf(_L("Code paging enabled\n"));
+	if (DPTest::Attributes() & DPTest::EDataPaging)
+		test.Printf(_L("Data paging enabled\n"));
+}
+
+
+//
+// E32Main
+//
+// Main entry point.
+//
+
+TInt E32Main()
+	{
+	test.Title();
+	PrintOutTheKernelVersion();
+	PrintOutTheMemoryModelInUse();
+	PrintOutTheEnabledPagingTypes();
+	return 0;
+	}
+
+
--- a/kerneltest/e32test/demandpaging/t_thrash.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kerneltest/e32test/demandpaging/t_thrash.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -27,6 +27,7 @@
 #include <e32msgqueue.h>
 #include <e32atomics.h>
 #include <e32math.h>
+#include <hal.h>
 
 #include "t_dpcmn.h"
 #include "../mmu/mmudetect.h"
@@ -39,11 +40,12 @@
 
 _LIT(KChunkName, "t_thrash chunk");
 
-class TRandom
+class TPRNG 
 	{
 public:
-	TRandom();
-	TUint32 Next();
+	TPRNG();
+	TUint32 IntRand();
+	TReal FloatRand();
 
 private:
 	enum
@@ -54,17 +56,178 @@
 	TUint32 iV;
 	};
 
-TRandom::TRandom()
+TPRNG::TPRNG()
 	{
 	iV = (TUint32)this + RThread().Id() + User::FastCounter() + 23;
 	}
 
-TUint32 TRandom::Next()
+TUint32 TPRNG::IntRand()
 	{
 	iV = KA * iV + KB;
 	return iV;
 	}
 
+TReal TPRNG::FloatRand()
+	{
+	return (TReal)IntRand() / KMaxTUint32;
+	}
+
+class TRandom
+	{
+public:
+	virtual ~TRandom() { }
+	virtual TUint32 Next() = 0;
+	};
+
+ class TUniformRandom : public TRandom
+	{
+public:
+	void SetParams(TUint aMax) { iMax = aMax; }
+	virtual TUint32 Next();
+
+private:
+	TPRNG iRand;
+	TUint iMax;
+	};
+
+TUint32 TUniformRandom::Next()
+	{
+	return iRand.IntRand() % iMax;
+	}
+
+class TNormalRandom : public TRandom
+	{
+public:
+	void SetParams(TInt aMax, TInt aSd);
+	virtual TUint32 Next();
+
+private:
+	TUint32 GetNext();
+
+private:
+	TPRNG iRand;
+	TInt iMax;
+	TInt iExpectation;
+	TInt iSd;
+	TUint32 iCached;
+	};
+
+void TNormalRandom::SetParams(TInt aMax, TInt aSd)
+	{
+	iMax = aMax;
+	iExpectation = aMax / 2;
+	iSd = aSd;
+	iCached = KMaxTUint32;
+	}
+
+TUint32 TNormalRandom::Next()
+	{
+	TUint32 r;
+	do
+		{
+		r = GetNext();
+		}
+	while (r > (TUint)iMax);
+	return r;
+	}
+
+TUint32 TNormalRandom::GetNext()
+	{
+	if (iCached != KMaxTUint32)
+		{
+		TUint32 r = iCached;
+		iCached = KMaxTUint32;
+		return r;
+		}
+	
+	// box-muller transform
+	// from http://www.taygeta.com/random/gaussian.html
+
+	TReal x1, x2, w, ln_w, y1, y2;
+	do
+		{
+		x1 = 2.0 * iRand.FloatRand() - 1.0;
+		x2 = 2.0 * iRand.FloatRand() - 1.0;
+		w = x1 * x1 + x2 * x2;
+		}
+	while ( w >= 1.0 );
+
+	TInt r = Math::Ln(ln_w, w);
+	__ASSERT_ALWAYS(r == KErrNone, User::Invariant());
+	w = (-2.0 * ln_w ) / w;
+	TReal w2;
+	r = Math::Sqrt(w2, w);
+	__ASSERT_ALWAYS(r == KErrNone, User::Invariant());
+	y1 = x1 * w2;
+	y2 = x2 * w2;
+
+	y1 = y1 * iSd + iExpectation;
+	y2 = y2 * iSd + iExpectation;
+
+	iCached = (TUint32)y2;
+
+	return (TUint32)y1;
+	}
+
+static TBool BenchmarksSupported = EFalse;
+static TReal BenchmarkMultiplier;
+
+static TInt InitBenchmarks()
+	{
+	BenchmarksSupported = UserSvr::HalFunction(EHalGroupVM, EVMHalResetPagingBenchmark, (TAny*)EPagingBmReadRomPage, NULL) == KErrNone;
+	if (!BenchmarksSupported)
+		return KErrNone;
+	
+	TInt freq = 0;
+	TInt r = HAL::Get(HAL::EFastCounterFrequency, freq);
+	if (r != KErrNone)
+		return r;
+	BenchmarkMultiplier = 1000000.0 / freq;
+	return KErrNone;
+	}
+
+static void ResetBenchmarks()
+	{
+	if (!BenchmarksSupported)
+		return;	
+	for (TInt i = 0 ; i < EMaxPagingBm ; ++i)
+		{
+		TInt r = UserSvr::HalFunction(EHalGroupVM, EVMHalResetPagingBenchmark, (TAny*)i, NULL);
+		if (r != KErrNone)
+			test.Printf(_L("Error resetting benchmark %d\n"), i);
+		test_KErrNone(r);
+		}
+	}
+
+static TInt GetBenchmark(TPagingBenchmark aBenchmark, TInt& aCountOut, TInt& aTotalTimeInMicrosOut)
+	{
+	
+	SPagingBenchmarkInfo info;
+	TInt r = UserSvr::HalFunction(EHalGroupVM, EVMHalGetPagingBenchmark, (TAny*)aBenchmark, &info);
+	if (r!=KErrNone)
+		return r;
+	
+	aCountOut = info.iCount;
+	aTotalTimeInMicrosOut = (TInt)(info.iTotalTime * BenchmarkMultiplier);
+	return KErrNone;
+	}
+
+static TInt GetAllBenchmarks(TInt aTestLengthInSeconds, TInt aCountOut[EMaxPagingBm], TInt aTimeOut[EMaxPagingBm])
+	{
+	for (TInt i = 0 ; i < EMaxPagingBm ; ++i)
+		{
+		TInt count = 0;
+		TInt timeInMicros = 0;
+		TInt r = GetBenchmark((TPagingBenchmark)i, count, timeInMicros);
+		if (r != KErrNone)
+			return r;
+		
+		aCountOut[i] = count / aTestLengthInSeconds;
+		aTimeOut[i] = timeInMicros / aTestLengthInSeconds;
+		}
+	return KErrNone;	
+	}
+
 void CreatePagedChunk(TInt aSizeInPages)
 	{
 	test_Equal(0,gChunk.Handle());
@@ -84,11 +247,70 @@
 	return (TUint32*)(gChunk.Base() + (gPageSize * aPage));
 	}
 
+TInt EnsureSystemIdleThread(TAny*)
+	{
+	RThread::Rendezvous(KErrNone);
+	for (;;)
+		{
+		// Spin
+		}
+	}
+
+void EnsureSystemIdle()
+	{
+	const TInt KMaxWait = 60 * 1000000;
+	const TInt KSampleTime = 1 * 1000000;
+	const TInt KWaitTime = 5 * 1000000;
+	
+	test.Printf(_L("Waiting for system to become idle\n"));
+	TInt totalTime = 0;
+	TBool idle;
+	do
+		{	
+		RThread thread;
+		test_KErrNone(thread.Create(_L("EnsureSystemIdleThread"), EnsureSystemIdleThread, 1024, NULL, NULL));		
+		thread.SetPriority(EPriorityLess);
+		thread.Resume();
+
+		TRequestStatus status;
+		thread.Rendezvous(status);
+		User::WaitForRequest(status);
+		test_KErrNone(status.Int());
+
+		User::After(KSampleTime);
+		thread.Suspend();
+
+		TTimeIntervalMicroSeconds time;
+		test_KErrNone(thread.GetCpuTime(time));
+		TReal error = (100.0 * Abs(time.Int64() - KSampleTime)) / KSampleTime;
+		test.Printf(_L("    time == %ld, error == %f%%\n"), time.Int64(), error);
+
+		idle = error < 2.0;		
+		
+		thread.Kill(KErrNone);
+		thread.Logon(status);
+		User::WaitForRequest(status);
+		test_KErrNone(status.Int());
+		CLOSE_AND_WAIT(thread);
+		
+		if (!idle)
+			User::After(KWaitTime);		// Allow system to finish whatever it's doing
+
+		totalTime += KSampleTime + KWaitTime;
+		test(totalTime < KMaxWait);
+		}
+	while(!idle);
+	}
+
 enum TWorkload
 	{
 	EWorkloadSequential,
-	EWorkloadRandom,
-	EWorkloadShuffle
+	EWorkloadUniformRandom,
+	EWorkloadNormalRandom1,
+	EWorkloadNormalRandom2,
+	EWorkloadShuffle,
+
+	EMaxWorkloads
 	};
 
 struct SThrashTestArgs
@@ -105,55 +327,86 @@
 	{
 	SThrashTestArgs* args = (SThrashTestArgs*)aArg;
 
-	TRandom random;
+	TPRNG random;
+	TUniformRandom uniformRand;
+	TNormalRandom normalRand;
+
 	TInt startPage = args->iThreadGroup * args->iGroupSize;
 	TInt* ptr = (TInt*)(args->iBasePtr + startPage * gPageSize);
+
+	
 	switch (args->iWorkload)
 		{
 		case EWorkloadSequential:
 			while (gRunThrashTest)
 				{
-				TInt size = (args->iPageCount * gPageSize) / sizeof(TInt);
-				for (TInt i = 0 ; i < size && gRunThrashTest ; ++i)
+				for (TUint i = 0 ;
+					 gRunThrashTest && i < (args->iPageCount * gPageSize) / sizeof(TInt)  ;
+					 ++i)
 					{
-					ptr[i] = random.Next();
+					ptr[i] = 1;
 					__e32_atomic_add_ord64(&args->iAccesses, 1);
 					}
 				}
 			break;
 				
-		case EWorkloadRandom:
+		case EWorkloadUniformRandom:
+		case EWorkloadNormalRandom1:
+		case EWorkloadNormalRandom2:
 			{
 			TInt acc = 0;
+			TInt oldSize = -1;
+			TUint32 writeMask = 0;
+			switch (args->iWorkload)
+				{
+				case EWorkloadUniformRandom:
+				case EWorkloadNormalRandom1:
+					writeMask = 0x80000000; break;
+				case EWorkloadNormalRandom2:
+					writeMask = 0xc0000000; break;
+				default: test(EFalse); break;
+				}
 			while (gRunThrashTest)
 				{
-				TInt size = (args->iPageCount * gPageSize) / sizeof(TInt);
-				for (TInt i = 0 ; i < size && gRunThrashTest ; ++i)
+				TInt size = args->iPageCount;
+				if (size != oldSize)
 					{
-					TUint32 rand = random.Next();
-					TInt action = rand >> 31;
-					TInt r = rand % size;
-					if (action == 0)
-						acc += ptr[r];
-					else
-						ptr[r] = acc;
-					__e32_atomic_add_ord64(&args->iAccesses, 1);
+					switch (args->iWorkload)
+						{
+						case EWorkloadUniformRandom:
+							uniformRand.SetParams(size); break;
+						case EWorkloadNormalRandom1:
+						case EWorkloadNormalRandom2:
+							normalRand.SetParams(size, size / 8); break;
+						default: test(EFalse); break;
+						}
+					oldSize = size;
 					}
+				
+				TInt page = args->iWorkload == EWorkloadUniformRandom ?
+					uniformRand.Next() : normalRand.Next();
+				TInt index = page * (gPageSize / sizeof(TInt));
+				TBool write = (random.IntRand() & writeMask) == 0;
+				if (write)
+					ptr[index] = acc;
+				else
+					acc += ptr[index];
+				__e32_atomic_add_ord64(&args->iAccesses, 1);
 				}
 			}
 			break;
 			
 		case EWorkloadShuffle:
 			{
-			TInt i;
+			TInt i = 0;
 			while (gRunThrashTest)
 				{
 				TInt size = (args->iPageCount * gPageSize) / sizeof(TInt);
-				for (i = 0 ; gRunThrashTest && i < (size - 1) ; ++i)
-					{
-					Mem::Swap(&ptr[i], &ptr[i + random.Next() % (size - i - 1) + 1], sizeof(TInt));
-					__e32_atomic_add_ord64(&args->iAccesses, 2);
-					}
+				Mem::Swap(&ptr[i], &ptr[i + random.IntRand() % (size - i - 1) + 1], sizeof(TInt));
+				__e32_atomic_add_ord64(&args->iAccesses, 2);
+				++i;
+				if (i >= size - 1)
+					i = 0;
 				}
 			}
 			break;
@@ -172,17 +425,32 @@
 	SThrashTestArgs iArgs;
 	};
 
-void ThrashTest(TInt aThreads,			// number of threads to run
+void ThrashTest(const TDesC& aTestName,	// name and description
+				TInt aThreads,			// number of threads to run
 				TBool aSharedData,		// whether all threads share the same data
 				TWorkload aWorkload,
 				TInt aBeginPages,		// number of pages to start with for last/all threads
 				TInt aEndPages,			// number of pages to end with for last/all threads
 				TInt aOtherPages)		// num of pages for other threads, or zero to use same value for all
 	{
-	RDebug::Printf("\nPages Accesses     ThL");
+	const TInt KTestLengthInSeconds = 2;
+	
+	test.Next(_L("Thrash test"));
+	
+	DPTest::FlushCache();
+	EnsureSystemIdle();
 
-	DPTest::FlushCache();
-	User::After(1000000);
+	TInt i;
+	test.Printf(_L("Table: %S\n"), &aTestName);
+	test.Printf(_L("totalPages, totalAccesses, thrashLevel"));
+	if (BenchmarksSupported)
+		test.Printf(_L(", rejuveCount, rejuveTime, codePageInCount, codePageInTime, initCount, initTime, readCount, readTime, writePages, writeCount, writeTime"));
+	if (aThreads > 1)
+		{
+		for (TInt i = 0 ; i < aThreads ; ++i)
+			test.Printf(_L(", Thread%dPages, Thread%dAccesses"), i, i);
+		}
+	test.Printf(_L("\n"));
 
 	TInt pagesNeeded;
 	TInt maxPages = Max(aBeginPages, aEndPages);
@@ -208,11 +476,10 @@
 	test_NotNull(threads);
 	
 	gRunThrashTest = ETrue;
-	TInt pageCount = aBeginPages;
 	const TInt maxSteps = 30;
 	TInt step = aEndPages >= aBeginPages ? Max((aEndPages - aBeginPages) / maxSteps, 1) : Min((aEndPages - aBeginPages) / maxSteps, -1);
+	TInt pageCount = aBeginPages - 5 * step; // first run ignored
 	
-	TInt i;
 	for (i = 0 ; i < aThreads ; ++i)
 		{
 		SThrashThreadData& thread = threads[i];
@@ -242,8 +509,10 @@
 		
 		for (i = 0 ; i < aThreads ; ++i)
 			__e32_atomic_store_ord64(&threads[i].iArgs.iAccesses, 0);
+		ResetBenchmarks();
 		
-		User::After(2000000);		
+		User::After(KTestLengthInSeconds * 1000 * 1000);
+
 		TInt thrashLevel = UserSvr::HalFunction(EHalGroupVM, EVMHalGetThrashLevel, 0, 0);
 		test(thrashLevel >= 0 && thrashLevel <= 255);
 		
@@ -257,20 +526,50 @@
 			else
 				totalPages += threads[i].iArgs.iPageCount;
 			}
+		TInt accessesPerSecond = (TInt)(totalAccesses / KTestLengthInSeconds);
 
-		test.Printf(_L("%5d %12ld %3d"), totalPages, totalAccesses, thrashLevel);
-		for (i = 0 ; i < aThreads ; ++i)
+		TBool warmingUp = (step > 0) ? pageCount < aBeginPages : pageCount > aBeginPages;
+		if (!warmingUp)
 			{
-			test.Printf(_L(" %5d %12ld"),
-						threads[i].iArgs.iPageCount,
-						__e32_atomic_load_acq64(&threads[i].iArgs.iAccesses));
-			test_Equal(KRequestPending, threads[i].iStatus.Int());
+			test.Printf(_L("%10d, %13d, %11.2f"), totalPages, accessesPerSecond, (TReal)thrashLevel / 255);
+		
+			if (BenchmarksSupported)
+				{
+				TInt benchmarkCount[EMaxPagingBm];
+				TInt benchmarkTime[EMaxPagingBm];
+				test_KErrNone(GetAllBenchmarks(KTestLengthInSeconds, benchmarkCount, benchmarkTime));
+
+				TInt otherPageInCount = benchmarkCount[EPagingBmReadRomPage] + benchmarkCount[EPagingBmReadCodePage];
+				TInt otherPageInTime = benchmarkTime[EPagingBmReadRomPage] + benchmarkTime[EPagingBmReadCodePage];
+		
+				TInt initCount = benchmarkCount[EPagingBmReadDataPage] - benchmarkCount[EPagingBmReadDataMedia];
+				TInt initTime = benchmarkTime[EPagingBmReadDataPage] - benchmarkTime[EPagingBmReadDataMedia];
+
+				test.Printf(_L(", %11d, %10d, %15d, %14d, %9d, %8d, %9d, %8d, %10d, %10d, %9d"),
+							benchmarkCount[EPagingBmRejuvenate], benchmarkTime[EPagingBmRejuvenate],
+							otherPageInCount, otherPageInTime,
+							initCount, initTime,
+							benchmarkCount[EPagingBmReadDataMedia], benchmarkTime[EPagingBmReadDataMedia],
+							benchmarkCount[EPagingBmWriteDataPage], 
+							benchmarkCount[EPagingBmWriteDataMedia], benchmarkTime[EPagingBmWriteDataMedia]);
+				}
+		
+			if (aThreads > 1)
+				{
+				for (i = 0 ; i < aThreads ; ++i)
+					{
+					test.Printf(_L(", %12d, %15ld"),
+								threads[i].iArgs.iPageCount,
+								__e32_atomic_load_acq64(&threads[i].iArgs.iAccesses));
+					test_Equal(KRequestPending, threads[i].iStatus.Int());
+					}
+				}
+			test.Printf(_L("\n"));
 			}
-		test.Printf(_L("\n"));
 
+		pageCount += step;
 		if (aEndPages >= aBeginPages ? pageCount >= aEndPages : pageCount < aEndPages)
 			break;
-		pageCount += step;
 		}
 	
 	gRunThrashTest = EFalse;
@@ -285,7 +584,7 @@
 		}
 
 	gChunk.Close();	
-	RDebug::Printf("\n");
+	test.Printf(_L("\n"));
 	}
 
 void TestThrashing()
@@ -298,47 +597,96 @@
 	TInt maxPages4 = (5 * gMaxCacheSize) / 16;
 
 	// Single thread increasing in size
-	test.Next(_L("Thrash test: single thread, sequential workload"));
-	ThrashTest(1, ETrue, EWorkloadSequential, minPages, maxPages, 0);
+	ThrashTest(_L("single thread, sequential workload"),
+			   1, ETrue, EWorkloadSequential, minPages, maxPages, 0);
 	
-	test.Next(_L("Thrash test: single thread, random workload"));
-	ThrashTest(1, ETrue, EWorkloadRandom, minPages, maxPages, 0);
+	ThrashTest(_L("single thread, random workload"),
+			   1, ETrue, EWorkloadUniformRandom, minPages, maxPages, 0);
 	
-	test.Next(_L("Thrash test: single thread, shuffle workload"));
-	ThrashTest(1, ETrue, EWorkloadShuffle, minPages, maxPages, 0);
+	ThrashTest(_L("single thread, shuffle workload"),
+			   1, ETrue, EWorkloadShuffle, minPages, maxPages, 0);
 
 	// Multiple threads with shared data, one thread incresing in size
-	test.Next(_L("Thrash test: two threads with shared data, one thread increasing, random workload"));
-	ThrashTest(2, ETrue, EWorkloadRandom, minPages, maxPages, minPages);
+	ThrashTest(_L("two threads with shared data, one thread increasing, random workload"),
+			   2, ETrue, EWorkloadUniformRandom, minPages, maxPages, minPages);
 	
-	test.Next(_L("Thrash test: four threads with shared data, one thread increasing, random workload"));
-	ThrashTest(4, ETrue, EWorkloadRandom, minPages, maxPages, minPages);
+	ThrashTest(_L("four threads with shared data, one thread increasing, random workload"),
+			   4, ETrue, EWorkloadUniformRandom, minPages, maxPages, minPages);
 
 	// Multiple threads with shared data, all threads incresing in size
-	test.Next(_L("Thrash test: two threads with shared data, all threads increasing, random workload"));
-	ThrashTest(2, ETrue, EWorkloadRandom, minPages, maxPages, 0);
+	ThrashTest(_L("two threads with shared data, all threads increasing, random workload"),
+			   2, ETrue, EWorkloadUniformRandom, minPages, maxPages, 0);
 	
-	test.Next(_L("Thrash test: four threads with shared data, all threads increasing, random workload"));
-	ThrashTest(4, ETrue, EWorkloadRandom, minPages, maxPages, 0);
+	ThrashTest(_L("four threads with shared data, all threads increasing, random workload"),
+			   4, ETrue, EWorkloadUniformRandom, minPages, maxPages, 0);
 	
 	// Multiple threads with independent data, one thread incresing in size
-	test.Next(_L("Thrash test: two threads with independent data, one thread increasing, random workload"));
-	ThrashTest(2, EFalse, EWorkloadRandom, minPages2, maxPages2, gMaxCacheSize / 2);
+	ThrashTest(_L("two threads with independent data, one thread increasing, random workload"),
+			   2, EFalse, EWorkloadUniformRandom, minPages2, maxPages2, gMaxCacheSize / 2);
 	
-	test.Next(_L("Thrash test: four threads with independent data, one thread increasing, random workload"));
-	ThrashTest(4, EFalse, EWorkloadRandom, minPages4, maxPages4, gMaxCacheSize / 4);
+	ThrashTest(_L("four threads with independent data, one thread increasing, random workload"),
+			   4, EFalse, EWorkloadUniformRandom, minPages4, maxPages4, gMaxCacheSize / 4);
 	
 	// Multiple threads with independant data, all threads incresing in size
-	test.Next(_L("Thrash test: two threads with independent data, all threads increasing, random workload"));
-	ThrashTest(2, EFalse, EWorkloadRandom, minPages2, maxPages2, 0);
+	ThrashTest(_L("two threads with independent data, all threads increasing, random workload"),
+			   2, EFalse, EWorkloadUniformRandom, minPages2, maxPages2, 0);
 
-	test.Next(_L("Thrash test: four threads with independent data, all threads increasing, random workload"));
-	ThrashTest(4, EFalse, EWorkloadRandom, minPages4, maxPages4, 0);
+	ThrashTest(_L("four threads with independent data, all threads increasing, random workload"),
+			   4, EFalse, EWorkloadUniformRandom, minPages4, maxPages4, 0);
 
 	// Attempt to create thrash state where there is sufficient cache
-	test.Next(_L("Thrash test: two threads with independent data, one threads decreasing, random workload"));
 	TInt halfCacheSize = gMaxCacheSize / 2;
-	ThrashTest(2, EFalse, EWorkloadRandom, halfCacheSize + 10, halfCacheSize - 30, halfCacheSize);
+	ThrashTest(_L("two threads with independent data, one threads decreasing, random workload"),
+			   2, EFalse, EWorkloadUniformRandom, halfCacheSize + 10, halfCacheSize - 30, halfCacheSize);
+	}
+
+void TestDistribution(TRandom& aRandom, TInt aSamples)
+	{
+	TUint32* data = new TUint32[aSamples];
+	test_NotNull(data);
+
+	TInt i;
+	TReal mean = 0.0;
+	for (i = 0 ; i < aSamples ; ++i)
+		{
+		data[i] = aRandom.Next();
+		mean += (TReal)data[i] / aSamples;
+		}
+
+	TReal sum2 = 0.0;
+	for (i = 0 ; i < aSamples ; ++i)
+		{
+		TReal d = (TReal)data[i] - mean;
+		sum2 += d * d;
+		}
+	TReal variance = sum2 / (aSamples - 1);
+
+	test.Printf(_L("  mean == %f\n"), mean);
+	test.Printf(_L("  variance == %f\n"), variance);
+
+	delete [] data;
+	}
+
+void BenchmarkReplacement()
+	{
+ 	test.Next(_L("Test uniform distribution"));
+	TUniformRandom rand1;
+	rand1.SetParams(100);
+	TestDistribution(rand1, 10000);
+	
+ 	test.Next(_L("Test normal distribution"));	
+	TNormalRandom rand2;
+	rand2.SetParams(100, 25);
+	TestDistribution(rand2, 10000);
+
+	ThrashTest(_L("Thrash test: single thread, normal random workload 1"),
+			   1, ETrue, EWorkloadNormalRandom1, (2 * gMaxCacheSize) / 3, 2 * gMaxCacheSize, 0);
+	
+	ThrashTest(_L("Thrash test: single thread, normal random workload 2"),
+			   1, ETrue, EWorkloadNormalRandom2, (2 * gMaxCacheSize) / 3, 2 * gMaxCacheSize, 0);
+
+	ThrashTest(_L("Thrash test: single thread, uniform random workload"),
+			   1, ETrue, EWorkloadUniformRandom, (2 * gMinCacheSize) / 3, (3 * gMaxCacheSize) / 2, 0);
 	}
 
 void TestThrashHal()
@@ -369,27 +717,44 @@
 	test_Equal(KRequestPending, status.Int());
 	
 	// stress system and check thrash level and notification
-	ThrashTest(1, ETrue, EWorkloadRandom, gMaxCacheSize * 2, gMaxCacheSize * 2 + 5, 0);
+	ThrashTest(_L("stress system"),
+			   1, ETrue, EWorkloadUniformRandom, gMaxCacheSize * 2, gMaxCacheSize * 2 + 5, 0);
 	r = UserSvr::HalFunction(EHalGroupVM, EVMHalGetThrashLevel, 0, 0);
 	test(r >= 0 && r <= 255);
 	test.Printf(_L("Thrash level == %d\n"), r);
 	test(r > 200);  // should indicate thrashing
-	test_Equal(EChangesThrashLevel, status.Int());
-	User::WaitForAnyRequest();
 
-	// wait for system to calm down and check notification again
-	test_KErrNone(notifier.Logon(status));
-	User::WaitForAnyRequest();
-	test_Equal(EChangesThreadDeath, status.Int());
-
-	test_KErrNone(notifier.Logon(status));
+	TBool gotThrashNotification = EFalse;
+	
+	// wait for EChangesThrashLevel notification
+	while(status.Int() != KRequestPending)
+		{
+		gotThrashNotification = (status.Int() & EChangesThrashLevel) != 0;
+		User::WaitForAnyRequest();
+		test_KErrNone(notifier.Logon(status));
+		User::After(1);		
+		}
+	test(gotThrashNotification);
+	
 	User::After(2000000);
 	r = UserSvr::HalFunction(EHalGroupVM, EVMHalGetThrashLevel, 0, 0);
 	test(r >= 0 && r <= 255);
 	test.Printf(_L("Thrash level == %d\n"), r);
 	test(r <= 10);  // should indicate lightly loaded system
-	test_Equal(EChangesThrashLevel, status.Int());	
+
+	// wait for EChangesThrashLevel notification
+	gotThrashNotification = EFalse;
+	while(status.Int() != KRequestPending)
+		{
+		gotThrashNotification = (status.Int() & EChangesThrashLevel) != 0;
+		User::WaitForAnyRequest();
+		test_KErrNone(notifier.Logon(status));
+		User::After(1);		
+		}
+	test(gotThrashNotification);
+	test_KErrNone(notifier.LogonCancel());
 	User::WaitForAnyRequest();
+	notifier.Close();
 	}
 
 void TestThrashHalNotSupported()
@@ -398,45 +763,105 @@
 	test_Equal(KErrNotSupported, UserSvr::HalFunction(EHalGroupVM, EVMHalSetThrashThresholds, 0, 0));
 	}
 
+_LIT(KUsageMessage, "usage: t_thrash [ test ] [ thrashing ] [ benchmarks ]\n");
+
+enum TTestAction
+	{
+	EActionTest       = 1 << 0,
+	EActionThrashing  = 1 << 1,
+	EActionBenchmarks = 1 << 2
+	};
+
+void BadUsage()
+	{
+	test.Printf(KUsageMessage);
+	test(EFalse);
+	}
+
+TInt ParseCommandLine()
+	{
+	const TInt KMaxLineLength = 64;
+	
+	if (User::CommandLineLength() > KMaxLineLength)
+		BadUsage();
+	TBuf<KMaxLineLength> buffer;
+	User::CommandLine(buffer);
+
+	if (buffer == KNullDesC)
+		return EActionTest;
+	
+	TLex lex(buffer);
+	TInt result = 0;
+	while (!lex.Eos())
+		{
+		TPtrC word = lex.NextToken();
+		if (word == _L("test"))
+			result |= EActionTest;
+		else if (word == _L("thrashing"))
+			result |= EActionThrashing;
+		else if (word == _L("benchmarks"))
+			result |= EActionBenchmarks;
+		else
+			{
+			test.Printf(_L("bad token '%S'\n"), &word);
+			BadUsage();
+			}
+		}
+	
+	return result;
+	}
+
 TInt E32Main()
 	{
 	test.Title();
 	test.Start(_L("Test thrashing monitor"));
+	
+	test_KErrNone(InitBenchmarks());
 
+	TInt actions = ParseCommandLine();
+	
 	test_KErrNone(GetGlobalPolicies());
 
 	TUint cacheOriginalMin = 0;
 	TUint cacheOriginalMax = 0;
-	TUint cacheCurrentSize = 0;
 
 	if (gDataPagingSupported)
 		{
-		test.Next(_L("Thrash test: change maximum cache size to minimal"));
-		//store original values
+		test.Next(_L("Thrash test: change cache size to maximum 2Mb"));
+		TUint cacheCurrentSize = 0;
 		DPTest::CacheSize(cacheOriginalMin, cacheOriginalMax, cacheCurrentSize);
-		gMaxCacheSize = 256;
-		gMinCacheSize = 64;
+		gMinCacheSize = 512;
+		gMaxCacheSize = 520;
 		test_KErrNone(DPTest::SetCacheSize(gMinCacheSize * gPageSize, gMaxCacheSize * gPageSize));
 		}
+	
+	if (actions & EActionTest)
+		{
+		TBool flexibleMemoryModel = (MemModelAttributes() & EMemModelTypeMask) == EMemModelTypeFlexible;
+		if (flexibleMemoryModel)
+			TestThrashHal();
+		else
+			TestThrashHalNotSupported();
+		}
 
-	TBool flexibleMemoryModel = (MemModelAttributes() & EMemModelTypeMask) == EMemModelTypeFlexible;
-	if (flexibleMemoryModel)
-		TestThrashHal();
-	else
-		TestThrashHalNotSupported();
-	
-	if (gDataPagingSupported && User::CommandLineLength() > 0)
-		{		
+	if (actions & EActionThrashing)
+		{	
 		test.Next(_L("Extended thrashing tests"));
 		TestThrashing();
 		}
+	
+	if (actions & EActionBenchmarks)
+		{	
+		test.Next(_L("Benchmarking page replacement"));
+		BenchmarkReplacement();
+		}
+
 	if (gDataPagingSupported)
 		{
-		//Reset the cache size to normal
 		test.Next(_L("Thrash test: Reset cache size to normal"));
 		test_KErrNone(DPTest::SetCacheSize(cacheOriginalMin, cacheOriginalMax));
 		}
-
+	
 	test.End();
 	return 0;
 	}
--- a/kerneltest/e32test/device/t_usb.h	Tue Feb 02 01:24:03 2010 +0200
+++ b/kerneltest/e32test/device/t_usb.h	Fri Apr 16 16:24:37 2010 +0300
@@ -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	Tue Feb 02 01:24:03 2010 +0200
+++ b/kerneltest/e32test/device/t_usbapi.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -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	Tue Feb 02 01:24:03 2010 +0200
+++ b/kerneltest/e32test/device/t_usbco2.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -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/dma/d_dma.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kerneltest/e32test/dma/d_dma.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -1,4 +1,4 @@
-// Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 2002-2010 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"
@@ -185,6 +185,8 @@
 	TInt Execute(const TDesC8& aDes);
 	static void Dfc(DDmaRequest::TResult aResult, TAny* aArg);
 	TInt DoGetInfo(TAny* aInfo);
+	void FreeDmaRequests();
+	void FreeClientRequests();
 private:
 	TUint32 iCookie;
 	TBufferMgr iBufMgr;
@@ -193,6 +195,7 @@
 	DDmaRequest* iRequests[KMaxRequests];
 	TClientRequest* iClientRequests[KMaxRequests];
 	DDmaTestChannel* iMap[KMaxRequests];
+	TBool iCloseInCb[KMaxRequests];
 	TUint32 iMemMemPslInfo;
 	DThread* iClient;
 	TDynamicDfcQue* iDfcQ;
@@ -277,6 +280,8 @@
 				}
 			if (! iRequests[i])
 				return KErrNoMemory;
+
+			iCloseInCb[i] = EFalse;
 			}
 		return KErrNone;
 		}
@@ -288,13 +293,10 @@
 	if (iChannel)
 		{
 		iChannel->CancelAll();
-		TInt i;
-		for (i=0; i<KMaxRequests; ++i)
-			delete iRequests[i];
+		FreeDmaRequests();
 		iChannel->Close();
-		for (i=0; i<KMaxRequests; ++i)
-			Kern::DestroyClientRequest(iClientRequests[i]);
 		}
+	FreeClientRequests();
 	if (iDfcQ)
 		{
 		iDfcQ->Destroy();
@@ -302,6 +304,23 @@
 	iBufMgr.FreeAll();
 	}
 
+void DDmaTestChannel::FreeDmaRequests()
+	{
+	for (TInt i=0; i<KMaxRequests; ++i)
+		{
+		delete iRequests[i];
+		iRequests[i] = NULL;
+		}
+	}
+
+void DDmaTestChannel::FreeClientRequests()
+	{
+	for (TInt i=0; i<KMaxRequests; ++i)
+		{
+		Kern::DestroyClientRequest(iClientRequests[i]);
+		}
+	}
+
 
 TInt DDmaTestChannel::Request(TInt aFunction, TAny* a1, TAny* a2)
 	{
@@ -401,14 +420,35 @@
 			{
 		case 'Q':
 			{
-			TInt arg = *p++ - '0';
-			__ASSERT_DEBUG(0 <= arg && arg < KMaxRequests, Kern::PanicCurrentThread(KClientPanicCat, __LINE__));
-			iRequests[arg]->Queue();
+			__ASSERT_DEBUG(p < pEnd, Kern::PanicCurrentThread(KClientPanicCat, __LINE__));
+			TInt nextChar = *p++;
+			TInt channel = -1;
+
+			if(nextChar == 'X')
+				{
+				// Channel should be closed in callback
+				__ASSERT_DEBUG(p < pEnd, Kern::PanicCurrentThread(KClientPanicCat, __LINE__));
+				channel = *p++ - '0';
+				iCloseInCb[channel] = ETrue;
+				}
+			else
+				{
+				channel = nextChar - '0';
+				}
+			__ASSERT_DEBUG(0 <= channel && channel < KMaxRequests, Kern::PanicCurrentThread(KClientPanicCat, __LINE__));
+			iRequests[channel]->Queue();
 			break;
 			}
 		case 'C':
+			{
 			iChannel->CancelAll();
+			for(TInt i=0; i<KMaxRequests; ++i)
+				{
+				if(iClientRequests[i]->IsReady())
+					iClientRequests[i]->Reset();
+				}
 			break;
+			}
 		default:
 			Kern::PanicCurrentThread(KClientPanicCat, __LINE__);
 			}
@@ -424,6 +464,17 @@
 	TInt i = ppC - pC->iMap;
 	TClientRequest* req = pC->iClientRequests[i];
 	TInt r = (aResult==DDmaRequest::EOk) ? KErrNone : KErrGeneral;
+
+	if(pC->iCloseInCb[i])
+		{
+		pC->iCloseInCb[i] = EFalse;
+		__KTRACE_OPT(KDMA, Kern::Printf("Close channel in callback"));
+
+		pC->FreeDmaRequests();
+		pC->iChannel->Close();
+		pC->iChannel = NULL;
+		}
+
 	if (req->IsReady())
 		Kern::QueueRequestComplete(pC->iClient, req, r);
 	}
--- a/kerneltest/e32test/dma/dmasim.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kerneltest/e32test/dma/dmasim.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -355,31 +355,69 @@
 public:
 	static void StartEmulation();
 	static void StopEmulation();
+	static TBool InISR();
+	static void Synchronize();
 private:
 	enum { KPeriod = 1 }; // in ms
+	enum { EDmaSimIdle=0u, EDmaSimStarted=1u, EDmaSimInISR=2u, EDmaSimStopping=0x80000000u };
 	static void TickCB(TAny* aThis);
 	static NTimer Timer;
+	static volatile TInt StartStop;
 	};
 
 NTimer DmacSim::Timer;
+volatile TInt DmacSim::StartStop;
 
 void DmacSim::StartEmulation()
 	{
+	__DMA_ASSERTA(StartStop==EDmaSimIdle);
 	new (&Timer) NTimer(&TickCB, 0);
+	__e32_atomic_store_ord32(&StartStop, EDmaSimStarted);
 	__DMA_ASSERTA(Timer.OneShot(KPeriod, EFalse) == KErrNone);
 	}
 
 void DmacSim::StopEmulation()
 	{
-	Timer.Cancel();
+	TInt orig = __e32_atomic_tas_ord32(&StartStop, (TInt)EDmaSimStarted, (TInt)EDmaSimStopping, 0);
+	if (orig == EDmaSimIdle)
+		return;		// wasn't running
+	// loop until we succeed in cancelling the timer or the timer callback
+	// notices that we are shutting down
+	while (!Timer.Cancel() && __e32_atomic_load_acq32(&StartStop)!=EDmaSimIdle)
+		{}
+	__e32_atomic_store_ord32(&StartStop, EDmaSimIdle);
 	}
 
 void DmacSim::TickCB(TAny*)
 	{
-	DmacSb::DoTransfer();
-	DmacDb::DoTransfer();
-	DmacSg::DoTransfer();
-	__DMA_ASSERTA(Timer.Again(KPeriod) == KErrNone);
+	TInt orig = (TInt)__e32_atomic_ior_acq32(&StartStop, EDmaSimInISR);
+	if (orig >= 0)
+		{
+		DmacSb::DoTransfer();
+		DmacDb::DoTransfer();
+		DmacSg::DoTransfer();
+		}
+	orig = (TInt)__e32_atomic_and_rel32(&StartStop, (TUint32)~EDmaSimInISR);
+	if (orig < 0)
+		{
+		__e32_atomic_store_rel32(&StartStop, EDmaSimIdle);
+		return;
+		}
+	TInt r = Timer.Again(KPeriod);
+	if (r == KErrArgument)
+		r = Timer.OneShot(KPeriod);
+	__DMA_ASSERTA(r == KErrNone);
+	}
+
+TBool DmacSim::InISR()
+	{
+	return __e32_atomic_load_acq32(&StartStop) & EDmaSimInISR;
+	}
+
+void DmacSim::Synchronize()
+	{
+	while (InISR())
+		{}
 	}
 
 //////////////////////////////////////////////////////////////////////////////
@@ -436,6 +474,7 @@
 void DSimSbController::StopTransfer(const TDmaChannel& aChannel)
 	{
 	__e32_atomic_and_ord32(&DmacSb::ControlStatus[aChannel.PslId()], (TUint32)~DmacSb::ECsRun);
+	DmacSim::Synchronize();
 	}
 
 
@@ -536,6 +575,7 @@
 void DSimDbController::StopTransfer(const TDmaChannel& aChannel)
 	{
 	__e32_atomic_and_ord32(&DmacDb::ControlStatus[aChannel.PslId()], (TUint32)~(DmacDb::ECsRun|DmacDb::ECsPrg));
+	DmacSim::Synchronize();
 	}
 
 
@@ -666,6 +706,7 @@
 void DSimSgController::StopTransfer(const TDmaChannel& aChannel)
 	{
 	__e32_atomic_and_ord32(&DmacSg::ChannelControl[aChannel.PslId()], (TUint32)~DmacSg::EChannelBitRun);
+	DmacSim::Synchronize();
 	}
 
 
--- a/kerneltest/e32test/dma/t_dma.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kerneltest/e32test/dma/t_dma.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -1,4 +1,4 @@
-// Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 2002-2010 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"
@@ -69,7 +69,7 @@
 _LIT(KTestFailure, "XTEST");
 static void TestPanic(TInt aLine, TUint32 a1, TUint32 a2, TUint32 a3)
 	{
-	RDebug::Printf("Line %d test failed a1=%08x a2=%08x a3=%08x", aLine, a1, a2, a3);
+	RDebug::Printf("Line %d test failed a1=%08x (%d) a2=%08x (%d) a3=%08x (%d)", aLine, a1, a1, a2, a2, a3, a3);
 	RThread().Panic(KTestFailure, aLine);
 	}
 #define XTEST(e)				if (!(e)) TestPanic(__LINE__, 0, 0, 0)
@@ -193,6 +193,71 @@
 	const TInt iTotalTransferSize;
 	};
 
+/**
+Test that it is possible to close a channel from a callback
+*/
+class CCloseInCb : public CTest
+	{
+public:
+	CCloseInCb()
+		: CTest(NULL, 1), iTransferSize(4 * KKilo)
+		{}
+
+	TInt virtual DoRunTest();
+
+	virtual void AnnounceTest(TDes& aDes)
+		{
+		aDes.AppendFormat(_L("CCloseInCb"));
+		CTest::AnnounceTest(aDes);
+		}
+
+	CTest* Clone() const
+		{return new CCloseInCb(*this);}
+private:
+	const TInt iTransferSize;
+
+	};
+
+/**
+Perform multiple transfers with different fragment counts and with smaller
+and smaller fragment size
+
+This checks that the PSL's ISR(s) are properly written, and do not miss interrupts
+or notify the PIL spuriously.
+*/
+class CFragSizeRange : public CTest
+	{
+public:
+	CFragSizeRange(TInt aMaxIter, TInt aFragCount, TInt aInitialFragmentSize, TInt aInnerIteraions)
+		: CTest(NULL, aMaxIter), iMaxFragCount(aFragCount), iFragCount(1), iInitialFragmentSize(aInitialFragmentSize),
+		iInnerIterations(aInnerIteraions)
+		{}
+
+	TInt virtual DoRunTest();
+
+	virtual void AnnounceTest(TDes& aDes)
+		{
+		aDes.AppendFormat(_L("CFragSizeRange: Fragments %d, intital frag size %d, inner iters %d "), iFragCount, iInitialFragmentSize, iInnerIterations);
+		CTest::AnnounceTest(aDes);
+		}
+
+	CTest* Clone() const
+		{return new CFragSizeRange(*this);}
+
+private:
+	/**
+	Run the transfer
+	*/
+	TInt Transfer(TInt aFragSize);
+
+
+	TInt iMaxFragCount;
+	TInt iFragCount;
+	const TInt iInitialFragmentSize;
+	const TInt iInnerIterations;
+
+	RTimer iTimer;
+	};
 
 //
 // Active object used to create a tester thread, log on to it and
@@ -346,6 +411,140 @@
 	return KErrNone;
 	}
 
+TInt CCloseInCb::DoRunTest()
+	{
+	TInt r = KErrNone;
+	RTest test(_L("CCloseInCb test"));
+
+	r = OpenChannel(1);
+	test_KErrNone(r);
+
+	const TInt KRequest = 0;
+	const TInt KSrcBuf = 0;
+	const TInt KDestBuf = 1;
+
+	const TInt size = Min(iTransferSize, Info.iMaxTransferSize);
+
+	r = iChannel.AllocBuffer(KSrcBuf, size);
+	test_KErrNone(r);
+	iChannel.FillBuffer(KSrcBuf, 'A');
+	r = iChannel.AllocBuffer(KDestBuf, size);
+	test_KErrNone(r);
+	iChannel.FillBuffer(KDestBuf, '\0');
+
+	TRequestStatus rs = KRequestPending;
+	r = iChannel.Fragment(KRequest, KSrcBuf, KDestBuf, size, &rs);
+	test_KErrNone(r);
+
+	// "X" will cause channel to be closed during callback
+	r = iChannel.Execute(_L8("QX0"));
+	test_KErrNone(r);
+
+	User::WaitForRequest(rs);
+	test_KErrNone(rs.Int());
+
+	test(iChannel.CheckBuffer(KDestBuf, 'A'));
+	iChannel.FreeAllBuffers();
+
+	test.Close();
+	return KErrNone;
+	}
+
+TInt CFragSizeRange::DoRunTest()
+	{
+	const TInt initialFragmentSize = Min(iInitialFragmentSize, Info.iMaxTransferSize);
+
+	TInt r = KErrNone;
+	RTest test(_L("CFragSizeRange test"));
+
+	r = iTimer.CreateLocal();
+	test_KErrNone(r);
+
+
+	TInt fragSize = initialFragmentSize;
+	TInt step = 0;
+	do
+		{
+		fragSize -= step;
+		// make sure size is aligned
+		fragSize = fragSize & ~Info.iMemAlignMask;
+
+		r = OpenChannel(iMaxFragCount, fragSize);
+		test_KErrNone(r);
+
+		for(iFragCount=1; iFragCount <= iMaxFragCount; iFragCount++)
+			{
+			test.Printf(_L("Fragment size %d bytes, %d fragments\nIter: "), fragSize, iFragCount);
+			for(TInt i=0; i<iInnerIterations; i++)
+				{
+
+				test.Printf(_L("%d "), i);
+				r = Transfer(fragSize);
+				test_KErrNone(r);
+
+				}
+			test.Printf(_L("\n"));
+			}
+		iChannel.Close();
+		// Reduce frag size by an eigth each iteration
+		step = (fragSize/8);
+		} while (step > 0);
+
+	iTimer.Close();
+
+	test.Close();
+	return r;
+	}
+
+TInt CFragSizeRange::Transfer(TInt aFragmentSize)
+	{
+	const TInt KRequest = 0;
+	const TInt KSrcBuf = 0;
+	const TInt KDestBuf = 1;
+
+	const TInt size = aFragmentSize * iFragCount;
+
+	TInt r = iChannel.AllocBuffer(KSrcBuf, size);
+	test_KErrNone(r);
+	iChannel.FillBuffer(KSrcBuf, 'A');
+	r = iChannel.AllocBuffer(KDestBuf, size);
+	XTEST2(r == KErrNone, r, size);
+	iChannel.FillBuffer(KDestBuf, '\0');
+
+	// Test simple transfer
+	TRequestStatus rs = KRequestPending;
+	r = iChannel.Fragment(KRequest, KSrcBuf, KDestBuf, size, &rs);
+	test_KErrNone(r);
+
+	test(iChannel.FragmentCheck(KRequest, iFragCount));
+	r = iChannel.Execute(_L8("Q0"));
+	test_KErrNone(r);
+
+	const TInt microSecTimeout = 1000000; // 1s
+	TRequestStatus timerStatus;
+	iTimer.After(timerStatus, microSecTimeout);
+
+	User::WaitForRequest(rs, timerStatus);
+	if(rs.Int() == KRequestPending)
+		{
+		RDebug::Print(_L("Transfer timed out!"));
+		// timed out
+		test(EFalse);
+		}
+	iTimer.Cancel();
+	test_KErrNone(rs.Int());
+	test(iChannel.CheckBuffer(KDestBuf, 'A'));
+
+	// Queue, then cancel request - Checks
+	// that there there is no spurious callback
+	// to the PIL
+	r = iChannel.Execute(_L8("Q0C"));
+	test_KErrNone(r);
+
+	iChannel.FreeAllBuffers();
+	return KErrNone;
+	}
+
 
 // Called when thread completed.
 void CTesterThread::RunL()
@@ -414,7 +613,6 @@
 
 	if (aMaxThread == 0)
 		{
-		delete aTest;
 		test.Printf(_L("transfer mode not supported - skipped\n"));
 		return;
 		}
@@ -444,9 +642,6 @@
 		test(new CTesterThread(i, dmaTest) != NULL);
 		dmaTest = NULL; //ownership transferred to CTesterThread
 		}
-	//the orginal isn't needed
-	delete aTest;
-	aTest = NULL;
 
 	const TTimeIntervalMicroSeconds32 KPeriod = 1000000;	// 1s
 	Bipper->Start(KPeriod, KPeriod, Bip);
@@ -459,17 +654,29 @@
 
 inline void RunSbTest(TInt aMaxThread, CTest* aTest)
 	{
+	RunTest(Info.iSbChannels, Min(1,Info.iMaxSbChannels), aTest);
 	RunTest(Info.iSbChannels, Min(aMaxThread,Info.iMaxSbChannels), aTest);
+
+	//the orginal isn't needed
+	delete aTest;
 	}
 
 inline void RunDbTest(TInt aMaxThread, CTest* aTest)
 	{
+	RunTest(Info.iDbChannels, Min(1,Info.iMaxDbChannels), aTest);
 	RunTest(Info.iDbChannels, Min(aMaxThread,Info.iMaxDbChannels), aTest);
+
+	//the orginal isn't needed
+	delete aTest;
 	}
 
 inline void RunSgTest(TInt aMaxThread, CTest* aTest)
 	{
+	RunTest(Info.iSgChannels, Min(1,Info.iMaxSgChannels), aTest);
 	RunTest(Info.iSgChannels, Min(aMaxThread,Info.iMaxSgChannels), aTest);
+
+	//the orginal isn't needed
+	delete aTest;
 	}
 //////////////////////////////////////////////////////////////////////////////
 
@@ -964,6 +1171,35 @@
 	test.Next(_L("Getting channel info"));
 	GetChannelInfo();
 
+	test.Next(_L("Test that channel can be closed from callback"));
+	test.Next(_L("sb"));
+	RunSbTest(maxchannel, new CCloseInCb() );
+	test.Next(_L("db"));
+	RunDbTest(maxchannel, new CCloseInCb() );
+	test.Next(_L("sg"));
+	RunSgTest(maxchannel, new CCloseInCb() );
+
+	test.Next(_L("Testing different fragment sizes"));
+
+	const TInt rangeFragSize = 4096;
+#ifdef __DMASIM__
+	// Use fewer iterations on the emulator
+	// since it is slower. Also this test is really
+	// intended to find errors in PSL implmentations
+	const TInt iterPerFragSize = 1;
+#else
+	const TInt iterPerFragSize = 30;
+#endif
+	const TInt rangeMaxFragCount = 8;
+
+	test.Next(_L("sb"));
+	RunSbTest(maxchannel, new CFragSizeRange(1, rangeMaxFragCount, rangeFragSize, iterPerFragSize));
+	test.Next(_L("db"));
+	RunDbTest(maxchannel, new CFragSizeRange(1, rangeMaxFragCount, rangeFragSize, iterPerFragSize));
+	test.Next(_L("sg"));
+	RunSgTest(maxchannel, new CFragSizeRange(1, rangeMaxFragCount, rangeFragSize, iterPerFragSize));
+
+
 	// Size for the single transfer test
 	TInt totalTransferSize = 64 * KKilo;
 
--- a/kerneltest/e32test/dmav2/test_cases.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kerneltest/e32test/dmav2/test_cases.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
 * All rights reserved.
 * This component and the accompanying materials are made available
 * under the terms of "Eclipse Public License v1.0"
@@ -325,7 +325,7 @@
 	//will only have one fragment
 	const TInt size = 0x40000;
 	TDmaTransferArgs dfcTransfer(0, size, size, KDmaMemAddr);
-	TDmaTransferArgs isrTransfer(size, 2 * size, size, KDmaMemAddr, KDmaSyncAuto, KDmaRequestCallbackFromIsr);
+	TDmaTransferArgs isrTransfer(2*size, 3*size, size, KDmaMemAddr, KDmaSyncAuto, KDmaRequestCallbackFromIsr);
 
 	const TResultSet success = TResultSet();
 	TResultSet queueFailure = TResultSet().
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/eabi/i2c_ctrlessu.def	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,24 @@
+EXPORTS
+	_Z20CreatePhysicalDevicev @ 1 NONAME
+	_ZN20TIicBusSlaveCallback7DfcFuncEPv @ 2 NONAME
+	_ZN25DIicBusChannelMasterSlaveC1EN14DIicBusChannel8TBusTypeENS0_14TChannelDuplexEP20DIicBusChannelMasterP19DIicBusChannelSlave @ 3 NONAME
+	_ZN25DIicBusChannelMasterSlaveC2EN14DIicBusChannel8TBusTypeENS0_14TChannelDuplexEP20DIicBusChannelMasterP19DIicBusChannelSlave @ 4 NONAME
+	_ZN31DSimulatedIicBusChannelSlaveI2cC1EN14DIicBusChannel8TBusTypeENS0_14TChannelDuplexE @ 5 NONAME
+	_ZN31DSimulatedIicBusChannelSlaveI2cC2EN14DIicBusChannel8TBusTypeENS0_14TChannelDuplexE @ 6 NONAME
+	_ZN32DSimulatedIicBusChannelMasterI2cC1EN14DIicBusChannel8TBusTypeENS0_14TChannelDuplexE @ 7 NONAME
+	_ZN32DSimulatedIicBusChannelMasterI2cC2EN14DIicBusChannel8TBusTypeENS0_14TChannelDuplexE @ 8 NONAME
+	_ZN37DSimulatedIicBusChannelMasterSlaveI2cC1EN14DIicBusChannel8TBusTypeENS0_14TChannelDuplexEP32DSimulatedIicBusChannelMasterI2cP31DSimulatedIicBusChannelSlaveI2c @ 9 NONAME
+	_ZN37DSimulatedIicBusChannelMasterSlaveI2cC2EN14DIicBusChannel8TBusTypeENS0_14TChannelDuplexEP32DSimulatedIicBusChannelMasterI2cP31DSimulatedIicBusChannelSlaveI2c @ 10 NONAME
+	_ZTI19DIicBusChannelSlave @ 11 NONAME
+	_ZTI20DIicBusChannelMaster @ 12 NONAME
+	_ZTI25DIicBusChannelMasterSlave @ 13 NONAME
+	_ZTI31DSimulatedIicBusChannelSlaveI2c @ 14 NONAME
+	_ZTI32DSimulatedIicBusChannelMasterI2c @ 15 NONAME
+	_ZTI37DSimulatedIicBusChannelMasterSlaveI2c @ 16 NONAME
+	_ZTV19DIicBusChannelSlave @ 17 NONAME
+	_ZTV20DIicBusChannelMaster @ 18 NONAME
+	_ZTV25DIicBusChannelMasterSlave @ 19 NONAME
+	_ZTV31DSimulatedIicBusChannelSlaveI2c @ 20 NONAME
+	_ZTV32DSimulatedIicBusChannelMasterI2c @ 21 NONAME
+	_ZTV37DSimulatedIicBusChannelMasterSlaveI2c @ 22 NONAME
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/eabi/spi_ctrlessu.def	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,20 @@
+EXPORTS
+	_Z20CreatePhysicalDevicev @ 1 NONAME
+	_ZN20TIicBusSlaveCallback7DfcFuncEPv @ 2 NONAME
+	_ZN25DIicBusChannelMasterSlaveC1EN14DIicBusChannel8TBusTypeENS0_14TChannelDuplexEP20DIicBusChannelMasterP19DIicBusChannelSlave @ 3 NONAME
+	_ZN25DIicBusChannelMasterSlaveC2EN14DIicBusChannel8TBusTypeENS0_14TChannelDuplexEP20DIicBusChannelMasterP19DIicBusChannelSlave @ 4 NONAME
+	_ZN31DSimulatedIicBusChannelSlaveSpiC1EN14DIicBusChannel8TBusTypeENS0_14TChannelDuplexE @ 5 NONAME
+	_ZN31DSimulatedIicBusChannelSlaveSpiC2EN14DIicBusChannel8TBusTypeENS0_14TChannelDuplexE @ 6 NONAME
+	_ZN32DSimulatedIicBusChannelMasterSpiC1EN14DIicBusChannel8TBusTypeENS0_14TChannelDuplexE @ 7 NONAME
+	_ZN32DSimulatedIicBusChannelMasterSpiC2EN14DIicBusChannel8TBusTypeENS0_14TChannelDuplexE @ 8 NONAME
+	_ZTI19DIicBusChannelSlave @ 9 NONAME
+	_ZTI20DIicBusChannelMaster @ 10 NONAME
+	_ZTI25DIicBusChannelMasterSlave @ 11 NONAME
+	_ZTI31DSimulatedIicBusChannelSlaveSpi @ 12 NONAME
+	_ZTI32DSimulatedIicBusChannelMasterSpi @ 13 NONAME
+	_ZTV19DIicBusChannelSlave @ 14 NONAME
+	_ZTV20DIicBusChannelMaster @ 15 NONAME
+	_ZTV25DIicBusChannelMasterSlave @ 16 NONAME
+	_ZTV31DSimulatedIicBusChannelSlaveSpi @ 17 NONAME
+	_ZTV32DSimulatedIicBusChannelMasterSpi @ 18 NONAME
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/eabi/t_wsd_dl1.def	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,4 @@
+EXPORTS
+	ExportedData @ 1 NONAME DATA 4 ; TInt32 ExportedData
+	_Z24CheckExportedDataAddressPv @ 2 NONAME ; void CheckExportedDataAddress(void* aDataAddr)
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/eabi/t_wsd_dl2.def	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,4 @@
+EXPORTS
+	_Z21GetAddressOfDataProxyRiRPvS1_ @ 1 NONAME
+	_Z23CheckWritableStaticDatav @ 2 NONAME
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/eabi/t_wsd_dl3.def	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,7 @@
+EXPORTS
+	_Z16GetAddressOfDataRiRPvS1_ @ 1 NONAME
+	TestDataSize @ 2 NONAME DATA 4
+	WritableTestData @ 3 NONAME DATA 65536
+	PointerToStaticData @ 4 NONAME DATA 4
+	PointerToWritableData @ 5 NONAME DATA 4
+
--- a/kerneltest/e32test/group/base_e32test.mrp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kerneltest/e32test/group/base_e32test.mrp	Fri Apr 16 16:24:37 2010 +0300
@@ -1,3 +1,18 @@
+#
+# 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 "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: 
+#
 # component name "E32 Tests"
 
 component	base_e32test
--- a/kerneltest/e32test/group/bld.inf	Tue Feb 02 01:24:03 2010 +0200
+++ b/kerneltest/e32test/group/bld.inf	Fri Apr 16 16:24:37 2010 +0300
@@ -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/
@@ -82,6 +83,7 @@
  positive check ( #ifdef SMP ), however these binaries will not be included in BTB 
  autotest images for SMP platforms. Refer to DTW-KHS BTB00055 for more details.
  ******************************************************************************/
+d_kerncorestats				support
 d_implicit					support
 d_emitest					support
 d_ldd						support
@@ -117,6 +119,7 @@
 d_shbuf_client				support
 d_shbuf_own					support
 d_asid						support
+d_entropysources			support
 
 #ifdef GENERIC_MARM
 d_schedhook					support
@@ -186,7 +189,6 @@
 #endif
 
 #if !defined(X86)
-#if defined(WINS)
 ../iic/iic_psl/iic_testpsl			support
 ../iic/iic_psl/spi					support
 ../iic/iic_psl/i2c					support
@@ -198,7 +200,6 @@
 ../iic/iic_psl/d_iic_client_ctrless		support
 ../iic/iic_psl/d_iic_slaveclient_ctrless	support
 #endif
-#endif
 
 #if !defined(WINS) && !defined(X86)
 d_crazyints support
@@ -219,6 +220,8 @@
 //T_ROMCHK      // check the ROM is OK before starting tests
 #endif
 
+t_printsysinfo		/* t_printsysinfo is the first test to run because it logs the system information */
+
 // todo: t_shadow tests currently need to run before any ROM pages get shadowed so do this first
 // for now
 #ifdef EPOC32
@@ -466,6 +469,29 @@
 t_wsdextension	support
 #endif
 
+// t_wsd_* suffixes:
+//   x => XIP; runs from ROM
+//   c => code loads & runs in RAM
+//   p => pagedcode
+//   u => unpagedcode
+t_wsd_dl3_xp	support
+t_wsd_dl3_xu	support
+t_wsd_dl2_xp	support
+t_wsd_dl2_xu	support
+t_wsd_dl1_xp	support
+t_wsd_dl1_xu	support
+t_wsd_tst_xp
+t_wsd_tst_xu
+
+t_wsd_dl3_cp	support
+t_wsd_dl3_cu	support
+t_wsd_dl2_cp	support
+t_wsd_dl2_cu	support
+t_wsd_dl1_cp	support
+t_wsd_dl1_cu	support
+t_wsd_tst_cp
+t_wsd_tst_cu
+
 // /e32test/ethernet
 ../ethernet/pump/etherpump  manual
 ../ethernet/macset/macset   manual
@@ -482,6 +508,11 @@
 t_heapdb
 t_kheap
 
+// Secure RNG tests
+t_securerng
+t_sha256
+t_entropysources
+
 // /E32TEST/LFFS tests
 t_lfsdrv2       manual
 t_lfsdrvbm		manual
@@ -536,6 +567,9 @@
 
 t_duid      support
 t_uid
+#ifdef EPOC32
+ccthrash	support
+#endif
 cpumeter    support
 crash       support
 reboot		support
@@ -561,6 +595,7 @@
 t_mem       support
 t_unzip     support
 t_ymodem    support
+ymodemtx	support
 t_ymodemz   support
 t_lbk       support
 t_forever   support
@@ -576,6 +611,8 @@
 eject       support
 t_pcreat    support
 
+t_loadsim	support
+
 #if !defined(WINS)
 t_zip       manual
 #endif
@@ -946,38 +983,55 @@
 
 // /E32TEST/IIC tests
 #if !defined(X86)
-#if defined(WINS)
 ../iic/t_iic
 #endif
-#endif
 
 #if defined(MARM_ARMV5)
 t_oeexport2
 #endif
 
 #if defined(MARM_ARMV5) || defined(MARM_ARMV4)
-t_trkdummyapp
+../rm_debug/group/t_trkdummyapp
 #endif
 
 #if defined(MARM_ARMV5)
-t_rmdebug_dll support
-t_rmdebug_security0 support
-t_rmdebug_security1 support
-t_rmdebug_security2 support
-t_rmdebug_security3 support
-t_rmdebug_app support
-t_rmdebug2
-t_rmdebug2_oem
-t_rmdebug2_oemtoken support
-t_rmdebug2_oem2
-t_rmdebug2_oemtoken2 support
-t_crashmonitor_lib
+../rm_debug/group/t_rmdebug_dll support
+../rm_debug/group/t_rmdebug_security0 support
+../rm_debug/group/t_rmdebug_security1 support
+../rm_debug/group/t_rmdebug_security2 support
+../rm_debug/group/t_rmdebug_security3 support
+../rm_debug/group/t_rmdebug_app support
+../rm_debug/group/t_rmdebug2
+../rm_debug/group/t_rmdebug2_oem
+../rm_debug/group/t_rmdebug2_oemtoken support
+../rm_debug/group/t_rmdebug2_oem2
+../rm_debug/group/t_rmdebug2_oemtoken2 support
+../rm_debug/group/t_crashmonitor_lib
+
+../rm_debug/group/t_rmdebug_app1 support
+../rm_debug/group/t_rmdebug_app2 support
+../rm_debug/group/t_rmdebug_app3 support
+../rm_debug/group/t_rmdebug_app4 support
+../rm_debug/group/t_rmdebug_app5 support
+../rm_debug/group/t_rmdebug_app6 support
+../rm_debug/group/t_rmdebug_app7 support
+../rm_debug/group/t_rmdebug_app8 support
+../rm_debug/group/t_rmdebug_app9 support
+../rm_debug/group/t_rmdebug_app10 support
+
+../rm_debug/group/t_rmdebug_target_launcher support
+../rm_debug/group/t_rmdebug_multi_target
+
+../rm_debug/group/t_rmdebug_multi_agent support
+../rm_debug/group/t_multi_agent_launcher
+
+
 #endif
 
 t_stacksize
 
 #if !defined(WINS) && !defined(X86)
-t_crazyints	
+t_crazyints
 #endif
 
 #endif	// SMP
@@ -998,4 +1052,13 @@
 t_camera_gen		manual
 d_mmcsc			support
 
+t_kerncorestats		support
+
 #include "../hcr/hcr.inf"
+
+//pci tests
+t_pci
+// timestamp or fastcounter test
+t_timestamp
+d_timestamp		support
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/group/ccthrash.mmp	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,28 @@
+// Copyright (c) 2009-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/ccthrash.mmp
+// 
+//
+
+target				ccthrash.exe
+targettype			exe
+
+sourcepath			../misc
+source				ccthrash.cpp
+library				euser.lib
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN
+
+capability			all
+vendorid			0x70000001
+smpsafe
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/group/d_entropysources.mmp	Fri Apr 16 16:24:37 2010 +0300
@@ -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/d_kerncorestats.mmp	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,31 @@
+// Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "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_kerncorestats.mmp
+// 
+//
+#include "kernel/kern_ext.mmh"
+
+target			d_TestKernCoreStats.ldd
+targettype		ldd
+sourcepath		../misc
+source			d_TestKernCoreStats.cpp
+epocallowdlldata
+
+start wins
+win32_headers
+end
+
+capability		all
+vendorid		0x70000001
+SMPSAFE
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/group/d_timestamp.mmp	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,41 @@
+// Copyright (c) 2010 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:
+// d_timestamp.mmp
+// 
+//
+
+
+
+#include "kernel\kern_ext.mmh"
+
+TARGET		        D_TIMESTAMP.LDD
+TARGETTYPE		LDD
+
+SOURCEPATH		../timestamp
+SOURCE			D_TIMESTAMP.CPP
+
+LIBRARY			EKERN.LIB
+
+epocallowdlldata
+
+UID		0x100000af
+VENDORID 0x70000001
+
+start wins
+win32_headers
+end
+
+capability		all
+
+SMPSAFE
--- a/kerneltest/e32test/group/romstuff.mke	Tue Feb 02 01:24:03 2010 +0200
+++ b/kerneltest/e32test/group/romstuff.mke	Fri Apr 16 16:24:37 2010 +0300
@@ -36,5 +36,6 @@
 	@echo data=##BASEPATH##kernelhwsrv\kerneltest\e32test\hcr\megalarge2.dat    sys\data\megalarge2.dat		unpaged paging_unmovable
 	@echo data=##BASEPATH##kernelhwsrv\kerneltest\e32test\hcr\filerepos_bc0.dat sys\data\filerepos_bc0.dat	unpaged paging_unmovable
 	@echo data=##BASEPATH##kernelhwsrv\kerneltest\e32test\hcr\filerepos_bc1.dat sys\data\filerepos_bc1.dat	unpaged paging_unmovable
+	@echo data=##BASEPATH##kernelhwsrv\kerneltest\e32test\hcr\filerepos_cds.dat sys\data\filerepos_cds.dat  unpaged paging_unmovable
 	@echo hcrdata=##BASEPATH##kernelhwsrv\kerneltest\e32test\hcr\filerepos.dat  sys\data\hcr.dat
 #endif
--- a/kerneltest/e32test/group/t_crashmonitor_lib.mmp	Tue Feb 02 01:24:03 2010 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,45 +0,0 @@
-// Copyright (c) 2008-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_crashmonitor_lib.mmp
-// 
-//
-
-ALWAYS_BUILD_AS_ARM
-
-targettype     exe
- 
-SYMBIAN_BASE_SYSTEMINCLUDE(nkern)
-OS_LAYER_SYSTEMINCLUDE_SYMBIAN
-
-userinclude    ../../../kernel/eka/debug/crashMonitor/inc
-sourcepath	   	../rm_debug/crashmonitor
-
-source        	t_crashmonitor.cpp
-
-library	euser.lib
-library hal.lib
-staticlibrary scmusr_lib.lib
-
-target         t_crashmonitor_lib.exe
-
-UID            0x0 0x4321bbbc
-SECUREID       0x2000B26F
-
-capability		none
-
-VENDORID       0x70000001
-
-DEBUGGABLE
-
-SMPSAFE
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/group/t_entropysources.mmp	Fri Apr 16 16:24:37 2010 +0300
@@ -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
--- a/kerneltest/e32test/group/t_extendedrescontrolcli.mmp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kerneltest/e32test/group/t_extendedrescontrolcli.mmp	Fri Apr 16 16:24:37 2010 +0300
@@ -25,7 +25,7 @@
 
 
 capability		all
-
+epocstacksize	0x8000
 vendorid 0x70000001
 
 start wins
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/group/t_kerncorestats.mmp	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,29 @@
+// Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "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_kerncorestats.mmp
+// 
+//
+
+TARGET         t_kerncorestats.exe
+TARGETTYPE     EXE
+SOURCEPATH     ../misc
+SOURCE         t_kerncorestats.cpp
+LIBRARY        euser.lib
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN
+
+capability     all
+
+VENDORID 0x70000001
+
+SMPSAFE
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/group/t_loadsim.mmp	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,27 @@
+// Copyright (c) 2009-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_loadsim.mmp
+// 
+//
+
+target			t_loadsim.exe
+targettype		exe
+sourcepath		../misc
+source			t_loadsim.cpp
+library			euser.lib hal.lib
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN
+capability		all
+vendorid		0x70000001
+epocheapsize	0x00001000 0x01000000
+smpsafe
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/group/t_pci.mmp	Fri Apr 16 16:24:37 2010 +0300
@@ -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_printsysinfo.mmp	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,27 @@
+// Copyright (c) 2010 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_printsysinfo.mmp
+//
+//
+
+target			t_printsysinfo.exe        
+targettype		exe
+sourcepath		../demandpaging
+source			t_printsysinfo.cpp
+library			euser.lib hal.lib dptest.lib
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN
+capability		all
+vendorid		0x70000001
+
+smpsafe
--- a/kerneltest/e32test/group/t_rmdebug.mmp	Tue Feb 02 01:24:03 2010 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,40 +0,0 @@
-// Copyright (c) 2006-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_rmdebug.mmp
-// 
-//
-
-ALWAYS_BUILD_AS_ARM
-
-target         t_rmdebug.exe
-targettype     exe
-
-sourcepath	   	../rm_debug
-source        	d_rmdebugserver.cpp 
-source        	d_rmdebugthread.cpp 
-source        	t_rmdebug.cpp 
-source			d_rmdebugthreadasm.cia
-
-library		euser.lib
-               
-SYMBIAN_BASE_SYSTEMINCLUDE(nkern)
-OS_LAYER_SYSTEMINCLUDE_SYMBIAN
-
-UID            0x100039CE 0x101F7159
-SECUREID       0x101F7159
-VENDORID       0x70000001
-
-CAPABILITY 	ALL -TCB
-
-SMPSAFE
--- a/kerneltest/e32test/group/t_rmdebug2.mmh	Tue Feb 02 01:24:03 2010 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,67 +0,0 @@
-// Copyright (c) 2006-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_rmdebug2.mmh
-// 
-//
-
-ALWAYS_BUILD_AS_ARM
-
-targettype     exe
-
-sourcepath	   	..\rm_debug
-
-source        	d_rmdebugthread2.cpp 
-source        	t_rmdebug2.cpp 
-source			d_rmdebugthreadasm2.cia
-source		r_low_memory_security_svr_session.cpp
-source		r_kernel_low_memory_security_svr_session.cpp
-source		r_user_low_memory_security_svr_session.cpp
-
-#if defined(MARM_ARMV5)
-source			d_rmdebug_step_test.s
-#endif
-
-#if defined(MARM_ARMV4)
-source			d_rmdebug_step_test_armv4.s
-#endif
-
-source			d_demand_paging.cia
-
-library		euser.lib
-library         hal.lib
-library         efsrv.lib
-library         t_rmdebug_dll.lib
-
-userinclude    ..\..\..\kernel\eka\include\drivers
-userinclude    ..\..\..\kernel\eka\debug\securityserver\inc
-#ifdef SYMBIAN_OLD_EXPORT_LOCATION
-SYMBIAN_BASE_SYSTEMINCLUDE(drivers)
-SYMBIAN_BASE_SYSTEMINCLUDE(kernel)
-#endif
-SYMBIAN_BASE_SYSTEMINCLUDE(nkern)
-OS_LAYER_SYSTEMINCLUDE_SYMBIAN
-
-PAGED
-
-// To test heap allocation failure uncomment one or other of the following macros.
-// NOTE: Do not uncomment both, the tests will panic if both are defined!
-
-// To test heap allocation failure in the Debug Device Driver uncomment this macro
-//macro KERNEL_OOM_TESTING
-
-// To test heap allocation failure in the Debug Security Server uncomment this macro
-//macro USER_OOM_TESTING
-
-
-SMPSAFE
--- a/kerneltest/e32test/group/t_rmdebug2.mmp	Tue Feb 02 01:24:03 2010 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,30 +0,0 @@
-// Copyright (c) 2006-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_rmdebug2.mmp
-// 
-//
-
-#include "t_rmdebug2.mmh"
-
-target         t_rmdebug2.exe
-
-UID            0x0 0x4321bbbb
-SECUREID       0x1234aaaa
-VENDORID       0x70000001
-
-CAPABILITY 	READUSERDATA POWERMGMT ALLFILES
-
-DEBUGGABLE
-
-macro SYMBIAN_STANDARDDEBUG
--- a/kerneltest/e32test/group/t_rmdebug2_oem.mmp	Tue Feb 02 01:24:03 2010 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,33 +0,0 @@
-// Copyright (c) 2006-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_rmdebug2_oem.mmp
-// Same tests as t_rmdebug2.mmp but with OEM rights conferred
-// by the OEMDebug_F123ABCD.exe token file.
-// 
-//
-
-#include "t_rmdebug2.mmh"
-
-target         t_rmdebug2_oem.exe
-
-UID            0x0 0x4321bbbb
-SECUREID       0xF123abcd
-VENDORID       0x70000001
-
-CAPABILITY 	READUSERDATA POWERMGMT ALLFILES
-
-// Used when compiling tests to work in the presence of an
-// OEM Debug Token
-macro SYMBIAN_OEMDEBUG
-
--- a/kerneltest/e32test/group/t_rmdebug2_oem2.mmp	Tue Feb 02 01:24:03 2010 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,33 +0,0 @@
-// Copyright (c) 2006-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_rmdebug2_oem2.mmp
-// Same tests as t_rmdebug2.mmp but with some OEM rights conferred
-// by the OEMDebug_F1234567.exe token file.
-// 
-//
-
-#include "t_rmdebug2.mmh"
-
-target         t_rmdebug2_oem2.exe
-
-UID            0x0 0x4321bbbb
-SECUREID       0xF1234567
-VENDORID       0x70000001
-
-CAPABILITY 	READUSERDATA POWERMGMT
-
-// Used when compiling tests to work in the presence of an
-// OEM Debug Token with AllFiles only capability
-macro SYMBIAN_OEM2DEBUG
-
--- a/kerneltest/e32test/group/t_rmdebug2_oemtoken.mmp	Tue Feb 02 01:24:03 2010 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,37 +0,0 @@
-// Copyright (c) 2007-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_rmdebug2_oemtoken.mmp
-// 
-//
-
-ALWAYS_BUILD_AS_ARM
-
-target         OEMDebug_F123ABCD.exe
-targettype     exe
-
-sourcepath	   	../rm_debug
-
-source        	t_rmdebug2_oemtoken.cpp 
-
-library		euser.lib
-
-OS_LAYER_SYSTEMINCLUDE_SYMBIAN
-
-capability PowerMgmt AllFiles Tcb ReadUserData WriteUserData
-
-UID            0x0 0x0
-SECUREID       0x0
-VENDORID       0x70000001
-
-SMPSAFE
--- a/kerneltest/e32test/group/t_rmdebug2_oemtoken2.mmp	Tue Feb 02 01:24:03 2010 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,38 +0,0 @@
-// Copyright (c) 2007-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_rmdebug2_oemtoken2.mmp
-// 
-//
-
-ALWAYS_BUILD_AS_ARM
-
-target         OEMDebug_F1234567.exe
-targettype     exe
-
-sourcepath	   	../rm_debug
-
-source        	t_rmdebug2_oemtoken.cpp 
-
-library		euser.lib
-
-OS_LAYER_SYSTEMINCLUDE_SYMBIAN
-
-// Token requires AllFiles
-capability AllFiles ReadUserData PowerMgmt
-
-UID            0x0 0x0
-SECUREID       0x0
-VENDORID       0x70000001
-
-SMPSAFE
--- a/kerneltest/e32test/group/t_rmdebug_app.mmp	Tue Feb 02 01:24:03 2010 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,36 +0,0 @@
-// Copyright (c) 2007-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_rmdebug_app.mmp
-// 
-//
-
-target             t_rmdebug_app.exe
-targettype         exe
-
-sourcepath         ../rm_debug
-source             t_rmdebug_app.cpp 
-source			   d_rmdebugthreadasm2.cia
-
-OS_LAYER_SYSTEMINCLUDE_SYMBIAN
-library            euser.lib
-
-uid                0x0 0x0
-capability         none
-
-always_build_as_arm
-pagedcode
-
-DEBUGGABLE
-
-SMPSAFE
--- a/kerneltest/e32test/group/t_rmdebug_dll.mmp	Tue Feb 02 01:24:03 2010 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,37 +0,0 @@
-// Copyright (c) 2007-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_rmdebug_dll.mmp
-// 
-//
-
-ALWAYS_BUILD_AS_ARM
-
-target         t_rmdebug_dll.dll
-targettype     dll
-
-sourcepath	   	../rm_debug
-
-source        	t_rmdebug_dll.cpp 
-
-library		euser.lib
-
-OS_LAYER_SYSTEMINCLUDE_SYMBIAN
-
-capability PowerMgmt AllFiles ReadUserData
-
-UID            0x0 0x0
-SECUREID       0x0
-VENDORID       0x70000001
-
-SMPSAFE
--- a/kerneltest/e32test/group/t_rmdebug_security0.mmp	Tue Feb 02 01:24:03 2010 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,38 +0,0 @@
-// Copyright (c) 2006-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_rmdebug_security0.mmp
-// All-TCB
-// 
-//
-
-ALWAYS_BUILD_AS_ARM
-
-target         t_rmdebug_security0.exe
-targettype     exe
-
-sourcepath	   	../rm_debug
-source        	t_rmdebug_security.cpp 
-
-library		euser.lib hal.lib
-               
-SYMBIAN_BASE_SYSTEMINCLUDE(nkern)
-OS_LAYER_SYSTEMINCLUDE_SYMBIAN
-
-UID            0x100039CE 0xbaaaf00d
-SECUREID       0x101F7159
-VENDORID       0x70000001
-
-DEBUGGABLE
-
-SMPSAFE
--- a/kerneltest/e32test/group/t_rmdebug_security1.mmp	Tue Feb 02 01:24:03 2010 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,37 +0,0 @@
-// Copyright (c) 2006-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_rmdebug_security1.mmp
-// All-TCB
-// 
-//
-
-ALWAYS_BUILD_AS_ARM
-
-target         t_rmdebug_security1.exe
-targettype     exe
-
-sourcepath	   	../rm_debug
-source        	t_rmdebug_security.cpp 
-
-library		euser.lib hal.lib
-               
-SYMBIAN_BASE_SYSTEMINCLUDE(nkern)
-OS_LAYER_SYSTEMINCLUDE_SYMBIAN
-
-UID            0x100039CE 0xdeadbaaa
-SECUREID       0x101F7159
-VENDORID       0x70000001
-
-
-SMPSAFE
--- a/kerneltest/e32test/group/t_rmdebug_security2.mmp	Tue Feb 02 01:24:03 2010 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,39 +0,0 @@
-// Copyright (c) 2006-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_rmdebug_security2.mmp
-// All-TCB
-// 
-//
-
-ALWAYS_BUILD_AS_ARM
-
-target         t_rmdebug_security2.exe
-targettype     exe
-
-sourcepath	   	../rm_debug
-source        	t_rmdebug_security.cpp 
-
-library		euser.lib hal.lib
-               
-SYMBIAN_BASE_SYSTEMINCLUDE(nkern)
-OS_LAYER_SYSTEMINCLUDE_SYMBIAN
-
-capability AllFiles
-
-UID            0x100039CE 0xdeadbaaa
-SECUREID       0x101F7159
-VENDORID       0x70000001
-
-
-SMPSAFE
--- a/kerneltest/e32test/group/t_rmdebug_security3.mmp	Tue Feb 02 01:24:03 2010 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,39 +0,0 @@
-// Copyright (c) 2006-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_rmdebug_security3.mmp
-// All-TCB
-// 
-//
-
-ALWAYS_BUILD_AS_ARM
-
-target         t_rmdebug_security3.exe
-targettype     exe
-
-sourcepath	   	../rm_debug
-source        	t_rmdebug_security.cpp 
-
-library		euser.lib hal.lib
-               
-SYMBIAN_BASE_SYSTEMINCLUDE(nkern)
-OS_LAYER_SYSTEMINCLUDE_SYMBIAN
-
-capability TCB AllFiles NetworkControl
-
-UID            0x100039CE 0xdeadbaaa
-SECUREID       0x101F7159
-VENDORID       0x70000001
-
-
-SMPSAFE
--- a/kerneltest/e32test/group/t_schedhook.mmp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kerneltest/e32test/group/t_schedhook.mmp	Fri Apr 16 16:24:37 2010 +0300
@@ -18,9 +18,7 @@
 target			t_schedhook.exe
 targettype		exe
 
-#if defined(GCC32)
 ALWAYS_BUILD_AS_ARM
-#endif
 
 sourcepath		../debug
 source			t_schedhook.cpp context.cia
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/group/t_securerng.mmp	Fri Apr 16 16:24:37 2010 +0300
@@ -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	Fri Apr 16 16:24:37 2010 +0300
@@ -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/group/t_smpsoakspin.mmp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kerneltest/e32test/group/t_smpsoakspin.mmp	Fri Apr 16 16:24:37 2010 +0300
@@ -1,7 +1,20 @@
-// e32test\group\t_smpsoakspin.mmp
-//
-// Copyright (c) 2005 Symbian Ltd. All rights reserved.
-//
+/*
+* Copyright (c) 2005 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "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			t_smpsoakspin.exe        
 targettype		exe
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/group/t_timestamp.mmp	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,31 @@
+// Copyright (c) 1996-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:
+// t_timestamp.mmp
+// 
+//
+
+
+target			t_timestamp.exe        
+targettype		exe
+SOURCEPATH		../timestamp
+source			t_timestamp.cpp
+library			euser.lib hal.lib
+
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN
+
+capability		none
+
+VENDORID 0x70000001
+
+SMPSAFE
--- a/kerneltest/e32test/group/t_trkdummyapp.mmp	Tue Feb 02 01:24:03 2010 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,44 +0,0 @@
-// Copyright (c) 2008-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_trkdummyapp.mmp
-// 
-//
-
-ALWAYS_BUILD_AS_ARM
-
-target         t_trkdummyapp.exe
-targettype     exe
-
-sourcepath	   	../rm_debug
-
-source        	t_trkdummyapp.cpp 
-
-library		euser.lib
-library         hal.lib
-library         efsrv.lib
-library         t_rmdebug_dll.lib
-
-SYMBIAN_BASE_SYSTEMINCLUDE(nkern)
-OS_LAYER_SYSTEMINCLUDE_SYMBIAN
-
-UID            0x0 0x0
-SECUREID       0x0
-VENDORID       0x70000001
-
-CAPABILITY 	none
-
-
-
-
-SMPSAFE
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/group/t_wsd_dl1.mmh	Fri Apr 16 16:24:37 2010 +0300
@@ -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:
+// e32test/group/t_wsd_dl1.mmh
+
+targettype			dll
+sourcepath			../mmu
+source				t_wsd_dl1.cpp
+deffile				t_wsd_dl1.def
+nostrictdef
+capability			all
+vendorid			0x70000001
+library				euser.lib
+
+macro T_WSD_DL1
+epocallowdlldata
+
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN
+UNPAGEDDATA
+SMPSAFE
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/group/t_wsd_dl1_cp.mmp	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,22 @@
+// Copyright (c) 2005-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_wsd_dl1_cp.mmp
+// 
+// This binary goes in ram and is paged
+
+ROMTARGET
+RAMTARGET			+
+PAGEDCODE
+target				t_wsd_dl1_cp.dll
+#include			"t_wsd_dl1.mmh"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/group/t_wsd_dl1_cu.mmp	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,22 @@
+// Copyright (c) 2005-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_wsd_dl1_cu.mmp
+// 
+// This binary goes in ram and is unpaged
+
+ROMTARGET
+RAMTARGET			+
+UNPAGEDCODE
+target				t_wsd_dl1_cu.dll
+#include			"t_wsd_dl1.mmh"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/group/t_wsd_dl1_xp.mmp	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,21 @@
+// Copyright (c) 2005-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_wsd_dl1_xp.mmp
+// 
+// This binary goes in rom and is paged
+
+ROMTARGET			+
+PAGEDCODE
+target				t_wsd_dl1_xp.dll
+#include			"t_wsd_dl1.mmh"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/group/t_wsd_dl1_xu.mmp	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,21 @@
+// Copyright (c) 2005-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_wsd_dl1_xu.mmp
+// 
+// This binary goes in rom and is unpaged
+
+ROMTARGET			+
+UNPAGEDCODE
+target				t_wsd_dl1_xu.dll
+#include			"t_wsd_dl1.mmh"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/group/t_wsd_dl2.mmh	Fri Apr 16 16:24:37 2010 +0300
@@ -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:
+// e32test/group/t_wsd_dl2.mmh
+
+targettype			dll
+sourcepath			../mmu
+source				t_wsd_dl2.cpp
+deffile				t_wsd_dl2.def
+nostrictdef
+capability			all
+vendorid			0x70000001
+library				euser.lib
+
+macro T_WSD_DL2
+// epocallowdlldata
+
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN
+UNPAGEDDATA
+SMPSAFE
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/group/t_wsd_dl2_cp.mmp	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,23 @@
+// Copyright (c) 2005-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_wsd_dl2_cp.mmp
+// 
+// This binary goes in ram and is paged
+
+ROMTARGET
+RAMTARGET			+
+PAGEDCODE
+target				t_wsd_dl2_cp.dll
+library				t_wsd_dl3_cp.lib
+#include			"t_wsd_dl2.mmh"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/group/t_wsd_dl2_cu.mmp	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,23 @@
+// Copyright (c) 2005-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_wsd_dl2_cu.mmp
+// 
+// This binary goes in ram and is unpaged
+
+ROMTARGET
+RAMTARGET			+
+UNPAGEDCODE
+target				t_wsd_dl2_cu.dll
+library				t_wsd_dl3_cu.lib
+#include			"t_wsd_dl2.mmh"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/group/t_wsd_dl2_xp.mmp	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,22 @@
+// Copyright (c) 2005-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_wsd_dl2_xp.mmp
+// 
+// This binary goes in rom and is paged
+
+ROMTARGET			+
+PAGEDCODE
+target				t_wsd_dl2_xp.dll
+library				t_wsd_dl3_xp.lib
+#include			"t_wsd_dl2.mmh"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/group/t_wsd_dl2_xu.mmp	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,22 @@
+// Copyright (c) 2005-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_wsd_dl2_xu.mmp
+// 
+// This binary goes in rom and is unpaged
+
+ROMTARGET			+
+UNPAGEDCODE
+target				t_wsd_dl2_xu.dll
+library				t_wsd_dl3_xu.lib
+#include			"t_wsd_dl2.mmh"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/group/t_wsd_dl3.mmh	Fri Apr 16 16:24:37 2010 +0300
@@ -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:
+// e32test/group/t_wsd_dl3.mmh
+
+targettype			dll
+sourcepath			../mmu
+source				t_wsd_dl3.cpp
+deffile				t_wsd_dl3.def
+nostrictdef
+capability			all
+vendorid			0x70000001
+library				euser.lib
+
+macro T_WSD_DL3
+epocallowdlldata
+
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN
+UNPAGEDDATA
+SMPSAFE
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/group/t_wsd_dl3_cp.mmp	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,22 @@
+// Copyright (c) 2005-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_wsd_dl3_cp.mmp
+// 
+// This binary goes in ram and is paged
+
+ROMTARGET
+RAMTARGET			+
+PAGEDCODE
+target				t_wsd_dl3_cp.dll
+#include			"t_wsd_dl3.mmh"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/group/t_wsd_dl3_cu.mmp	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,22 @@
+// Copyright (c) 2005-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_wsd_dl3_cu.mmp
+// 
+// This binary goes in ram and is unpaged
+
+ROMTARGET
+RAMTARGET			+
+UNPAGEDCODE
+target				t_wsd_dl3_cu.dll
+#include			"t_wsd_dl3.mmh"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/group/t_wsd_dl3_xp.mmp	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,21 @@
+// Copyright (c) 2005-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_wsd_dl3_xp.mmp
+// 
+// This binary goes in rom and is paged
+
+ROMTARGET			+
+PAGEDCODE
+target				t_wsd_dl3_xp.dll
+#include			"t_wsd_dl3.mmh"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/group/t_wsd_dl3_xu.mmp	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,21 @@
+// Copyright (c) 2005-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_wsd_dl3_xu.mmp
+// 
+// This binary goes in rom and is unpaged
+
+ROMTARGET			+
+UNPAGEDCODE
+target				t_wsd_dl3_xu.dll
+#include			"t_wsd_dl3.mmh"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/group/t_wsd_tst.mmh	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,26 @@
+// 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_wsd_tst.mmh
+
+targettype			exe
+sourcepath			../mmu
+source				t_wsd_tst.cpp
+library				euser.lib
+library				efsrv.lib
+capability			all
+vendorid			0x70000001
+
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN
+UNPAGEDDATA
+SMPSAFE
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/group/t_wsd_tst_cp.mmp	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,23 @@
+// Copyright (c) 2005-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_wsd_tst_cp.mmp
+// 
+// This binary goes in ram and is paged
+
+ROMTARGET
+RAMTARGET			+
+PAGEDCODE
+target				t_wsd_tst_cp.exe
+library				t_wsd_dl1_cp.lib
+#include			"t_wsd_tst.mmh"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/group/t_wsd_tst_cu.mmp	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,23 @@
+// Copyright (c) 2005-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_wsd_tst_cu.mmp
+// 
+// This binary goes in ram and is unpaged
+
+ROMTARGET
+RAMTARGET			+
+UNPAGEDCODE
+target				t_wsd_tst_cu.exe
+library				t_wsd_dl1_cu.lib
+#include			"t_wsd_tst.mmh"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/group/t_wsd_tst_xp.mmp	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,22 @@
+// Copyright (c) 2005-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_wsd_tst_xp.mmp
+// 
+// This binary goes in rom and is paged
+
+ROMTARGET			+
+PAGEDCODE
+target				t_wsd_tst_xp.exe
+library				t_wsd_dl1_xp.lib
+#include			"t_wsd_tst.mmh"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/group/t_wsd_tst_xu.mmp	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,22 @@
+// Copyright (c) 2005-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_wsd_tst_xu.mmp
+// 
+// This binary goes in rom and is unpaged
+
+ROMTARGET			+
+UNPAGEDCODE
+target				t_wsd_tst_xu.exe
+library				t_wsd_dl1_xu.lib
+#include			"t_wsd_tst.mmh"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/group/ymodemtx.mmp	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,31 @@
+// Copyright (c) 2009-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\ymodemtx.mmp
+// 
+//
+
+target			ymodemtx.exe
+targettype		exe
+sourcepath		../misc
+source			ymodemtx.cpp
+library			euser.lib efsrv.lib
+userinclude		../misc
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN
+epocheapsize	0x1000 0x01000000
+
+capability		all
+
+VENDORID 0x70000001
+
+SMPSAFE
--- a/kerneltest/e32test/hcr/d_hcrsim.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kerneltest/e32test/hcr/d_hcrsim.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -742,38 +742,62 @@
 			}
 		case RHcrSimTestChannel::EHcrGetDataArray:
 			{
+			//args[0] - &aId
+			//args[1] - aMaxLen
+			//args[2] - aValue
+			//args[3] - &aLen
+			
 			// Get list of pointers
 			TAny* args[4];
 			TEST_MEMGET(a1, args, sizeof(args));
 			TUint maxlen = (TUint) args[1];
+			
 			// Retrieve structures from client
 			TSettingId id;
 			TEST_MEMGET(args[0], &id, sizeof(TSettingId));
 			// Allocate temporary memory
 			TUint16 len;
 			TUint8* value;
+			
 			TEST_ENTERCS();
-			value = (TUint8*) Kern::Alloc(maxlen * sizeof(TUint8));
-			TEST_LEAVECS();
-			if (value == NULL)
-				{
-				r = KErrNoMemory;
-				}
+			//Analyse user input. Some test cases can pass either aMaxLen == 0,
+			//aValue == NULL or both
+			if(args[2] != 0 && args[1] != 0)
+			    {
+			    value = (TUint8*) Kern::Alloc(maxlen);
+			    if(!value) return KErrNoMemory;
+			    }
+			//aValue == NULL, just pass NULL to HCR PIL
+			else if(args[2] == 0)
+			    value = NULL;
+			//aMaxLen = 0, allocate 4 bytes memory 
+			else if(args[1] == 0)
+			    {
+			    value = (TUint8*) Kern::Alloc(4);
+			    if(!value) return KErrNoMemory;
+			    }
+			//aVallue == NULL && aMaxLen == 0
 			else
-				{
-				// Actual API call
-				r = GetData(id, (TUint16) maxlen,
-							value, len);
-				// Send value back to client
-				if (!r)
-					{
-					TEST_MEMPUT(args[2], value, maxlen * sizeof(TUint8));
-					TEST_MEMPUT(args[3], &len, sizeof(TUint16));
-					}
-				TEST_ENTERCS();
-				Kern::Free(value);
-				TEST_LEAVECS();
-				}
+			    value = NULL;
+			TEST_LEAVECS();
+			
+			
+			// Actual API call
+			r = GetData(id, (TUint16) maxlen,
+			        value, len);
+			// Send value back to client
+			if(value && maxlen)
+			    {
+			    TEST_MEMPUT(args[2], value, maxlen * sizeof(TUint8));
+			    TEST_MEMPUT(args[3], &len, sizeof(TUint16));
+			    }
+			
+			if(value)
+			    {
+			    TEST_ENTERCS();
+			    Kern::Free(value);
+			    TEST_LEAVECS();
+			    }
 			break;
 			}
 		case RHcrSimTestChannel::EHcrGetDataDes:
@@ -837,43 +861,74 @@
 			break;
 			}
 		case RHcrSimTestChannel::EHcrGetArrayInt:
-			{
-			// Get list of pointers
-			TAny* args[4];
-			TEST_MEMGET(a1, args, sizeof(args));
-			TUint maxlen = (TUint) args[1];
-			// Retrieve structures from client
-			TSettingId id;
-			TEST_MEMGET(args[0], &id, sizeof(TSettingId));
-			// Allocate temporary memory
-			TUint16 len;
-			TInt32* value;
-			TEST_ENTERCS();
-			value = (TInt32*) Kern::Alloc(maxlen);
-			TEST_LEAVECS();
-			if (value == NULL)
-				{
-				r = KErrNoMemory;
-				}
-			else
-				{
-				// Actual API call
-				r = GetArray(id, (TUint16) maxlen,
-							value, len);
-				// Send value back to client
-				if (!r)
-					{
-					TEST_MEMPUT(args[2], value, maxlen);
-					TEST_MEMPUT(args[3], &len, sizeof(TUint16));
-					}
-				TEST_ENTERCS();
-				Kern::Free(value);
-				TEST_LEAVECS();
-				}
-			break;
+		    {
+		    //args[0] - &aId
+		    //args[1] - aMaxLen
+		    //args[2] - aValue
+		    //args[3] - &aLen
+
+		    // Get list of pointers
+		    TAny* args[4];
+		    TEST_MEMGET(a1, args, sizeof(args));
+		    TUint maxlen = (TUint) args[1];
+		    // Retrieve structures from client
+		    TSettingId id;
+		    TEST_MEMGET(args[0], &id, sizeof(TSettingId));
+		    // Allocate temporary memory
+		    TUint16 len;
+		    TInt32* value;
+
+		    TEST_ENTERCS();
+		    //Analyse user input. Some test cases can pass either aMaxLen == 0,
+		    //aValue == NULL or both
+		    if(args[2] != 0 && args[1] != 0)
+		        {
+                value = (TInt32*) Kern::Alloc(maxlen*sizeof(TInt32));
+                if(!value) return KErrNoMemory;
+		        }
+		    //aValue == NULL, just pass NULL to HCR PIL
+		    else if(args[2] == 0)
+		        value = NULL;
+		    //aMaxLen = 0, allocate 4 bytes memory 
+		    else if(args[1] == 0)
+		        {
+                value = (TInt32*) Kern::Alloc(maxlen*sizeof(TInt32));
+                if(!value) return KErrNoMemory;
+		        }
+		    //aVallue == NULL && aMaxLen == 0
+		    else
+		        value = NULL;
+		    TEST_LEAVECS();
+
+
+		    // Actual API call
+		    r = GetArray(id, (TUint16) maxlen,
+		            value, len);
+
+		    // Send value back to client
+		    //aMaxLen > 0 && aValue != NULL
+		    if (args[1] && args[2])
+		        {
+		    TEST_MEMPUT(args[2], value, maxlen);
+		    TEST_MEMPUT(args[3], &len, sizeof(TUint16));
+		        }
+
+		    if(value)
+		        {
+		    TEST_ENTERCS();
+		    Kern::Free(value);
+		    TEST_LEAVECS();
+		        }
+
+		        break;
 			}
 		case RHcrSimTestChannel::EHcrGetArrayUInt:
-			{
+		    {
+		    //args[0] - &aId
+		    //args[1] - aMaxLen
+		    //args[2] - aValue
+		    //args[3] - &aLen
+		    
 			// Get list of pointers
 			TAny* args[4];
 			TEST_MEMGET(a1, args, sizeof(args));
@@ -884,35 +939,63 @@
 			// Allocate temporary memory
 			TUint16 len;
 			TUint32* value;
+			
 			TEST_ENTERCS();
-			value = (TUint32*) Kern::Alloc(maxlen);
-			TEST_LEAVECS();
-			if (value == NULL)
-				{
-				r = KErrNoMemory;
-				}
+			//Analyse user input. Some test cases can pass either aMaxLen == 0,
+			//aValue == NULL or both
+			if(args[2] != 0 && args[1] != 0)
+			    {
+			    value = (TUint32*) Kern::Alloc(maxlen*sizeof(TUint32));
+			    if(!value) return KErrNoMemory;
+			    }
+			//aValue == NULL, just pass NULL to HCR PIL
+			else if(args[2] == 0)
+			    value = NULL;
+			//aMaxLen = 0, allocate 4 bytes memory 
+			else if(args[1] == 0)
+			    {
+			    value = (TUint32*) Kern::Alloc(maxlen*sizeof(TUint32));
+			    if(!value) return KErrNoMemory;
+			    }
+			//aVallue == NULL && aMaxLen == 0
 			else
-				{
-				// Actual API call
-				r = GetArray(id, (TUint16) maxlen,
-							value, len);
-				// Send value back to client
-				if (!r)
-					{
-					TEST_MEMPUT(args[2], value, maxlen);
-					TEST_MEMPUT(args[3], &len, sizeof(TUint16));
-					}
-				TEST_ENTERCS();
-				Kern::Free(value);
-				TEST_LEAVECS();
-				}
+			    value = NULL;
+			TEST_LEAVECS();
+			
+
+			// Actual API call
+			r = GetArray(id, (TUint16) maxlen,
+			        value, len);
+			// Send value back to client
+			
+			//aMaxLine != 0 && aValue != NULL
+			if (args[1] && args[2])
+			    {
+			    TEST_MEMPUT(args[2], value, maxlen);
+			    TEST_MEMPUT(args[3], &len, sizeof(TUint16));
+			    }
+			
+			if(value)
+			    {
+			    TEST_ENTERCS();
+			    Kern::Free(value);
+			    TEST_LEAVECS();
+			    }
+
 			break;
 			}
+		    
 		case RHcrSimTestChannel::EHcrGetStringArray:
 			{
 			// Get list of pointers
 			TAny* args[4];
 			TEST_MEMGET(a1, args, sizeof(args));
+			
+			//args[0] - &aId
+			//args[1] - aMaxLen
+			//args[2] - aValue
+			//args[3] - &aLen
+			
 			TUint maxlen = (TUint) args[1];
 			// Retrieve structures from client
 			TSettingId id;
@@ -920,28 +1003,49 @@
 			// Allocate temporary memory
 			TUint16 len;
 			TText8* value;
+
 			TEST_ENTERCS();
-			value = (TText8*) Kern::Alloc(maxlen * sizeof(TText8));
-			TEST_LEAVECS();
-			if (value == NULL)
-				{
-				r = KErrNoMemory;
-				}
+			
+			//Analyse user input. Some test cases can pass either aMaxLen == 0,
+			//aValue == NULL or both
+			if(args[2] != 0 && args[1] != 0)
+			    {
+			    value = (TText8*) Kern::Alloc(maxlen*sizeof(TText8));
+			    if(!value) return KErrNoMemory;
+			    }
+			//aValue == NULL, just pass NULL to HCR PIL
+			else if(args[2] == 0)
+			    value = NULL;
+			//aMaxLen = 0, allocate 4 bytes memory 
+			else if(args[1] == 0)
+			    {
+			    value = (TText8*) Kern::Alloc(maxlen*sizeof(TText8));
+			    if(!value) return KErrNoMemory;
+			    }
+			//aVallue == NULL && aMaxLen == 0
 			else
-				{
-				// Actual API call
-				r = GetString(id, (TUint16) maxlen,
-							value, len);
-				// Send value back to client
-				if (!r)
-					{
-					TEST_MEMPUT(args[2], value, maxlen * sizeof(TText8));
-					TEST_MEMPUT(args[3], &len, sizeof(TUint16));
-					}
-				TEST_ENTERCS();
-				Kern::Free(value);
-				TEST_LEAVECS();
-				}
+			    value = NULL;
+			TEST_LEAVECS();
+
+
+			// Actual API call
+			r = GetString(id, (TUint16) maxlen,
+			        value, len);
+			// Send value back to client
+			//aMaxLen != 0 && aValue != NULL
+			if (args[1] && args[2])
+			    {
+			    TEST_MEMPUT(args[2], value, maxlen * sizeof(TText8));
+			    TEST_MEMPUT(args[3], &len, sizeof(TUint16));
+			    }
+
+			if(value)
+			    {
+			    TEST_ENTERCS();
+			    Kern::Free(value);
+			    TEST_LEAVECS();
+			    }
+			
 			break;
 			}
 		case RHcrSimTestChannel::EHcrGetStringDes:
--- a/kerneltest/e32test/hcr/d_hcrsim_testdata.h	Tue Feb 02 01:24:03 2010 +0200
+++ b/kerneltest/e32test/hcr/d_hcrsim_testdata.h	Fri Apr 16 16:24:37 2010 +0300
@@ -259,7 +259,7 @@
 	{{{ KTestCategories[0], 2}, ETypeInt32, 0x0000, 0 }, {{ 0 }}},
 	};
 #if !defined(__KERNEL_MODE__) || defined(HCRTEST_USERSIDE_INTERFACE)
-const TUint32 KTestInvalidCategory = 1234;
+const TUint32 KTestInvalidCategory = 0;
 const TUint32 KTestInvalidSettingId = 5678;
 
 // The following repositories are only used for reference by the test application
Binary file kerneltest/e32test/hcr/filerepos_cds.dat has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/hcr/filerepos_cds.txt	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,580 @@
+#Accelerometer device capabilities
+#-------------------------------------------------------------------------------
+#ColumnId   0x0001      0x0002      0x0003      0x0004      0x0005      0x0006
+#-------------------------------------------------------------------------------
+#Name       ManufId     DeviceId    DevName     DataRate    Resol.      Scale
+#-------------------------------------------------------------------------------
+#RowId
+#0x0001     0x12003335  0x2001    "KISemiInc8g" 20          8           8
+#0x0002     0x72103301  0x0012    "SPE Co 4g"   50          16          4
+   
+############################### 
+# KI SemiInc 8g Accelerometer #
+###############################
+# Manafacturer Id
+@
+cuid: 0x00000001
+eid: 65537 
+type: UInt32
+flags: 0x0000
+hexval: 0x12003335 
+.
+
+# Device Id
+@
+cuid: 0x00000001
+eid: 65538 
+type: UInt16
+flags: 0x0000
+hexval: 0x2001 
+.
+
+#Friendly Name
+@
+cuid: 0x00000001
+eid: 65539 
+type: Text8
+flags: 0x0000
+strval: "KI Semi Inc 8g Accelerometer"
+.
+
+# Data Rate(Hz)
+@
+cuid: 0x00000001
+eid: 65540 
+type: UInt16
+flags: 0x0000
+intval: 20 
+.
+
+# Resolution(bits)
+@
+cuid: 0x00000001
+eid: 65541 
+type: UInt16
+flags: 0x0000
+intval: 8 
+.
+
+# Scale g
+@
+cuid: 0x00000001
+eid: 65542 
+type: UInt16
+flags: 0x0000
+intval: 8 
+.
+
+############################### 
+# SPE Co 4g Accelerometer     #
+###############################
+# Manafacturer Id
+@
+cuid: 0x00000001
+eid: 131073 
+type: UInt32
+flags: 0x0000
+hexval: 0x72103301 
+.
+
+# Device Id
+@
+cuid: 0x00000001
+eid: 131074 
+type: UInt16
+flags: 0x0000
+hexval: 0x0012
+.
+
+#Friendly Name
+@
+cuid: 0x00000001
+eid: 131075 
+type: Text8
+flags: 0x0000
+strval: "SPE Co 4g Accelerometer"
+.
+
+# Data Rate(Hz)
+@
+cuid: 0x00000001
+eid: 131076 
+type: UInt16
+flags: 0x0000
+intval: 50 
+.
+
+# Resolution(bits)
+@
+cuid: 0x00000001
+eid: 131077 
+type: UInt16
+flags: 0x0000
+intval: 16 
+.
+
+# Scale g
+@
+cuid: 0x00000001
+eid: 131078 
+type: UInt16
+flags: 0x0000
+intval: 4 
+.
+#############################################
+
+@
+cuid: 0x00000002
+eid: 2
+type: UInt32
+flags: 0x0000
+intval: 555555
+.
+
+@
+cuid: 0x00000002
+eid: 5
+type: UInt16
+flags: 0x0000
+intval: 60000
+.
+
+@
+cuid: 0x00000002
+eid: 8
+type: UInt8
+flags: 0x0000
+intval: 11
+.
+
+@
+cuid: 0x00000002
+eid: 12
+type: LinAddr
+flags: 0x0000
+hexval: 0x0faece50
+.
+
+@
+cuid: 0x000003e8
+eid: 4096
+type: BinData
+flags: 0x0000
+binval: 18 a1 0b bc 61 41 de c9 cd d2 f9 3b ba 99 e5 e2
+binval: fa e0 13 fe 8f d4 e3 50 1a 5e a3 32 39 34 1f 16
+binval: 9a a8 b3 61 1d 7d 7f fd b1 58 af 91 53 f7 76 c4
+binval: da dd
+
+.
+
+@
+cuid: 0x000003e8
+eid: 28672
+type: Text8
+flags: 0x0000
+strval: "These two strings walk up to a bar. The first string walks in and orders and the bartender throws him out and yells 'I don't serve strings in this bar'. The other string ruffs himself up on the street and curls up and orders. The bartender shouts, 'Hey, didn't you hear what I told your buddy?'. The string says 'Yeah.' The bartender says, 'aren't you a string?' The string says, 'No, I'm a frayed knot...'*********************************************************************************************************?"
+.
+
+@
+cuid: 0x000003e8
+eid: 32768
+type: ArrayInt32
+flags: 0x0000
+arrval: 2034128484
+arrval: 358489471
+arrval: -1196607986
+arrval: -1223123619
+arrval: -643073403
+arrval: -1330549099
+.
+
+@
+cuid: 0x10000001
+eid: 4096
+type: Int32
+flags: 0x0000
+intval: 333
+.
+
+@
+cuid: 0x10000001
+eid: 4112
+type: Int16
+flags: 0x0000
+intval: 17632
+.
+
+@
+cuid: 0x10000001
+eid: 4128
+type: Int8
+flags: 0x0000
+intval: 44
+.
+
+@
+cuid: 0x10000001
+eid: 4144
+type: Bool
+flags: 0x0000
+intval: 1
+.
+
+@
+cuid: 0x10000001
+eid: 4160
+type: UInt32
+flags: 0x0000
+intval: 3123123123
+.
+
+@
+cuid: 0x10000001
+eid: 4176
+type: UInt16
+flags: 0x0000
+intval: 18
+.
+
+@
+cuid: 0x10000001
+eid: 4192
+type: UInt8
+flags: 0x0000
+intval: 80
+.
+
+@
+cuid: 0x10000001
+eid: 4208
+type: LinAddr
+flags: 0x0000
+hexval: 0xdeadbeef
+.
+
+@
+cuid: 0x10000002
+eid: 128
+type: BinData
+flags: 0x0000
+binval: 18 a1 0b bc 61 41 de c9 cd d2 f9 3b ba 99 e5 e2
+binval: fa e0 13 fe 8f d4 e3 50 1a 5e a3 32 39 34 1f 16
+binval: 9a a8 b3 61 1d 7d 7f fd b1 58 af 91 53 f7 76 c4
+binval: da dd
+
+.
+
+@
+cuid: 0x10000002
+eid: 147
+type: Text8
+flags: 0x0000
+strval: "A termite walks into a bar and says, 'Is the bar tender here?' #"
+.
+
+@
+cuid: 0x10000002
+eid: 160
+type: ArrayInt32
+flags: 0x0000
+arrval: 2034128484
+arrval: 358489471
+arrval: -1196607986
+arrval: -1223123619
+arrval: -643073403
+arrval: -1330549099
+.
+
+@
+cuid: 0x10000002
+eid: 177
+type: ArrayUInt32
+flags: 0x0000
+arrval: 2034128484
+arrval: 358489471
+arrval: 3098359310
+arrval: 3071843677
+arrval: 3651893893
+arrval: 2964418197
+arrval: 2696294136
+arrval: 1696227301
+arrval: 1516067404
+arrval: 1171111215
+arrval: 45904065
+arrval: 3152352058
+arrval: 204038089
+arrval: 3427962251
+arrval: 3455401965
+arrval: 1362098275
+arrval: 2253564637
+arrval: 3426182366
+arrval: 173516448
+arrval: 3814089518
+arrval: 136723162
+arrval: 2036722935
+arrval: 4113668927
+arrval: 1744493008
+arrval: 2493449248
+arrval: 3579645660
+arrval: 567353362
+arrval: 882914186
+arrval: 386211010
+arrval: 3553761645
+arrval: 2569035486
+arrval: 508738370
+arrval: 2156711458
+arrval: 1917508866
+arrval: 4265921673
+arrval: 2570997289
+arrval: 3925131413
+arrval: 3804548107
+arrval: 2789297085
+arrval: 3612835159
+arrval: 2938836477
+arrval: 2656050096
+arrval: 3214230399
+arrval: 3908414061
+arrval: 2565375854
+arrval: 2461262451
+arrval: 1843121370
+arrval: 3664914997
+arrval: 3998453453
+arrval: 956775374
+arrval: 3966551413
+arrval: 3687801665
+arrval: 2761783920
+arrval: 3143394259
+arrval: 2885547835
+arrval: 1464987787
+arrval: 1940297660
+arrval: 257153229
+arrval: 1950234869
+arrval: 404798999
+arrval: 4170795976
+arrval: 449084638
+arrval: 2206107629
+arrval: 1726753423
+arrval: 3649910521
+arrval: 3495736484
+arrval: 2906992014
+arrval: 696657641
+arrval: 3811005607
+arrval: 1429964498
+arrval: 2130501125
+arrval: 126113280
+arrval: 657988026
+arrval: 412465877
+arrval: 1468324572
+arrval: 2212639033
+arrval: 526226762
+arrval: 4199939442
+arrval: 2447247776
+arrval: 580919075
+arrval: 3399586879
+arrval: 1773665383
+arrval: 2596675710
+arrval: 2204277779
+arrval: 3440949747
+arrval: 2163247371
+arrval: 374652132
+arrval: 2265994439
+arrval: 2525472208
+arrval: 751154667
+arrval: 60655135
+arrval: 1819822599
+arrval: 1996296943
+arrval: 1160968304
+arrval: 3511898622
+arrval: 4008505154
+arrval: 3363107771
+arrval: 3003598970
+arrval: 2321824624
+arrval: 1793148977
+arrval: 192387216
+arrval: 2391359999
+arrval: 3986410788
+arrval: 4170387316
+arrval: 112839256
+arrval: 957431730
+arrval: 2403276842
+arrval: 2443299891
+arrval: 3871206705
+arrval: 2309718684
+arrval: 4239645330
+arrval: 749665729
+arrval: 1567563783
+arrval: 3770371262
+arrval: 3625425678
+arrval: 3724751159
+arrval: 3335150391
+arrval: 1301676466
+arrval: 4209560974
+arrval: 4214040856
+arrval: 1115066926
+arrval: 2972142156
+arrval: 2476797414
+arrval: 882703343
+arrval: 3596997643
+arrval: 3633196855
+arrval: 1247060582
+arrval: 3141938928
+.
+
+@
+cuid: 0x10000002
+eid: 194
+type: Int64
+flags: 0x0000
+binval: ff ff ff ff ff ff ff ff
+.
+
+@
+cuid: 0x10000002
+eid: 208
+type: UInt64
+flags: 0x0000
+binval: 00 00 00 00 00 00 00 00
+.
+
+@
+cuid: 0x10000002
+eid: 4294967295
+type: Int8
+flags: 0x0000
+intval: 1
+.
+
+@
+cuid: 0xffffffff
+eid: 32
+type: ArrayUInt32
+flags: 0x0000
+arrval: 2034128484
+arrval: 358489471
+arrval: 3098359310
+arrval: 3071843677
+arrval: 3651893893
+arrval: 2964418197
+arrval: 2696294136
+arrval: 1696227301
+arrval: 1516067404
+arrval: 1171111215
+arrval: 45904065
+arrval: 3152352058
+arrval: 204038089
+arrval: 3427962251
+arrval: 3455401965
+arrval: 1362098275
+arrval: 2253564637
+arrval: 3426182366
+arrval: 173516448
+arrval: 3814089518
+arrval: 136723162
+arrval: 2036722935
+arrval: 4113668927
+arrval: 1744493008
+arrval: 2493449248
+arrval: 3579645660
+arrval: 567353362
+arrval: 882914186
+arrval: 386211010
+arrval: 3553761645
+arrval: 2569035486
+arrval: 508738370
+arrval: 2156711458
+arrval: 1917508866
+arrval: 4265921673
+arrval: 2570997289
+arrval: 3925131413
+arrval: 3804548107
+arrval: 2789297085
+arrval: 3612835159
+arrval: 2938836477
+arrval: 2656050096
+arrval: 3214230399
+arrval: 3908414061
+arrval: 2565375854
+arrval: 2461262451
+arrval: 1843121370
+arrval: 3664914997
+arrval: 3998453453
+arrval: 956775374
+arrval: 3966551413
+arrval: 3687801665
+arrval: 2761783920
+arrval: 3143394259
+arrval: 2885547835
+arrval: 1464987787
+arrval: 1940297660
+arrval: 257153229
+arrval: 1950234869
+arrval: 404798999
+arrval: 4170795976
+arrval: 449084638
+arrval: 2206107629
+arrval: 1726753423
+arrval: 3649910521
+arrval: 3495736484
+arrval: 2906992014
+arrval: 696657641
+arrval: 3811005607
+arrval: 1429964498
+arrval: 2130501125
+arrval: 126113280
+arrval: 657988026
+arrval: 412465877
+arrval: 1468324572
+arrval: 2212639033
+arrval: 526226762
+arrval: 4199939442
+arrval: 2447247776
+arrval: 580919075
+arrval: 3399586879
+arrval: 1773665383
+arrval: 2596675710
+arrval: 2204277779
+arrval: 3440949747
+arrval: 2163247371
+arrval: 374652132
+arrval: 2265994439
+arrval: 2525472208
+arrval: 751154667
+arrval: 60655135
+arrval: 1819822599
+arrval: 1996296943
+arrval: 1160968304
+arrval: 3511898622
+arrval: 4008505154
+arrval: 3363107771
+arrval: 3003598970
+arrval: 2321824624
+arrval: 1793148977
+arrval: 192387216
+arrval: 2391359999
+arrval: 3986410788
+arrval: 4170387316
+arrval: 112839256
+arrval: 957431730
+arrval: 2403276842
+arrval: 2443299891
+arrval: 3871206705
+arrval: 2309718684
+arrval: 4239645330
+arrval: 749665729
+arrval: 1567563783
+arrval: 3770371262
+arrval: 3625425678
+arrval: 3724751159
+arrval: 3335150391
+arrval: 1301676466
+arrval: 4209560974
+arrval: 4214040856
+arrval: 1115066926
+arrval: 2972142156
+arrval: 2476797414
+arrval: 882703343
+arrval: 3596997643
+arrval: 3633196855
+arrval: 1247060582
+arrval: 3141938928
+.
--- a/kerneltest/e32test/hcr/hcr.inf	Tue Feb 02 01:24:03 2010 +0200
+++ b/kerneltest/e32test/hcr/hcr.inf	Fri Apr 16 16:24:37 2010 +0300
@@ -48,6 +48,7 @@
 // The emulator test data exported next must match that included into a
 // ROM for the HCR Test suite. See hcr_tests.iby
 
+filerepos_cds.dat     /epoc32/release/wins/udeb/z/sys/data/filerepos_cds.dat
 filerepos_bc0.dat     /epoc32/release/wins/udeb/z/sys/data/filerepos_bc0.dat
 filerepos_bc1.dat     /epoc32/release/wins/udeb/z/sys/data/filerepos_bc1.dat
 filerepos.dat         /epoc32/release/wins/udeb/z/sys/data/filerepos.dat
@@ -59,6 +60,8 @@
 megalarge2.dat        /epoc32/release/wins/udeb/z/sys/data/megalarge2.dat
 filerepos.dat         /epoc32/release/wins/udeb/z/sys/data/hcr.dat
 
+
+filerepos_cds.dat     /epoc32/release/wins/urel/z/sys/data/filerepos_cds.dat
 filerepos_bc0.dat     /epoc32/release/wins/urel/z/sys/data/filerepos_bc0.dat
 filerepos_bc1.dat     /epoc32/release/wins/urel/z/sys/data/filerepos_bc1.dat
 filerepos.dat         /epoc32/release/wins/urel/z/sys/data/filerepos.dat
@@ -70,6 +73,8 @@
 megalarge2.dat        /epoc32/release/wins/urel/z/sys/data/megalarge2.dat
 filerepos.dat         /epoc32/release/wins/urel/z/sys/data/hcr.dat
 
+
+filerepos_cds.dat     /epoc32/release/winscw/udeb/z/sys/data/filerepos_cds.dat
 filerepos_bc0.dat     /epoc32/release/winscw/udeb/z/sys/data/filerepos_bc0.dat
 filerepos_bc1.dat     /epoc32/release/winscw/udeb/z/sys/data/filerepos_bc1.dat
 filerepos.dat         /epoc32/release/winscw/udeb/z/sys/data/filerepos.dat
@@ -81,6 +86,8 @@
 megalarge2.dat        /epoc32/release/winscw/udeb/z/sys/data/megalarge2.dat
 filerepos.dat         /epoc32/release/winscw/udeb/z/sys/data/hcr.dat
 
+
+filerepos_cds.dat     /epoc32/release/winscw/urel/z/sys/data/filerepos_cds.dat
 filerepos_bc0.dat     /epoc32/release/winscw/urel/z/sys/data/filerepos_bc0.dat
 filerepos_bc1.dat     /epoc32/release/winscw/urel/z/sys/data/filerepos_bc1.dat
 filerepos.dat         /epoc32/release/winscw/urel/z/sys/data/filerepos.dat
--- a/kerneltest/e32test/hcr/hcr_tests.iby	Tue Feb 02 01:24:03 2010 +0200
+++ b/kerneltest/e32test/hcr/hcr_tests.iby	Fri Apr 16 16:24:37 2010 +0300
@@ -44,5 +44,6 @@
 data=##BASEPATH##kernelhwsrv\kerneltest\e32test\hcr\megalarge2.dat    \sys\data\megalarge2.dat	unpaged paging_unmovable
 data=##BASEPATH##kernelhwsrv\kerneltest\e32test\hcr\filerepos_bc0.dat     \sys\data\filerepos_bc0.dat   unpaged paging_unmovable
 data=##BASEPATH##kernelhwsrv\kerneltest\e32test\hcr\filerepos_bc1.dat     \sys\data\filerepos_bc1.dat   unpaged paging_unmovable
+data=##BASEPATH##kernelhwsrv\kerneltest\e32test\hcr\filerepos_cds.dat     \sys\data\filerepos_cds.dat   unpaged paging_unmovable
 hcrdata=##BASEPATH##kernelhwsrv\kerneltest\e32test\hcr\filerepos.dat  \sys\data\hcr.dat
 #endif // __HCR_TEST_IBY__
--- a/kerneltest/e32test/hcr/t_hcr.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kerneltest/e32test/hcr/t_hcr.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -147,22 +147,27 @@
 				{
 				TBuf8<KMaxSettingLength> dval;
 				TUint8* pval;
-				pval = (TUint8*) User::Alloc(setting->iName.iLen);
+				TUint16 maxLen = setting->iName.iLen == 0 ? (TUint16)4: setting->iName.iLen; 
+				
+				pval = (TUint8*) User::Alloc(maxLen);
 				test_NotNull(pval);
 				//
 				r = HcrSimTest.GetData(id, dval);
 				test_KErrNone(r);
 				//
 				TUint16 actuallength;
-				r = HcrSimTest.GetData(id, setting->iName.iLen, pval, actuallength);
+				r = HcrSimTest.GetData(id, maxLen, pval, actuallength);
 				test_KErrNone(r);
 				//
-				test_Equal(0, Mem::Compare(
-						setting->iValue.iPtr.iData, setting->iName.iLen,
-						pval, actuallength));
-				test_Equal(0, Mem::Compare(
-						setting->iValue.iPtr.iData, setting->iName.iLen,
-						dval.Ptr(), dval.Length()));
+				if(setting->iName.iLen > 0)
+				    {
+                    test_Equal(0, Mem::Compare(
+				        setting->iValue.iPtr.iData, setting->iName.iLen,
+				        pval, actuallength));
+                    test_Equal(0, Mem::Compare(
+				        setting->iValue.iPtr.iData, setting->iName.iLen,
+				        dval.Ptr(), dval.Length()));
+				    }
 				User::Free(pval);
 				break;
 				}
@@ -170,35 +175,41 @@
 				{
 				TBuf8<KMaxSettingLength> dval;
 				TText8* pval;
-				pval = (TText8*) User::Alloc(setting->iName.iLen);
+				TUint16 maxLen = setting->iName.iLen == 0 ? (TUint16)4: setting->iName.iLen;
+				
+				pval = (TText8*) User::Alloc(maxLen);
 				test_NotNull(pval);
 				//
 				r = HcrSimTest.GetString(id, dval);
 				test_KErrNone(r);
 				//
 				TUint16 actuallength;
-				r = HcrSimTest.GetString(id, setting->iName.iLen, pval, actuallength);
+				r = HcrSimTest.GetString(id, maxLen, pval, actuallength);
 				test_KErrNone(r);
-				//
-				test_Equal(0, Mem::Compare(
-						setting->iValue.iPtr.iString8, setting->iName.iLen,
-						pval, actuallength));
-				test_Equal(0, Mem::Compare(
-						setting->iValue.iPtr.iString8, setting->iName.iLen,
-						dval.Ptr(), dval.Length()));
+
+				if(setting->iName.iLen > 0)
+				    {
+                    test_Equal(0, Mem::Compare(
+				        setting->iValue.iPtr.iString8, setting->iName.iLen,
+				        pval, actuallength));
+                    test_Equal(0, Mem::Compare(
+				        setting->iValue.iPtr.iString8, setting->iName.iLen,
+				        dval.Ptr(), dval.Length()));
+				    }
 				User::Free(pval);
 				break;
 				}
 			case ETypeArrayInt32:
 				{
 				TInt32* pval;
-				pval = (TInt32*) User::Alloc(setting->iName.iLen);
+				TUint16 maxLen = setting->iName.iLen == 0 ? (TUint16)4: setting->iName.iLen;
+				pval = (TInt32*) User::Alloc(maxLen);
 				test_NotNull(pval);
 				//
 				TUint16 actuallength;
-				r = HcrSimTest.GetArray(id, setting->iName.iLen, pval, actuallength);
+				r = HcrSimTest.GetArray(id, maxLen, pval, actuallength);
 				test_KErrNone(r);
-				//
+
 				test_Equal(setting->iName.iLen, actuallength);
 				TInt32* pexpected = setting->iValue.iPtr.iArrayInt32;
 				TUint i;
@@ -212,12 +223,14 @@
 			case ETypeArrayUInt32:
 				{
 				TUint32* pval;
-				pval = (TUint32*) User::Alloc(setting->iName.iLen);
+				TUint16 maxLen = setting->iName.iLen == 0 ? (TUint16)4: setting->iName.iLen;
+				pval = (TUint32*) User::Alloc(maxLen);
 				test_NotNull(pval);
 				//
 				TUint16 actuallength;
-				r = HcrSimTest.GetArray(id, setting->iName.iLen, pval, actuallength);
+				r = HcrSimTest.GetArray(id, maxLen, pval, actuallength);
 				test_KErrNone(r);
+				
 				//
 				test_Equal(setting->iName.iLen, actuallength);
 				TUint32* pexpected = setting->iValue.iPtr.iArrayUInt32;
@@ -426,7 +439,135 @@
 			r = HcrSimTest.GetUInt(id, val);
 			test_Equal(KErrArgument, r);
 			}
+
+		
+		
+		if(setting->iName.iType == ETypeBinData)
+		    {
+		    TUint8* valBuf;
+		    TUint8* nullBuf = NULL;
+
+		    
+		    //
+		    TUint16 actuallength;
+
+		    TSettingId id(setting->iName.iId.iCat, setting->iName.iId.iKey);
+		    valBuf = (TUint8*) User::Alloc(KMaxSettingLength);
+		    test_NotNull(valBuf);
+
+		    //MaxLength = 0
+		    r = HcrSimTest.GetData(id, 0, valBuf, actuallength);
+		    test_Equal(KErrArgument, r);
+
+		    //buffer is not provided
+		    r = HcrSimTest.GetData(id, KMaxSettingLength, nullBuf, actuallength);
+		    test_Equal(KErrArgument, r);
+		    
+		    //neither buffer is provided nor MaxLength is not zero 
+		    r = HcrSimTest.GetData(id, 0, nullBuf, actuallength);
+		    test_Equal(KErrArgument, r);
+
+
+		    //descriptor MaxLength is zero
+		    //Default constructor sets the MaxLength to zero, so we don't need to call Create(0)
+		    //We also don't need to call Close() for this buffer as well.
+		    RBuf8 nullDes;
+		    r = HcrSimTest.GetData(id, nullDes);
+		    test_Equal(KErrArgument, r);
+
+		    //
+		    User::Free(valBuf);
+		    }
+
+		
+		if(setting->iName.iType == ETypeText8)
+		    {
+		    TUint8* valBuf;
+		    TUint8* nullBuf = NULL;
+		    //
+		    TUint16 actuallength;
+
+		    TSettingId id(setting->iName.iId.iCat, setting->iName.iId.iKey);
+		    valBuf = (TUint8*) User::Alloc(KMaxSettingLength);
+		    test_NotNull(valBuf);
+
+		    //MaxLength = 0
+		    r = HcrSimTest.GetString(id, 0, valBuf, actuallength);
+		    test_Equal(KErrArgument, r);
+
+		    //buffer is not provided
+		    r = HcrSimTest.GetString(id, KMaxSettingLength, nullBuf, actuallength);
+		    test_Equal(KErrArgument, r);
+		    
+		    //neither buffer is not provided nor the aMaxLen is not non-zero
+		    r = HcrSimTest.GetString(id, 0, nullBuf, actuallength);
+		    test_Equal(KErrArgument, r);
+
+
+		    //descriptor MaxLength is zero
+		    //Default constructor sets the MaxLength to zero, so we don't need to call Create(0)
+		    //We also don't need to call Close() for this buffer as well.
+		    RBuf8 nullDesc;
+		    r = HcrSimTest.GetString(id, nullDesc);
+		    test_Equal(KErrArgument, r);
+		    //
+		    User::Free(valBuf);
+		    }
+
+		if(setting->iName.iType == ETypeArrayInt32)
+		    {
+		    TInt32* valBuf;
+		    TInt32* nullBuf = NULL;
+		    valBuf = (TInt32*)User::Alloc(4*KMaxSettingLength);
+		    test_NotNull(valBuf);
+
+		    TUint16 actuallength;
+		    TSettingId id(setting->iName.iId.iCat, setting->iName.iId.iKey);
+
+		    //MaxLength = 0
+		    r = HcrSimTest.GetArray(id, 0, valBuf, actuallength);
+		    test_Equal(KErrArgument, r);
+
+		    //buffer is not provided
+		    r = HcrSimTest.GetArray(id, KMaxSettingLength, nullBuf, actuallength);
+		    test_Equal(KErrArgument, r);
+		    
+		    //neither buffer is not provided nor aMaxLen is not non-zero
+		    r = HcrSimTest.GetArray(id, 0, nullBuf, actuallength);
+		    test_Equal(KErrArgument, r);
+
+
+		    User::Free(valBuf);
+		    }
+
+		if(setting->iName.iType == ETypeArrayUInt32)
+		    {
+		    TUint32* valBuf;
+		    TUint32* nullBuf = NULL;
+		    valBuf = (TUint32*)User::Alloc(4*KMaxSettingLength);
+		    test_NotNull(valBuf);
+
+		    TUint16 actuallength;
+		    TSettingId id(setting->iName.iId.iCat, setting->iName.iId.iKey);
+
+		    //MaxLength = 0
+		    r = HcrSimTest.GetArray(id, 0, valBuf, actuallength);
+		    test_Equal(KErrArgument, r);
+
+		    //buffer is not provided
+		    r = HcrSimTest.GetArray(id, KMaxSettingLength,nullBuf, actuallength);
+		    test_Equal(KErrArgument, r);
+		    
+		    //neither buffer is not provided nor aMaxLen is not non-zero
+		    r = HcrSimTest.GetArray(id, 0, nullBuf, actuallength);
+		    test_Equal(KErrArgument, r);
+
+
+		    User::Free(valBuf);
+		    }
+
 		}
+
 	}
 
 void HcrSimSettingProperties(SSettingC* aRepository, TUint aNumberOfSettings)
@@ -815,6 +956,68 @@
 	User::Free(types);
 	User::Free(errs);
 
+	
+#ifdef _DEBUG
+	test.Next(_L("Multiple Get on all settings, aIds[] is not ordered"));
+	    nosettings = 0;
+	    for (setting = aRepository; setting < aRepository + aNumberOfSettings; setting++)
+	        {
+	        if (setting->iName.iType < 0x00010000)
+	            {
+	            nosettings++;
+	            }
+	        }
+	    test_Compare(2, <, nosettings);
+	    
+	    ids = (SSettingId*) User::Alloc(sizeof(SSettingId) * nosettings);
+	    test_NotNull(ids);
+	    vals = (TInt32*) User::Alloc(sizeof(TInt32) * nosettings);
+	    test_NotNull(vals);
+	    types = (TSettingType*) User::Alloc(sizeof(TSettingType) * nosettings);
+	    test_NotNull(types);
+	    errs = (TInt*) User::Alloc(sizeof(TInt) * nosettings);
+	    test_NotNull(errs);
+	    
+	    n = 0;
+
+	    for (setting = aRepository; setting < aRepository + aNumberOfSettings; setting++)
+	        {
+	        if (setting->iName.iType < 0x00010000)
+	            {
+	            ids[n].iCat = setting->iName.iId.iCat;
+	            ids[n].iKey = setting->iName.iId.iKey;
+	            n++;
+	            }
+	        }
+	    test_Equal(nosettings, n);
+	    
+	    //Swap two neigbours elements in the middle of the user array
+	    HCR::SSettingId tmpSet;
+	    TUint swappedIndex = (n >> 1) - 1;
+	    //Make a copy of one of the swaped element
+	    tmpSet.iCat = ids[swappedIndex].iCat;
+	    tmpSet.iKey = ids[swappedIndex].iKey;
+	    
+	    //Initialized that element with the values of the next one
+	    ids[swappedIndex].iCat = ids[swappedIndex + 1].iCat;
+	    ids[swappedIndex].iKey = ids[swappedIndex + 1].iKey;
+	    
+	    //Write back data from the temproary element
+	    ids[swappedIndex + 1].iCat = tmpSet.iCat;
+	    ids[swappedIndex + 1].iKey = tmpSet.iKey;
+
+	    r = HcrSimTest.GetWordSettings(nosettings, ids, vals, types, errs);
+
+	    //HCR returns KErrArgument because ids array was not properly ordered
+	    test_Equal(KErrArgument, r);
+
+	    User::Free(ids);
+	    User::Free(vals);
+	    User::Free(types);
+	    User::Free(errs);
+#endif
+	
+
 	test.Next(_L("Multiple Get on a large setting"));
 	if (largesetting.iKey)
 		{
@@ -2430,6 +2633,500 @@
 	test.End();
 	}
 
+void HcrCatRecodsExampleTest(const TDesC& aDriver)
+    {
+    using namespace HCR;
+
+   
+    test.Start(_L("HCR Record Structured Category Test"));
+    test.Next(_L("Load HCR Test driver"));
+    
+    test.Printf(_L("%S\n"), &aDriver);
+    TInt r;
+    
+    _LIT8(KTestCatRecordsRepos, "filerepos_cds.dat");
+
+    r = User::LoadLogicalDevice(aDriver);
+    if (r == KErrAlreadyExists)
+        {
+        test.Printf(_L("Unload Device Driver and load it again\n"));
+        r = User::FreeLogicalDevice(aDriver);
+        test_KErrNone(r);
+        r = User::LoadLogicalDevice(aDriver);
+        test_KErrNone(r);
+        }
+    else
+        {
+        test_KErrNone(r);
+        }
+
+    test.Next(_L("Open test channel"));
+    r = HcrSimTest.Open(aDriver);
+    test_KErrNone(r);
+
+    test.Next(_L("Initialise HCR"));
+    //r = HcrSimTest.InitExtension();
+    // *** The NULL Repository ***
+    r = HcrSimTest.InitExtension(ETestNullRepository);
+    test_KErrNone(r);
+
+    test.Next(_L("Load Test File repository"));
+    r = HcrSimTest.SwitchRepository(KTestCatRecordsRepos, HCRInternal::ECoreRepos);
+    test_KErrNone(r);
+    r = HcrSimTest.CheckIntegrity();
+    test_KErrNone(r);
+
+
+
+    struct TAccelCaps
+        {
+        TUint32 iManufactureId;
+        TUint16 iDeviceId;
+        char* iDevName;
+        TUint16 iDataRate;
+        TUint16 iResolution;
+        TUint16 iScale;
+        };
+
+    const TInt KCapsField_Manufacturer = 1;
+    const TInt KCapsField_Device = 2;
+    const TInt KCapsField_Name = 3;
+    const TInt KCapsField_DataRate = 4;
+    const TInt KCapsField_Resolution = 5;
+    const TInt KCapsField_Scale = 6;
+
+    const TInt KMaxNumAccelerateDevices = 2;
+    const TInt KNumElementsInRow = 6;
+
+    const TInt KKiSemiIndex = 0;
+    const TInt KSpecCo4gIndex = 1;
+    char KKiSemiIncDevName[] = "KI Semi Inc 8g Accelerometer";
+    const TUint16 KKiSemiIncDevNameLength = sizeof(KKiSemiIncDevName) - 1;
+    char KSpecCo4gDevName[] = "SPE Co 4g Accelerometer";
+    const TUint16 KSpecCo4gDevNameLength = sizeof(KSpecCo4gDevName) - 1;
+
+    TAccelCaps* capsStructs = new TAccelCaps[KMaxNumAccelerateDevices];
+
+    test_NotNull(capsStructs);
+
+    //Initialisation with the sample data
+    //KI SemiInc 8g
+    capsStructs[KKiSemiIndex].iManufactureId = 0x12003335;
+    capsStructs[KKiSemiIndex].iDeviceId = 0x2001;
+    capsStructs[KKiSemiIndex].iDevName = KKiSemiIncDevName; 
+    capsStructs[KKiSemiIndex].iDataRate = 20;
+    capsStructs[KKiSemiIndex].iResolution = 8;
+    capsStructs[KKiSemiIndex].iScale = 8;
+    //SPE Co 4g
+    capsStructs[KSpecCo4gIndex].iManufactureId = 0x72103301;
+    capsStructs[KSpecCo4gIndex].iDeviceId = 0x0012;
+    capsStructs[KSpecCo4gIndex].iDevName = KSpecCo4gDevName; 
+    capsStructs[KSpecCo4gIndex].iDataRate = 50;
+    capsStructs[KSpecCo4gIndex].iResolution = 16;
+    capsStructs[KSpecCo4gIndex].iScale = 4;
+
+    
+    //Setting the value
+    TUint32 mask = 0x0000ffff;
+    const TUint32 KKiSemiPattern = 0x00010000u;
+    const TUint32 KSpecCo4gPattern = 0x00020000u;
+    const HCR::TCategoryUid category = 0x00000001u;
+
+    //SettingId container, it's used further down in the retrieve operations
+    HCR::TSettingId setId(category,0);
+    
+    //Test Repository elements Ids data
+    HCR::SSettingId repIds[KMaxNumAccelerateDevices][KNumElementsInRow] =
+            {
+                    {
+                            {0x01, 65537}, {0x01, 65538}, {0x01, 65539},
+                            {0x01, 65540}, {0x01, 65541}, {0x01, 65542}
+                    },
+                    {
+                            {0x01, 131073}, {0x01, 131074}, {0x01, 131075},
+                            {0x01, 131076}, {0x01, 131077}, {0x01, 131078}
+                    }
+            };
+    
+
+
+    HCR::TElementId* ids = new TElementId[KNumElementsInRow];
+    test_NotNull(ids);
+    HCR::TSettingType* types = new TSettingType[KNumElementsInRow];
+    test_NotNull(types);
+    TUint16* lengths = new TUint16[KNumElementsInRow];
+    test_NotNull(lengths);
+
+    //------------------------------------------------------------------
+    //Retrieve "ManufactureId" (column request) values for all devices
+    //------------------------------------------------------------------
+    r = HcrSimTest.FindSettings(category, KMaxNumAccelerateDevices, mask, 
+            KCapsField_Manufacturer, ids, types, lengths);
+    //Assert against the error
+    test_Compare(r,>=,0);
+
+    //Check the number of elements
+    test_Equal(KMaxNumAccelerateDevices, r);
+
+    // Check the ids, lengths and types
+    test_Equal(repIds[KKiSemiIndex][KCapsField_Manufacturer - 1].iKey, ids[KKiSemiIndex]);
+    test_Equal(HCR::ETypeUInt32, types[KKiSemiIndex]);
+    test_Equal(0,lengths[KKiSemiIndex]);
+    
+
+    // Check the ids, lengths and types
+    test_Equal(repIds[KSpecCo4gIndex][KCapsField_Manufacturer - 1].iKey, ids[KSpecCo4gIndex]);
+    test_Equal(HCR::ETypeUInt32, types[KSpecCo4gIndex]);
+    test_Equal(0,lengths[KSpecCo4gIndex]);
+
+    
+    //----------------------------
+    //Get all ManufactureId values
+    //----------------------------
+    TUint32 manufId;
+    //KiSemi
+    setId.iKey = ids[KKiSemiIndex];
+    r = HcrSimTest.GetUInt(setId,  manufId);
+    test_KErrNone(r);
+    test_Equal(capsStructs[KKiSemiIndex].iManufactureId,  manufId);
+  
+    //SpecCo 
+    setId.iKey = ids[KSpecCo4gIndex];
+    r = HcrSimTest.GetUInt(setId,  manufId);
+    test_KErrNone(r);
+    test_Equal(capsStructs[KSpecCo4gIndex].iManufactureId,  manufId);
+    
+    
+    
+    //------------------------------------------------------------------
+    //Retrieve "DeviceId" (column request) values for all devices
+    //------------------------------------------------------------------
+    r = HcrSimTest.FindSettings(category, KMaxNumAccelerateDevices, mask, 
+            KCapsField_Device, ids, types, lengths);
+    //Assert against the error
+    test_Compare(r,>=,0);
+
+    //Check the number of elements
+    test_Equal(KMaxNumAccelerateDevices, r);
+
+    // Check the ids, lengths and types
+    test_Equal(repIds[KKiSemiIndex][KCapsField_Device - 1].iKey, ids[KKiSemiIndex]);
+    test_Equal(HCR::ETypeUInt16, types[KKiSemiIndex]);
+    test_Equal(0,lengths[KKiSemiIndex]);
+
+    // Check the ids, lengths and types
+    test_Equal(repIds[KSpecCo4gIndex][KCapsField_Device - 1].iKey, ids[KSpecCo4gIndex]);
+    test_Equal(HCR::ETypeUInt16, types[KSpecCo4gIndex]);
+    test_Equal(0,lengths[KSpecCo4gIndex]);
+
+    
+    //----------------------------
+    //Get all DeviceId values
+    //----------------------------
+    TUint16 devId;
+
+    //KiSemi
+    setId.iKey = ids[KKiSemiIndex];
+    r = HcrSimTest.GetUInt(setId,  devId);
+    test_KErrNone(r);
+    test_Equal(capsStructs[KKiSemiIndex].iDeviceId,  devId);
+  
+    //SpecCo 
+    setId.iKey = ids[KSpecCo4gIndex];
+    r = HcrSimTest.GetUInt(setId, devId);
+    test_KErrNone(r);
+    test_Equal(capsStructs[KSpecCo4gIndex].iDeviceId,  devId);
+
+
+    
+    //------------------------------------------------------------------
+    //Retrieve "DeviceName" (column request) values for all devices
+    //------------------------------------------------------------------
+    r = HcrSimTest.FindSettings(category, KMaxNumAccelerateDevices, mask, 
+            KCapsField_Name, ids, types, lengths);
+    
+    //Assert against the error
+    test_Compare(r,>=,0);
+
+    //Check the number of elements
+    test_Equal(KMaxNumAccelerateDevices, r);
+
+    // Check the ids, lengths and types
+    test_Equal(repIds[KKiSemiIndex][KCapsField_Name - 1].iKey, ids[KKiSemiIndex]);
+    test_Equal(HCR::ETypeText8, types[KKiSemiIndex]);
+    test_Equal(KKiSemiIncDevNameLength,lengths[KKiSemiIndex]);
+
+    // Check the ids, lengths and types
+    test_Equal(repIds[KSpecCo4gIndex][KCapsField_Name - 1].iKey, ids[KSpecCo4gIndex]);
+    test_Equal(HCR::ETypeText8, types[KSpecCo4gIndex]);
+    test_Equal(KSpecCo4gDevNameLength,lengths[KSpecCo4gIndex]);
+
+
+    //----------------------------
+    //Get all DeviceName values
+    //----------------------------
+    TUint16 len;
+    
+    //KiSemi
+    TText8* nameKiSemi = new TText8[KKiSemiIncDevNameLength];
+    test_NotNull(nameKiSemi);
+    
+    setId.iKey = ids[KKiSemiIndex];
+    r = HcrSimTest.GetString(setId, KKiSemiIncDevNameLength, 
+            nameKiSemi, len);
+    test_KErrNone(r);
+    r = memcompare((unsigned char*)capsStructs[KKiSemiIndex].iDevName, (int)KKiSemiIncDevNameLength,
+            nameKiSemi, (int)KKiSemiIncDevNameLength);
+    test_KErrNone(r);
+
+    //SpecCo 
+    TText8* nameSpecCo = new TText8[KSpecCo4gDevNameLength];
+    test_NotNull(nameSpecCo);
+    
+    setId.iKey = ids[KSpecCo4gIndex];
+    r = HcrSimTest.GetString(setId, KSpecCo4gDevNameLength, 
+            nameSpecCo, len);
+    test_KErrNone(r);
+    r = memcompare((unsigned char*)capsStructs[KSpecCo4gIndex].iDevName, 
+            (int)KSpecCo4gDevNameLength, nameSpecCo, (int)KSpecCo4gDevNameLength);
+    test_KErrNone(r);
+
+    
+    
+    //------------------------------------------------------------------
+    //Retrieve "DataRate" (column request) values for all devices
+    //------------------------------------------------------------------
+    r = HcrSimTest.FindSettings(category, KMaxNumAccelerateDevices, mask, 
+            KCapsField_DataRate, ids, types, lengths);
+    //Assert against the error
+    test_Compare(r,>=,0);
+
+    //Check the number of elements
+    test_Equal(KMaxNumAccelerateDevices, r);
+
+    // Check the ids, lengths and types
+    test_Equal(repIds[KKiSemiIndex][KCapsField_DataRate - 1].iKey, ids[KKiSemiIndex]);
+    test_Equal(HCR::ETypeUInt16, types[KKiSemiIndex]);
+    test_Equal(0,lengths[KKiSemiIndex]);
+
+    // Check the ids, lengths and types
+    test_Equal(repIds[KSpecCo4gIndex][KCapsField_DataRate - 1].iKey, ids[KSpecCo4gIndex]);
+    test_Equal(HCR::ETypeUInt16, types[KSpecCo4gIndex]);
+    test_Equal(0,lengths[KSpecCo4gIndex]);
+
+
+    //----------------------------
+    //Get all DataRate values
+    //----------------------------
+    TUint16 dataRate;
+
+    //KiSemi
+    setId.iKey = ids[KKiSemiIndex];
+    r = HcrSimTest.GetUInt(setId,  dataRate);
+    test_KErrNone(r);
+    test_Equal(capsStructs[KKiSemiIndex].iDataRate, dataRate);
+
+    //SpecCo 
+    setId.iKey = ids[KSpecCo4gIndex];
+    r = HcrSimTest.GetUInt(setId, dataRate);
+    test_KErrNone(r);
+    test_Equal(capsStructs[KSpecCo4gIndex].iDataRate,  dataRate);
+
+    
+    //------------------------------------------------------------------
+    //Retrieve "Resolution" (column request) values for all devices
+    //------------------------------------------------------------------
+    r = HcrSimTest.FindSettings(category, KMaxNumAccelerateDevices, mask, 
+            KCapsField_Resolution, ids, types, lengths);
+    //Assert against the error
+    test_Compare(r,>=,0);
+
+    //Check the number of elements
+    test_Equal(KMaxNumAccelerateDevices, r);
+
+    // Check the ids, lengths and types
+    test_Equal(repIds[KKiSemiIndex][KCapsField_Resolution - 1].iKey, ids[KKiSemiIndex]);
+    test_Equal(HCR::ETypeUInt16, types[KKiSemiIndex]);
+    test_Equal(0,lengths[KKiSemiIndex]);
+
+    // Check the ids, lengths and types
+    test_Equal(repIds[KSpecCo4gIndex][KCapsField_Resolution - 1].iKey, ids[KSpecCo4gIndex]);
+    test_Equal(HCR::ETypeUInt16, types[KSpecCo4gIndex]);
+    test_Equal(0,lengths[KSpecCo4gIndex]);
+
+
+    //----------------------------
+    //Get all "Resolution" values
+    //----------------------------
+    TUint16 resolution;
+
+    //KiSemi
+    setId.iKey = ids[KKiSemiIndex];
+    r = HcrSimTest.GetUInt(setId,  resolution);
+    test_KErrNone(r);
+    test_Equal(capsStructs[KKiSemiIndex].iResolution, resolution);
+
+    //SpecCo 
+    setId.iKey = ids[KSpecCo4gIndex];
+    r = HcrSimTest.GetUInt(setId, resolution);
+    test_KErrNone(r);
+    test_Equal(capsStructs[KSpecCo4gIndex].iResolution, resolution);
+
+
+    //------------------------------------------------------------------
+    //Retrieve "Scale" (column request) values for all devices
+    //------------------------------------------------------------------
+    r = HcrSimTest.FindSettings(category, KMaxNumAccelerateDevices, mask, 
+            KCapsField_Scale, ids, types, lengths);
+    //Assert against the error
+    test_Compare(r,>=,0);
+
+    //Check the number of elements
+    test_Equal(KMaxNumAccelerateDevices, r);
+
+    // Check the ids, lengths and types
+    test_Equal(repIds[KKiSemiIndex][KCapsField_Scale - 1].iKey, ids[KKiSemiIndex]);
+    test_Equal(HCR::ETypeUInt16, types[KKiSemiIndex]);
+    test_Equal(0,lengths[KKiSemiIndex]);
+
+    // Check the ids, lengths and types
+    test_Equal(repIds[KSpecCo4gIndex][KCapsField_Scale - 1].iKey, ids[KSpecCo4gIndex]);
+    test_Equal(HCR::ETypeUInt16, types[KSpecCo4gIndex]);
+    test_Equal(0,lengths[KSpecCo4gIndex]);
+
+
+    //----------------------------
+    //Get all "Scale" values
+    //----------------------------
+    TUint16 scale;
+
+    //KiSemi
+    setId.iKey = ids[KKiSemiIndex];
+    r = HcrSimTest.GetUInt(setId,  scale);
+    test_KErrNone(r);
+    test_Equal(capsStructs[KKiSemiIndex].iScale, scale);
+
+    //SpecCo 
+    setId.iKey = ids[KSpecCo4gIndex];
+    r = HcrSimTest.GetUInt(setId, scale);
+    test_KErrNone(r);
+    test_Equal(capsStructs[KSpecCo4gIndex].iScale, scale);
+    
+    
+    
+    //-----------------------------------------------------------------------
+    //Read a complete row data for the single device
+    //-----------------------------------------------------------------------
+    mask = 0xffff0000; //retrive a row
+    
+    //------------------------
+    //KiSemi
+    //------------------------
+    r = HcrSimTest.FindSettings(category, KNumElementsInRow, mask, 
+            KKiSemiPattern, ids, types, lengths);
+    //Assert against the error
+    test_Compare(r,>=,0);
+    
+    //Assert the number of found elements
+    test_Equal(KNumElementsInRow, r);
+    
+    //Check the ManufactureId
+    setId.iKey = ids[KCapsField_Manufacturer-1];
+    r = HcrSimTest.GetUInt(setId,  manufId);
+    test_KErrNone(r);
+    test_Equal(capsStructs[KKiSemiIndex].iManufactureId,  manufId);
+    
+    //Check the DeviceId
+    setId.iKey = ids[KCapsField_Device-1];
+    r = HcrSimTest.GetUInt(setId,  devId);
+    test_KErrNone(r);
+    test_Equal(capsStructs[KKiSemiIndex].iDeviceId,  devId);
+    
+    //Check the DeviceName
+    setId.iKey = ids[KCapsField_Name-1];
+    r = HcrSimTest.GetString(setId, KKiSemiIncDevNameLength, 
+            nameKiSemi, len);
+    test_KErrNone(r);
+    r = memcompare((unsigned char*)capsStructs[KKiSemiIndex].iDevName,
+        (int)KKiSemiIncDevNameLength, nameKiSemi, (int)KKiSemiIncDevNameLength);
+    test_KErrNone(r);
+    
+    //Check the DataRate
+    setId.iKey = ids[KCapsField_DataRate-1];
+    r = HcrSimTest.GetUInt(setId,  dataRate);
+    test_KErrNone(r);
+    test_Equal(capsStructs[KKiSemiIndex].iDataRate, dataRate);
+
+    
+    //Check the Resolution
+    setId.iKey = ids[KCapsField_Resolution-1];
+    r = HcrSimTest.GetUInt(setId,  resolution);
+    test_KErrNone(r);
+    test_Equal(capsStructs[KKiSemiIndex].iResolution, resolution);
+
+    //------------------------
+    //SpecCo
+    //------------------------
+    r = HcrSimTest.FindSettings(category, KNumElementsInRow, mask, 
+            KSpecCo4gPattern, ids, types, lengths);
+    //Assert against the error
+    test_Compare(r,>=,0);
+
+    //Assert the number of found elements
+    test_Equal(KNumElementsInRow, r);
+
+    //Check the ManufactureId
+    setId.iKey = ids[KCapsField_Manufacturer-1];
+    r = HcrSimTest.GetUInt(setId,  manufId);
+    test_KErrNone(r);
+    test_Equal(capsStructs[KSpecCo4gIndex].iManufactureId,  manufId);
+
+    //Check the DeviceId
+    setId.iKey = ids[KCapsField_Device-1];
+    r = HcrSimTest.GetUInt(setId,  devId);
+    test_KErrNone(r);
+    test_Equal(capsStructs[KSpecCo4gIndex].iDeviceId,  devId);
+
+    //Check the DeviceName
+    setId.iKey = ids[KCapsField_Name-1];
+    r = HcrSimTest.GetString(setId, KSpecCo4gDevNameLength, 
+            nameSpecCo, len);
+    test_KErrNone(r);
+    r = memcompare((unsigned char*)capsStructs[KSpecCo4gIndex].iDevName,
+          (int)KSpecCo4gDevNameLength, nameSpecCo, (int)KSpecCo4gDevNameLength);
+    test_KErrNone(r);
+
+    //Check the DataRate
+    setId.iKey = ids[KCapsField_DataRate-1];
+    r = HcrSimTest.GetUInt(setId,  dataRate);
+    test_KErrNone(r);
+    test_Equal(capsStructs[KSpecCo4gIndex].iDataRate, dataRate);
+
+    //Check the Resolution
+    setId.iKey = ids[KCapsField_Resolution-1];
+    r = HcrSimTest.GetUInt(setId,  resolution);
+    test_KErrNone(r);
+    test_Equal(capsStructs[KSpecCo4gIndex].iResolution, resolution);
+
+
+    //Deallocate allocated resources
+    delete[] ids;
+    delete[] types;
+    delete[] lengths;
+    
+    delete[] nameKiSemi;
+    delete[] nameSpecCo;
+    
+    delete[] capsStructs;
+    
+
+    HcrSimTest.Close();
+    r = User::FreeLogicalDevice(aDriver);
+    test_KErrNone(r);
+    test.End();
+    }
+    
+
 void HcrSimBenchmarkTests(const TDesC& aDriver)
 	{
 	test.Next(_L("Simulated HCR Benchmark"));
@@ -2639,7 +3336,9 @@
 	HcrPslTests(KTestHcrSimClient);
 	HcrSimTests(KTestHcrSimOwn);
 	HcrSimTests(KTestHcrSimClient);
-
+	
+	HcrCatRecodsExampleTest(KTestHcrSimOwn);
+	HcrCatRecodsExampleTest(KTestHcrSimClient);
 
 	//Benchmark tests
 	HcrSimBenchmarkTests(KTestHcrSimOwn);
--- a/kerneltest/e32test/heap/t_heap.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kerneltest/e32test/heap/t_heap.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -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();
--- a/kerneltest/e32test/iic/iic_psl/d_iic_client_ctrless.mmp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kerneltest/e32test/iic/iic_psl/d_iic_client_ctrless.mmp	Fri Apr 16 16:24:37 2010 +0300
@@ -33,7 +33,7 @@
 OS_LAYER_SYSTEMINCLUDE_SYMBIAN
 
 // un-comment the following if debug printing is required
-macro LOG_CLIENT
+//macro LOG_CLIENT
 
 library spi_ctrless.lib
 library i2c_ctrless.lib
--- a/kerneltest/e32test/iic/iic_psl/d_iic_slaveclient_ctrless.mmp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kerneltest/e32test/iic/iic_psl/d_iic_slaveclient_ctrless.mmp	Fri Apr 16 16:24:37 2010 +0300
@@ -33,7 +33,7 @@
 OS_LAYER_SYSTEMINCLUDE_SYMBIAN
 
 // un-comment the following if debug printing is required
-macro LOG_SLAVECLIENT
+//macro LOG_SLAVECLIENT
 
 library i2c_ctrless.lib
 
--- a/kerneltest/e32test/iic/iic_psl/i2c.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kerneltest/e32test/iic/iic_psl/i2c.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -20,7 +20,7 @@
 #include <drivers/iic_trace.h>
 #endif
 
-
+#ifndef STANDALONE_CHANNEL
 #if defined(MASTER_MODE) && !defined(SLAVE_MODE)
 const TInt KChannelTypeArray[NUM_CHANNELS] = {DIicBusChannel::EMaster, DIicBusChannel::EMaster, DIicBusChannel::EMaster};
 #elif defined(MASTER_MODE) && defined(SLAVE_MODE)
@@ -30,6 +30,7 @@
 #endif
 #define CHANNEL_TYPE(n) (KChannelTypeArray[n])	
 #define CHANNEL_DUPLEX(n) (DIicBusChannel::EHalfDuplex)
+#endif/*STANDALONE_CHANNEL*/
 
 #ifdef STANDALONE_CHANNEL
 _LIT(KPddNameI2c,"i2c_ctrless.pdd");
@@ -125,9 +126,10 @@
 	aDes.Copy((TUint8*)&caps,size);
     }
 
+#ifndef STANDALONE_CHANNEL
 // supported channels for this implementation
 static DIicBusChannel* ChannelPtrArray[NUM_CHANNELS];
-
+#endif
 
 //DECLARE_EXTENSION_WITH_PRIORITY(BUS_IMPLMENTATION_PRIORITY)	
 DECLARE_STANDARD_PDD()		// I2c test driver to be explicitly loaded as an LDD, not kernel extension
@@ -439,14 +441,46 @@
 void DSimulatedIicBusChannelSlaveI2c::SlaveAsyncSimCallback(TAny* aPtr)
 	{
 	// To support simulating an asynchronous capture operation
-	// NOTE: this will be invoked in the context of DfcThread1
 	I2C_PRINT(("SlaveAsyncSimCallback\n"));
 	DSimulatedIicBusChannelSlaveI2c* channel = (DSimulatedIicBusChannelSlaveI2c*)aPtr;
-	TInt r=KErrNone;// Just simulate successful capture
+
+	// This will be invoked in the context of DfcThread1, so require
+	// synchronised access to iAsyncEvent and iRxTxTrigger
+	// Use local variables to enable early release of the spin lock
+	//
+	// If DfcThread1 runs on a separate core to the simulated I2C bus, the other core
+	// will have updated values, and since this core may cached copies, memory access
+	// should be observed. The spin lock mechanism is expected to incorpoate this.
+	TInt intState=__SPIN_LOCK_IRQSAVE(channel->iEventSpinLock);
+	
+	TAsyncEvent asyncEvent = channel->iAsyncEvent;
+	TInt rxTxTrigger = channel->iRxTxTrigger;
+	channel->iAsyncEvent = ENoEvent;
+	channel->iRxTxTrigger =  0;
+	__SPIN_UNLOCK_IRQRESTORE(channel->iEventSpinLock,intState);
+
+	switch(asyncEvent)
+		{
+		case (EAsyncChanCapture):
+			{
+			TInt r=KErrNone;// Just simulate successful capture
 #ifdef IIC_INSTRUMENTATION_MACRO
-	IIC_SCAPTCHANASYNC_END_PSL_TRACE;
+			IIC_SCAPTCHANASYNC_END_PSL_TRACE;
 #endif
-	channel->ChanCaptureCb(r);
+			channel->ChanCaptureCb(r);
+			break;
+			}
+		case (ERxWords):
+		case (ETxWords):
+		case (ERxTxWords):
+			{
+			channel->ChanNotifyClient(rxTxTrigger);
+			break;
+			}
+		default:
+			{
+			}
+		}
 	}
 
 #ifdef STANDALONE_CHANNEL
@@ -454,8 +488,9 @@
 #endif
 DSimulatedIicBusChannelSlaveI2c::DSimulatedIicBusChannelSlaveI2c(const DIicBusChannel::TBusType aBusType, const DIicBusChannel::TChannelDuplex aChanDuplex)
 	: DIicBusChannelSlave(aBusType,aChanDuplex,0), // 0 to be ignored by base class
-	iBlockedTrigger(0),iBlockNotification(EFalse),
-	iSlaveTimer(DSimulatedIicBusChannelSlaveI2c::SlaveAsyncSimCallback,this)
+	iBlockedTrigger(0),iBlockNotification(EFalse),iAsyncEvent(ENoEvent),iRxTxTrigger(0),
+	iSlaveTimer(DSimulatedIicBusChannelSlaveI2c::SlaveAsyncSimCallback,this),
+	iEventSpinLock(TSpinLock::EOrderGenericIrqHigh2)  // Semi-arbitrary, high priority value (NTimer used)
 	{
 	I2C_PRINT(("DSimulatedIicBusChannelSlaveI2c::DSimulatedIicBusChannelSlaveI2c, aBusType=%d,aChanDuplex=%d\n",aBusType,aChanDuplex));
 #ifndef STANDALONE_CHANNEL
@@ -488,7 +523,10 @@
 	IIC_SCAPTCHANASYNC_START_PSL_TRACE;
 #endif
 		// To simulate an asynchronous capture operation, just set a timer to expire
-		iSlaveTimer.OneShot(1000, ETrue); // Arbitrary timeout - expiry executes callback in context of DfcThread1
+		TInt intState=__SPIN_LOCK_IRQSAVE(iEventSpinLock);
+		iAsyncEvent = EAsyncChanCapture;
+		__SPIN_UNLOCK_IRQRESTORE(iEventSpinLock,intState);
+		iSlaveTimer.OneShot(KI2cSlaveAsyncDelaySim, ETrue); // Arbitrary timeout - expiry executes callback in context of DfcThread1
 		}
 	else
 		{
@@ -600,7 +638,7 @@
 
 void DSimulatedIicBusChannelSlaveI2c::ProcessData(TInt aTrigger, TIicBusSlaveCallback*  aCb)
 	{
-	I2C_PRINT(("DSimulatedIicBusChannelSlaveI2c::ProcessData\n"));
+	I2C_PRINT(("DSimulatedIicBusChannelSlaveI2c::ProcessData trigger=0x%x\n",aTrigger));
 	// fills in iReturn, iRxWords and/or iTxWords
 	//
 	if(aTrigger & ERxAllBytes)
@@ -631,7 +669,6 @@
 			iRxTxUnderOverRun&= ~ETxOverrun;
 			}
 		}
-
 	aCb->SetTrigger(aTrigger);
 	}
 
@@ -709,8 +746,13 @@
 			if(iBlockNotification == EFalse)
 				{
 				//
-				// Invoke DIicBusChannelSlave::NotifyClient - this will invoke ProcessData and invoke the client callback
-				NotifyClient(trigger);
+				// Use a timer for asynchronous call to NotifyClient - this will invoke ProcessData and invoke the client callback
+				TInt intState=__SPIN_LOCK_IRQSAVE(iEventSpinLock);
+				// Tx may already have been requested, to add to the existing flags set in iRxTxTrigger
+				iRxTxTrigger |= trigger;
+				iAsyncEvent = ERxWords;
+				__SPIN_UNLOCK_IRQRESTORE(iEventSpinLock,intState);
+				iSlaveTimer.OneShot(KI2cSlaveAsyncDelaySim, ETrue); // Arbitrary timeout - expiry executes callback in context of DfcThread1
 				}
 			else
 				{
@@ -784,8 +826,14 @@
 			if(iBlockNotification == EFalse)
 				{
 				//
-				// Invoke DIicBusChannelSlave::NotifyClient - this will invoke ProcessData and invoke the client callback
-				NotifyClient(trigger);
+				// Use a timer for asynchronous call to NotifyClient - this will invoke ProcessData and invoke the client callback
+				TInt intState=__SPIN_LOCK_IRQSAVE(iEventSpinLock);
+				// Rx may already have been requested, to add to the existing flags set in iRxTxTrigger
+				iRxTxTrigger |= trigger;
+				iAsyncEvent = ETxWords;
+				__SPIN_UNLOCK_IRQRESTORE(iEventSpinLock,intState);
+				iSlaveTimer.OneShot(KI2cSlaveAsyncDelaySim, ETrue); // Arbitrary timeout - expiry executes callback in context of DfcThread1
+																	// No effect if OneShot already invoked
 				}
 			else
 				{
@@ -868,8 +916,13 @@
 			if(iBlockNotification == EFalse)
 				{
 				//
-				// Invoke DIicBusChannelSlave::NotifyClient - this will invoke ProcessData and invoke the client callback
-				NotifyClient(trigger);
+				// Use a timer for asynchronous call to NotifyClient - this will invoke ProcessData and invoke the client callback
+				TInt intState=__SPIN_LOCK_IRQSAVE(iEventSpinLock);
+				// Rx or Tx may already have been requested, to add to the existing flags set in iRxTxTrigger
+				iRxTxTrigger |= trigger;
+				iAsyncEvent = ERxTxWords;
+				__SPIN_UNLOCK_IRQRESTORE(iEventSpinLock,intState);
+				iSlaveTimer.OneShot(KI2cSlaveAsyncDelaySim, ETrue); // Arbitrary timeout - expiry executes callback in context of DfcThread1
 				}
 			else
 				{
@@ -1035,7 +1088,7 @@
 #ifndef STANDALONE_CHANNEL
 			r=DIicBusController::DeRegisterChannel(this);
 #else
-			return KErrNotSupported;
+			r = KErrNotSupported;
 #endif
 			break;
 			}
--- a/kerneltest/e32test/iic/iic_psl/i2c.h	Tue Feb 02 01:24:03 2010 +0200
+++ b/kerneltest/e32test/iic/iic_psl/i2c.h	Fri Apr 16 16:24:37 2010 +0300
@@ -48,6 +48,8 @@
 
 const TInt16 KI2cSlaveChannelIdBase = 0x1D00;	// Arbitrary
 
+const TInt KI2cSlaveAsyncDelaySim = 20;	// Arbitrary delay, for timer to simulate asynchronous processing
+
 #ifdef MASTER_MODE
 class DSimulatedIicBusChannelMasterI2c : public DIicBusChannelMaster
 	{
@@ -110,6 +112,16 @@
 
 	inline void SetChanNum(TInt8 aChanNum) {iChannelNumber = aChanNum;};
 
+	enum TAsyncEvent
+		{
+		ENoEvent = 0,
+		EAsyncChanCapture,
+		ERxWords,
+		ETxWords,
+		ERxTxWords
+		};
+	inline void ChanNotifyClient(TInt aTrigger) {NotifyClient(aTrigger);}
+
 	protected:
 		virtual void SendBusErrorAndReturn() {return;} // Not implemented in simulated PSL
 
@@ -132,7 +144,11 @@
 		TInt iBlockedTrigger;
 		TBool iBlockNotification;
 
+		TAsyncEvent iAsyncEvent;
+		TInt iRxTxTrigger;
+
 		NTimer iSlaveTimer; // Used to simulate an asynchronous capture operation
+		TSpinLock iEventSpinLock; // To serialise simulated bus events - Rx, Tx or Rx+Tx
 		};
 #endif/*SLAVE_MODE*/
 
--- a/kerneltest/e32test/iic/iic_psl/i2c_ctrless.mmp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kerneltest/e32test/iic/iic_psl/i2c_ctrless.mmp	Fri Apr 16 16:24:37 2010 +0300
@@ -39,7 +39,7 @@
 macro SLAVE_MODE
 
 // un-comment the following if debug printing is required
-macro LOG_I2C
+//macro LOG_I2C
 
 // un-comment the following if BTRACE output is required
 macro IIC_INSTRUMENTATION_MACRO
--- a/kerneltest/e32test/iic/iic_psl/iic_client.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kerneltest/e32test/iic/iic_psl/iic_client.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -90,7 +90,7 @@
 class DIicClientChan : public DBase
 	{
 public:
-	DIicClientChan(DIicBusChannel* aChan, TInt8 aChanNum, TUint8 aChanType):iChan(aChan),iChanNumber(aChanNum),iChanType(aChanType){};
+	DIicClientChan(DIicBusChannel* aChan, TInt8 aChanNum, TUint8 aChanType):iChanNumber(aChanNum),iChanType(aChanType),iChan(aChan){};
 	~DIicClientChan();
 	TInt GetChanNum()const {return iChanNumber;};
 	TUint8 GetChanType()const {return iChanType;};
@@ -499,7 +499,7 @@
 // Constructor
     {
 	CLIENT_PRINT(("> DDeviceIicClient::DDeviceIicClient()"));
-    __KTRACE_OPT(KRESMANAGER, Kern::Printf("> DDeviceIicClient::DDeviceIicClient()"));
+    __KTRACE_OPT(KIIC, Kern::Printf("> DDeviceIicClient::DDeviceIicClient()"));
     iParseMask=0;		// No info, no PDD, no Units
     iUnitsMask=0;
     iVersion=TVersion(KIicClientMajorVersionNumber,
@@ -529,7 +529,7 @@
 DDeviceIicClient::~DDeviceIicClient()
     {
 	CLIENT_PRINT(("> DDeviceIicClient::~DDeviceIicClient()"));
-    __KTRACE_OPT(KRESMANAGER, Kern::Printf("> DDeviceIicClient::~DDeviceIicClient()"));
+    __KTRACE_OPT(KIIC, Kern::Printf("> DDeviceIicClient::~DDeviceIicClient()"));
 #ifdef STANDALONE_CHANNEL
     //For Standalone Channel, the client is responsible for channel destroy
     ChannelArray.ResetAndDestroy();
@@ -540,7 +540,7 @@
 // Install the device driver.
     {
 	CLIENT_PRINT(("> DDeviceIicClient::Install()"));
-    __KTRACE_OPT(KRESMANAGER, Kern::Printf("> DDeviceIicClient::Install()"));
+    __KTRACE_OPT(KIIC, Kern::Printf("> DDeviceIicClient::Install()"));
     return(SetName(&KLddRootName));
     }
 
@@ -763,7 +763,7 @@
 	DIicClientChan* aClientChan;
 	TInt r = KErrNone;
 	DIicBusChannel *chan = NULL, *chanM = NULL, *chanS = NULL;
-	TInt i;
+	TUint i;
 	for(i=0; i<NUM_CHANNELS_SPI; i++)
 		{
 		CLIENT_PRINT(("\n"));
@@ -1019,7 +1019,7 @@
 // Destructor
     {
 	CLIENT_PRINT(("> DChannelIicClient::~DChannelIicClient()"));
-    __KTRACE_OPT(KRESMANAGER, Kern::Printf("> DChannelIicClient::~DChannelIicClient()"));
+    __KTRACE_OPT(KIIC, Kern::Printf("> DChannelIicClient::~DChannelIicClient()"));
     delete iNotif;
     iArrayMutex->Close(NULL);
     iChanArrWrtSem->Close(NULL);
@@ -2075,7 +2075,6 @@
 	delete iI2cBuf;
 	iI2cBuf=NULL;
 	TIicBusTransfer* currTfer = iTfer;
-	TIicBusTransfer* nextTfer = NULL;
 	while(currTfer)
 		{
 		TIicBusTransfer* nextTfer = (TIicBusTransfer*)(currTfer->Next());
@@ -2087,7 +2086,6 @@
 		};
 	iTfer=NULL;
 	currTfer = iFdTfer;
-	nextTfer = NULL;
 	while(currTfer)
 		{
 		TIicBusTransfer* nextTfer = (TIicBusTransfer*)(currTfer->Next());
--- a/kerneltest/e32test/iic/iic_psl/iic_slaveclient.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kerneltest/e32test/iic/iic_psl/iic_slaveclient.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -67,7 +67,7 @@
 class DIicSlaveClientChan : public DBase
 	{
 public:
-	DIicSlaveClientChan(DIicBusChannel* aChan, TInt8 aChanNum, TInt aChanType):iChan(aChan),iChanNumber(aChanNum),iChanType(aChanType){};
+	DIicSlaveClientChan(DIicBusChannel* aChan, TInt8 aChanNum, TInt aChanType):iChanNumber(aChanNum),iChanType(aChanType),iChan(aChan){};
 	~DIicSlaveClientChan();
 	TInt GetChanNum()const {return iChanNumber;};
 	TInt GetChanType()const {return iChanType;};
@@ -207,7 +207,7 @@
 	TInt iFullDuplexReq;
 	TInt iBlockedTrigger;
 
-	typedef enum TTestOverUnderState
+	enum TTestOverUnderState
 		{
 		EStartState  = 0x1,
 		ERxOverrun_1,
@@ -1416,7 +1416,6 @@
 				iExpectedTrigger |= tempTrigger;
 			else
 				iBlockedTrigger |= tempTrigger;
-
 			// The bytes "transmitted" are stored in the simulated bus' iTxCheckBuf
 			// Since the simulated bus channel is also in the kernel process it shares the same address space
 			// Get the address of the buffer
@@ -1468,7 +1467,6 @@
 				iExpectedTrigger |= tempTrigger;
 			else
 				iBlockedTrigger |= tempTrigger;
-
 			// The bytes "transmitted" are stored in the simulated bus' iTxCheckBuf
 			// Since the simulated bus channel is also in the kernel process it shares the same address space
 			// Get the address of the buffer
--- a/kerneltest/e32test/iic/iic_psl/spi.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kerneltest/e32test/iic/iic_psl/spi.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -19,6 +19,7 @@
 #include <drivers/iic_trace.h>
 #endif
 
+#ifndef STANDALONE_CHANNEL
 #define NUM_CHANNELS 4 // Arbitrary
 
 // Macros to be updated(?) with interaction with Configuration Repository
@@ -26,6 +27,7 @@
 #define CHANNEL_TYPE(n) (KChannelTypeArray[n])	
 const DIicBusChannel::TChannelDuplex KChannelDuplexArray[NUM_CHANNELS] = {DIicBusChannel::EHalfDuplex, DIicBusChannel::EHalfDuplex, DIicBusChannel::EHalfDuplex, DIicBusChannel::EFullDuplex};
 #define CHANNEL_DUPLEX(n) (KChannelDuplexArray[n]) 
+#endif/*STANDALONE_CHANNEL*/
 
 #ifdef LOG_SPI
 #define SPI_PRINT(str) Kern::Printf str
@@ -122,8 +124,10 @@
 	aDes.Copy((TUint8*)&caps,size);
     }
 
+#ifndef STANDALONE_CHANNEL
 // supported channels for this implementation
 static DIicBusChannel* ChannelPtrArray[NUM_CHANNELS];
+#endif
 
 //DECLARE_EXTENSION_WITH_PRIORITY(BUS_IMPLMENTATION_PRIORITY)	
 DECLARE_STANDARD_PDD()		// SPI test driver to be explicitly loaded as an LDD, not kernel extension
@@ -487,10 +491,7 @@
 TInt DSimulatedIicBusChannelMasterSpi::DoSimulatedTransaction()
 	{
 	TInt r = AsynchStateMachine(EHwTransferDone);
-	if(iTimeoutTimer.Cancel() == FALSE)
-		{
-		SPI_PRINT(("timer is not cancelled"));
-		}
+	CancelTimeOut();
 	return r;
 	}
 
--- a/kerneltest/e32test/iic/t_iic.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kerneltest/e32test/iic/t_iic.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -1148,10 +1148,6 @@
 	gTest.Printf(_L("BlockNotification\n"));
 	r=gChanSlaveI2c.BlockNotification(busIdI2c, chanId);
 	gTest(r==KErrNone);
-	// Now instruct the bus implementation to represent the bus master attempting to read the required number of words
-	gTest.Printf(_L("\nStarting SimulateTxNWords\n"));
-	r=gChanSlaveI2c.SimulateTxNWords(busIdI2c, chanId, 12);
-	gTest(r==KErrNone);
 	//
 	// Wait for the notification
 	User::WaitForRequest(status);
@@ -1162,6 +1158,10 @@
 		gTest(r==KErrNone);
 		}
 	gTest.Printf(_L("Blocked notification test completed OK\n"));
+    // Now instruct the bus implementation to represent the bus master attempting to read the required number of words
+    gTest.Printf(_L("\nStarting SimulateTxNWords\n"));
+    r=gChanSlaveI2c.SimulateTxNWords(busIdI2c, chanId, 12);
+    gTest(r==KErrNone);
 	// Re-set the notification trigger - for the 'blocked' Tx
 	// This is required because, in the event of a bus error, the set of requested Rx,Tx
 	// flags are cleared
--- a/kerneltest/e32test/iic/t_iic.h	Tue Feb 02 01:24:03 2010 +0200
+++ b/kerneltest/e32test/iic/t_iic.h	Fri Apr 16 16:24:37 2010 +0300
@@ -217,7 +217,7 @@
 // 27:23 - Reserved
 // 22:20 - Bus type
 // 19:15 - Channel number
-// 14:10 - Transaction speed
+// 14:10 - Transaction speed	// deprecated
 //  9:0  - Slave address
 #define HS_MASTER_ADDR_SHIFT 29
 #define HS_MASTER_ADDR_MASK 0x7
@@ -227,8 +227,8 @@
 #define BUS_TYPE_MASK 0x7
 #define CHANNEL_NO_SHIFT 15
 #define CHANNEL_NO_MASK 0x1F
-#define TRANS_SPEED_SHIFT 10
-#define TRANS_SPEED_MASK 0x1F
+//#define TRANS_SPEED_SHIFT 10
+//#define TRANS_SPEED_MASK 0x1F
 #define SLAVE_ADDR_SHIFT 0
 #define SLAVE_ADDR_MASK 0x3FF
 //
@@ -244,8 +244,8 @@
 #define SET_BUS_TYPE(aBusId,aBusType) SET_CONFIG_FIELD(aBusId,aBusType,BUS_TYPE_MASK,BUS_TYPE_SHIFT)
 #define GET_CHAN_NUM(aBusId) GET_CONFIG_FIELD(aBusId,CHANNEL_NO_MASK,CHANNEL_NO_SHIFT)
 #define SET_CHAN_NUM(aBusId,aChanNum) SET_CONFIG_FIELD(aBusId,aChanNum,CHANNEL_NO_MASK,CHANNEL_NO_SHIFT)
-#define SET_TRANS_SPEED(aBusId,aTransSpeed) SET_CONFIG_FIELD(aBusId,aTransSpeed,TRANS_SPEED_MASK,TRANS_SPEED_SHIFT)
-#define GET_TRANS_SPEED(aBusId) GET_CONFIG_FIELD(aBusId,TRANS_SPEED_MASK,TRANS_SPEED_SHIFT)
+//#define SET_TRANS_SPEED(aBusId,aTransSpeed) SET_CONFIG_FIELD(aBusId,aTransSpeed,TRANS_SPEED_MASK,TRANS_SPEED_SHIFT)
+//#define GET_TRANS_SPEED(aBusId) GET_CONFIG_FIELD(aBusId,TRANS_SPEED_MASK,TRANS_SPEED_SHIFT)
 #define SET_SLAVE_ADDR(aBusId,aSlaveAddr) SET_CONFIG_FIELD(aBusId,aSlaveAddr,SLAVE_ADDR_MASK,SLAVE_ADDR_SHIFT)
 #define GET_SLAVE_ADDR(aBusId) GET_CONFIG_FIELD(aBusId,SLAVE_ADDR_MASK,SLAVE_ADDR_SHIFT)
 
@@ -375,7 +375,7 @@
 	inline TInt ReleaseChannel(TInt aChannelId){return(DoControl(EReleaseChan,(TAny*)aChannelId,NULL));};
 	inline TInt RegisterRxBuffer(TInt aChannelId, TInt8 aBufGranularity, TInt8 aNumWords, TInt8 aOffset){TInt8 parms[3]; parms[0]=aBufGranularity; parms[1]=aNumWords; parms[2]=aOffset;return(DoControl(ERegisterRxBuffer,(TAny*)aChannelId,(TAny*)(&parms[0])));};
 	inline TInt RegisterTxBuffer(TInt aChannelId, TInt8 aBufGranularity, TInt8 aNumWords, TInt8 aOffset){TInt8 parms[3]; parms[0]=aBufGranularity; parms[1]=aNumWords; parms[2]=aOffset;return(DoControl(ERegisterTxBuffer,(TAny*)aChannelId,(TAny*)(&parms[0])));};
-	inline TInt SetNotificationTrigger(TInt aChannelId, TInt aTrigger, TRequestStatus* aStatus){TInt parms[2]; parms[0]=aChannelId; parms[1]=aTrigger;return(DoControl(ESetNotifTrigger,(TAny*)aStatus,(TAny*)(&parms[0])));};
+	inline TInt SetNotificationTrigger(TInt aChannelId, TInt aTrigger, TRequestStatus* aStatus){TInt parms[2]; parms[0]=aChannelId; parms[1]=aTrigger; *aStatus=KRequestPending; return(DoControl(ESetNotifTrigger,(TAny*)aStatus,(TAny*)(&parms[0])));};
 
 	// ControlIO functions follow
 	inline TInt BlockReqCompletion(TInt aBusId) {return(DoControl(ECtlIoBlockReqCompletion,(TAny*)aBusId));}
--- a/kerneltest/e32test/locl/t_lat1.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kerneltest/e32test/locl/t_lat1.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -1,7 +1,7 @@
 // Copyright (c) 1995-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"
+// under the terms of "Eclipse Public License v1.0"
 // which accompanies this distribution, and is available
 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
 //
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/misc/ccthrash.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,217 @@
+// Copyright (c) 2009-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\misc\ccthrash.cpp
+// 
+//
+
+#define __E32TEST_EXTENSION__
+
+#include <e32test.h>
+#include <e32hal.h>
+#include <e32svr.h>
+#include <e32atomics.h>
+#include "u32std.h"
+#include "prbs.h"
+
+RTest test(_L("Core Control Thrasher"));
+
+TInt NumberOfCpus()
+	{
+	TInt r = UserSvr::HalFunction(EHalGroupKernel, EKernelHalNumLogicalCpus, 0, 0);
+	test(r>0);
+	return r;
+	}
+
+const TInt NCPU = NumberOfCpus();
+volatile TInt STFU = 1;
+
+TInt NumberOfActiveCpus(TInt* a)
+	{
+	SCpuStates s;
+	TInt r = UserSvr::HalFunction(EHalGroupKernel, EKernelHalCpuStates, &s, 0);
+	test_KErrNone(r);
+	TUint32 ta = s.iTA;
+	TUint32 ia = s.iIA;
+	if (a)
+		*a = __e32_bit_count_32(ta);
+	return __e32_bit_count_32(ia);
+	}
+
+TInt StableState()
+	{
+	SCpuStates s;
+	TInt r = UserSvr::HalFunction(EHalGroupKernel, EKernelHalCpuStates, &s, 0);
+	test_KErrNone(r);
+	if (s.iCU || s.iDC)
+		return KErrNotReady;
+	if (s.iTA != s.iIA)
+		return KErrNotReady;
+	if (s.iGD & s.iIA)
+		return KErrNotReady;
+	TInt i;
+	for (i=0; i<NCPU; ++i)
+		{
+		TBool attached = (s.iUDC[i] == s.iUAC[i]);
+		TBool on = s.iIA & (1u<<i);
+		if ((on && !attached) || (!on && attached))
+			return KErrNotReady;
+		}
+	return __e32_bit_count_32(s.iTA);
+	}
+
+class CThrasher : public CBase
+	{
+public:
+	CThrasher();
+	~CThrasher();
+	static CThrasher* New();
+	TInt Construct();
+	void Run();
+	void Display();
+	TInt ChangeNumberOfCores(TInt aNum, TInt* aCores);
+public:
+	TUint64 iRunCount;
+	TUint64 iTotalTime;
+	TUint32 iTimeouts;
+	TUint32 iDiff;
+	TUint32 iPeriod;
+	TUint iSeed[2];
+	TUint32 iLastDisplay;
+	TUint32 iDisplayPeriod;
+	TUint32 iTimeoutPeriod;
+	};
+
+CThrasher::CThrasher()
+	{
+	iSeed[0] = 0xb504f334u;
+	iPeriod = 19;
+	iLastDisplay = User::NTickCount();
+	iDisplayPeriod = 2000;
+	iTimeoutPeriod = 200;
+	}
+
+CThrasher::~CThrasher()
+	{
+	}
+
+TInt CThrasher::Construct()
+	{
+	return KErrNone;
+	}
+
+CThrasher* CThrasher::New()
+	{
+	CThrasher* p = new CThrasher;
+	if (!p)
+		return 0;
+	TInt r = p->Construct();
+	if (r!=KErrNone)
+		{
+		delete p;
+		return 0;
+		}
+	return p;
+	}
+
+TInt CThrasher::ChangeNumberOfCores(TInt aNum, TInt* aCores)
+	{
+	TUint32 initial = User::NTickCount();
+	TUint32 final = initial;
+	TUint32 elapsed = 0;
+	TInt n = -1;
+	TInt r = UserSvr::HalFunction(EHalGroupKernel, EKernelHalSetNumberOfCpus, (TAny*)aNum, 0);
+	test_KErrNone(r);
+	FOREVER
+		{
+		n = StableState();
+		final = User::NTickCount();
+		elapsed = final - initial;
+		if (n<0 || elapsed<iTimeoutPeriod)
+			break;
+		User::AfterHighRes(1000);
+		}
+	if (aCores)
+		*aCores = n;
+	if (n>=0)
+		return elapsed;
+	return KErrTimedOut;
+	}
+
+void CThrasher::Run()
+	{
+	TUint x = Random(iSeed);
+	x %= iPeriod;
+	x += 1;
+	x *= 1000;
+	User::AfterHighRes(x);
+	TUint y = Random(iSeed);
+	y %= TUint(NCPU);
+	y += 1;
+	TInt n = 0;
+	TInt t = ChangeNumberOfCores(y, &n);
+	if (t < 0)
+		{
+		++iTimeouts;
+		iTotalTime += TUint64(iTimeoutPeriod);
+		}
+	else
+		{
+		iTotalTime += TUint64(t);
+		if (TUint(n) != y)
+			++iDiff;
+		}
+	++iRunCount;
+	TUint32 now = User::NTickCount();
+	TUint32 elapsed = now - iLastDisplay;
+	if (elapsed >= iDisplayPeriod)
+		{
+		iLastDisplay = now;
+		Display();
+		}
+	}
+
+void CThrasher::Display()
+	{
+	TUint64 avg = iTotalTime;
+	avg *= TUint64(100);
+	avg += TUint64(50);
+	avg /= iRunCount;
+	TUint32 frac = TUint32(avg % TUint64(100));
+	TUint32 integer = TUint32(avg / TUint64(100));
+	TUint32 rc32 = (TUint32)iRunCount;
+	test.Printf(_L("RC:%10u AVG:%10u.%02u TO:%10u D:%10u\n"), rc32, integer, frac, iTimeouts, iDiff);
+	}
+
+GLDEF_C TInt E32Main()
+	{
+	test.Title();
+	RThread().SetPriority(EPriorityAbsoluteHigh);
+
+	if (NCPU==1)
+		{
+		test.Printf(_L("Only works on SMP systems\n"));
+		return 0;
+		}
+
+	CThrasher* p = CThrasher::New();
+	test_NotNull(p);
+	while(STFU)
+		{
+		p->Run();
+		}
+
+
+	return 0;
+	}
+
--- a/kerneltest/e32test/misc/cpumeter.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kerneltest/e32test/misc/cpumeter.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -48,6 +48,8 @@
 	TInt Construct();
 	void Measure();
 	void Display(TInt aInterval);
+	void DisplayCoreControlInfo();
+	void ChangeNumberOfCores(TInt aNum);
 public:
 	TInt iNumCpus;
 	TInt iNextMeas;
@@ -152,6 +154,38 @@
 	test.Printf(buf);
 	}
 
+void CCpuMeter::DisplayCoreControlInfo()
+	{
+	SCpuStates s;
+	TInt r = UserSvr::HalFunction(EHalGroupKernel, EKernelHalCpuStates, &s, 0);
+	if (r != KErrNone)
+		{
+		test.Printf(_L("Error %d\n"), r);
+		return;
+		}
+	test.SetLogged(ETrue);
+	test.Printf(_L("  TA=%08x IA=%08x CU=%08x GD=%08x DC=%08x\n"), s.iTA, s.iIA, s.iCU, s.iGD, s.iDC);
+	test.Printf(_L("  SC=%08x RC=%08x PO=%02x      CCS=%08x PODC=%08x\n"), s.iSC, s.iRC, s.iPO, s.iCCS, s.iPODC);
+	TInt i;
+	for (i=0; i<iNumCpus; ++i)
+		{
+		test.Printf(_L("%1d:DS=%08x UDC=%08x UAC=%08x OP=%08x F=%08x\n"), i, s.iDS[i], s.iUDC[i], s.iUAC[i], s.iOP[i], s.iF[i]);
+		}
+	test.SetLogged(EFalse);
+	}
+
+void CCpuMeter::ChangeNumberOfCores(TInt aNum)
+	{
+	test.SetLogged(ETrue);
+	test.Printf(_L("#CORES->%d\n"), aNum);
+	TInt r = UserSvr::HalFunction(EHalGroupKernel, EKernelHalSetNumberOfCpus, (TAny*)aNum, 0);
+	if (r != KErrNone)
+		{
+		test.Printf(_L("Error %d\n"), r);
+		}
+	test.SetLogged(EFalse);
+	}
+
 void UseKernelCpuTime()
 	{
 	test.Start(_L("Create CCpuMeter"));
@@ -175,6 +209,14 @@
 				delete m;
 				return;
 				}
+			if (m->iNumCpus > 1)
+				{
+				// SMP only options
+				if (k == EKeySpace)
+					m->DisplayCoreControlInfo();
+				else if (k>='1' && k<=('0'+m->iNumCpus))
+					m->ChangeNumberOfCores(k - '0');
+				}
 			console->Read(s);
 			}
 		}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/misc/d_testkerncorestats.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,168 @@
+// Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "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\misc\d_kerncorestas.cpp
+// 
+//
+
+#include "d_TestKernCoreStats.h"
+
+#include <kernel/kernel.h>
+#include <kernel/kerncorestats.h>
+
+
+class DTestKernCoreStatsFactory : public DLogicalDevice
+        {
+public:
+        DTestKernCoreStatsFactory();
+        ~DTestKernCoreStatsFactory();
+        virtual TInt Install();
+        virtual void GetCaps(TDes8& aDes) const;
+        virtual TInt Create(DLogicalChannelBase*& aChannel);
+        };
+
+class DTestKernCoreStatsChannel : public DLogicalChannelBase
+        {
+public:
+        DTestKernCoreStatsChannel();
+        virtual ~DTestKernCoreStatsChannel();
+        TInt Request(TInt aFunction, TAny* a1, TAny* a2);
+        virtual TInt DoCreate(TInt aUnit, const TDesC8* anInfo, const TVersion&
+aVer);
+private:
+	TInt GetStats(TAny* aBuffer);
+	TInt Configure(TInt aMode);
+	TInt DumpInfo();
+private:
+	TInt iLength;
+        };
+
+
+DECLARE_STANDARD_LDD()
+        {
+        return new DTestKernCoreStatsFactory;
+        }
+
+DTestKernCoreStatsFactory::DTestKernCoreStatsFactory()
+        {
+        }
+
+DTestKernCoreStatsFactory::~DTestKernCoreStatsFactory()
+        {
+        }
+
+TInt DTestKernCoreStatsFactory::Install()
+        {
+        return SetName(&KTestKernCoreStatsName);
+        }
+
+
+void DTestKernCoreStatsFactory::GetCaps(TDes8&) const
+        {
+        }
+
+
+TInt DTestKernCoreStatsFactory::Create(DLogicalChannelBase*& aChannel)
+        {
+        aChannel=new DTestKernCoreStatsChannel();
+        if(!aChannel)
+                return KErrNoMemory;
+
+        return KErrNone;
+        }
+
+DTestKernCoreStatsChannel::DTestKernCoreStatsChannel()
+	{
+	}
+
+
+DTestKernCoreStatsChannel::~DTestKernCoreStatsChannel()
+	{
+	}
+
+TInt DTestKernCoreStatsChannel::DoCreate(TInt, const TDesC8*, const TVersion&)
+        {
+        return KErrNone;
+        }
+
+TInt DTestKernCoreStatsChannel::Request(TInt aFunction, TAny* a1, TAny*)
+        {
+        switch (aFunction)
+                {
+                case RTestKernCoreStats::ERequestGetStats:
+                        return GetStats( (TAny*) a1);
+                case RTestKernCoreStats::ERequestConfigure:
+                        return Configure( (TInt) a1);
+                case RTestKernCoreStats::ERequestDumpInfo:
+                        return DumpInfo();
+                default:
+                        return KErrNotSupported;
+                }
+        }
+
+
+TInt DTestKernCoreStatsChannel::GetStats(TAny* aBuffer)
+	{
+	NKern::ThreadEnterCS();
+	
+	if (iLength==0)
+		return KErrNone;
+	
+	TAny* tempBuff = Kern::Alloc(iLength);
+	if (!tempBuff)
+		{
+		NKern::ThreadLeaveCS();
+		return KErrNoMemory;
+		}
+
+	TInt r = KernCoreStats::Stats(tempBuff);
+
+
+	if (r==KErrNone)
+		kumemput(aBuffer, tempBuff, iLength);
+
+	Kern::Free(tempBuff);
+	NKern::ThreadLeaveCS();
+
+	return r;
+	}
+
+TInt DTestKernCoreStatsChannel::Configure(TInt aMode)
+	{
+
+	NKern::ThreadEnterCS();
+	TInt cores = NKern::NumberOfCpus();
+
+	TInt len = 0;
+	len+= (aMode & KStatsCoreTotalTimeInIdle)?		sizeof(TUint)*cores :0;
+	len+= (aMode & KStatsTimeCrossIdleAndActive)?		sizeof(TUint)*(cores+1) :0;
+	len+= (aMode & KStatsCoreNumTimesInIdle)?		sizeof(TUint)*cores :0;
+	len+= (aMode & KStatsNumEvents)?			sizeof(TUint) :0;
+	len+= (aMode & KStatsReadyStateChanges)?		sizeof(TUint)*2:0;
+	len+= (aMode & KStatsNumTimeSliceExpire)?		sizeof(TUint):0;
+
+	iLength=len;
+	Kern::Printf("KernCoreStats packet length = %d", len);
+	TInt r =  KernCoreStats::Configure(aMode);
+	NKern::ThreadLeaveCS();
+	return r;
+	}
+
+
+TInt DTestKernCoreStatsChannel::DumpInfo()
+	{
+
+	//KernCoreStats::Engage(0);
+
+	return iLength;
+	}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/misc/d_testkerncorestats.h	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,79 @@
+// Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "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\misc\d_kerncorestas.h
+// 
+
+
+#ifndef D_TESTKERNCORESTATS
+#define D_TESTKERNCORESTATS
+
+
+#include <e32cmn.h>
+#include <e32ver.h>
+#ifndef __KERNEL_MODE__
+#include <e32std.h>
+#endif
+
+
+
+_LIT(KTestKernCoreStatsName,"TestKernCoreStats");
+
+
+
+class RTestKernCoreStats : public RBusLogicalChannel
+        {
+public:
+
+        enum TControl
+                {
+
+        ERequestGetStats,
+        ERequestConfigure,
+        ERequestDumpInfo
+                };
+public:
+        inline TInt Open();
+        inline TInt GetStats( TAny* a0);
+        inline TInt Configure( TInt a0);
+        inline TInt DumpInfo();
+
+        };
+
+#ifndef __KERNEL_MODE__
+
+inline TInt RTestKernCoreStats::Open()
+		{ return DoCreate(KTestKernCoreStatsName,TVersion(0,1,1),KNullUnit,NULL,NULL); }
+
+
+inline TInt RTestKernCoreStats::GetStats( TAny* a0)
+        { return DoControl(ERequestGetStats, (TAny*) a0); }
+
+inline TInt RTestKernCoreStats::Configure( TInt a0)
+        { return DoControl(ERequestConfigure, (TAny*) a0); }
+
+inline TInt RTestKernCoreStats::DumpInfo()
+        { return DoControl(ERequestDumpInfo,NULL); }
+
+
+
+
+#else
+
+#define DRIVER_NAME(x)
+#define DRIVER_REQUEST TInt
+
+#endif // __KERNEL_MODE__
+
+#endif
+
--- a/kerneltest/e32test/misc/inflate.c	Tue Feb 02 01:24:03 2010 +0200
+++ b/kerneltest/e32test/misc/inflate.c	Fri Apr 16 16:24:37 2010 +0300
@@ -1,3 +1,19 @@
+/*
+* 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 "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: 
+*
+*/
 /* inflate.c -- Not copyrighted 1992 by Mark Adler
    version c10p1, 10 January 1993 */
 
--- a/kerneltest/e32test/misc/t_cputime.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kerneltest/e32test/misc/t_cputime.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -228,6 +228,7 @@
 	test(s==KRequestPending);
 
 	TTimeIntervalMicroSeconds time, time2;
+	TUint us;
 	
 	// Test time is initially zero
 	FailIfError(thread.GetCpuTime(time));
@@ -237,13 +238,22 @@
 	thread.Resume();
 	User::After(KShortWait);
 	FailIfError(thread.GetCpuTime(time));
+	us = I64LOW(time.Int64());
+	test.Printf(_L("Time %dus\n"), us);
 	test(time < KTolerance); // wait happens in less than 0.5ms
 
 	// Test increases when thread allowed to run
 	(threadParam.iSem).Signal();
 	User::After(KShortWait);
 	FailIfError(thread.GetCpuTime(time));
+	us = I64LOW(time.Int64());
+	test.Printf(_L("Time %dus\n"), us);
 	test(time > (KShortWait - KTolerance));
+	User::After(KLongWait);
+	FailIfError(thread.GetCpuTime(time2));
+	us = I64LOW(time2.Int64());
+	test.Printf(_L("Time %dus\n"), us);
+	test(time2.Int64() - time.Int64() > (KLongWait - KTolerance));
 
 	// Test not increased while suspended
 	thread.Suspend();
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/misc/t_kerncorestats.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,398 @@
+// Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "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\misc\t_kerncorestas.cpp
+// 
+//
+
+#define __E32TEST_EXTENSION__
+#include <e32test.h>
+#include <e32svr.h>
+#include <u32hal.h>
+#include <e32property.h>
+
+#include "d_testkerncorestats.h"
+
+LOCAL_D RTest test(_L("t_KernCoreStats"));
+
+
+// Kernel side stats (also used when obtaining stats from Kernel)
+const TInt KStatsCoreNumTimesInIdle	 = 0x0001;
+const TInt KStatsCoreTotalTimeInIdle	 = 0x0002;
+const TInt KStatsTimeCrossIdleAndActive	 = 0x0004;
+const TInt KStatsReadyStateChanges	 = 0x0008;
+const TInt KStatsNumTimeSliceExpire	 = 0x0010;
+const TInt KStatsNumEvents		 = 0x0020;
+
+
+_LIT(KLddName, "d_testkerncorestats");
+static RTestKernCoreStats gChan;
+TInt gCores;
+TInt gDelay = 500;
+TInt gThreads=0;
+
+void DisplayBuf(TInt aMode, TAny* aBuffer)
+	{
+	TUint* pVal = (TUint*) aBuffer;
+	test.Printf(_L("\nKernel Stats\n============\n"));
+
+	TInt core;
+	TUint TTI=0;
+
+	if (aMode & KStatsCoreTotalTimeInIdle)
+		{
+		test.Printf(_L("Time in Idle thread:"));	
+		TTI=0;
+		for (core=0; core<gCores; core++)
+			{
+			test.Console()->SetPos(22);
+			test.Printf(_L("%d: %10d \n"),core,*pVal);
+			TTI+=*pVal;
+			pVal++;
+			}
+
+		test.Console()->SetPos(22);
+		test.Printf(_L("Total:%10d \n\n"),TTI);
+		}
+
+
+	if (aMode & KStatsTimeCrossIdleAndActive)
+		{
+		TUint total=0;
+		TUint idletotal=0;
+		
+		TUint* pSavedPlace = pVal;
+
+		for (core=0;  core<(gCores+1); core++)
+			{
+			total+=*pVal;
+			idletotal+= *pVal*core;
+			pVal++;		
+			}
+		pVal = pSavedPlace;
+
+		TInt percent;
+		test.Printf(_L("Time in permutations: "));
+		for (core=0;  core<(gCores+1); core++)
+			{
+			test.Console()->SetPos(22);
+			percent = (total>0)?*pVal*100/total:0;
+			test.Printf(_L("%d: %10d (%3d%%)\n"),core,*pVal, percent);
+			pVal++;		
+			}
+
+
+
+
+		test.Console()->SetPos(22);
+		test.Printf(_L("Total Time :%10d        "),total);
+		if ((total- (TUint) gDelay > 100000) || ((TUint) gDelay>total))
+			test.Printf(_L("FAIL!\n"));
+		else
+			test.Printf(_L("PASS \n"));
+		
+
+		test.Console()->SetPos(22);
+		percent = (total>0)?idletotal*25/total:0;
+		test.Printf(_L("Total Idle :%10d (%3d%%) "), idletotal, percent);
+		if (aMode & KStatsCoreTotalTimeInIdle)
+			{
+			if (idletotal==TTI)
+				test.Printf(_L("PASS "));
+			else
+				test.Printf(_L("FAIL!"));
+			}
+		test.Printf(_L("\n\n"));
+		}
+
+	if (aMode & KStatsCoreNumTimesInIdle)
+		{
+		test.Printf(_L("Numer times in idle :"));
+		for (core=0; core<gCores; core++)
+			{
+			test.Console()->SetPos(22);
+			test.Printf(_L(" %d: %6d \n"),core,*pVal);
+			pVal++;
+			}
+		test.Printf(_L(" \n"));	
+		}
+
+	if (aMode & KStatsNumEvents)
+		{	
+		test.Printf(_L("Number of Events    : %d   \n"),*pVal);
+		pVal++;
+		}
+
+
+
+	if (aMode & KStatsReadyStateChanges)
+	{	
+		test.Printf(_L("Threads made Ready  : %d   \n"),*pVal);
+		pVal++;
+		test.Printf(_L("Threads made unready: %d   \n"),*pVal);
+		pVal++;
+	}
+
+	if (aMode & KStatsNumTimeSliceExpire)
+		test.Printf(_L("Time slices expired : %d   \n"),*pVal);
+
+	test.Printf(_L("BG threads: %d, delay %d \n"),gThreads,gDelay);
+
+	}
+	
+void InitBuff(TAny* aBuffer, TInt aSize)
+	{
+	TInt* pos = (TInt*) aBuffer;
+
+	TInt i;
+	for (i=0; i<aSize; i+=4)
+		{
+		*pos = -1;
+		pos++;
+		}
+	}
+
+RProperty gThreadsProperty;
+
+
+LOCAL_C TInt BusyThread(TAny* aThreadNo)
+	{
+	TInt threadNo= (TInt) aThreadNo;
+	TInt threadsNeeded;
+	TInt dummy=0;
+	do
+		{
+		TInt count;
+		for (count=0; count<10000; count++)
+			{
+			dummy=(dummy+count/3)/7;
+			}
+
+		gThreadsProperty.Get(threadsNeeded);
+		}
+	while (threadNo<=threadsNeeded);
+	return(KErrNone);
+	}
+
+
+
+const TInt KMaxThreads=16;
+RThread gThreadlist[KMaxThreads];
+TRequestStatus gThreadlist_stat[KMaxThreads];
+
+void AddThread()
+	{
+	if (gThreads==KMaxThreads)
+		return;
+	gThreads+=1;
+	test_KErrNone(gThreadsProperty.Set(gThreads));
+
+	test_KErrNone(gThreadlist[gThreads-1].Create(_L(""),BusyThread,KDefaultStackSize,NULL,(TAny*) gThreads));
+	gThreadlist[gThreads-1].Logon(gThreadlist_stat[gThreads-1]);
+	gThreadlist[gThreads-1].SetPriority(EPriorityLess);
+	gThreadlist[gThreads-1].Resume();
+	}
+void DecThread()
+	{
+	if (gThreads==0)
+		return;
+	gThreads-=1;
+	test_KErrNone(gThreadsProperty.Set(gThreads));
+
+	User::WaitForRequest(gThreadlist_stat[gThreads]);
+	gThreadlist[gThreads].Close();
+	}
+
+void RunTest(TInt aMode)
+	{
+	TAny* buffer;
+	TInt r;
+	gCores = UserSvr::HalFunction(EHalGroupKernel, EKernelHalNumLogicalCpus, 0, 0);
+	test_Compare(gCores, >, 0);
+
+	test.Next(_L("Load test kerncorestats LDD"));
+	r = User::LoadLogicalDevice(KLddName);
+	test_Value(r, r == KErrNone || r == KErrAlreadyExists);  
+	test.Next(_L("Open test kerncorestats LDD"));
+
+	test_KErrNone(gChan.Open());
+	
+	test.Next(_L("Call configure"));
+
+	r = gChan.Configure(aMode);
+	if (r==KErrInUse)
+		{
+		test.Printf(_L("Cannot configure KernCoreStats!!\nThis could be becouse you have already run this test since the last reboot (You can only call it once.) or that you are running a power manager that has already configured this."));
+		test.Printf(_L("Any such power manager must be disabled in order to run this test/util.\n\nPress a key.\n"));
+		test.Getch();
+		}
+	test_KErrNone(r);
+		
+
+	test.Next(_L("Call DumpInfo"));
+
+	r = gChan.DumpInfo();
+	test_NotNegative(r);
+	TInt size = r;
+
+	RProcess thisProcess;
+
+	test_KErrNone(RProperty::Define(thisProcess.SecureId(), 0, RProperty::EInt));
+
+	test_KErrNone(gThreadsProperty.Attach(thisProcess.SecureId(), 0));
+	test_KErrNone(gThreadsProperty.Set(0));
+
+
+	test.Printf(_L("Press a key to show output\n"));
+	test.Getch();
+
+
+	test.Next(_L("Start showing output."));
+	test.Printf(_L("Press ESC to stop. u/k threads h/m delay.\n"));
+
+
+
+	buffer=User::Alloc(size);
+	test_NotNull(buffer);
+
+	CConsoleBase* con = test.Console();
+	TInt y = con->WhereY();
+	TRequestStatus s;
+	TInt keycode;
+
+	do 
+		{
+		con->Read(s);
+		while (s==KRequestPending)
+			{
+			con->SetPos(0,y);
+			InitBuff(buffer,size);
+			test_KErrNone(gChan.GetStats(buffer));
+		
+			DisplayBuf(aMode,buffer);
+			User::After(gDelay*1000);
+			};
+
+		keycode=con->KeyCode();
+		switch ((TChar) keycode)
+			{
+			case 'u': AddThread();
+			break;
+			case 'k': DecThread();
+			break;
+			case 'h': gDelay+=100;
+			break;
+			case 'm': gDelay=(gDelay>99)?gDelay-100:gDelay;
+			break;
+			}
+
+		}
+	while (keycode!=27);
+
+	test.Next(_L("Close test kerncorestats LDD"));
+	while (gThreads>0)
+		DecThread();
+
+	gThreadsProperty.Close();
+	RProperty::Delete(0);
+	gChan.Close();
+
+	test_KErrNone( User::FreeLogicalDevice(KTestKernCoreStatsName) );
+	User::Free(buffer);
+	}
+
+// -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
+
+//
+// ParseCommandLine reads the arguments and sets globals accordingly.
+//
+
+TInt ParseCommandLine()
+	{
+	TInt mode=0;
+	TInt moderead;
+	TBuf<32> args;
+	User::CommandLine(args);
+	TLex lex(args);
+	TInt err=KErrNone;
+	FOREVER
+		{
+		TPtrC token=lex.NextToken();
+		TPtrC subtoken(_L(""));
+
+		if(token.Length()!=0)
+			{
+			if ((token==_L("help")) || (token==_L("-h")) || (token==_L("/h")) || (token==_L("-?")) || (token==_L("/?")))
+				{
+				test.Printf(_L("\nThis tests kerncorestats - but not automatically.  It can only be run *ONCE* per boot.\n\n"));
+				test.Printf(_L("\n -h : Help.\n -m mode number, which specifies which stats are collected."));
+				err=KErrCancel;
+				}
+			
+			else
+				if (token==_L("-m"))
+					{
+					subtoken.Set(lex.NextToken());
+
+					TLex lexv(subtoken);
+
+					if(subtoken.Length()==0)
+						{
+						subtoken.Set(_L("<NOTHING>"));
+						err = KErrArgument;
+						}
+					else if (lexv.Val(moderead)!=KErrNone)
+						err = KErrArgument;
+					else
+						mode|=moderead;
+
+					} // endif -m
+			else
+				{
+				err = KErrArgument;
+				} // endif token 
+			}
+		else
+			break;
+		
+		if (err!=KErrNone)
+			{
+			if (err==KErrArgument)
+				test.Printf(_L("\nUnknown argument '%S%s%S'\n"), &token, (subtoken.Length()==0)?"":" ", &subtoken);
+			test.Printf(_L("\nUsage:  t_kerncorestats -m <mode>\n\n"));
+			test.Getch();
+			return err;
+			}
+		}
+
+	if (mode==0)
+		{
+		mode=63;
+		}
+
+	return mode;
+	}
+
+
+GLDEF_C TInt E32Main()
+	{
+	test.Title();
+	test.Start(_L("KernCoreStats manual test"));
+	TInt mode = ParseCommandLine();
+	if (mode>0)
+		RunTest(mode);
+   	test.End();
+
+	return KErrNone;  
+	}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/misc/t_loadsim.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,2351 @@
+// Copyright (c) 2009-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\misc\t_loadsim.cpp
+// 
+//
+
+
+//-------------------------------------------------------------------------------------------
+//! @SYMTestCaseID				KBASE-t_loadsim-2705
+//! @SYMTestCaseDesc			verifying the behaviour of the load balancer
+//! @SYMPREQ					417-52765/417-58889
+//! @SYMTestPriority			Critical
+//! @SYMTestActions				
+//! 1. This test runs a variety of loads on an SMP system. Loads types are:
+//!    1.1 Cpu intensive loads
+//!    1.2 memory intensive loads (high locality)
+//!    1.3 memory intensive loads (low locality)
+//!    1.4 memory intensive loads with atomic operations
+//!    1.5 cpu intensive loads with some serialization
+//! 2. For each test, the load is first run on a single cpu locked thread as a baseline
+//!    benchmark. Then the tests are run in the following configurations:
+//!    2.1 For n = 1 to 2*Number of cpus do a run with i threads.
+//!    2.2 For h = 1 to NumCpus ; For n = h to 2*NumCpus; run with h high priorty threads and 
+//!         n standard priority threads, with high priority threads cpu locked.
+//!    2.3 For h = 1 to NumCpus ; For n = h to 2*NumCpus; run with h high priorty threads and 
+//!         n standard priority threads.
+//! @SYMTestExpectedResults 
+//!     test passed. TTest is manual:
+//! 1. For each test we expect to see that the amount of CPU time obtained by each CPU is 
+//!     balanced. That is, all standard priority threads get roughly same amount of CPU time
+//!     and all high priority threads get roughly same amount of CPU time and a higher value
+//!     than lower priority threads.
+//! 2. We also expect the relative efficiency reported by the test between the benchmark
+//!    and each test run to be >=95% on average. Values well below this are acceptable in 
+//!    test runs involving atomic operations (1.4)
+
+//-------------------------------------------------------------------------------------------
+
+#define __E32TEST_EXTENSION__
+#include <e32test.h>
+#include <e32base.h>
+#include <hal.h>
+#include <e32atomics.h>
+#include <u32hal.h>
+#include <e32svr.h>
+
+//#define	TRACE(x)	x
+#define	TRACE(x)
+
+void Panic(TInt aLine)
+	{
+	User::Panic(_L("T_LOADSIM"),aLine);
+	}
+
+#define	assert(x)		((void)((x)||(Panic(__LINE__),0)))
+
+RTest test(_L("T_LOADSIM"));
+
+const TInt KErrCouldNotStart = -99;
+
+volatile TInt STFU = 1;
+
+/******************************************************************************
+ * Random Number Generation
+ ******************************************************************************/
+void LFSR(TUint64& a)
+	{
+	TInt i;
+	for (i=64; i>0; --i)
+		{
+		TUint64 x = a<<1;
+		TUint64 y = x<<1;
+		x^=y;
+		a = (y>>1) | (x>>63);
+		}
+	}
+
+// Returns 256*log2(a/2^64)
+TInt Log2(TUint64 a)
+	{
+	const TUint64 KBit63 = UI64LIT(0x8000000000000000);
+	TInt n = __e32_find_ms1_64(a);
+	a <<= (63-n);
+	n -= 64;
+	TInt i;
+	for (i=0; i<8; ++i)
+		{
+		a >>= 32;
+		a *= a;
+		n <<= 1;
+		if (a & KBit63)
+			{
+			++n;
+			}
+		else
+			{
+			a <<= 1;
+			}
+		}
+	return n;
+	}
+
+TUint32 ExpRV(TUint64 aU, TUint32 aMean, TUint32 aTick)
+	{
+	TInt n = -Log2(aU);
+	TUint64 x = TUint64(n) * TUint64(aMean);
+	x *= TUint64(22713);	// 2^15 * ln2
+	TUint64 p(aTick);
+	p <<= 22;
+	x += p;
+	p += p;
+	x /= p;
+	return I64LOW(x);
+	}
+
+
+
+/******************************************************************************
+ * Generic High-Resolution Timing
+ ******************************************************************************/
+class TTimestamp
+	{
+public:
+	typedef void (*TSampleFunc)(TAny*);
+public:
+	void Sample();
+	void Sample(TSampleFunc aFunc, TAny* aPtr);
+	TInt64 operator-(const TTimestamp&) const;
+	static void Init();
+private:
+	TUint32		iF;		// User::FastCounter() value
+	TUint32		iN;		// User::NTickCount() value
+private:
+	static TUint32 FF;	// User::FastCounter() frequency
+	static TUint32 NP;	// User::NTickCount() period
+	static TBool FU;	// User::FastCounter() counts up
+	static TUint32 FWrapM;	// Number of nanokernel ticks for FastCounter() to wrap / 2 * 2^FWrapS
+	static TInt FWrapS;	// Shift so that 2^31<=FWrapM<2^32
+	};
+
+TUint32	TTimestamp::FF;
+TUint32	TTimestamp::NP;
+TBool	TTimestamp::FU;
+TUint32	TTimestamp::FWrapM;
+TInt	TTimestamp::FWrapS;
+
+
+void TTimestamp::Sample()
+	{
+	TUint32 n = User::NTickCount();
+	do	{
+		iN = n;
+		iF = User::FastCounter();
+		n = User::NTickCount();
+		} while (n!=iN);
+	}
+
+void TTimestamp::Sample(TSampleFunc aFunc, TAny* aPtr)
+	{
+	TUint32 n = User::NTickCount();
+	do	{
+		iN = n;
+		(*aFunc)(aPtr);
+		iF = User::FastCounter();
+		n = User::NTickCount();
+		} while (n!=iN);
+	}
+
+// return (x*a)/b
+TUint64 scale(TUint64 x, TUint32 a, TUint32 b)
+	{
+	TUint64 mask = KMaxTUint32;
+	TUint64 x0 = x & mask;
+	TUint64 x1 = x >> 32;
+	x0 *= TUint64(a);
+	x1 *= TUint64(a);
+	x1 += (x0 >> 32);
+	x0 &= mask;
+	TUint64	q1 = x1 / TUint64(b);
+	TUint64 q0 = x1 - q1*TUint64(b);
+	q0 <<= 32;
+	q0 |= x0;
+	q0 /= TUint64(b);
+	return (q1<<32)|q0;
+	}
+
+
+// Return difference between a and this in microseconds
+TInt64 TTimestamp::operator-(const TTimestamp& a) const
+	{
+	TInt sign = 1;
+	TTimestamp start;
+	TTimestamp end;
+	if (iN-a.iN >= 0x80000000u)
+		{
+		sign = -1;
+		start = *this;
+		end = a;
+		}
+	else
+		{
+		start = a;
+		end = *this;
+		}
+	TUint32 fd32 = end.iF - start.iF;
+	if (!FU)
+		fd32 = ~fd32 + 1u;
+	TUint64 nd = TUint64(end.iN) - TUint64(start.iN);
+	nd <<= 31;	// 2^31 * difference in NTickCount
+	TUint64 x = TUint64(fd32) * TUint64(FWrapM);
+	x >>= FWrapS;	// ftick difference * (FWrapM/2^FWrapS) = 2^31 * ntick difference
+	nd -= x;	// Should now be a multiple of 2^31N where N=2^32*ftickp/ntickp
+				// i.e. should be a multiple of 2^63*ftickp/ntickp
+
+	// FWrapM = 2^(31+FWrapS)*ftickp/ntickp
+	// FWrapM << (32-FWrapS) = 2^63*ftickp/ntickp
+	TUint64 m = TUint64(FWrapM) << (32-FWrapS);
+
+	nd += (m>>1);
+	nd /= m;
+
+	nd = (nd<<32) + TUint64(fd32);	// final result in fast counter ticks
+	TInt64 r = scale(nd, 1000000, FF);	// convert to microseconds
+	if (sign<0)
+		r = -r;
+	return r;
+	}
+
+void TTimestamp::Init()
+	{
+	TInt r;
+	r = HAL::Get(HAL::ENanoTickPeriod, (TInt&)NP);
+	assert(r==KErrNone);
+	r = HAL::Get(HAL::EFastCounterFrequency, (TInt&)FF);
+	assert(r==KErrNone);
+	r = HAL::Get(HAL::EFastCounterCountsUp, (TInt&)FU);
+	assert(r==KErrNone);
+	TReal fpn = TReal(FF) * TReal(NP) / 1000000.0;	// fast counter ticks per NTick
+	TReal fwrap = 2147483648.0 / fpn;	// NTicks between fast counter wraparounds / 2
+	TInt exp = 0;
+	while (fwrap < 2147483648.0)
+		{
+		fwrap *= 2.0;
+		++exp;
+		}
+	fwrap += 0.5;
+	if (fwrap >= 4294967296.0)
+		{
+		fwrap *= 0.5;
+		--exp;
+		}
+	FWrapM = (TUint32)fwrap;
+	FWrapS = exp;	// NTicks for 2^31 fast ticks = FWrapM/2^FWrapS
+
+	test.Printf(_L("FastCounter frequency  %uHz\n"), FF);
+	if (FU)
+		test.Printf(_L("FastCounter counts     UP\n"));
+	else
+		test.Printf(_L("FastCounter counts     DOWN\n"));
+	test.Printf(_L("Nanokernel tick period %uus\n"), NP);
+	test.Printf(_L("FWrapM                 %08x\n"), FWrapM);
+	test.Printf(_L("FWrapS                 %d\n"), FWrapS);
+	}
+
+/******************************************************************************
+ * CPU Usage Measurement
+ ******************************************************************************/
+class TThreadCpuUsageSample
+	{
+public:
+	void Sample(RThread aThread);
+	TInt64 ElapsedTimeDelta(const TThreadCpuUsageSample& aStart) const;
+	TInt64 CpuTimeDelta(const TThreadCpuUsageSample& aStart) const;
+private:
+	static void SampleThreadCpuTime(TAny* aPtr);
+private:
+	TTimestamp	iElapsedTime;
+	TInt64		iCpuTime;
+	RThread		iThread;
+	};
+
+void TThreadCpuUsageSample::Sample(RThread aThread)
+	{
+	iThread = aThread;
+	iElapsedTime.Sample(&SampleThreadCpuTime, this);
+	}
+
+void TThreadCpuUsageSample::SampleThreadCpuTime(TAny* aPtr)
+	{
+	TThreadCpuUsageSample& me = *(TThreadCpuUsageSample*)aPtr;
+	TTimeIntervalMicroSeconds& rt = *(TTimeIntervalMicroSeconds*)&me.iCpuTime;
+	assert(me.iThread.GetCpuTime(rt) == KErrNone);
+	}
+
+TInt64 TThreadCpuUsageSample::ElapsedTimeDelta(const TThreadCpuUsageSample& aStart) const
+	{
+	return iElapsedTime - aStart.iElapsedTime;
+	}
+
+TInt64 TThreadCpuUsageSample::CpuTimeDelta(const TThreadCpuUsageSample& aStart) const
+	{
+	return iCpuTime - aStart.iCpuTime;
+	}
+
+class TCpuUsage
+	{
+public:
+	enum {EMaxCpus=8};
+public:
+	void Sample();
+	TInt64 ElapsedTimeDelta(const TCpuUsage& aStart) const;
+	TInt64 CpuTimeDelta(const TCpuUsage& aStart, TInt aCpu) const;
+	static TInt N() { return NumberOfCpus; }
+public:
+	static void Init();
+private:
+	static void SampleIdleTimes(TAny* aPtr);
+private:
+	TTimestamp	iElapsedTime;
+	TInt64		iIdleTime[EMaxCpus];
+private:
+	static TInt NumberOfCpus;
+	static RThread IdleThread[EMaxCpus];
+	};
+
+TInt TCpuUsage::NumberOfCpus = -1;
+RThread TCpuUsage::IdleThread[TCpuUsage::EMaxCpus];
+
+void TCpuUsage::Init()
+	{
+	TTimestamp::Init();
+
+	NumberOfCpus = UserSvr::HalFunction(EHalGroupKernel, EKernelHalNumLogicalCpus, 0, 0);
+	test.Printf(_L("NumberOfCpus = %d\n"), NumberOfCpus);
+	assert(NumberOfCpus > 0);
+	assert(NumberOfCpus <= EMaxCpus);
+
+	TTimeIntervalMicroSeconds ms;
+	TInt r;
+	r = RThread().GetCpuTime(ms);
+	if (r != KErrNone)
+		{
+		test.Printf(_L("RThread::GetCpuTime() returned %d\n"), r);
+		test.Printf(_L("This test requires a working RThread::GetCpuTime() to run\n"));
+		test(0);
+		}
+
+	TFullName kname;
+	_LIT(KLitKernelName, "ekern.exe*");
+	_LIT(KLitNull, "::Null");
+	TFindProcess fp(KLitKernelName);
+	test_KErrNone(fp.Next(kname));
+	test.Printf(_L("Found kernel process: %S\n"), &kname);
+	kname.Append(KLitNull);
+	TInt i;
+	for (i=0; i<NumberOfCpus; ++i)
+		{
+		TFullName tname(kname);
+		TFullName tname2;
+		if (i>0)
+			tname.AppendNum(i);
+		TFindThread ft(tname);
+		test_KErrNone(ft.Next(tname2));
+		TInt r = IdleThread[i].Open(ft);
+		test_KErrNone(r);
+		IdleThread[i].FullName(tname2);
+		test.Printf(_L("Found and opened %S\n"), &tname2);
+		}
+	}
+
+void TCpuUsage::Sample()
+	{
+	iElapsedTime.Sample(&SampleIdleTimes, this);
+	}
+
+void TCpuUsage::SampleIdleTimes(TAny* aPtr)
+	{
+	TCpuUsage& me = *(TCpuUsage*)aPtr;
+	assert(NumberOfCpus > 0);
+	TInt i;
+	for (i=0; i<NumberOfCpus; ++i)
+		assert(IdleThread[i].GetCpuTime((TTimeIntervalMicroSeconds&)me.iIdleTime[i]) == KErrNone);
+	}
+
+TInt64 TCpuUsage::ElapsedTimeDelta(const TCpuUsage& aStart) const
+	{
+	return iElapsedTime - aStart.iElapsedTime;
+	}
+
+TInt64 TCpuUsage::CpuTimeDelta(const TCpuUsage& aStart, TInt aCpu) const
+	{
+	assert(TUint(aCpu) < TUint(EMaxCpus));
+	if (aCpu >= NumberOfCpus)
+		return 0;
+	TInt64 idle_time = iIdleTime[aCpu] - aStart.iIdleTime[aCpu];
+	TInt64 elapsed_time = iElapsedTime - aStart.iElapsedTime;
+	return elapsed_time - idle_time;
+	}
+
+ 
+ 
+/******************************************************************************
+ * Generic CPU Consumer
+ ******************************************************************************/
+enum TCpuEaterType
+	{
+	EEaterStd				=0,		// do CPU-intensive work with few memory references
+	EEaterMemoryLocalS		=1,		// do loads of memory references with reasonable locality, shared
+	EEaterMemoryNonLocalS	=2,		// do loads of memory references with poor locality, shared
+	EEaterMemoryLocalU		=3,		// do loads of memory references with reasonable locality, unshared
+	EEaterMemoryNonLocalU	=4,		// do loads of memory references with poor locality, unshared
+	EEaterMemoryAtomic		=5,		// do loads of atomic memory references
+	EEaterMemoryAtomic2		=6,		// do loads of atomic memory references
+	EEaterAmdahl			=7,		// do CPU-intensive work interspersed with serialized sections
+	};
+
+class CDefaultCpuEater;
+
+class REaterArray;
+class MCpuEater
+	{
+public:
+	MCpuEater();
+	virtual ~MCpuEater();
+	virtual void Eat(TInt aTime, TUint32* aWorkDone)=0;
+	virtual void Calibrate();
+	inline TBool IsCalibrated() { return iCalibration!=0; }
+protected:
+	TUint32 WorkValue(TInt aTime);
+	TUint32	iCalibration;	// work value for 2^16 microseconds
+	TUint16	iInstance;
+	TUint16	iType;
+
+	friend class REaterArray;
+	};
+
+MCpuEater::MCpuEater()
+	{
+	iCalibration = 0;			// uncalibrated
+	iInstance = KMaxTUint16;	// dummy value
+	iType = KMaxTUint16;		// dummy value
+	}
+
+MCpuEater::~MCpuEater()
+	{
+	}
+
+// Calibration is for 2^KLog2CalibrateTime microseconds
+const TInt KLog2CalibrateTime = 13;
+
+TUint32 MCpuEater::WorkValue(TInt aTime)
+	{
+	if (iCalibration == 0)
+		return aTime;
+	TUint64 x = TUint64(aTime) * TUint64(iCalibration);
+	x >>= (KLog2CalibrateTime + 2);	// Factor of 4 margin for slowdowns
+	TUint32 r = I64LOW(x);
+	if (I64HIGH(x))
+		r = KMaxTUint32;
+	if (r == 0)
+		return 1;
+	if (r > iCalibration)
+		return iCalibration;
+	return r;
+	}
+
+void MCpuEater::Calibrate()
+	{
+	iCalibration = 0;
+	TUint32 work = 1;
+	TUint64 used = 1;
+	TUint64 threshold = 1;
+	threshold <<= KLog2CalibrateTime;
+	while (work)
+		{
+		TThreadCpuUsageSample initial;
+		TThreadCpuUsageSample final;
+		initial.Sample(RThread());
+		Eat(work, 0);
+		final.Sample(RThread());
+		used = final.CpuTimeDelta(initial);
+		if (used >= threshold)
+			break;
+		work <<= 1;
+		}
+	assert(work > 0);
+	TUint64 c(work);
+	c <<= KLog2CalibrateTime;
+	c /= used;
+	if (I64HIGH(c))
+		iCalibration = KMaxTUint32;
+	else if (I64LOW(c))
+		iCalibration = I64LOW(c);
+	else
+		iCalibration = 1;
+	test.Printf(_L("MCpuEater::Calibrate() %u\n"), iCalibration);
+	}
+
+
+class REaterArray : public RPointerArray<MCpuEater>
+	{
+public:
+	REaterArray();
+	void Close();
+	MCpuEater* Find(TInt aType, TInt aInstance);
+	MCpuEater* FindOrCreateL(TInt aType, TInt aInstance);
+private:
+	MCpuEater* CreateLC(TInt aType);
+private:
+	class MDummy : public MCpuEater
+		{
+	public:
+		MDummy(TInt aType, TInt aInstance)
+			{ iType=TUint16(aType); iInstance=TUint16(aInstance); }
+		virtual ~MDummy()
+			{}
+		virtual void Eat(TInt, TUint32*)
+			{}
+		};
+private:
+	static TBool Identity(const MCpuEater& aL, const MCpuEater& aR);
+	static TInt Ordering(const MCpuEater& aL, const MCpuEater& aR);
+	};
+
+REaterArray::REaterArray()
+	:	RPointerArray<MCpuEater>(8, 2*256)
+	{
+	}
+
+void REaterArray::Close()
+	{
+	ResetAndDestroy();
+	}
+
+TBool REaterArray::Identity(const MCpuEater& aL, const MCpuEater& aR)
+	{
+	return (aL.iType==aR.iType && aL.iInstance==aR.iInstance);
+	}
+
+TInt REaterArray::Ordering(const MCpuEater& aL, const MCpuEater& aR)
+	{
+	if (aL.iType > aR.iType)
+		return 1;
+	if (aL.iType < aR.iType)
+		return -1;
+	if (aL.iInstance > aR.iInstance)
+		return 1;
+	if (aL.iInstance < aR.iInstance)
+		return -1;
+	return 0;
+	}
+
+MCpuEater* REaterArray::Find(TInt aType, TInt aInstance)
+	{
+	MDummy search(aType, aInstance);
+	TInt ix = FindInOrder(&search, &Ordering);
+	if (ix < 0)
+		return 0;
+	return (*this)[ix];
+	}
+
+MCpuEater* REaterArray::FindOrCreateL(TInt aType, TInt aInstance)
+	{
+	MCpuEater* p = Find(aType, aInstance);
+	if (p)
+		return p;
+	p = CreateLC(aType);
+	p->iType = TUint16(aType);
+	p->iInstance = TUint16(aInstance);
+	InsertInOrderL(p, &Ordering);
+	CleanupStack::Pop();
+	return p;
+	}
+
+/******************************************************************************
+ * Generic zero-drift timed events
+ ******************************************************************************/
+class CLoadSim;
+class MEvent
+	{
+public:
+	MEvent(CLoadSim*, TInt);
+	virtual void Start()=0;
+	virtual ~MEvent();
+	inline TBool Queued() const
+		{ return iQueued; }
+protected:
+	void QueueAt(TUint32 aTime);
+	void QueueAfter(TUint32 aInterval);
+	void Dequeue();
+	virtual TInt Event();
+	inline TUint64 Random();
+protected:
+	TUint8		iId;
+	TUint8		iQueued;
+	TUint8		iE1;
+	TUint8		iE2;
+	MEvent*		iChain;
+	CLoadSim*	iT;
+	TUint32		iNextEventTime;
+	friend class CLoadSim;
+	};
+
+class CLoadSim : public CActive
+	{
+public:
+	static CLoadSim* NewL();
+	~CLoadSim();
+	inline TInt TimerPeriod() const
+		{ return iTimerPeriod; }
+	TUint64 Random();
+private:
+	CLoadSim();
+	virtual void RunL();
+	virtual void DoCancel();
+	void StartTimer();
+private:
+	RTimer		iTimer;
+	TUint64		iSeed;
+	MEvent*		iNextEvent;
+	TUint32		iIterations;
+	TUint32		iLastTrigger;		// Last trigger time in ticks
+	TInt		iCarry;
+	TInt		iTimerPeriod;		// Timer tick period in microseconds
+	TInt		iMaxDelta;
+	TUint8		iInRunL;
+	TUint8		iTimerRunning;
+	TUint8		iTimerInit;
+	TUint8		iOffsetInit;
+	TUint32		iOffset;
+private:
+	friend class MEvent;
+	};
+
+inline TUint64 MEvent::Random()
+	{ return iT->Random(); }
+
+CLoadSim::CLoadSim()
+	: CActive(EPriorityStandard)
+	{
+	iSeed = 0xadf85458;
+	assert(HAL::Get(HAL::ENanoTickPeriod, iTimerPeriod)==KErrNone);
+	iMaxDelta = KMaxTInt / (2*iTimerPeriod);
+	}
+
+CLoadSim::~CLoadSim()
+	{
+	Cancel();
+	iTimer.Close();
+	}
+
+CLoadSim* CLoadSim::NewL()
+	{
+	CLoadSim* p = new (ELeave) CLoadSim();
+	CleanupStack::PushL(p);
+	User::LeaveIfError(p->iTimer.CreateLocal());
+	CleanupStack::Pop();
+	return p;
+	}
+
+void CLoadSim::DoCancel()
+	{
+	iTimer.Cancel();
+	iTimerRunning = 0;
+	}
+
+void CLoadSim::RunL()
+	{
+	TRACE(RDebug::Printf("!%d\n", iStatus.Int()));
+	iTimerRunning = 0;
+	iInRunL = 1;
+	TUint32 now = iLastTrigger;
+	if (iStatus == KErrNone)
+		{
+		now += iCarry;
+		iLastTrigger = now;
+		}
+	else if (iStatus == KErrArgument)
+		{
+		now += iCarry;
+		}
+	else if (iStatus == KErrCancel)
+		{
+		iLastTrigger += iCarry;	// trigger time was still updated
+		}
+	iCarry = 0;
+	MEvent* e = 0;
+	FOREVER
+		{
+		++iIterations;
+		e = iNextEvent;
+		if (!e || e->iNextEventTime>now)
+			break;
+		iNextEvent = e->iChain;
+		e->iChain = 0;
+		e->iQueued = 0;
+		e->Event();
+		}
+	if (e)
+		{
+		TInt delta = TInt(e->iNextEventTime - iLastTrigger);
+		if (delta > iMaxDelta)
+			delta = iMaxDelta;
+		if (delta < -iMaxDelta)
+			delta = -iMaxDelta;
+		iCarry = delta;
+		TInt us = delta * iTimerPeriod;
+		TRACE(RDebug::Printf("T+%d\n", us));
+		iTimer.AgainHighRes(iStatus, us);
+		SetActive();
+		iTimerRunning = 1;
+		}
+	iInRunL = 0;
+	}
+
+void CLoadSim::StartTimer()
+	{
+	if (iInRunL)
+		return;
+	if (iTimerRunning)
+		{
+		TRACE(RDebug::Printf("TC\n"));
+		iTimer.Cancel();	// will cause RunL with KErrCancel which will restart timer
+		return;
+		}
+	TInt delta = TInt(iNextEvent->iNextEventTime - iLastTrigger);
+	if (delta > iMaxDelta)
+		delta = iMaxDelta;
+	if (delta < -iMaxDelta)
+		delta = -iMaxDelta;
+	iCarry = delta;
+	TInt us = delta * iTimerPeriod;
+	if (iTimerInit)
+		{
+		TRACE(RDebug::Printf("sT+%d\n", us));
+		iTimer.AgainHighRes(iStatus, us);
+		}
+	else
+		{
+		if (!iOffsetInit)
+			iOffsetInit=1, iOffset=User::NTickCount();
+		TRACE(RDebug::Printf("sT++%d\n", us));
+		iTimer.HighRes(iStatus, us);
+		iTimerInit = 1;
+		}
+	SetActive();
+	iTimerRunning = 1;
+	}
+
+TUint64 CLoadSim::Random()
+	{
+	LFSR(iSeed);
+	TUint32 h = I64HIGH(iSeed);
+	TUint32 l = I64LOW(iSeed);
+	h *= 0x9e3779b9u;
+	l *= 0x9e3779b9u;
+	return MAKE_TUINT64(l,h);
+	}
+
+MEvent::MEvent(CLoadSim* aT, TInt aId)
+	{
+	iId = (TUint8)aId;
+	iQueued = 0;
+	iE1 = 0;
+	iE2 = 0;
+	iChain = 0;
+	iT = aT;
+	iNextEventTime = 0;
+	}
+
+MEvent::~MEvent()
+	{
+	if (iT)
+		Dequeue();
+	}
+
+void MEvent::QueueAt(TUint32 aTime)
+	{
+	TRACE(RDebug::Printf("Q%d@%u\n", iId, aTime));
+	if (iQueued)
+		Dequeue();
+	MEvent** p = &iT->iNextEvent;
+	MEvent* e = iT->iNextEvent;
+	for (; e && e->iNextEventTime <= aTime; p=&e->iChain, e=e->iChain)
+		{}
+	iChain = e;
+	*p = this;
+	iNextEventTime = aTime;
+	iQueued = 1;
+	if (iT->iNextEvent==this && !iT->iInRunL)
+		iT->StartTimer();
+	}
+
+void MEvent::QueueAfter(TUint32 aInterval)
+	{
+	TRACE(RDebug::Printf("Q%d+%u\n", iId, aInterval));
+	TUint32 now = User::NTickCount();
+	if (!iT->iTimerInit)
+		iT->iOffset=now, iT->iOffsetInit=1;
+	QueueAt(now-iT->iOffset+aInterval);
+	}
+
+void MEvent::Dequeue()
+	{
+	TRACE(RDebug::Printf("DQ%d\n", iId));
+	if (!iQueued)
+		return;
+	MEvent* e = iT->iNextEvent;
+	for (; e && e->iChain!=this; e=e->iChain)
+		{}
+	if (e)
+		{
+		e->iChain = iChain;
+		}
+	iChain = 0;
+	iQueued = 0;
+	}
+
+TInt MEvent::Event()
+	{
+	TRACE(RDebug::Printf("*%d\n", iId));
+	return iId;
+	}
+
+
+
+/******************************************************************************
+ * Poisson process simulation
+ ******************************************************************************/
+class MDiscretePoisson : public MEvent
+	{
+public:
+	MDiscretePoisson(CLoadSim* aT, TInt aId, TUint32 aMicroseconds);
+	~MDiscretePoisson();
+	virtual void Start();
+	virtual TInt Event();
+	virtual void PoissonEvent();
+public:
+	TUint32		iUs;
+	TBool		iContinue;
+	};
+
+MDiscretePoisson::MDiscretePoisson(CLoadSim* aT, TInt aId, TUint32 aMicroseconds)
+	:	MEvent(aT, aId)
+	{
+	iUs = aMicroseconds;
+	iContinue = EFalse;
+	}
+
+MDiscretePoisson::~MDiscretePoisson()
+	{
+	}
+
+void MDiscretePoisson::Start()
+	{
+	iContinue = ETrue;
+	TUint32 gap = ExpRV(Random(), iUs, iT->TimerPeriod());
+	TRACE(RDebug::Printf("GG%u\n", gap));
+	QueueAt(iNextEventTime + gap);
+	}
+
+TInt MDiscretePoisson::Event()
+	{
+	PoissonEvent();
+	if (iContinue)
+		Start();
+	return MEvent::Event();
+	}
+
+void MDiscretePoisson::PoissonEvent()
+	{
+	}
+
+
+
+/******************************************************************************
+ * Consume a specified amount of CPU time in either a continuous
+ * or 'staccato' fashion (i.e. in irregular intervals punctuated by gaps)
+ ******************************************************************************/
+class CStaccatoCpuEater : public CActive, public MEvent
+	{
+public:
+	CStaccatoCpuEater(CLoadSim* aT, MCpuEater* aE, TUint32 aGranularity, TUint32 aMeanGap);
+	~CStaccatoCpuEater();
+	void EatMore(TInt64 aMicroseconds);
+	TUint32 WorkDone() const { return iWorkDone; }
+	TUint32 Invocations() const { return iInvocations; }
+private:
+	virtual void RunL();
+	virtual void DoCancel();
+	virtual void Start();
+	virtual TInt Event();
+	void StartEating();
+private:
+	MCpuEater* iE;
+	TUint32 iWorkDone;
+	TUint32 iInvocations;
+	TUint32 iGranularity;
+	TUint32 iMeanGap;
+	TBool iEating;
+	TInt64 iRemainingCpuTime;
+	TTimeIntervalMicroSeconds iInitialCpuTime;
+	TTimeIntervalMicroSeconds iFinalCpuTime;
+	TInt64 iTotalCpuTime;
+	};
+
+CStaccatoCpuEater::CStaccatoCpuEater(CLoadSim* aT, MCpuEater* aE, TUint32 aGranularity, TUint32 aMeanGap)
+	:	CActive(EPriorityIdle),
+		MEvent(aT, 0x53)
+	{
+	iE = aE;
+	iWorkDone = 0;
+	iInvocations = 0;
+	iGranularity = aGranularity;
+	iMeanGap = aMeanGap;
+	iEating = EFalse;
+	iRemainingCpuTime = 0;
+	}
+
+CStaccatoCpuEater::~CStaccatoCpuEater()
+	{
+	Cancel();
+	}
+
+void CStaccatoCpuEater::EatMore(TInt64 aMicroseconds)
+	{
+	TRACE(RDebug::Printf("E+%08x %08x\n", I64HIGH(aMicroseconds), I64LOW(aMicroseconds)));
+	iRemainingCpuTime += aMicroseconds;
+	if (!Queued() && !iEating && iRemainingCpuTime>0)
+		StartEating();
+	}
+
+void CStaccatoCpuEater::RunL()
+	{
+	TInt time = KMaxTInt;
+	if (iRemainingCpuTime < TInt64(KMaxTInt))
+		time = I64LOW(iRemainingCpuTime);
+	++iInvocations;
+	iE->Eat(time, &iWorkDone);
+	TTimeIntervalMicroSeconds ms;
+	TInt r = RThread().GetCpuTime(ms);
+	assert(r==KErrNone);
+	if (ms < iFinalCpuTime)
+		{
+		SetActive();
+		TRequestStatus* pS = &iStatus;
+		User::RequestComplete(pS, 0);
+		return;
+		}
+	iEating = EFalse;
+	TInt64 delta = ms.Int64() - iInitialCpuTime.Int64();
+	iRemainingCpuTime -= delta;
+	iTotalCpuTime += delta;
+	TRACE(RDebug::Printf("D=%8u T=%10u\n",I64LOW(delta),I64LOW(iTotalCpuTime)));
+	if (iRemainingCpuTime > 0)
+		{
+		TUint32 gap = ExpRV(Random(), iMeanGap, iT->TimerPeriod());
+		TRACE(RDebug::Printf("G%u\n", gap));
+		QueueAfter(gap);
+		}
+	}
+
+void CStaccatoCpuEater::DoCancel()
+	{
+	MEvent::Dequeue();
+	iEating = EFalse;
+	}
+
+void CStaccatoCpuEater::Start()
+	{
+	}
+
+TInt CStaccatoCpuEater::Event()
+	{
+	if (!iEating && iRemainingCpuTime>0)
+		{
+		StartEating();
+		}
+	return MEvent::Event();
+	}
+
+void CStaccatoCpuEater::StartEating()
+	{
+	iEating = ETrue;
+	TInt r = RThread().GetCpuTime(iInitialCpuTime);
+	assert(r==KErrNone);
+	if (iGranularity)
+		{
+		TInt howmuch = ExpRV(iT->Random(), iGranularity, 1);
+		TRACE(RDebug::Printf("SE+%08x\n", howmuch));
+		iFinalCpuTime = iInitialCpuTime.Int64() + TInt64(howmuch);
+		}
+	else
+		iFinalCpuTime = iInitialCpuTime.Int64() + iRemainingCpuTime;	// continuous CPU use
+	SetActive();
+	TRequestStatus* pS = &iStatus;
+	User::RequestComplete(pS, 0);
+	}
+
+
+
+/******************************************************************************
+ * Consume CPU time in a bursty fashion
+ ******************************************************************************/
+class CBurstyCpuEater : public CStaccatoCpuEater, public MDiscretePoisson
+	{
+public:
+	struct SParams
+		{
+		MCpuEater*	iE;
+		TUint32		iGranularity;
+		TUint32		iMeanIntraBurstGap;
+		TUint32		iMeanBurstLength;
+		TUint32		iMeanInterBurstGap;
+		};
+public:
+	CBurstyCpuEater(CLoadSim* aT, const SParams& aParams);
+	~CBurstyCpuEater();
+	virtual void Start();
+	virtual void PoissonEvent();
+public:
+	TUint32		iMeanBurstLength;
+	TUint32		iMeanInterBurstGap;
+	};
+
+CBurstyCpuEater::CBurstyCpuEater(CLoadSim* aT, const SParams& aParams)
+	:	CStaccatoCpuEater(aT, aParams.iE, aParams.iGranularity, aParams.iMeanIntraBurstGap),
+		MDiscretePoisson(aT, 0x42, aParams.iMeanInterBurstGap)
+	{
+	iMeanBurstLength = aParams.iMeanBurstLength;
+	iMeanInterBurstGap = aParams.iMeanInterBurstGap;
+	}
+
+CBurstyCpuEater::~CBurstyCpuEater()
+	{
+	}
+
+void CBurstyCpuEater::Start()
+	{
+	if (iMeanInterBurstGap > 0)
+		{
+		PoissonEvent();
+		MDiscretePoisson::Start();
+		}
+	else
+		{
+		EatMore(iMeanBurstLength);	// one single burst
+		}
+	}
+
+void CBurstyCpuEater::PoissonEvent()
+	{
+	TInt burstLen = ExpRV(CStaccatoCpuEater::Random(), iMeanBurstLength, 1);
+	EatMore(burstLen);
+	}
+
+
+
+/******************************************************************************
+ * Stop the active scheduler after a certain time
+ ******************************************************************************/
+class CTimedStopper : public CActive
+	{
+public:
+	static CTimedStopper* NewL();
+	~CTimedStopper();
+	void Start(TInt64 aMicroseconds);
+private:
+	CTimedStopper();
+	virtual void RunL();
+	virtual void DoCancel();
+private:
+	RTimer	iTimer;
+	};
+
+CTimedStopper::CTimedStopper()
+	:	CActive(EPriorityHigh)
+	{
+	}
+
+CTimedStopper::~CTimedStopper()
+	{
+	Cancel();
+	iTimer.Close();
+	}
+
+CTimedStopper* CTimedStopper::NewL()
+	{
+	CTimedStopper* p = new (ELeave) CTimedStopper();
+	CleanupStack::PushL(p);
+	User::LeaveIfError(p->iTimer.CreateLocal());
+	CleanupStack::Pop();
+	return p;
+	}
+
+void CTimedStopper::DoCancel()
+	{
+	iTimer.Cancel();
+	}
+
+void CTimedStopper::RunL()
+	{
+	CActiveScheduler::Stop();
+	}
+
+void CTimedStopper::Start(TInt64 aMicroseconds)
+	{
+	TInt p = (TInt)aMicroseconds;
+	iTimer.HighRes(iStatus, p);
+	SetActive();
+	}
+
+
+
+
+
+/******************************************************************************
+ * Do something CPU intensive to consume CPU time
+ ******************************************************************************/
+class CDefaultCpuEater : public CBase, public MCpuEater
+	{
+public:
+	CDefaultCpuEater();
+	~CDefaultCpuEater();
+	virtual void Eat(TInt aTime, TUint32* aWorkDone);
+protected:
+	TUint64 iX;
+	};
+
+CDefaultCpuEater::CDefaultCpuEater()
+	{
+	iX = 1;
+	}
+
+CDefaultCpuEater::~CDefaultCpuEater()
+	{
+	}
+
+void CDefaultCpuEater::Eat(TInt aTime, TUint32* aWorkDone)
+	{
+	const TUint64 KMagic = UI64LIT(0x9e3779b97f4a7c15);
+	TUint32 work = WorkValue(aTime);
+	if (aWorkDone)
+		*aWorkDone += work;
+	while (work--)
+		iX *= KMagic;
+	}
+
+
+
+/******************************************************************************
+ * Do something CPU intensive to consume CPU time, partially serialized
+ ******************************************************************************/
+class CAmdahlCpuEater : public CDefaultCpuEater
+	{
+public:
+	static CAmdahlCpuEater* NewLC();
+	~CAmdahlCpuEater();
+	virtual void Eat(TInt aTime, TUint32* aWorkDone);
+protected:
+	CAmdahlCpuEater();
+	void ConstructL();
+protected:
+	RMutex iMutex;
+	TUint32 iFactor;
+	};
+
+CAmdahlCpuEater::CAmdahlCpuEater()
+	{
+	}
+
+CAmdahlCpuEater::~CAmdahlCpuEater()
+	{
+	iMutex.Close();
+	}
+
+CAmdahlCpuEater* CAmdahlCpuEater::NewLC()
+	{
+	CAmdahlCpuEater* p = new (ELeave) CAmdahlCpuEater();
+	CleanupStack::PushL(p);
+	p->ConstructL();
+	return p;
+	}
+
+void CAmdahlCpuEater::ConstructL()
+	{
+	User::LeaveIfError(iMutex.CreateLocal());
+	iFactor = KMaxTUint32 / (4*TCpuUsage::N());
+	}
+
+void CAmdahlCpuEater::Eat(TInt aTime, TUint32* aWorkDone)
+	{
+	TUint64 t(aTime);
+	t *= TUint64(iFactor);
+	t += TUint64(0x80000000u);
+	t >>= 32;
+	TInt stime = I64LOW(t);
+	if (IsCalibrated())
+		{
+		iMutex.Wait();
+		CDefaultCpuEater::Eat(stime, aWorkDone);
+		aTime -= stime;
+		iMutex.Signal();
+		}
+	CDefaultCpuEater::Eat(aTime, aWorkDone);
+	}
+
+
+
+/******************************************************************************
+ * Do something memory intensive to consume CPU time
+ ******************************************************************************/
+class CMemoryBandwidthEater : public CBase, public MCpuEater
+	{
+public:
+	static CMemoryBandwidthEater* NewLC(TUint32 aSize, TUint32 aRegionSize, TUint32 aRegionOffset);
+	~CMemoryBandwidthEater();
+	virtual void Calibrate();
+protected:
+	CMemoryBandwidthEater(TUint32 aSize, TUint32 aRegionSize, TUint32 aRegionOffset);
+	void ConstructL();
+	virtual void Eat(TInt aTime, TUint32* aWorkDone);
+	TAny* At(TUint32 aRegion, TUint32 aIndex);
+	TAny* StepWithinRegion(TAny* aInitial, TUint32 aStep);
+protected:
+	volatile TUint32 iRegionAlloc;
+	TUint32 iPageSize;
+	TUint32 iSize;				// multiple of page size
+	TAny* iData;				// page aligned
+	RChunk iChunk;
+	TUint8 iLog2RegionSize;		// log2(bytes per region)
+	TUint8 iLog2RO;				// log2(offset from region n to n+1 in bytes)
+	TUint8 iLog2PageSize;
+	TUint8 iRegionBits;			// number of bits to specify region
+	TUint32 iNRgn;
+	TUint32 iRegionMask;
+	TUint32 iLowerIndexMask;
+	TUint32 iUpperIndexMask;
+	};
+
+TUint32 AtomicClearLS1(volatile TUint32* aMask)
+	{
+	TUint32 initial = *aMask;
+	TUint32 final;
+	do	{
+		final = initial & (initial-1);
+		} while(!__e32_atomic_cas_ord32(aMask, &initial, final));
+	return initial;
+	}
+
+TInt AtomicAllocBit(volatile TUint32* aMask)
+	{
+	return __e32_find_ls1_32(AtomicClearLS1(aMask));
+	}
+
+TUint32 AtomicFreeBit(volatile TUint32* aMask, TInt aBit)
+	{
+	return __e32_atomic_ior_ord32(aMask, 1u<<aBit);
+	}
+
+
+
+CMemoryBandwidthEater* CMemoryBandwidthEater::NewLC(TUint32 aSize, TUint32 aRegionSize, TUint32 aRegionOffset)
+	{
+	CMemoryBandwidthEater* p = new (ELeave) CMemoryBandwidthEater(aSize, aRegionSize, aRegionOffset);
+	CleanupStack::PushL(p);
+	p->ConstructL();
+	return p;
+	}
+
+CMemoryBandwidthEater::CMemoryBandwidthEater(TUint32 aSize, TUint32 aRegionSize, TUint32 aRegionOffset)
+	{
+	TInt r = HAL::Get(HAL::EMemoryPageSize, (TInt&)iPageSize);
+	assert(r==KErrNone);
+	iLog2PageSize = (TUint8)__e32_find_ms1_32(iPageSize);
+	assert( !(aRegionSize & (aRegionSize-1)) );
+	assert( !(aRegionOffset & (aRegionOffset-1)) );
+	iLog2RegionSize = (TUint8)__e32_find_ms1_32(aRegionSize);
+	iLog2RO = (TUint8)__e32_find_ms1_32(aRegionOffset);
+	TUint32 round = (aRegionSize>iPageSize) ? aRegionSize : iPageSize;
+	iSize = (aSize + round - 1) &~ (round - 1);
+	--iSize;
+	iSize |= (iSize>>1);
+	iSize |= (iSize>>2);
+	iSize |= (iSize>>4);
+	iSize |= (iSize>>8);
+	iSize |= (iSize>>16);
+	++iSize;
+	iNRgn = iSize >> iLog2RegionSize;
+	if (iNRgn>=32)
+		iRegionAlloc = ~0u;
+	else
+		iRegionAlloc = ~((~0u)<<iNRgn);
+	iRegionBits = TUint8(1 + __e32_find_ms1_32(iNRgn-1));
+	iLowerIndexMask = ~((~0u)<<iLog2RO);
+	iRegionMask = (~((~0u)<<iRegionBits))<<iLog2RO;
+	iUpperIndexMask = ((iSize-1)>>(iRegionBits+iLog2RO))<<(iRegionBits+iLog2RO);
+	}
+
+CMemoryBandwidthEater::~CMemoryBandwidthEater()
+	{
+	iChunk.Close();
+	}
+
+void CMemoryBandwidthEater::ConstructL()
+	{
+	TInt mask = (1<<20)-1;
+	TInt maxSize = (TInt(iSize)+mask)&~mask;
+	User::LeaveIfError(iChunk.CreateLocal(iSize, maxSize, EOwnerThread));
+	iData = iChunk.Base();
+	}
+
+void CMemoryBandwidthEater::Calibrate()
+	{
+	MCpuEater::Calibrate();
+	MCpuEater::Calibrate();
+	}
+
+TAny* CMemoryBandwidthEater::At(TUint32 aRegion, TUint32 aIndex)
+	{
+	TUint32 offset = aIndex & iLowerIndexMask;
+	offset |= (aRegion<<iLog2RO);
+	offset |= ((aIndex<<iRegionBits) & iUpperIndexMask);
+	return ((TUint8*)iData) + offset;
+	}
+
+TAny* CMemoryBandwidthEater::StepWithinRegion(TAny* aInitial, TUint32 aStep)
+	{
+	TUintPtr offset = TUintPtr(aInitial) - TUintPtr(iData);
+	TUintPtr offset2 = offset + (aStep & iLowerIndexMask);
+	if ((offset^offset2)&iRegionMask)
+		{
+		offset2 -= (iLowerIndexMask+1);
+		aStep += (iLowerIndexMask+1);
+		}
+	offset2 += ((aStep<<iRegionBits)&iUpperIndexMask);
+	offset2 &= (iSize-1);
+	return ((TUint8*)iData) + offset2;
+	}
+
+void CMemoryBandwidthEater::Eat(TInt aTime, TUint32* aWorkDone)
+	{
+	TUint32 work = WorkValue(aTime);
+	if (aWorkDone)
+		*aWorkDone += work;
+	TInt region = AtomicAllocBit(&iRegionAlloc);
+	assert(region>=0);
+	TUint32 done = 0;
+	TUint32 rgnsz = 1u << iLog2RegionSize;
+	for (; work; work-=done)
+		{
+		done = (work>rgnsz) ? rgnsz : work;
+		TUint8* p = (TUint8*)At(region,0);
+		TUint8 prev = *p;
+		TUint32 n = done;
+		do	{
+			TUint8* q = p;
+			p = (TUint8*)StepWithinRegion(p, 31);
+			*q = *p;
+			} while(--n);
+		*p = prev;
+		}
+	AtomicFreeBit(&iRegionAlloc, region);
+	}
+
+
+/******************************************************************************
+ * Do lots of atomic operations to consume CPU time
+ ******************************************************************************/
+class CAtomicMemoryBandwidthEater : public CMemoryBandwidthEater
+	{
+public:
+	static CAtomicMemoryBandwidthEater* NewLC(TUint32 aSize);
+	~CAtomicMemoryBandwidthEater();
+protected:
+	CAtomicMemoryBandwidthEater(TUint32 aSize);
+	void ConstructL();
+	virtual void Eat(TInt aTime, TUint32* aWorkDone);
+protected:
+	volatile TUint32 iX;
+	};
+
+CAtomicMemoryBandwidthEater* CAtomicMemoryBandwidthEater::NewLC(TUint32 aSize)
+	{
+	CAtomicMemoryBandwidthEater* p = new (ELeave) CAtomicMemoryBandwidthEater(aSize);
+	CleanupStack::PushL(p);
+	p->ConstructL();
+	return p;
+	}
+
+CAtomicMemoryBandwidthEater::CAtomicMemoryBandwidthEater(TUint32 aSize)
+	:	CMemoryBandwidthEater(aSize, aSize, aSize)
+	{
+	iX = TUint32(this) ^ RThread().Id().operator TUint();
+	iX *= 0x9e3779b9u;
+	}
+
+CAtomicMemoryBandwidthEater::~CAtomicMemoryBandwidthEater()
+	{
+	}
+
+void CAtomicMemoryBandwidthEater::ConstructL()
+	{
+	CMemoryBandwidthEater::ConstructL();
+	}
+
+TUint32 AtomicRandom(volatile TUint32* a)
+	{
+	TUint32 initial = *a;
+	TUint32 final;
+	do	{
+		final = 69069*initial + 41;
+		} while(!__e32_atomic_cas_ord32(a, &initial, final));
+	return final;
+	}
+
+void CAtomicMemoryBandwidthEater::Eat(TInt aTime, TUint32* aWorkDone)
+	{
+	TUint32 work = WorkValue(aTime);
+	if (aWorkDone)
+		*aWorkDone += work;
+	volatile TUint32* pW = (volatile TUint32*)iData;
+	const TUint32 mask = iSize/sizeof(TUint32)-1;
+	TUint32 x = AtomicRandom(&iX);
+	TUint32 n = work;
+	do	{
+		TUint32 offset = (x>>2) & mask;
+		x = 69069*x+41;
+		__e32_atomic_add_rlx32(pW+offset, 1);
+		} while(--n);
+	}
+
+
+/******************************************************************************
+ *
+ ******************************************************************************/
+struct SThreadResult
+	{
+	TUint64		iElapsedTime;
+	TUint64		iCpuTime;
+	TUint32		iWorkDone;
+	TUint32		iInvocations;
+	};
+
+struct SThreadParams
+	{
+	TInt64		iTestTime;
+
+	TInt		iId;
+	TUint32		iCpuAffinity;
+
+	TInt		iPriority;
+	RSemaphore	iTurnstile;
+
+	SThreadResult* iResult;
+	TInt		iGroupId;
+
+	MCpuEater*	iE;
+	TUint32		iGranularity;
+	TUint32		iMeanIntraBurstGap;
+	TUint32		iMeanBurstLength;
+	TUint32		iMeanInterBurstGap;
+	};
+
+class MThreadCompletion
+	{
+public:
+	virtual void Complete(TBool aOk, SThreadParams* aParams)=0;
+	};
+
+class CThreadI : public CBase
+	{
+public:
+	CThreadI();
+	~CThreadI();
+	static TInt ThreadFunc(TAny* aPtr);
+	TInt Run();
+	void InitL();
+public:
+	CTrapCleanup*		iCleanup;
+	CActiveScheduler*	iAS;
+	CLoadSim*			iL;
+	CBurstyCpuEater*	iB;
+	CTimedStopper*		iStopper;
+	RSemaphore			iTurnstile;
+	SThreadParams*		iParams;
+	};
+
+CThreadI::CThreadI()
+	{
+	}
+
+CThreadI::~CThreadI()
+	{
+	iTurnstile.Close();
+	delete iStopper;
+	delete iB;
+	delete iL;
+	delete iAS;
+	delete iCleanup;
+	}
+
+TInt CThreadI::ThreadFunc(TAny* aPtr)
+	{
+	CThreadI* p = new CThreadI;
+	if (!p)
+		return KErrNoMemory;
+	p->iParams = (SThreadParams*)aPtr;
+	return p->Run();
+	}
+
+void CThreadI::InitL()
+	{
+	iTurnstile = iParams->iTurnstile;
+	User::LeaveIfError(iTurnstile.Duplicate(RThread(), EOwnerThread));
+	iAS = new (ELeave) CActiveScheduler;
+	CActiveScheduler::Install(iAS);
+	iL = CLoadSim::NewL();
+	CActiveScheduler::Add(iL);
+	const CBurstyCpuEater::SParams* params = (const CBurstyCpuEater::SParams*)&iParams->iE;
+	iB = new (ELeave) CBurstyCpuEater(iL, *params);
+	CActiveScheduler::Add(iB);
+	iStopper = CTimedStopper::NewL();
+	CActiveScheduler::Add(iStopper);
+	memclr(iParams->iResult, sizeof(*iParams->iResult));
+	RThread().SetPriority(TThreadPriority(iParams->iPriority));
+	UserSvr::HalFunction(EHalGroupKernel, EKernelHalLockThreadToCpu, (TAny*)iParams->iCpuAffinity, 0);
+	}
+
+TInt CThreadI::Run()
+	{
+	iCleanup = CTrapCleanup::New();
+	if (!iCleanup)
+		return KErrNoMemory;
+	TRAPD(r,InitL());
+	if (r == KErrNone)
+		{
+		TThreadCpuUsageSample initial;
+		TThreadCpuUsageSample final;
+		RThread::Rendezvous(KErrNone);
+		iTurnstile.Wait();
+		iB->Start();
+		initial.Sample(RThread());
+		iStopper->Start(iParams->iTestTime);
+		CActiveScheduler::Start();
+		final.Sample(RThread());
+		iParams->iResult->iWorkDone = iB->WorkDone();
+		iParams->iResult->iInvocations = iB->Invocations();
+		iParams->iResult->iElapsedTime = final.ElapsedTimeDelta(initial);
+		iParams->iResult->iCpuTime = final.CpuTimeDelta(initial);
+		}
+	delete this;
+	return r;
+	}
+
+
+/******************************************************************************
+ *
+ ******************************************************************************/
+class CThreadX : public CActive
+	{
+public:
+	static CThreadX* NewL(SThreadParams* aParams, MThreadCompletion* aComplete);
+	static CThreadX* NewLC(SThreadParams* aParams, MThreadCompletion* aComplete);
+	CThreadX();
+	~CThreadX();
+	void ConstructL();
+	virtual void RunL();
+	virtual void DoCancel();
+public:
+	RThread				iThread;
+	RTimer				iTimer;
+	SThreadParams*		iParams;
+	MThreadCompletion*	iComplete;
+	};
+
+CThreadX::CThreadX()
+	:	CActive(EPriorityStandard)
+	{
+	}
+
+CThreadX::~CThreadX()
+	{
+	Cancel();
+	iTimer.Close();
+	iThread.Close();
+	}
+
+CThreadX* CThreadX::NewL(SThreadParams* aParams, MThreadCompletion* aComplete)
+	{
+	CThreadX* p = NewLC(aParams, aComplete);
+	CleanupStack::Pop();
+	return p;
+	}
+
+CThreadX* CThreadX::NewLC(SThreadParams* aParams, MThreadCompletion* aComplete)
+	{
+	CThreadX* p = new (ELeave) CThreadX();
+	p->iParams = aParams;
+	p->iComplete = aComplete;
+	CleanupStack::PushL(p);
+	p->ConstructL();
+	return p;
+	}
+
+const TInt KThreadHeapMin = 0x1000;
+const TInt KThreadHeapMax = 0x200000;
+void CThreadX::ConstructL()
+	{
+	CActiveScheduler::Add(this);
+	TRequestStatus s0, s1;
+	User::LeaveIfError(iTimer.CreateLocal());
+	User::LeaveIfError(iThread.Create(KNullDesC, &CThreadI::ThreadFunc, 0x1000, KThreadHeapMin, KThreadHeapMax, iParams));
+	iThread.Rendezvous(s1);
+	if (s1!=KRequestPending)
+		{
+		User::WaitForRequest(s1);
+		User::Leave(s1.Int());
+		}
+	iTimer.After(s0, 5*1000*1000);
+	iThread.Resume();
+	User::WaitForRequest(s0, s1);
+	if (s1==KRequestPending)
+		{
+		iThread.Terminate(KErrCouldNotStart);
+		User::WaitForRequest(s1);
+		User::Leave(KErrTimedOut);
+		}
+	iTimer.Cancel();
+	User::WaitForRequest(s0);
+	if (iThread.ExitType() != EExitPending)
+		{
+		User::Leave(KErrDied);
+		}
+	iThread.Logon(iStatus);
+	if (iStatus!=KRequestPending)
+		{
+		User::WaitForRequest(iStatus);
+		User::Leave(iStatus.Int());
+		}
+	SetActive();
+	User::LeaveIfError(s1.Int());
+	}
+
+void CThreadX::DoCancel()
+	{
+	iThread.Terminate(KErrCouldNotStart);
+	}
+
+void CThreadX::RunL()
+	{
+	TBool ok = ETrue;
+	if (iThread.ExitType() != EExitKill)
+		ok = EFalse;
+	if (iThread.ExitReason() != KErrNone)
+		ok = EFalse;
+	if (iComplete)
+		iComplete->Complete(ok, iParams);
+	}
+
+
+/******************************************************************************
+ *
+ ******************************************************************************/
+struct STestThreadDesc
+	{
+	TUint32		iCpuAffinity;
+	TInt		iPriority;
+	TInt		iGroupId;
+	TUint16		iEaterType;
+	TUint16		iEaterInstance;
+	TUint32		iGranularity;
+	TUint32		iMeanIntraBurstGap;
+	TUint32		iMeanBurstLength;
+	TUint32		iMeanInterBurstGap;
+
+	static STestThreadDesc* ContinuousL(TInt aPri = EPriorityNormal);
+	static STestThreadDesc* ContinuousLC(TInt aPri = EPriorityNormal);
+	static STestThreadDesc* StaccatoL(TUint32 aGranularity, TUint32 aMeanGap, TInt aPri = EPriorityNormal);
+	static STestThreadDesc* StaccatoLC(TUint32 aGranularity, TUint32 aMeanGap, TInt aPri = EPriorityNormal);
+	};
+
+STestThreadDesc* STestThreadDesc::ContinuousLC(TInt aPri)
+	{
+	STestThreadDesc* p = (STestThreadDesc*)User::AllocLC(sizeof(STestThreadDesc));
+	p->iCpuAffinity = 0xffffffff;
+	p->iPriority = aPri;
+	p->iGroupId = 0;
+	p->iEaterType = EEaterStd;
+	p->iEaterInstance = 0;
+	p->iGranularity = 0;
+	p->iMeanIntraBurstGap = 0;
+	p->iMeanBurstLength = KMaxTInt32;
+	p->iMeanInterBurstGap = 0;
+	return p;
+	}
+
+STestThreadDesc* STestThreadDesc::ContinuousL(TInt aPri)
+	{
+	STestThreadDesc* p = ContinuousLC(aPri);
+	CleanupStack::Pop();
+	return p;
+	}
+
+STestThreadDesc* STestThreadDesc::StaccatoLC(TUint32 aGranularity, TUint32 aMeanGap, TInt aPri)
+	{
+	STestThreadDesc* p = (STestThreadDesc*)User::AllocLC(sizeof(STestThreadDesc));
+	p->iCpuAffinity = 0xffffffff;
+	p->iPriority = aPri;
+	p->iGroupId = 0;
+	p->iEaterType = EEaterStd;
+	p->iEaterInstance = 0;
+	p->iGranularity = aGranularity;
+	p->iMeanIntraBurstGap = aMeanGap;
+	p->iMeanBurstLength = KMaxTInt32;
+	p->iMeanInterBurstGap = 0;
+	return p;
+	}
+
+STestThreadDesc* STestThreadDesc::StaccatoL(TUint32 aGranularity, TUint32 aMeanGap, TInt aPri)
+	{
+	STestThreadDesc* p = StaccatoLC(aGranularity, aMeanGap, aPri);
+	CleanupStack::Pop();
+	return p;
+	}
+
+
+class CTest : public CBase, public MThreadCompletion
+	{
+public:
+	struct SStats
+		{
+		TInt64	iTotalCpu;
+		TInt64	iMinCpu;
+		TInt64	iMaxCpu;
+		TInt64	iTotalWork;
+		TInt64	iMinWork;
+		TInt64	iMaxWork;
+		};
+public:
+	static CTest* NewL(TInt64 aTestTime, TInt aNumTypes, ...);
+	~CTest();
+	RPointerArray<SThreadParams>& Threads()
+		{ return iP; }
+	TInt Execute();
+	void PrintResults() const;
+	void GetStats(SStats& aStats, TInt aFirstThread=0, TInt aCount=KMaxTInt) const;
+	TInt64 TotalCpuAll() const;
+private:
+	CTest();
+	void ConstructL(TInt64 aTestTime, TInt aNumTypes, VA_LIST aList);
+	SThreadParams* AddThreadParamsL();
+	CThreadX* AddThreadXL(SThreadParams* aParams);
+
+	virtual void Complete(TBool aOk, SThreadParams* aParams);
+private:
+	RPointerArray<SThreadParams> iP;
+	RPointerArray<CThreadX> iTX;
+	REaterArray iEaters;
+	RSemaphore iTurnstile;
+	TInt iCompleteCount;
+	TCpuUsage iInitialCpuUsage;
+	TCpuUsage iFinalCpuUsage;
+	};
+
+CTest::CTest()
+	:	iP(32),
+		iTX(32)
+	{
+	}
+
+CTest::~CTest()
+	{
+	iTX.ResetAndDestroy();
+
+	TInt i;
+	TInt c = iP.Count();
+	for (i=0; i<c; ++i)
+		{
+		SThreadParams* p = iP[i];
+		iP[i] = 0;
+		if (p)
+			{
+			User::Free(p->iResult);
+			User::Free(p);
+			}
+		}
+	iP.Close();
+	iEaters.Close();
+	iTurnstile.Close();
+	}
+
+CTest* CTest::NewL(TInt64 aTestTime, TInt aNumTypes, ...)
+	{
+	VA_LIST list;
+	VA_START(list, aNumTypes);
+	CTest* p = new (ELeave) CTest;
+	CleanupStack::PushL(p);
+	p->ConstructL(aTestTime, aNumTypes, list);
+	CleanupStack::Pop();
+	return p;
+	}
+
+SThreadParams* CTest::AddThreadParamsL()
+	{
+	SThreadResult* tr = (SThreadResult*)User::AllocLC(sizeof(SThreadResult));
+	SThreadParams* tp = (SThreadParams*)User::AllocLC(sizeof(SThreadParams));
+	memclr(tr, sizeof(SThreadResult));
+	tp->iResult = tr;
+	iP.AppendL(tp);
+	CleanupStack::Pop(2);
+	tp->iTurnstile = iTurnstile;
+	return tp;
+	}
+
+CThreadX* CTest::AddThreadXL(SThreadParams* aP)
+	{
+	if (aP->iGranularity==0 && aP->iMeanInterBurstGap==0)
+		{
+		// continuous use thread
+		if (TInt64(aP->iMeanBurstLength) >= aP->iTestTime)
+			aP->iMeanBurstLength = I64LOW(aP->iTestTime) + (I64LOW(aP->iTestTime)>>1);
+		}
+	CThreadX* tx = CThreadX::NewLC(aP, this);
+	iTX.AppendL(tx);
+	CleanupStack::Pop();
+	return tx;
+	}
+
+void CTest::Complete(TBool aOk, SThreadParams*)
+	{
+	if (!aOk || --iCompleteCount==0)
+		CActiveScheduler::Stop();
+	}
+
+
+void CTest::ConstructL(TInt64 aTestTime, TInt aNumTypes, VA_LIST aList)
+	{
+	typedef const STestThreadDesc* TTestThreadDescPtrC;
+
+	User::LeaveIfError(iTurnstile.CreateLocal(0));
+	TInt tt;
+	TInt tid = 0;
+	for (tt=0; tt<aNumTypes; ++tt)
+		{
+		TInt nThreads = VA_ARG(aList, TInt);
+		TInt inc = 0;
+		const TTestThreadDescPtrC* ppttd = 0;
+		TTestThreadDescPtrC pttd = 0;
+		if (nThreads < 0)
+			{
+			ppttd = VA_ARG(aList, const TTestThreadDescPtrC*);
+			nThreads = -nThreads;
+			inc = 1;
+			}
+		else
+			{
+			pttd = VA_ARG(aList, TTestThreadDescPtrC);
+			ppttd = &pttd;
+			}
+		TInt k;
+		for (k=0; k<nThreads; ++k, ++tid)
+			{
+			const STestThreadDesc& ttd = **ppttd;
+			ppttd += inc;
+			SThreadParams* tp = AddThreadParamsL();
+			tp->iId = tid;
+			tp->iTestTime = aTestTime;
+			tp->iCpuAffinity = ttd.iCpuAffinity;
+			tp->iPriority = ttd.iPriority;
+			tp->iGroupId = ttd.iGroupId;
+			tp->iE = iEaters.FindOrCreateL(ttd.iEaterType, ttd.iEaterInstance);
+			tp->iGranularity = ttd.iGranularity;
+			tp->iMeanIntraBurstGap = ttd.iMeanIntraBurstGap;
+			tp->iMeanBurstLength = ttd.iMeanBurstLength;
+			tp->iMeanInterBurstGap = ttd.iMeanInterBurstGap;
+			AddThreadXL(tp);
+			}
+		}
+	}
+
+TInt CTest::Execute()
+	{
+	iCompleteCount = iP.Count();
+	iInitialCpuUsage.Sample();
+	iTurnstile.Signal(iCompleteCount);
+	CActiveScheduler::Start();
+	iFinalCpuUsage.Sample();
+	return iCompleteCount ? KErrGeneral : KErrNone;
+	}
+
+void CTest::GetStats(SStats& a, TInt aFirstThread, TInt aCount) const
+	{
+	a.iTotalCpu = 0;
+	a.iMinCpu = KMaxTInt64;
+	a.iMaxCpu = KMinTInt64;
+	a.iTotalWork = 0;
+	a.iMinWork = KMaxTInt64;
+	a.iMaxWork = KMinTInt64;
+	TInt nt = iP.Count();
+	if (aFirstThread > nt)
+		aFirstThread = nt;
+	if (aCount > nt - aFirstThread)
+		aCount = nt - aFirstThread;
+	TInt i = aFirstThread;
+	for (; i<aFirstThread+aCount; ++i)
+		{
+		SThreadResult* tr = iP[i]->iResult;
+		TInt64 cpu = tr->iCpuTime;
+		TInt64 work = tr->iWorkDone;
+		a.iTotalCpu += cpu;
+		a.iTotalWork += work;
+		if (cpu < a.iMinCpu)
+			a.iMinCpu = cpu;
+		if (cpu > a.iMaxCpu)
+			a.iMaxCpu = cpu;
+		if (work < a.iMinWork)
+			a.iMinWork = work;
+		if (work > a.iMaxWork)
+			a.iMaxWork = work;
+		}
+	}
+
+TInt64 CTest::TotalCpuAll() const
+	{
+	TInt i;
+	TInt nc = TCpuUsage::N();
+	TInt64 totalCpuAll = 0;
+	for (i=0; i<nc; ++i)
+		{
+		TInt64 u = iFinalCpuUsage.CpuTimeDelta(iInitialCpuUsage, i);
+		totalCpuAll += u;
+		}
+	return totalCpuAll;
+	}
+
+void CTest::PrintResults() const
+	{
+	TInt i;
+	TInt nt = iP.Count();
+	TInt nc = TCpuUsage::N();
+	TInt64 totalCpuAll = 0;
+	TInt64 totalCpu = 0;
+	TInt64 totalWork = 0;
+	for (i=0; i<nt; ++i)
+		{
+		SThreadResult* tr = iP[i]->iResult;
+		test.Printf(_L("%2u: E=%10u     C=%10u     I=%10u     W=%10u\n"),
+			i, I64LOW(tr->iElapsedTime), I64LOW(tr->iCpuTime), tr->iInvocations, tr->iWorkDone );
+		totalCpu += tr->iCpuTime;
+		totalWork += TInt64(tr->iWorkDone);
+		}
+	test.Printf(_L("Total              C=%12Lu                    W=%12Lu\n"), totalCpu, totalWork);
+	for (i=0; i<nc; ++i)
+		{
+		TInt64 u = iFinalCpuUsage.CpuTimeDelta(iInitialCpuUsage, i);
+		totalCpuAll += u;
+		test.Printf(_L("Cpu%1u: %10u "), i, I64LOW(u));
+		}
+	test.Printf(_L("\n"));
+	test.Printf(_L("Total %12Lu\n"), totalCpuAll);
+	}
+
+
+
+MCpuEater* REaterArray::CreateLC(TInt aType)
+	{
+	switch (aType)
+		{
+		case EEaterStd:
+			{
+			CDefaultCpuEater* p = new (ELeave) CDefaultCpuEater();
+			CleanupStack::PushL(p);
+			p->Calibrate();
+			return p;
+			}
+		case EEaterMemoryLocalS:
+			{
+			CMemoryBandwidthEater* p = CMemoryBandwidthEater::NewLC(0x8000, 0x0800, 0x0800);
+			p->Calibrate();
+			return p;
+			}
+		case EEaterMemoryNonLocalS:
+			{
+			CMemoryBandwidthEater* p = CMemoryBandwidthEater::NewLC(0x100000, 0x10000, 0x4);
+			p->Calibrate();
+			return p;
+			}
+		case EEaterMemoryLocalU:
+			{
+			CMemoryBandwidthEater* p = CMemoryBandwidthEater::NewLC(0x4000, 0x4000, 0x4000);
+			p->Calibrate();
+			return p;
+			}
+		case EEaterMemoryNonLocalU:
+			{
+			CMemoryBandwidthEater* p = CMemoryBandwidthEater::NewLC(0x80000, 0x80000, 0x80000);
+			p->Calibrate();
+			return p;
+			}
+		case EEaterMemoryAtomic:
+			{
+			CAtomicMemoryBandwidthEater* p = CAtomicMemoryBandwidthEater::NewLC(0x1000);
+			p->Calibrate();
+			return p;
+			}
+		case EEaterMemoryAtomic2:
+			{
+			CAtomicMemoryBandwidthEater* p = CAtomicMemoryBandwidthEater::NewLC(0x8000);
+			p->Calibrate();
+			return p;
+			}
+		case EEaterAmdahl:
+			{
+			CAmdahlCpuEater* p = CAmdahlCpuEater::NewLC();
+			p->Calibrate();
+			return p;
+			}
+		default:
+			User::Leave(KErrNotSupported);
+		}
+	return 0;
+	}
+
+
+
+/******************************************************************************
+ *
+ ******************************************************************************/
+
+void RunBenchmarkL(CTest::SStats& aB, STestThreadDesc* aT, TInt aLength)
+	{
+	const TInt NC = TCpuUsage::N();
+	CTest* p;
+	TUint32 saved_aff = aT->iCpuAffinity;
+	aT->iCpuAffinity = NC-1;
+	p = CTest::NewL(aLength, 1, 1, aT);
+	TInt r = p->Execute();
+	test_KErrNone(r);
+	p->PrintResults();
+	p->GetStats(aB);
+	delete p;
+	aT->iCpuAffinity = saved_aff;
+	}
+
+void CompareToBenchmark(const CTest::SStats& aS, const CTest::SStats& aB)
+	{
+	TReal bCpu = (TReal)aB.iTotalCpu;
+	TReal bWork = (TReal)aB.iTotalWork;
+	TReal bEff = bWork/bCpu*1000000.0;
+	TReal tCpu = (TReal)aS.iTotalCpu;
+	TReal tWork = (TReal)aS.iTotalWork;
+	TReal tEff = tWork/tCpu*1000000.0;
+	TReal mCpu = (TReal)aS.iMinCpu;
+	TReal MCpu = (TReal)aS.iMaxCpu;
+	TReal mWork = (TReal)aS.iMinWork;
+	TReal MWork = (TReal)aS.iMaxWork;
+	test.Printf(_L("Total CPU usage %6.1f%% of benchmark\n"), 100.0*tCpu/bCpu);
+	test.Printf(_L("Total work done %6.1f%% of benchmark\n"), 100.0*tWork/bWork);
+	test.Printf(_L("Max/min ratio   %6.1f%% (CPU) %6.1f%% (Work)\n"), 100.0*MCpu/mCpu, 100.0*MWork/mWork);
+	test.Printf(_L("Work/sec bench: %10.1f test: %10.1f  Relative Efficiency %6.1f%%\n"), bEff, tEff, tEff/bEff*100.0);
+	}
+
+void ContinuousTestL(TInt aLength, TUint32 aWhich)
+	{
+	aLength *= 1000;
+	const TInt NC = TCpuUsage::N();
+	TInt r = 0;
+	TInt i = 0;
+	CTest::SStats benchmark;
+	CTest::SStats st;
+	CTest::SStats stm;
+	CTest* p = 0;
+	TUint et = aWhich >> 28;
+	TBool separate = (aWhich & 0x08000000u);
+	TInt instance = 0;
+	STestThreadDesc* td[2*TCpuUsage::EMaxCpus] = {0};
+	STestThreadDesc* tdm[TCpuUsage::EMaxCpus] = {0};
+	STestThreadDesc* tdl[TCpuUsage::EMaxCpus] = {0};
+	for (i=0; i<2*NC; ++i)
+		{
+		td[i] = STestThreadDesc::ContinuousLC();
+		td[i]->iEaterType = (TUint16)et;
+		td[i]->iEaterInstance = (TUint16)(separate ? (instance++) : 0);
+		if (i<NC)
+			{
+			tdm[i] = STestThreadDesc::ContinuousLC(EPriorityMore);
+			tdm[i]->iEaterType = (TUint16)et;
+			tdm[i]->iEaterInstance = (TUint16)(separate ? (instance++) : 0);
+			tdl[i] = STestThreadDesc::ContinuousLC();
+			tdl[i]->iCpuAffinity = i;
+			tdl[i]->iEaterType = (TUint16)et;
+			tdl[i]->iEaterInstance = (TUint16)(separate ? (instance++) : 0);
+			}
+		}
+
+	test.Printf(_L("\nTesting a single continuous CPU-locked thread\n"));
+	RunBenchmarkL(benchmark, tdl[NC-1], aLength);
+
+	TInt n;
+
+	if (aWhich & 1)
+		{
+		for (n=1; n<=2*NC; ++n)
+			{
+			test.Printf(_L("\nTesting %d continuous thread(s) ...\n"), n);
+			p = CTest::NewL(aLength, 1, -n, td);
+			r = p->Execute();
+			test_KErrNone(r);
+			p->PrintResults();
+			p->GetStats(st);
+			delete p;
+			CompareToBenchmark(st, benchmark);
+			}
+		}
+
+	TInt h;
+	if (aWhich & 2)
+		{
+		for (h=1; h<NC; ++h)
+			{
+			for (n=h; n<=2*NC; ++n)
+				{
+				TInt l = n - h;
+				test.Printf(_L("\nTesting %d continuous thread(s) (%d higher priority) CPU-locked...\n"), n, h);
+				p = CTest::NewL(aLength, 2, -h, tdl, l, tdl[h]);
+				r = p->Execute();
+				test_KErrNone(r);
+				p->PrintResults();
+				p->GetStats(st, h, l);
+				p->GetStats(stm, 0, h);
+				delete p;
+				CompareToBenchmark(stm, benchmark);
+				if (l>0)
+					CompareToBenchmark(st, benchmark);
+				}
+			}
+		}
+
+	if (aWhich & 4)
+		{
+		for (h=1; h<NC; ++h)
+			{
+			for (n=h; n<=2*NC; ++n)
+				{
+				TInt l = n - h;
+				test.Printf(_L("\nTesting %d continuous thread(s) (%d higher priority)...\n"), n, h);
+				p = CTest::NewL(aLength, 2, -h, tdm, -l, td);
+				r = p->Execute();
+				test_KErrNone(r);
+				p->PrintResults();
+				p->GetStats(st, h, l);
+				p->GetStats(stm, 0, h);
+				delete p;
+				CompareToBenchmark(stm, benchmark);
+				if (l>0)
+					CompareToBenchmark(st, benchmark);
+				}
+			}
+		}
+
+	CleanupStack::PopAndDestroy(NC*4);
+	}
+
+
+void TestWithOneSpecialL(const TDesC& aTitle, TInt aLength, const CTest::SStats& aB1, const CTest::SStats& aB0, STestThreadDesc* aT1, STestThreadDesc* aT0)
+	{
+	const TInt NC = TCpuUsage::N();
+	CTest::SStats st;
+	CTest::SStats sti;
+	CTest* p = 0;
+	TInt n;
+	TInt r;
+	for (n=1; n<=2*NC-1; ++n)
+		{
+		test.Printf(_L("\nTesting %d continuous thread(s) plus %S ...\n"), n, &aTitle);
+		p = CTest::NewL(aLength, 2, 1, aT1, n, aT0);
+		r = p->Execute();
+		test_KErrNone(r);
+		p->PrintResults();
+		p->GetStats(st, 1, n);
+		p->GetStats(sti, 0, 1);
+		delete p;
+		CompareToBenchmark(sti, aB1);
+		CompareToBenchmark(st, aB0);
+
+		test.Printf(_L("\nTesting %d continuous thread(s) plus %Sh ...\n"), n, &aTitle);
+		TInt orig_pri = aT1->iPriority;
+		aT1->iPriority = EPriorityMore;
+		p = CTest::NewL(aLength, 2, 1, aT1, n, aT0);
+		r = p->Execute();
+		test_KErrNone(r);
+		p->PrintResults();
+		p->GetStats(st, 1, n);
+		p->GetStats(sti, 0, 1);
+		delete p;
+		CompareToBenchmark(sti, aB1);
+		CompareToBenchmark(st, aB0);
+		aT1->iPriority = orig_pri;
+		}
+	}
+
+void ContinuousPlusIntermittentTestL(TInt aLength, TUint32 aWhich)
+	{
+	aLength *= 1000;
+	const TInt NC = TCpuUsage::N();
+	TInt i = 0;
+	CTest::SStats bmc, bmilc, bmilf, bmihc, bmihf;
+	STestThreadDesc* td = STestThreadDesc::ContinuousLC();
+	STestThreadDesc* tdl[TCpuUsage::EMaxCpus] = {0};
+	STestThreadDesc* tdilc[TCpuUsage::EMaxCpus] = {0};	// light load, coarse grained
+	STestThreadDesc* tdilf[TCpuUsage::EMaxCpus] = {0};	// light load, fine grained
+	STestThreadDesc* tdihc[TCpuUsage::EMaxCpus] = {0};	// heavy load, coarse grained
+	STestThreadDesc* tdihf[TCpuUsage::EMaxCpus] = {0};	// heavy load, fine grained
+	for (i=0; i<NC; ++i)
+		{
+		tdl[i] = STestThreadDesc::ContinuousLC();
+		tdl[i]->iCpuAffinity = i;
+		tdilc[i] = STestThreadDesc::StaccatoLC(45000, 500000);
+		tdilf[i] = STestThreadDesc::StaccatoLC(1000, 50000);
+		tdihc[i] = STestThreadDesc::StaccatoLC(400000, 500000);
+		tdihf[i] = STestThreadDesc::StaccatoLC(3000, 5000);
+		}
+
+	test.Printf(_L("\nTesting a single continuous CPU-locked thread\n"));
+	RunBenchmarkL(bmc, tdl[NC-1], aLength);
+
+	if (aWhich & 1)
+		{
+		test.Printf(_L("\nTesting a single ILC CPU-locked thread\n"));
+		RunBenchmarkL(bmilc, tdilc[NC-1], aLength);
+		}
+
+	if (aWhich & 2)
+		{
+		test.Printf(_L("\nTesting a single ILF CPU-locked thread\n"));
+		RunBenchmarkL(bmilf, tdilf[NC-1], aLength);
+		}
+
+	if (aWhich & 4)
+		{
+		test.Printf(_L("\nTesting a single IHC CPU-locked thread\n"));
+		RunBenchmarkL(bmihc, tdihc[NC-1], aLength);
+		}
+
+	if (aWhich & 8)
+		{
+		test.Printf(_L("\nTesting a single IHF CPU-locked thread\n"));
+		RunBenchmarkL(bmihf, tdihf[NC-1], aLength);
+		}
+
+	if (aWhich & 1)
+		{
+		TestWithOneSpecialL(_L("ILC"), aLength, bmilc, bmc, tdilc[0], td);
+		}
+	if (aWhich & 2)
+		{
+		TestWithOneSpecialL(_L("ILF"), aLength, bmilf, bmc, tdilf[0], td);
+		}
+	if (aWhich & 4)
+		{
+		TestWithOneSpecialL(_L("IHC"), aLength, bmihc, bmc, tdihc[0], td);
+		}
+	if (aWhich & 8)
+		{
+		TestWithOneSpecialL(_L("IHF"), aLength, bmihf, bmc, tdihf[0], td);
+		}
+	CleanupStack::PopAndDestroy(5*NC+1);
+	}
+
+
+TInt E32Main()
+	{
+	RThread().SetPriority(EPriorityAbsoluteHigh);
+	test.Title();
+	User::SetCritical(User::ESystemCritical);
+	TCpuUsage::Init();
+	TInt r = 0;
+
+	CTrapCleanup* cln = CTrapCleanup::New();
+	test_NotNull(cln);
+	CActiveScheduler* as = new CActiveScheduler;
+	test_NotNull(as);
+	CActiveScheduler::Install(as);
+
+	test.Printf(_L("\n************************************************************************\n"));
+	test.Printf(_L("* Testing with CPU intensive loads...\n"));
+	test.Printf(_L("************************************************************************\n"));
+	TRAP(r, ContinuousTestL(3000, 1+4));
+	test_KErrNone(r);
+	TRAP(r, ContinuousTestL(10000, 1+4));
+	test_KErrNone(r);
+	TRAP(r, ContinuousPlusIntermittentTestL(10000, 15));
+	test_KErrNone(r);
+
+	test.Printf(_L("\n************************************************************************\n"));
+	test.Printf(_L("* Testing with memory intensive loads, good locality...\n"));
+	test.Printf(_L("************************************************************************\n"));
+	TRAP(r, ContinuousTestL(3000, 1+4+0x08000000u+(EEaterMemoryLocalU<<28)));
+	test_KErrNone(r);
+	TRAP(r, ContinuousTestL(10000, 1+4+0x08000000u+(EEaterMemoryLocalU<<28)));
+	test_KErrNone(r);
+
+	test.Printf(_L("\n************************************************************************\n"));
+	test.Printf(_L("* Testing with memory intensive loads, poor locality...\n"));
+	test.Printf(_L("************************************************************************\n"));
+	TRAP(r, ContinuousTestL(3000, 1+4+0x08000000u+(EEaterMemoryNonLocalU<<28)));
+	test_KErrNone(r);
+	TRAP(r, ContinuousTestL(10000, 1+4+0x08000000u+(EEaterMemoryNonLocalU<<28)));
+	test_KErrNone(r);
+
+	test.Printf(_L("\n************************************************************************\n"));
+	test.Printf(_L("* Testing with memory intensive loads, atomic operations...\n"));
+	test.Printf(_L("************************************************************************\n"));
+	TRAP(r, ContinuousTestL(3000, 1+4+(EEaterMemoryAtomic<<28)));
+	test_KErrNone(r);
+	TRAP(r, ContinuousTestL(10000, 1+4+(EEaterMemoryAtomic<<28)));
+	test_KErrNone(r);
+
+	test.Printf(_L("\n************************************************************************\n"));
+	test.Printf(_L("* Testing with memory intensive loads, atomic operations 2...\n"));
+	test.Printf(_L("************************************************************************\n"));
+	TRAP(r, ContinuousTestL(3000, 1+4+(EEaterMemoryAtomic2<<28)));
+	test_KErrNone(r);
+	TRAP(r, ContinuousTestL(10000, 1+4+(EEaterMemoryAtomic2<<28)));
+	test_KErrNone(r);
+
+	test.Printf(_L("\n************************************************************************\n"));
+	test.Printf(_L("* Testing with CPU intensive loads with some serialization...\n"));
+	test.Printf(_L("************************************************************************\n"));
+	TRAP(r, ContinuousTestL(3000, 1+4+(EEaterAmdahl<<28)));
+	test_KErrNone(r);
+	TRAP(r, ContinuousTestL(10000, 1+4+(EEaterAmdahl<<28)));
+	test_KErrNone(r);
+
+	delete as;
+	delete cln;
+	return r;
+	}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/misc/test_thread.h	Fri Apr 16 16:24:37 2010 +0300
@@ -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
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/misc/ymodemtx.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,472 @@
+// Copyright (c) 2009-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\misc\ymodemtx.cpp
+// 
+//
+
+#include <e32std.h>
+#include <e32svr.h>
+#include <f32file.h>
+#include <d32comm.h>
+
+RFs TheFs;
+RFile TheFile;
+TInt FileSize;
+RBusDevComm TheComm;
+RTimer TheTimer;
+TFileName FileName;
+TFileName FileName8b;
+TPtr8 FileName8(0,0,0);
+
+const TUint8 STX=0x02;
+const TUint8 EOT=0x04;
+const TUint8 ACK=0x06;
+const TUint8 BIGC=0x43;
+const TUint8 BIGG=0x47;
+
+#define PACKET_SIZE		1024
+
+#define MIN(a,b)		((a)<(b)?(a):(b))
+#define OFFSET(p,off)	((void*)((char*)p+off))
+
+#define RESET_COMM()	TheComm.ResetBuffers()
+
+#define assert(x)			((void)( (x) || (__Panic(__LINE__, #x),0) ))
+#define assert_KErrNone(r)	((void)( ((r)==KErrNone) || (__Panic(__LINE__, (r)),0) ))
+
+
+void __Panic(TInt aLine, TInt aError)
+	{
+	RDebug::Printf("Line %d Expected KErrNone got %d", aLine, aError);
+	User::Panic(_L("YMODEMTX"), aLine);
+	}
+
+void __Panic(TInt aLine, const char* aMessage)
+	{
+	RDebug::Printf("Line %d Assertion \"%s\" failed", aLine, aMessage);
+	User::Panic(_L("YMODEMTX"), aLine);
+	}
+
+/*
+YModem packet structure:
+Byte 0 = STX
+Byte 1 = sequence number (first user data packet is 1)
+Byte 2 = complement of sequence number
+Bytes 3-1026 = data (1K per packet)
+Bytes 1027, 1028 = 16-bit CRC (big-endian)
+
+A herald packet is sent first, with sequence number 0
+The data field consists of the null-terminated file name
+followed by the null-terminated file size in ASCII decimal
+digits.
+*/
+struct SPacket
+	{
+	TUint8 iPTI;
+	TUint8 iSeq;
+	TUint8 iSeqBar;
+	TUint8 iData[PACKET_SIZE];
+	TUint8 iCRC1;
+	TUint8 iCRC0;
+	};
+
+static const TUint16 crcTab[256] =
+    {
+	0x0000,0x1021,0x2042,0x3063,0x4084,0x50a5,0x60c6,0x70e7,0x8108,0x9129,0xa14a,
+	0xb16b,0xc18c,0xd1ad,0xe1ce,0xf1ef,0x1231,0x0210,0x3273,0x2252,0x52b5,0x4294,
+	0x72f7,0x62d6,0x9339,0x8318,0xb37b,0xa35a,0xd3bd,0xc39c,0xf3ff,0xe3de,0x2462,
+	0x3443,0x0420,0x1401,0x64e6,0x74c7,0x44a4,0x5485,0xa56a,0xb54b,0x8528,0x9509,
+	0xe5ee,0xf5cf,0xc5ac,0xd58d,0x3653,0x2672,0x1611,0x0630,0x76d7,0x66f6,0x5695,
+	0x46b4,0xb75b,0xa77a,0x9719,0x8738,0xf7df,0xe7fe,0xd79d,0xc7bc,0x48c4,0x58e5,
+	0x6886,0x78a7,0x0840,0x1861,0x2802,0x3823,0xc9cc,0xd9ed,0xe98e,0xf9af,0x8948,
+	0x9969,0xa90a,0xb92b,0x5af5,0x4ad4,0x7ab7,0x6a96,0x1a71,0x0a50,0x3a33,0x2a12,
+	0xdbfd,0xcbdc,0xfbbf,0xeb9e,0x9b79,0x8b58,0xbb3b,0xab1a,0x6ca6,0x7c87,0x4ce4,
+	0x5cc5,0x2c22,0x3c03,0x0c60,0x1c41,0xedae,0xfd8f,0xcdec,0xddcd,0xad2a,0xbd0b,
+	0x8d68,0x9d49,0x7e97,0x6eb6,0x5ed5,0x4ef4,0x3e13,0x2e32,0x1e51,0x0e70,0xff9f,
+	0xefbe,0xdfdd,0xcffc,0xbf1b,0xaf3a,0x9f59,0x8f78,0x9188,0x81a9,0xb1ca,0xa1eb,
+	0xd10c,0xc12d,0xf14e,0xe16f,0x1080,0x00a1,0x30c2,0x20e3,0x5004,0x4025,0x7046,
+	0x6067,0x83b9,0x9398,0xa3fb,0xb3da,0xc33d,0xd31c,0xe37f,0xf35e,0x02b1,0x1290,
+	0x22f3,0x32d2,0x4235,0x5214,0x6277,0x7256,0xb5ea,0xa5cb,0x95a8,0x8589,0xf56e,
+	0xe54f,0xd52c,0xc50d,0x34e2,0x24c3,0x14a0,0x0481,0x7466,0x6447,0x5424,0x4405,
+	0xa7db,0xb7fa,0x8799,0x97b8,0xe75f,0xf77e,0xc71d,0xd73c,0x26d3,0x36f2,0x0691,
+	0x16b0,0x6657,0x7676,0x4615,0x5634,0xd94c,0xc96d,0xf90e,0xe92f,0x99c8,0x89e9,
+	0xb98a,0xa9ab,0x5844,0x4865,0x7806,0x6827,0x18c0,0x08e1,0x3882,0x28a3,0xcb7d,
+	0xdb5c,0xeb3f,0xfb1e,0x8bf9,0x9bd8,0xabbb,0xbb9a,0x4a75,0x5a54,0x6a37,0x7a16,
+	0x0af1,0x1ad0,0x2ab3,0x3a92,0xfd2e,0xed0f,0xdd6c,0xcd4d,0xbdaa,0xad8b,0x9de8,
+	0x8dc9,0x7c26,0x6c07,0x5c64,0x4c45,0x3ca2,0x2c83,0x1ce0,0x0cc1,0xef1f,0xff3e,
+	0xcf5d,0xdf7c,0xaf9b,0xbfba,0x8fd9,0x9ff8,0x6e17,0x7e36,0x4e55,0x5e74,0x2e93,
+	0x3eb2,0x0ed1,0x1ef0
+    };
+
+void UpdateCrc(const void* aPtr, TInt aLength, TUint16& aCrc)
+//
+// Perform a CCITT CRC checksum.
+//
+	{
+
+	register const TUint8* pB = (const TUint8*)aPtr;
+	register TUint16 crc=aCrc;
+    while (aLength--)
+		crc=TUint16((crc<<8)^crcTab[(crc>>8)^*pB++]);
+	aCrc=crc;
+	}
+
+void ClearCommError()
+	{
+	}
+
+TInt CommRead1(TInt aTimeout)
+	{
+	TBuf8<1> c;
+	TRequestStatus s0, s1;
+	TheComm.ReadOneOrMore(s1, c);
+	TheTimer.After(s0, aTimeout*1000);
+	User::WaitForRequest(s0, s1);
+	if (s1 != KRequestPending)
+		{
+		TheTimer.Cancel();
+		User::WaitForRequest(s0);
+		return (s1==KErrNone) ? c[0] : s1.Int();
+		}
+	TheComm.ReadCancel();
+	User::WaitForRequest(s1);
+	return KErrTimedOut;
+	}
+
+TInt CommRead(TDes8& aBuf, TInt aTimeout)
+	{
+	aBuf.Zero();
+	TRequestStatus s0, s1;
+	TInt timeout = aTimeout * 1000;
+
+	TUint8* b = (TUint8*)aBuf.Ptr();
+	while (aBuf.Length() < aBuf.MaxLength())
+		{
+		TPtr8 p(b+aBuf.Length(), 0, aBuf.MaxLength()-aBuf.Length());
+		TheComm.ReadOneOrMore(s1, p);
+		TheTimer.After(s0, timeout);
+		User::WaitForRequest(s0, s1);
+		if (s1 == KErrNone)
+			{
+			TheTimer.Cancel();
+			User::WaitForRequest(s0);
+			aBuf.SetLength(aBuf.Length() + p.Length());
+			timeout = 500000;
+			continue;
+			}
+		if (s1 != KRequestPending)
+			{
+			TheTimer.Cancel();
+			User::WaitForRequest(s0);
+			break;
+			}
+		if (s0 != KRequestPending)
+			{
+			TheComm.ReadCancel();
+			User::WaitForRequest(s1);
+			break;
+			}
+		}
+	if (aBuf.Length()==0)
+		return KErrTimedOut;
+	return aBuf.Length();
+	}
+
+void CommWrite(const TDesC8& aBuf)
+	{
+	TRequestStatus s;
+	TheComm.Write(s, aBuf);
+	User::WaitForRequest(s);
+	}
+
+void CommWriteC(TUint aChar)
+	{
+	TBuf8<1> b;
+	b.SetLength(1);
+	b[0] = (TUint8)aChar;
+	CommWrite(b);
+	}
+
+void CommWriteS(const char* aString)
+	{
+	CommWrite(TPtrC8((const TUint8*)aString));
+	}
+
+TInt PreparePacket(SPacket& pkt, TInt aSeq)
+	{
+	TInt r = KErrNone;
+	TUint16 crc = 0;
+
+	pkt.iPTI = STX;
+	pkt.iSeq = (TUint8)(aSeq>=0 ? aSeq : 0);
+	pkt.iSeqBar = (TUint8)~pkt.iSeq;
+	if (aSeq>0)
+		{
+		TInt l;
+		TInt fpos = (aSeq-1)*PACKET_SIZE;	// file position of packet
+		if ( fpos >= FileSize )
+			return KErrEof;
+		l = MIN(PACKET_SIZE, FileSize-fpos);
+		TPtr8 d(pkt.iData, 0, l);
+		assert_KErrNone(TheFile.Read(d));
+		if (l<PACKET_SIZE)
+			memset(pkt.iData+l, 0, PACKET_SIZE-l);
+		}
+	else
+		{
+		memset(pkt.iData, 0, PACKET_SIZE);
+		if (aSeq==0)
+			{
+			TInt pos = FileName8.LocateReverse('\\');
+			TPtrC8 fn8(FileName8.Mid(pos+1));
+			memcpy(pkt.iData, fn8.Ptr(), fn8.Length());
+			TPtr8 d2(pkt.iData+fn8.Length()+1, 0, PACKET_SIZE-fn8.Length()-1);
+			d2.Num(FileSize);
+			}
+		}
+	UpdateCrc(pkt.iData, PACKET_SIZE, crc);
+	pkt.iCRC1 = (TUint8)(crc>>8);
+	pkt.iCRC0 = (TUint8)crc;
+	return r;
+	}
+
+TInt SendPacket(TInt& aSeq, TBool aStream)
+	{
+	TInt c;
+	SPacket pkt;
+	TInt retries = 10;
+	TInt tmout = (aSeq>=0) ? 2000 : 500;
+	TInt r = PreparePacket(pkt, aSeq);
+	if (r!=KErrNone)
+		return r;
+	for(;;)
+		{
+		RESET_COMM();
+		CommWrite(TPtrC8( (const TUint8*)&pkt, sizeof(pkt) ));
+		if (aStream)
+			break;
+		c = CommRead1(tmout);
+		if (c==KErrTimedOut && aSeq<0)
+			return KErrNone;
+		if (c>=0)
+			{
+			if (c==ACK)
+				break;
+			}
+		if (--retries==0)
+			return KErrTimedOut;
+		}
+	if (aSeq==0)
+		{
+		c = CommRead1(100);
+		if (c==KErrTimedOut)
+			{
+			++aSeq;
+			return KErrNone;
+			}
+		if (aStream && c!=BIGG)
+			return KErrTimedOut;
+		else if (!aStream && c!=BIGC)
+			return KErrTimedOut;
+		}
+	++aSeq;
+	return r;
+	}
+
+TInt SendImageFile()
+	{
+	TInt r = 0;
+	TInt b1;
+	TBool stream;
+	TInt seq = 0;
+
+	RESET_COMM();
+	r = CommRead1(20000);
+	if (r<0)
+		return r;
+	if (r!=BIGG && r!=BIGC)
+		return KErrTimedOut;
+	stream = (r==BIGG);
+	seq = 0;
+	r = KErrNone;
+	while (r==KErrNone)
+		{
+		r = SendPacket(seq, stream);
+		}
+	if (r!=KErrEof)
+		return r;
+	r=KErrNone;
+	RESET_COMM();
+	CommWriteC(EOT);
+	b1 = CommRead1(500);
+	if (b1==KErrTimedOut)
+		return KErrNone;
+	if (b1!=ACK)
+		return KErrNone;
+	b1 = CommRead1(1000);
+	if (b1==KErrTimedOut)
+		return KErrNone;
+	if (stream && b1!=BIGG)
+		return KErrNone;
+	else if (!stream && b1!=BIGC)
+		return KErrNone;
+	seq = -1;
+	r = SendPacket(seq, stream);
+	return r;
+	}
+
+
+#define	ALLOWBPS(x)	case x : bps = EBps##x; break
+
+void ParseCommandLine()
+	{
+	TInt r = 0;
+	TInt cmdLineLen = User::CommandLineLength();
+	HBufC* cmdLine = HBufC::New(cmdLineLen);
+	assert(cmdLine!=0);
+	TPtr cmdLineW(cmdLine->Des());
+	User::CommandLine(cmdLineW);
+	TLex16 cmdLineLex(*cmdLine);
+	TInt baud = 115200;
+	TInt port = 0;
+	while (!cmdLineLex.Eos())
+		{
+		TPtrC token(cmdLineLex.NextToken());
+		cmdLineLex.SkipSpace();
+		if (token[0]=='-')
+			{
+			switch (token[1])
+				{
+				case 'p':
+					{
+					r = cmdLineLex.Val(port);
+					assert_KErrNone(r);
+					break;
+					}
+				case 'b':
+					{
+					r = cmdLineLex.Val(baud);
+					assert_KErrNone(r);
+					break;
+					}
+				default:
+					assert(0);
+					break;
+				}
+			continue;
+			}
+		FileName = token;
+		assert(cmdLineLex.Eos());
+		}
+	assert(FileName.Length()>0);
+
+	TBps bps = EBpsSpecial;
+	switch (baud)
+		{
+		ALLOWBPS(50);
+		ALLOWBPS(75);
+		ALLOWBPS(110);
+		ALLOWBPS(134);
+		ALLOWBPS(150);
+		ALLOWBPS(300);
+		ALLOWBPS(600);
+		ALLOWBPS(1200);
+		ALLOWBPS(1800);
+		ALLOWBPS(2000);
+		ALLOWBPS(2400);
+		ALLOWBPS(3600);
+		ALLOWBPS(4800);
+		ALLOWBPS(7200);
+		ALLOWBPS(9600);
+		ALLOWBPS(19200);
+		ALLOWBPS(38400);
+		ALLOWBPS(57600);
+		ALLOWBPS(115200);
+		ALLOWBPS(230400);
+		ALLOWBPS(460800);
+		ALLOWBPS(576000);
+		ALLOWBPS(1152000);
+		ALLOWBPS(4000000);
+		ALLOWBPS(921600);
+		}
+	assert(bps != EBpsSpecial);
+
+	assert_KErrNone(TheFs.Connect());
+	assert_KErrNone(TheFile.Open(TheFs, FileName, EFileShareReadersOnly|EFileRead));
+	assert_KErrNone(TheFile.Size(FileSize));
+	FileName8b = FileName;
+	new (&FileName8) TPtr8(FileName8b.Collapse());
+	assert(TheComm.Open(port)==KErrNone);
+	TCommConfig cfgBuf;
+	TCommConfigV01& cfg = cfgBuf();
+	cfg.iRate = bps;
+	cfg.iDataBits = EData8;
+	cfg.iStopBits = EStop1;
+	cfg.iParity = EParityNone;
+	cfg.iHandshake = 0;
+	cfg.iParityError = 0;
+	cfg.iFifo = EFifoEnable;
+	cfg.iSpecialRate = 0;
+	cfg.iTerminatorCount = 0;
+	cfg.iSIREnable = ESIRDisable;
+	cfg.iSIRSettings = KConfigSIRShutDown;
+	assert_KErrNone(TheComm.SetConfig(cfgBuf));
+	CommWrite(_L8("Sending "));
+	CommWrite(FileName8);
+	CommWrite(_L8("\r\nWaiting for YModem or YModem-G receive...\r\n"));
+	}
+
+_LIT(KLddName,"ECOMM");
+_LIT(KPddName,"EUART");
+
+void LoadCommDrivers()
+	{
+	TInt r=User::LoadLogicalDevice(KLddName);
+	if (r!=KErrAlreadyExists)
+		assert_KErrNone(r);
+
+	TInt i;
+	TInt n=0;
+	for (i=-1; i<10; ++i)
+		{
+		TBuf<16> pddName=KPddName();
+		if (i>=0)
+			pddName.Append('0'+i);
+		r=User::LoadPhysicalDevice(pddName);
+		if (r==KErrNone || r==KErrAlreadyExists)
+			++n;
+		}
+	assert(n!=0);
+	}
+
+TInt E32Main()
+	{
+	TInt r;
+
+	LoadCommDrivers();
+	ParseCommandLine();
+
+	r = TheTimer.CreateLocal();
+	assert_KErrNone(r);
+
+	r = SendImageFile();
+	assert_KErrNone(r);
+
+	TheTimer.Close();
+	TheComm.Close();
+	TheFile.Close();
+	TheFs.Close();
+
+	return KErrNone;
+	}
--- a/kerneltest/e32test/mmu/d_memorytest.h	Tue Feb 02 01:24:03 2010 +0200
+++ b/kerneltest/e32test/mmu/d_memorytest.h	Fri Apr 16 16:24:37 2010 +0300
@@ -25,7 +25,7 @@
 
 _LIT(KMemoryTestLddName,"d_memorytest");
 
-const TInt KUCPageCount = 4;//Page count of user chunk used in physical pinning tests.
+const TInt KUCPageCount = 16;//Page count of user chunk used in physical pinning tests.
 
 class RMemoryTestLdd : public RBusLogicalChannel
 	{
--- a/kerneltest/e32test/mmu/d_shadow.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kerneltest/e32test/mmu/d_shadow.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -27,6 +27,15 @@
 
 _LIT(KLddName,"Shadow");
 
+#ifdef __CPU_X86
+const TUint KPageDirectorySize = 1024;
+const TUint KMaxNumberOfPageDirectories = 1024;
+const TUint KPsudoX86TTBCR = 512;
+#else 
+const TUint KPageDirectorySize = 4096;  // Full size (ttbr0+ttbr1)
+const TUint KMaxNumberOfPageDirectories = 256;
+#endif
+
 class DShadow;
 
 class DShadowFactory : public DLogicalDevice
@@ -52,6 +61,11 @@
 protected:
 	virtual TInt DoCreate(TInt aUnit, const TDesC8* anInfo, const TVersion& aVer);
 	virtual TInt Request(TInt aFunction, TAny* a1, TAny* a2);
+
+	// Memory model specific values will be initialised when the channel is created.
+	TUint iPageDirectoryBase;
+	TUint iPageTableBase;
+	TMemModel  iMemoryModel;
 	};
 
 DECLARE_STANDARD_LDD()
@@ -111,6 +125,30 @@
 
     if (!Kern::QueryVersionSupported(TVersion(KMajorVersionNumber,KMinorVersionNumber,KBuildVersionNumber),aVer))
     	return KErrNotSupported;
+	// Set memory model specific values.
+	TUint32 memoryModelAttrib = (TUint32)Kern::HalFunction(EHalGroupKernel,EKernelHalMemModelInfo,0,0);    
+	switch (memoryModelAttrib & EMemModelTypeMask)
+		{
+		case EMemModelTypeMoving:
+			iPageDirectoryBase = 0x61000000;
+			iPageTableBase = 0x62000000;
+			iMemoryModel = EMemModelMoving;
+			break;
+		case EMemModelTypeMultiple:
+			iPageDirectoryBase = 0xC1000000;
+			iPageTableBase = 0xC2000000;
+			iMemoryModel = EMemModelMultiple;
+			break;
+		case EMemModelTypeFlexible:
+			iPageDirectoryBase = 0xF4000000u;
+			iPageTableBase = 0xF8000000u;
+			iMemoryModel = EMemModelFlexible;
+			break;
+		default:
+			iPageDirectoryBase = 0x00000000;
+			iPageTableBase = 0x00000000;
+			iMemoryModel = EMemModelOther;
+		}
 	return KErrNone;
 	}
 
@@ -291,14 +329,13 @@
 						 
 #ifdef __EPOC32__
 
-#if defined(__MEMMODEL_MULTIPLE__) || defined(__MEMMODEL_FLEXIBLE__)
-			numPds = KMaxNumberOfPageDirectories;
-#else
-			numPds = 0;								
-#endif			
-			r = KMemoryModel;
+			if (iMemoryModel == EMemModelFlexible || iMemoryModel == EMemModelMultiple)
+				numPds = KMaxNumberOfPageDirectories;
+			else
+				numPds = 0;	
+			r = iMemoryModel;
 #endif
-			pageTable = KPageTableBase;			
+			pageTable = iPageTableBase;			
 
 			kumemput(a1, &pageTable, sizeof(TUint));
 			kumemput(a2, &numPds, sizeof(TUint));
@@ -317,39 +354,38 @@
 
 			r=KErrNoPageTable;
 
-#if defined(__MEMMODEL_MOVING__)
-
-			if (pd==KGlobalPageDirectory)
+			if (iMemoryModel == EMemModelMoving)
 				{
-				pdSize=KPageDirectorySize;
-				pdBase=KPageDirectoryBase;
-				r = KErrNone;
+				if (pd==KGlobalPageDirectory)
+					{
+					pdSize=KPageDirectorySize;
+					pdBase=iPageDirectoryBase;
+					r = KErrNone;
+					}
 				}
-
-#elif defined(__MEMMODEL_MULTIPLE__) || defined(__MEMMODEL_FLEXIBLE__)
-
+			else if(iMemoryModel == EMemModelFlexible || iMemoryModel == EMemModelMultiple)
+				{
 #ifdef __CPU_X86
-			TUint ttbcr = KPsudoX86TTBCR;
+				TUint ttbcr = KPsudoX86TTBCR;
 #else
-			TUint ttbcr = KPageDirectorySize >> GetTTBCR();
-#endif
+				TUint ttbcr = KPageDirectorySize >> GetTTBCR();
+#endif // __CPU_X86
 
-			if (pd==KGlobalPageDirectory)
-				{
-				pdSize=KPageDirectorySize - ttbcr;
-				pdBase=KPageDirectoryBase + ttbcr*4;
-				r = ttbcr & KPageOffsetMask;
+				if (pd==KGlobalPageDirectory)
+					{
+					pdSize=KPageDirectorySize - ttbcr;
+					pdBase=iPageDirectoryBase + ttbcr*4;
+					r = ttbcr & KPageOffsetMask;
+					}
+				else
+					{
+					pdSize = ttbcr;
+					pdBase=iPageDirectoryBase + pd * KPageDirectorySize * 4;
+
+					TPhysAddr phys=Epoc::LinearToPhysical((TLinAddr)pdBase);				
+					r = (phys==KPhysAddrInvalid) ? KErrNoPageTable : KErrNone;
+					}
 				}
-			else
-				{
-				pdSize = ttbcr;
-				pdBase=KPageDirectoryBase + pd * KPageDirectorySize * 4;
-
-				TPhysAddr phys=Epoc::LinearToPhysical((TLinAddr)pdBase);				
-				r = (phys==KPhysAddrInvalid) ? KErrNoPageTable : KErrNone;
-				}
-			
-#endif  //memmodel
 
 			if ((r & KErrNoPageTable) == 0)
 				{
--- a/kerneltest/e32test/mmu/d_shadow.h	Tue Feb 02 01:24:03 2010 +0200
+++ b/kerneltest/e32test/mmu/d_shadow.h	Fri Apr 16 16:24:37 2010 +0300
@@ -37,45 +37,6 @@
 	ECpuArm,
 	ECpuX86
 	};
-	
-	
-#ifdef __KERNEL_MODE__
-
-// Memory Model Architecture
-
-#ifdef __CPU_X86
-	const TUint KPageDirectorySize = 1024;
-	const TUint KMaxNumberOfPageDirectories = 1024;
-	const TUint KPsudoX86TTBCR = 512;
-
-#else 
-	const TUint KPageDirectorySize = 4096;  // Full size (ttbr0+ttbr1)
-	const TUint KMaxNumberOfPageDirectories = 256;
-#endif
-
-#if defined(__MEMMODEL_MOVING__)
-	const TUint KPageDirectoryBase = 0x61000000;
-	const TUint KPageTableBase = 0x62000000;
-	const TMemModel  KMemoryModel = EMemModelMoving;
-	
-#elif defined(__MEMMODEL_MULTIPLE__)
-	const TUint KPageDirectoryBase = 0xC1000000;
-	const TUint KPageTableBase = 0xC2000000;
-	const TMemModel  KMemoryModel = EMemModelMultiple;
-
-#elif defined(__MEMMODEL_FLEXIBLE__)
-	const TUint KPageDirectoryBase = 0xF4000000u;
-	const TUint KPageTableBase = 0xF8000000u;
-	const TMemModel  KMemoryModel = EMemModelFlexible;
-	
-#else // other memory model
-	const TUint KPageDirectoryBase = 0x00000000;
-	const TUint KPageTableBase = 0x00000000;
-	const TMemModel  KMemoryModel = EMemModelOther;
-#endif
-
-#endif
-
 
 
 class TCapsShadowV01
--- a/kerneltest/e32test/mmu/paging_info.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kerneltest/e32test/mmu/paging_info.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -36,6 +36,7 @@
 	(const TUint8*)"Del notify data page",
 	(const TUint8*)"Read media data page",
 	(const TUint8*)"Write media data page",
+	(const TUint8*)"Rejuvenate page",
 	};
 
 __ASSERT_COMPILE(sizeof(BenchmarkNames)/sizeof(TUint8*) == EMaxPagingBm);
--- a/kerneltest/e32test/mmu/t_cache.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kerneltest/e32test/mmu/t_cache.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -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	Tue Feb 02 01:24:03 2010 +0200
+++ b/kerneltest/e32test/mmu/t_codepaging.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -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();
 	}
 
--- a/kerneltest/e32test/mmu/t_shbuf.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kerneltest/e32test/mmu/t_shbuf.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -2819,6 +2819,11 @@
 	test_KErrNone(r);
 	r = HAL::Get(HAL::EMemoryRAM, ram);
 	test_KErrNone(r);
+	test_Compare(ram, >, 0);
+	// Total system RAM returned by EMemoryRAM should always be < 2GB anyway
+	TUint uram = (TUint) ram;
+	test.Printf(_L("Total system RAM: %u bytes\n"), uram);
+	test.Printf(_L("Page size: %d bytes\n"), pagesize);
 
 	RShPool pool;
 	{ TShPoolCreateInfo inf(TShPoolCreateInfo::EPageAlignedBuffer, 0, 0); r = pool.Create(inf,KDefaultPoolHandleFlags); test_Equal(KErrArgument, r); }
@@ -2835,9 +2840,7 @@
 	{ TShPoolCreateInfo inf(TShPoolCreateInfo::EPageAlignedBuffer, 4096, 10); inf.SetExclusive(); r = pool.Create(inf, KDefaultPoolHandleFlags); test_Equal(KErrNotSupported, r); pool.Close(); }
 	{ TShPoolCreateInfo inf(TShPoolCreateInfo::ENonPageAlignedBuffer, 4096, 10, 12); r = pool.Create(inf, KDefaultPoolHandleFlags); test_Equal(KErrNone, r); pool.Close(); }
 	{ TShPoolCreateInfo inf(TShPoolCreateInfo::ENonPageAlignedBuffer, 4096, 10, 12); inf.SetExclusive(); r = pool.Create(inf, KDefaultPoolHandleFlags); test_Equal(KErrArgument, r); pool.Close(); }
-#ifndef __WINS__
-	{ TShPoolCreateInfo inf(TShPoolCreateInfo::EPageAlignedBuffer, 128 * pagesize, (ram / (128 * pagesize)) + 1); r = pool.Create(inf,KDefaultPoolHandleFlags); test_Equal(KErrNoMemory, r); }
-#endif
+	{ TShPoolCreateInfo inf(TShPoolCreateInfo::EPageAlignedBuffer, 128 * pagesize, (uram / (128 * pagesize)) + 1); r = pool.Create(inf,KDefaultPoolHandleFlags); test_Equal(KErrNoMemory, r); }
 	{ TShPoolCreateInfo inf(TShPoolCreateInfo::ENonPageAlignedBuffer, 0, 0, 0); r = pool.Create(inf,KDefaultPoolHandleFlags); test_Equal(KErrArgument, r); }
 	{ TShPoolCreateInfo inf(TShPoolCreateInfo::ENonPageAlignedBuffer, 100, 0, 0); r = pool.Create(inf,KDefaultPoolHandleFlags); test_Equal(KErrArgument, r); }
 	{ TShPoolCreateInfo inf(TShPoolCreateInfo::ENonPageAlignedBuffer, 0, 100, 0); r = pool.Create(inf,KDefaultPoolHandleFlags); test_Equal(KErrArgument, r); }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/mmu/t_wsd_dl1.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,30 @@
+// Copyright (c) 2006-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\mmu\t_wsd_dl1.cpp
+//
+
+// MMH file will define	T_WSD_DL1
+#include "t_wsd_tst.h"
+
+// Exported writable static data
+EXPORT_D TInt32 ExportedData = 0x717a1ee7;
+
+// Exported Function
+EXPORT_C TInt CheckExportedDataAddress(void* aDataAddr)
+	{
+	RDebug::Printf("CheckExportedDataAddress: ExportedData@%08x, aDataAddr %08x",
+		&ExportedData, aDataAddr);
+	return aDataAddr == (void*)&ExportedData ? KErrNone : KErrGeneral;
+	}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/mmu/t_wsd_dl2.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,65 @@
+// Copyright (c) 2006-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\mmu\t_wsd_dl2.cpp
+// 
+
+// MMH file will define	T_WSD_DL2
+#include "t_wsd_tst.h"
+
+// Ordinal 1
+EXPORT_C void** GetAddressOfDataProxy(TInt& aSize, void*& aCodeAddr, void*& aDataAddr)
+	{
+	return GetAddressOfData(aSize, aCodeAddr, aDataAddr);
+	}
+
+// Ordinal 2
+EXPORT_C TInt CheckWritableStaticData(void)
+	{
+	RDebug::Printf("CheckWritableStaticData: start");
+	TInt err = KErrNone;
+	TInt size;
+	void* codeAddr;
+	void* dataAddr;
+	const void*** dataPtrPtr = (const void***)GetAddressOfData(size, codeAddr, dataAddr);
+
+	RDebug::Printf("CheckWritableStaticData: size %d, codeAddr %08x, dataAddr %08x",
+		size, codeAddr, dataAddr);
+	RDebug::Printf("CheckWritableStaticData: dataPtrPtr %08x, PointerToStaticData is at %08x",
+		dataPtrPtr, &PointerToStaticData);
+
+	if (dataPtrPtr != (const void***)&PointerToStaticData)
+		err = KErrGeneral;
+	const void** p1 = *dataPtrPtr;
+	RDebug::Printf("CheckWritableStaticData: *dataPtrPtr %08x", p1);
+	const void* const* p2 = PointerToStaticData;
+	RDebug::Printf("CheckWritableStaticData: PointerToStaticData %08x", p2);
+	if (p1 != (const void**)p2)
+		err = KErrGeneral;
+	if (p1 != (const void**)dataAddr)
+		err = KErrGeneral;
+
+	RDebug::Printf("CheckWritableStaticData: TestDataSize is at %08x", &TestDataSize);
+	TInt sz = TestDataSize;
+	RDebug::Printf("CheckWritableStaticData: TestDataSize is %d", sz);
+	if (sz != size)
+		err = KErrGeneral;
+
+	void** p3 = WritableTestData;
+	void** p4 = PointerToWritableData;
+	if (p3 != p4)
+		err = KErrGeneral;
+
+	return err;
+	}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/mmu/t_wsd_dl3.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,80 @@
+// Copyright (c) 2006-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\mmu\t_wsd_dl3.cpp
+//
+
+// MMH file will define	T_WSD_DL3
+#include "t_wsd_tst.h"
+
+#define C 		((void*)DummyFn)
+#define D 		((void*)TestData)
+#define A4W		C, D, C, D												// 4 words
+#define A16W	A4W, A4W, A4W, A4W										// 16 words
+#define A64W 	A16W, A16W, A16W, A16W									// 64 words
+#define A256W 	A64W, A64W, A64W, A64W									// 256 words
+#define A1KW	A256W, A256W, A256W, A256W								// 1Kwords
+#define A4KW	A1KW, A1KW, A1KW, A1KW									// 4Kwords
+
+// Non-exported dummy function whose address is put in the initialised
+// data, to check that it gets relocated correctly
+void DummyFn(void)
+	{
+	}
+
+// Non-exported const data, which should end up in the text segment
+// but doesn't on some platforms :(
+static const void* const TestData[] = { A4KW, A4KW };					// 8Kwords
+const TInt KSizeOfTestData = sizeof(TestData);							// 32Kbytes
+
+// Exported Ordinals 2-5
+EXPORT_D TInt32 TestDataSize = KSizeOfTestData;
+EXPORT_D void* WritableTestData[] = { A4KW, A4KW };
+EXPORT_D const void* const* PointerToStaticData = TestData;
+EXPORT_D void** PointerToWritableData = WritableTestData;
+
+// Dummy function, just so that this DLL contains more than one page of
+// text even on platforms where the read-only data ends up in the data
+// rather than the text segment ...
+TUint AddEmUp()
+	{
+	const void* const* p = TestData;
+	TUint sum = 0;
+
+#define	ADD1W	{ sum += (TUint)*p++; }									// 1 word
+#define	ADD4W	{ ADD1W; ADD1W; ADD1W; ADD1W; }							// 4 words
+#define	ADD16W	{ ADD4W; ADD4W; ADD4W; ADD4W; }							// 16 words
+#define	ADD64W	{ ADD16W; ADD16W; ADD16W; ADD16W; }						// 64 words
+#define	ADD256W	{ ADD64W; ADD64W; ADD64W; ADD64W; }						// 256 words
+#define	ADD1KW	{ ADD256W; ADD256W; ADD256W; ADD256W; }					// 1K words
+
+	// The macro ADD1KW should expand to ~2K instructions i.e. ~8Kb of inline code
+	for (TUint i = 0; i < sizeof(TestData)/(1024*sizeof(void*)); ++i)
+		ADD1KW;
+
+	// We've added up all 8Kwords (32kb) of the test data ...
+	return sum;
+	}
+
+// Exported Ordinal 1
+EXPORT_C void** GetAddressOfData(TInt& aSize, void*& aCodeAddr, void*& aDataAddr)
+	{
+	TAny* p = User::Alloc(KSizeOfTestData);
+	aSize = AddEmUp();
+	aSize = KSizeOfTestData;
+	aCodeAddr = C;
+	aDataAddr = D;
+	User::Free(p);
+	return (void**)&PointerToStaticData;
+	}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/mmu/t_wsd_tst.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,466 @@
+// Copyright (c) 2006-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\mmu\t_wsd_tst.cpp
+// Test exporting and importing writable static data in DLLs.
+// This test relies on three dlls:
+// - t_wsd_dl1_[cx][pu]		Which is statically linked, and exports both code & data
+// - t_wsd_dl2_[cx][pu]		Which is dyanamically loaded, and imports code & writable static data from
+// - t_wsd_dl3_[cx][pu]		Which exports code and writable static data
+// The [cx] suffix indicates code-in-RAM vs XIP (ROM), and [pu] indicate paged or unpaged code.
+//
+
+//! @SYMTestCaseID			KBASE-T_CODEPAGING-0335
+//! @SYMTestType			UT
+//! @SYMPREQ				PREQ1110
+//! @SYMTestCaseDesc		Demand Paging Code Paging tests.
+//! @SYMTestActions			001 Code paging tests
+//! @SYMTestExpectedResults All tests should pass.
+//! @SYMTestPriority        High
+//! @SYMTestStatus          Implemented
+
+#define __E32TEST_EXTENSION__
+#include <e32test.h>
+#include <e32math.h>
+#include <f32file.h>
+#include <f32dbg.h>
+
+#include "mmudetect.h"
+#include "t_wsd_tst.h"
+
+// Global data /////////////////////////////////////////////////////////////////
+
+_LIT(KSearchPathTemplate, "%c:\\sys\\bin");		// drive letter
+_LIT(KLibraryName, "t_wsd_dl%d_%c%c");			// [23] [cx] [pu]
+
+TInt TheFailure = KErrNone;
+TChar CurrentDrive = 'Z';
+
+void SetCurrentDrive(TChar aDrive)
+	{
+	CurrentDrive = aDrive;
+	}
+
+class TPagingDriveInfo
+	{
+public:
+	TChar iDriveLetter;
+	TDriveInfo iDriveInfo;
+	};
+
+RArray<TPagingDriveInfo> SupportedDrives;
+
+// RTest stuff /////////////////////////////////////////////////////////////////
+
+RTest test(_L("T_WSD"));
+
+#define test_noError(x) { TInt _r = (x); if (_r < 0) HandleError(_r, __LINE__); }
+#define test_notNull(x) { TAny* _a = (TAny*)(x); if (_a == NULL) HandleNull(__LINE__); }
+#define test_equal(e, a) { TInt _e = TInt(e); TInt _a = TInt(a); if (_e != _a) HandleNotEqual(_e, _a, __LINE__); }
+
+void HandleError(TInt aError, TInt aLine)
+	{
+	test.Printf(_L("Error %d\n"), aError);
+	test.operator()(EFalse, aLine);
+	}
+
+void HandleNull(TInt aLine)
+	{
+	test.Printf(_L("Null value\n"));
+	test.operator()(EFalse, aLine);
+	}
+
+void HandleNotEqual(TInt aExpected, TInt aActual, TInt aLine)
+	{
+	test.Printf(_L("Expected 0x%x but got 0x%x\n"), aExpected, aActual);
+	test.operator()(EFalse, aLine);
+	}
+
+// Utility functions ///////////////////////////////////////////////////////////
+
+TPtrC16 GetMediaType(TInt aMediaType)
+	{
+	_LIT(KMediaNotPresent, "MediaNotPresent");
+	_LIT(KMediaUnknown, "MediaUnknown");
+	_LIT(KMediaFloppy, "MediaFloppy");
+	_LIT(KMediaHardDisk, "MediaHardDisk");
+	_LIT(KMediaCdRom, "MediaCdRom");
+	_LIT(KMediaRam, "MediaRam");
+	_LIT(KMediaFlash, "MediaFlash");
+	_LIT(KMediaRom, "MediaRom");
+	_LIT(KMediaRemote, "MediaRemote");
+	_LIT(KMediaNANDFlash, "MediaNANDFlash");
+	_LIT(KMediaUnKnown, "MediaUnKnown");
+
+	switch (aMediaType)
+		{
+	case EMediaNotPresent:
+		return KMediaNotPresent();
+	case EMediaUnknown:
+		return KMediaUnknown();
+	case EMediaFloppy:
+		return KMediaFloppy();
+	case EMediaHardDisk:
+		return KMediaHardDisk();
+	case EMediaCdRom:
+		return KMediaCdRom();
+	case EMediaRam:
+		return KMediaRam();
+	case EMediaFlash:
+		return KMediaFlash();
+	case EMediaRom:
+		return KMediaRom();
+	case EMediaRemote:
+		return KMediaRemote();
+	case EMediaNANDFlash:
+		return KMediaNANDFlash();
+	default:
+		return KMediaUnKnown();
+		}
+	}
+
+// Get the list of testable drives
+void GetSupportedDrives(TBool aVerbose = EFalse)
+	{
+	TUint32 memModelAttributes = UserSvr::HalFunction(EHalGroupKernel, EKernelHalMemModelInfo, NULL, NULL);
+	TBool codePagingSupported = (memModelAttributes & EMemModelAttrCodePaging) != 0;
+	TUint32 pagingPolicy = E32Loader::PagingPolicy();
+	TBool pagingPolicyAllowsPaging = pagingPolicy != EKernelConfigCodePagingPolicyNoPaging;
+	test_Equal(codePagingSupported, pagingPolicyAllowsPaging);
+	if (codePagingSupported)
+		test.Printf(_L("Code paging is enabled.\n"));
+	else
+		test.Printf(_L("Code paging is NOT enabled.\n"));
+
+	if (aVerbose)
+		{
+		test.Printf(_L("Available drives:\n"));
+		test.Printf(_L("     Type             Attr     MedAttr  Filesystem\n"));
+		}
+
+	RFs fs;
+	test_noError(fs.Connect());
+
+	TDriveList driveList;
+	TInt r = fs.DriveList(driveList);
+	test_noError(r);
+
+	TBool NandPageableMediaFound = EFalse;
+	for (TInt drvNum=0; drvNum<KMaxDrives; ++drvNum)
+		{
+		if (!driveList[drvNum])
+			continue;   //-- skip unexisting drive
+
+		TDriveInfo driveInfo;
+		r = fs.Drive(driveInfo, drvNum);
+		test_noError(r);
+
+		TChar ch;
+		r = fs.DriveToChar(drvNum, ch);
+		test_noError(r);
+
+		TBuf<256> fileSystemName;
+		r = fs.FileSystemName(fileSystemName, drvNum);
+		test_noError(r);
+
+		// Decide which drives to exclude:
+		//		Locked/nonwritable drives, except the Z: ROM drive
+		//		Win32 drives on the emulator
+		//		Remote/nonlocal, removable/noninternal, redirected, substed drives
+		//	All others are included by default iff code paging is supported
+		//	If not, only the Z: ROM/XIP drive is tested
+		_LIT(KWin32FS, "Win32");
+		TBool include = codePagingSupported;
+		if (driveInfo.iDriveAtt & KDriveAttRom)
+			include = (ch == 'Z');
+		else if (driveInfo.iMediaAtt & (KMediaAttWriteProtected|KMediaAttLocked))
+			include = EFalse;
+		else if (fileSystemName == KWin32FS())
+			include = EFalse;
+		else if (driveInfo.iDriveAtt & (KDriveAttRedirected|KDriveAttSubsted|KDriveAttRemovable|KDriveAttRemote))
+			include = EFalse;
+		else if ((KDriveAttInternal|KDriveAttLocal) & ~driveInfo.iDriveAtt)
+			include = EFalse;
+
+		if (include)
+			{
+			TPagingDriveInfo pagingDriveInfo;
+			pagingDriveInfo.iDriveLetter = ch;
+			pagingDriveInfo.iDriveInfo = driveInfo;
+			r = SupportedDrives.Append(pagingDriveInfo);
+			test_noError(r);
+			}
+
+		TBool pageable = EFalse;
+		if (driveInfo.iDriveAtt & KDriveAttPageable)
+			{
+			pageable = ETrue;
+			if (driveInfo.iType == EMediaNANDFlash)
+				NandPageableMediaFound = ETrue;
+			}
+
+		// If we've already found a pageable NAND drive, then assume the
+		// Z: drive is pageable too if it's got a composite file system
+		_LIT(KCompositeName,"Composite");
+		if (NandPageableMediaFound && fileSystemName == KCompositeName())
+			pageable = ETrue;
+
+		if (aVerbose)
+			{
+			TPtrC16 mediaType = GetMediaType(driveInfo.iType);
+			_LIT(KPageable, "pageable");
+			test.Printf(_L("%c  %c: %16S %08x %08x %10S %S\n"),
+						include ? '*' : ' ', (TUint)ch, &mediaType,
+						driveInfo.iDriveAtt, driveInfo.iMediaAtt,
+			            &fileSystemName, (pageable ? &KPageable : &KNullDesC));
+			}
+		}
+
+	fs.Close();
+	}
+
+const TDesC& LibrarySearchPath(TChar aDrive)
+	{
+	static TBuf<64> path;
+	path.Format(KSearchPathTemplate, (TUint)aDrive);
+	return path;
+	}
+
+const TDesC& LibraryName(TChar aDrive, TInt aLibNo, TBool aRam, TBool aPaged)
+	{
+	// this gives DLL#2 a different name on each drive so we can be sure we're loading the right one
+	static TBuf<64> name;
+	name.Format(KLibraryName, aLibNo, aRam ? 'c' : 'x', aPaged ? 'p' : 'u');
+	if (aLibNo == 2 && aDrive != 'Z')
+		name.AppendFormat(_L("_%c"), (TUint)aDrive);
+	return name;
+	}
+
+const TDesC& LibraryFilename(TChar aDrive, TInt aLibNo, TBool aRam, TBool aPaged)
+	{
+	static TBuf<64> filename;
+	filename = LibrarySearchPath(aDrive);
+	filename.AppendFormat(_L("\\%S.dll"), &LibraryName(aDrive, aLibNo, aRam, aPaged));
+	return filename;
+	}
+
+TInt LoadSpecificLibrary(RLibrary& aLibrary, TChar aDrive, TInt aLibNo, TBool aRam, TBool aPaged)
+	{
+	const TDesC& path = LibrarySearchPath(aDrive);
+	const TDesC& name = LibraryName(aDrive, aLibNo, aRam, aPaged);
+	TInt err = aLibrary.Load(name, path);
+	TBuf<256> message;
+	message.Format(_L("Loading %S\\%S.dll returns %d\n"), &path, &name, err);
+	test.Printf(message);
+	return err;
+	}
+
+// Test functions //////////////////////////////////////////////////////////////
+
+void CopyDllToCurrentDrive(RFs& aFs, TBool aPaged, TInt aLibNo)
+	{
+	TBuf<64> source = LibraryFilename('Z', aLibNo, ETrue, aPaged);
+	TBuf<64> dest = LibraryFilename(CurrentDrive, aLibNo, ETrue, aPaged);
+	test.Printf(_L("Copying %S to %S\n"), &source, &dest);
+
+	TInt r = aFs.MkDirAll(dest);
+	test(r == KErrNone || r == KErrAlreadyExists);
+
+	TBuf<64> tempName(dest);
+	tempName.Append(_L(".tmp"));
+
+	RFile in, out, temp;
+	test_noError(in.Open(aFs, source, EFileRead));
+	test_noError(out.Replace(aFs, dest, EFileWrite));
+	test_noError(temp.Replace(aFs, tempName, EFileWrite));
+
+	const TInt KBufferSize = 3333;
+	TBuf8<KBufferSize> buffer;
+
+	test_noError(temp.Write(buffer));
+	test_noError(temp.Flush());
+
+	TInt size;
+	test_noError(in.Size(size));
+	TInt pos = 0;
+	while (pos < size)
+		{
+		test_noError(in.Read(buffer));
+		test_noError(out.Write(buffer));
+		test_noError(out.Flush());
+		test_noError(temp.Write(buffer));
+		test_noError(temp.Flush());
+		pos += buffer.Length();
+		}
+
+	out.SetAtt(KEntryAttNormal, KEntryAttReadOnly|
+								KEntryAttHidden|
+								KEntryAttSystem|
+								KEntryAttArchive|
+								KEntryAttXIP);
+
+	in.Close();
+	out.Close();
+	temp.Close();
+	}
+
+void CopyDllsToCurrentDrive()
+	{
+	RFs fs;
+	test_noError(fs.Connect());
+
+	CopyDllToCurrentDrive(fs, EFalse, 2);		// Unpaged library 2
+	CopyDllToCurrentDrive(fs, EFalse, 3);		// Unpaged library 3
+	CopyDllToCurrentDrive(fs, ETrue, 2);		// Paged library 2
+	CopyDllToCurrentDrive(fs, ETrue, 3);		// Paged library 3
+
+	fs.Close();
+	}
+
+void EraseDllsFromCurrentDrive()
+	{
+	RFs fs;
+	test_noError(fs.Connect());
+
+	CTrapCleanup* cleanup = CTrapCleanup::New();
+	test_notNull(cleanup);
+
+	CFileMan* fileMan = NULL;
+	TRAPD(r, fileMan = CFileMan::NewL(fs));
+	test_noError(r);
+
+	TBuf<64> libdir = LibrarySearchPath(CurrentDrive);
+	test.Printf(_L("Erasing %S\n"), &libdir);
+	fileMan->RmDir(libdir);
+
+	delete fileMan;
+	delete cleanup;
+	fs.Close();
+	}
+
+void CheckRelocatableData(RLibrary& library)
+	{
+	TGetAddressOfDataFunction func = (TGetAddressOfDataFunction)library.Lookup(KGetAddressOfDataFunctionOrdinal);
+	test_notNull(func);
+
+	TInt size;
+	void* codeAddr;
+	void* dataAddr;
+	void*** dataPtrPtr = (void***)func(size, codeAddr, dataAddr);
+	void **dp = (void **)dataAddr;
+
+	for (TInt i = 0; i < size/4; i += 2)
+		{
+		test_equal(dp[i], codeAddr);
+		test_equal(dp[i+1], dataAddr);
+		}
+
+	test_equal(*dataPtrPtr, dp);
+	}
+
+void CheckWritableStaticData(RLibrary& library)
+	{
+	TInt (*func)(void) = (TInt (*)(void))library.Lookup(KCheckWritableStaticDataFunctionOrdinal);
+	RDebug::Printf("CheckWritableStaticData() is export %d at %08x", KCheckWritableStaticDataFunctionOrdinal, func);
+	test_notNull(func);
+	TInt err = func();
+	RDebug::Printf("CheckWritableStaticData() returned %d", err);
+	// test_noError(err);
+	if (TheFailure == KErrNone)
+		TheFailure = err;
+	}
+
+void RunPerDriveTests(TBool aPaged, TBool aRam)
+	{
+	TBuf<64> message = _L("Running ");
+	if (!aPaged)
+		message.Append(_L("un"));
+	message.AppendFormat(_L("paged R%cM tests on drive %c:"),
+		aRam ? 'A' : 'O', (TUint)CurrentDrive);
+	test.Next(message);
+
+	RFs fs;
+	test_noError(fs.Connect());
+	fs.SetDebugRegister(KFLDR);
+
+	// Explicitly loading dl2 will implicitly load dl3 as well
+	RLibrary dl2;
+	test_noError(LoadSpecificLibrary(dl2, CurrentDrive, 2, aRam, aPaged));
+	CheckRelocatableData(dl2);
+	CheckWritableStaticData(dl2);
+	dl2.Close();
+
+	fs.SetDebugRegister(0);
+	fs.Close();
+	}
+
+TInt E32Main()
+	{
+	test.Title();
+	test.Start(_L("WSD tests"));
+
+	// Check static linkage to dl1
+	test_noError(CheckExportedDataAddress(&ExportedData));
+
+	GetSupportedDrives(ETrue);
+	test(SupportedDrives.Count() > 0);
+
+	// Turn off evil lazy dll unloading
+	RLoader l;
+	test(l.Connect()==KErrNone);
+	test(l.CancelLazyDllUnload()==KErrNone);
+	l.Close();
+
+	// Make sure there aren't any DLLs left over from earlier tests
+	TInt i = SupportedDrives.Count();
+	while (--i >= 0)
+		{
+		SetCurrentDrive(SupportedDrives[i].iDriveLetter);
+		if (CurrentDrive != 'Z')
+				EraseDllsFromCurrentDrive();
+		}
+
+	// We want to test all supported drives in order of increasing priority, so
+	// that the CurrentDrive is always the hghest priority of those tested so far.
+	// Therefore, if Z (XIP ROM, lowest priority) is a valid test drive, do it first
+	i = SupportedDrives.Count();
+	if (--i >= 0)
+		{
+		SetCurrentDrive(SupportedDrives[i].iDriveLetter);
+		if (CurrentDrive == 'Z')
+			{
+			// ROM (XIP) tests can only be run from Z:
+			RunPerDriveTests(EFalse, EFalse);		// Unpaged ROM
+			RunPerDriveTests(ETrue, EFalse);		// Paged ROM
+			RunPerDriveTests(EFalse, ETrue);		// Unpaged RAM
+			RunPerDriveTests(ETrue, ETrue);			// Paged RAM
+			}
+		}
+
+	// Now run the RAM-based versions from each remaining drive in turn
+	for (i = 0; i < SupportedDrives.Count(); ++i)
+		{
+		SetCurrentDrive(SupportedDrives[i].iDriveLetter);
+		if (CurrentDrive != 'Z')
+			{
+			CopyDllsToCurrentDrive();
+			RunPerDriveTests(EFalse, ETrue);			// Unpaged RAM
+			RunPerDriveTests(ETrue, ETrue);				// Paged RAM
+			}
+		}
+
+	test_noError(TheFailure);
+	test.End();
+	return 0;
+	}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/mmu/t_wsd_tst.h	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,74 @@
+// Copyright (c) 2006-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\mmu\t_wsd_tst.h
+//
+
+#include <e32std.h>
+#include <e32debug.h>
+
+#ifndef __T_WSD_TST_H__
+#define __T_WSD_TST_H__
+
+#if		defined(__MARM_ARM4__)
+// ARM4: definition of IMPORT_D is wrong?
+#undef	IMPORT_D
+#define	IMPORT_D	 __declspec(dllimport)
+#endif	// defined(__MARM_ARM4__)
+
+#if		defined(__MARM_ARMV5__)
+// ARMV5: definition of IMPORT_D is wrong?
+#undef	IMPORT_D
+#define	IMPORT_D	 __declspec(dllimport)
+#endif	// defined(__MARM_ARMV5__)
+
+#if		defined(__MSVC6__)
+// MSVC6: definition of IMPORT_D is wrong?
+#undef	IMPORT_D
+#define	IMPORT_D	 __declspec(dllimport)
+#endif	// defined(__MSVC6__)
+
+#if		defined(__WINS__)
+// WINSCW: definition of IMPORT_D is wrong?
+#undef	IMPORT_D
+#define	IMPORT_D	 __declspec(dllimport)
+#endif	// defined(__WINS__)
+
+// Exports of DLL1
+#ifdef	T_WSD_DL1
+#else
+IMPORT_D TInt32 ExportedData;
+IMPORT_C TInt CheckExportedDataAddress(void *aDataAddr);
+#endif	// T_WSD_DL1
+
+// Exports of DLL2
+#ifdef	T_WSD_DL2
+#else
+typedef void** (*TGetAddressOfDataFunction)(TInt&, void*&, void*&);
+const TInt KGetAddressOfDataFunctionOrdinal = 1;
+IMPORT_C void** GetAddressOfDataProxy(TInt& aSize, void*& aCodeAddr, void*& aDataAddr);
+const TInt KCheckWritableStaticDataFunctionOrdinal = 2;
+IMPORT_C TInt CheckWritableStaticData(void);
+#endif	// T_WSD_DL2
+
+// Exports of DLL3
+#ifdef	T_WSD_DL3
+#else
+IMPORT_C void** GetAddressOfData(TInt& aSize, void*& aCodeAddr, void*& aDataAddr);
+IMPORT_D TInt32 TestDataSize;
+IMPORT_D void* WritableTestData[1 /* refer TestDataSize */];
+IMPORT_D const void* const* PointerToStaticData;
+IMPORT_D void** PointerToWritableData;
+#endif	// T_WSD_DL3
+
+#endif	// __T_WSD_TST_H__
--- a/kerneltest/e32test/nkernsa/arm/armutils.cia	Tue Feb 02 01:24:03 2010 +0200
+++ b/kerneltest/e32test/nkernsa/arm/armutils.cia	Fri Apr 16 16:24:37 2010 +0300
@@ -90,7 +90,7 @@
 	asm("nop ");
 	asm("nop ");
 	asm("nop ");
-	asm("ldr	r0, [r0, #%a0]" : : "i" _FOFF(TSubScheduler,i_LocalTimerAddr));
+	asm("ldr	r0, [r0, #%a0]" : : "i" _FOFF(TSubScheduler,iSSX.iLocalTimerAddr));
 	asm("nop ");
 	asm("nop ");
 	asm("nop ");
@@ -103,7 +103,7 @@
 	asm("nop ");
 	asm("nop ");
 	asm("nop ");
-	asm("ldr	r1, [r0, #%a0]" : : "i" _FOFF(TSubScheduler,i_LocalTimerAddr));
+	asm("ldr	r1, [r0, #%a0]" : : "i" _FOFF(TSubScheduler,iSSX.iLocalTimerAddr));
 	asm("nop ");
 	asm("nop ");
 	asm("nop ");
@@ -118,7 +118,7 @@
 	asm("nop ");
 	asm("nop ");
 	asm("nop ");
-	asm("ldr	r1, [r0, #%a0]" : : "i" _FOFF(TSubScheduler,i_LocalTimerAddr));
+	asm("ldr	r1, [r0, #%a0]" : : "i" _FOFF(TSubScheduler,iSSX.iLocalTimerAddr));
 	asm("nop ");
 	asm("nop ");
 	asm("nop ");
@@ -133,7 +133,7 @@
 	asm("nop ");
 	asm("nop ");
 	asm("nop ");
-	asm("ldr	r1, [r0, #%a0]" : : "i" _FOFF(TSubScheduler,i_LocalTimerAddr));
+	asm("ldr	r1, [r0, #%a0]" : : "i" _FOFF(TSubScheduler,iSSX.iLocalTimerAddr));
 	asm("nop ");
 	asm("nop ");
 	asm("nop ");
--- a/kerneltest/e32test/nkernsa/fastmutex.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kerneltest/e32test/nkernsa/fastmutex.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -1036,6 +1036,7 @@
 	NThreadGroup group;
 	SNThreadGroupCreateInfo ginfo;
 	ginfo.iCpuAffinity = aRWCpu;
+	ginfo.iDestructionDfc = 0;	//FIXME
 	TInt r = NKern::GroupCreate(&group, ginfo);
 	TEST_RESULT(r==KErrNone, "");
 	winfo->iGroup = &group;
--- a/kerneltest/e32test/nkernsa/kprintf.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kerneltest/e32test/nkernsa/kprintf.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -302,7 +302,7 @@
 #define NEXT_FMT(c,p) if (((c)=*(p)++)==0) return outLen;
 
 	TInt outLen = 0;
-	FOREVER
+	while(outLen>=0)
 		{
 		char c;
 		NEXT_FMT(c,aFmt);
--- a/kerneltest/e32test/nkernsa/testdfc.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kerneltest/e32test/nkernsa/testdfc.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -1199,7 +1199,7 @@
 	TInt ncpus = NKern::NumberOfCpus();
 	TInt ocpu = NKern::CurrentCpu();
 	NThread* pC = NKern::CurrentThread();
-	volatile TUint32* pX = (volatile TUint32*)&pC->iRunCount32[1];	// HACK!
+	volatile TUint32* pX = (volatile TUint32*)&pC->iRunCount.i32[1];	// HACK!
 	TInt cpu = ocpu;
 	TInt i;
 	if ((iS->iMode & TDfcStress::EMode_SelfMigrate) && !pC->iEvents.IsEmpty())
@@ -1429,19 +1429,19 @@
 	{
 //	volatile TUint32* xc = 0;
 	NThreadBase* t = iS->iDfcQ[0]->iThread;
-	volatile TUint32* xc = &t->iRunCount32[1];	// HACK!
+	volatile TUint32* xc = &t->iRunCount.i32[1];	// HACK!
 	if (!(iFlags & EFlag_Timer))
 		{
 		TDfc* d = 0;
 		if (!(iFlags & EFlag_IDFC))
 			{
 			d = new TDfc(&TDfcX::DfcFn, this, iDfcQ, 1);
-			xc = (volatile TUint32*)&iDfcQ->iThread->iRunCount32[1];
+			xc = (volatile TUint32*)&iDfcQ->iThread->iRunCount.i32[1];
 			}
 		else if (iFlags & EFlag_Tied)
 			{
 			d = new TDfc(iXTied, &TDfcX::IDfcFn, this);
-			xc = (volatile TUint32*)&iXTied->iRunCount32[1];
+			xc = (volatile TUint32*)&iXTied->iRunCount.i32[1];
 			}
 		else
 			d = new TDfc(&TDfcX::IDfcFn, this);
@@ -1454,12 +1454,12 @@
 		if (iFlags & EFlag_DFC)
 			{
 			tmr = new NTimer(&TDfcX::TimerDfcFn, this, iDfcQ, 1);
-			xc = (volatile TUint32*)&iDfcQ->iThread->iRunCount32[1];
+			xc = (volatile TUint32*)&iDfcQ->iThread->iRunCount.i32[1];
 			}
 		else if (iFlags & EFlag_Tied)
 			{
 			tmr = new NTimer(iXTied, &TDfcX::TimerIsrFn, this);
-			xc = (volatile TUint32*)&iXTied->iRunCount32[1];
+			xc = (volatile TUint32*)&iXTied->iRunCount.i32[1];
 			}
 		else
 			tmr = new NTimer(&TDfcX::TimerIsrFn, this);
--- a/kerneltest/e32test/nkernsa/threadbasic.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kerneltest/e32test/nkernsa/threadbasic.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -1246,6 +1246,7 @@
 	NThreadGroup* group = aJoin ? &TG1 : 0;
 	SNThreadGroupCreateInfo ginfo;
 	ginfo.iCpuAffinity = 0xffffffff;
+	ginfo.iDestructionDfc = 0;	//FIXME
 	TInt r = KErrNone;
 	if (group)
 		r = NKern::GroupCreate(group, ginfo);
--- a/kerneltest/e32test/nkernsa/tlsf.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kerneltest/e32test/nkernsa/tlsf.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -357,7 +357,6 @@
 	TUint32 a;
 	TUint32 szs = 0;
 	TUint32 size;
-	TUint32 total_user_size;
 	TUint32 total_block_size = 0;
 	TUint32 block_count = 0;
 	TUint32 flb = 0;
@@ -367,34 +366,35 @@
 	TUint32 total_free = 0;
 	SBlock* b = iff;
 	SBlock* pb = 0;
+	TUint32 total_user_size;
 
 	memset(slb, 0, sizeof(slb));
-	__NK_ASSERT_DEBUG(imin_size == 16);
-	__NK_ASSERT_DEBUG(insl == 16);
-	__NK_ASSERT_DEBUG(il2min == 4);
-	__NK_ASSERT_DEBUG(il2nsl == 4);
-	__NK_ASSERT_DEBUG(infl == __e32_find_ms1_32(itotal_size) - il2min + 1);
+	__NK_ASSERT_ALWAYS(imin_size == 16);
+	__NK_ASSERT_ALWAYS(insl == 16);
+	__NK_ASSERT_ALWAYS(il2min == 4);
+	__NK_ASSERT_ALWAYS(il2nsl == 4);
+	__NK_ASSERT_ALWAYS(infl == __e32_find_ms1_32(itotal_size) - il2min + 1);
 	a = (TUint32)&islb[infl];
 	a = (a+63)&~63;
-	__NK_ASSERT_DEBUG(isll == (SFreeBlock**)a);
+	__NK_ASSERT_ALWAYS(isll == (SFreeBlock**)a);
 	a += insl * infl * sizeof(TUint32*);
-	__NK_ASSERT_DEBUG(iff == (SBlock*)a);
+	__NK_ASSERT_ALWAYS(iff == (SBlock*)a);
 	total_user_size = itotal_size - (a - (TUint32)this);
 
 	do	{
 		szs = b->size;
 		size = szs & BLOCK_SIZE_MASK;
-		__NK_ASSERT_DEBUG(b->predecessor == pb);
-		__NK_ASSERT_DEBUG(size > 0);
-		__NK_ASSERT_DEBUG(size <= total_user_size);
-		__NK_ASSERT_DEBUG(size == ((size >> il2min) << il2min));
+		__NK_ASSERT_ALWAYS(b->predecessor == pb);
+		__NK_ASSERT_ALWAYS(size > 0);
+		__NK_ASSERT_ALWAYS(size <= total_user_size);
+		__NK_ASSERT_ALWAYS(size == ((size >> il2min) << il2min));
 		total_block_size += size;
 		++block_count;
 		pb = b;
 		b = (SBlock*)((TUint32)b + size);
 		} while(!(szs & BLOCK_STATUS_FINAL));
-	__NK_ASSERT_DEBUG((TUint32)b == (TUint32)this + itotal_size);
-	__NK_ASSERT_DEBUG(total_block_size == total_user_size);
+	__NK_ASSERT_ALWAYS((TUint32)b == (TUint32)this + itotal_size);
+	__NK_ASSERT_ALWAYS(total_block_size == total_user_size);
 
 	b = iff;
 	do	{
@@ -403,9 +403,9 @@
 		if (szs & BLOCK_STATUS_FREE)
 			{
 			SFreeBlock* fb = (SFreeBlock*)b;
-			SFreeBlock* pfb = fb;
+			TUint32 lhi;
 			SFreeBlock* lh;
-			TUint32 lhi;
+			SFreeBlock* pfb = fb;
 			TInt lh_found = 0;
 			TInt c = (TInt)block_count;
 			TUint32 fli = __e32_find_ms1_32(size) - il2min;
@@ -415,8 +415,8 @@
 			(void)sli2, (void)fli2;
 			if (fli > il2nsl)
 				sli >>= (fli - il2nsl);
-			__NK_ASSERT_DEBUG(fli == fli2);
-			__NK_ASSERT_DEBUG(sli == sli2);
+			__NK_ASSERT_ALWAYS(fli == fli2);
+			__NK_ASSERT_ALWAYS(sli == sli2);
 			flb |= (1u << fli);
 			slb[fli] |= (1u << sli);
 			lhi = (fli << il2nsl) | sli;
@@ -426,28 +426,27 @@
 					lh_found = 1;
 				pfb = fb;
 				fb = fb->next;
-				__NK_ASSERT_DEBUG(fb->prev == pfb);
-				__NK_ASSERT_DEBUG(fb->b.size & BLOCK_STATUS_FREE);
+				__NK_ASSERT_ALWAYS(fb->prev == pfb);
+				__NK_ASSERT_ALWAYS(fb->b.size & BLOCK_STATUS_FREE);
 				} while ((fb != (SFreeBlock*)b) && --c>=0);
-			__NK_ASSERT_DEBUG(fb == (SFreeBlock*)b);
-			__NK_ASSERT_DEBUG(lh_found);
+			__NK_ASSERT_ALWAYS(fb == (SFreeBlock*)b);
+			__NK_ASSERT_ALWAYS(lh_found);
 			total_free += size;
 			}
 		b = (SBlock*)((TUint32)b + size);
 		} while(!(szs & BLOCK_STATUS_FINAL));
 
-	__NK_ASSERT_DEBUG(flb == iflb);
+	__NK_ASSERT_ALWAYS(flb == iflb);
 	for (fli=0; fli<infl; ++fli)
 		{
-		__NK_ASSERT_DEBUG(slb[fli] == islb[fli]);
+		__NK_ASSERT_ALWAYS(slb[fli] == islb[fli]);
 		if (!(flb & (1u<<fli)))
-			__NK_ASSERT_DEBUG(slb[fli]==0);
+			__NK_ASSERT_ALWAYS(slb[fli]==0);
 		for (sli=0; sli<insl; ++sli)
 			{
 			TUint32 lhi = (fli << il2nsl) | sli;
-			(void)lhi;
 			if (!(slb[fli] & (1u<<sli)))
-				__NK_ASSERT_DEBUG(!isll[lhi]);
+				__NK_ASSERT_ALWAYS(!isll[lhi]);
 			}
 		}
 	return total_free;
--- a/kerneltest/e32test/pccd/t_idrv.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kerneltest/e32test/pccd/t_idrv.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -102,28 +102,23 @@
 
 	test.Next(_L("Find internal drive"));
 	
-	TDriveInfoV1Buf driveInfoBuf;
-	UserHal::DriveInfo(driveInfoBuf);
-	TDriveInfoV1& driveInfo = driveInfoBuf();
-
-	TInt drive = 0;
-	for ( ; drive < driveInfo.iTotalSupportedDrives; ++drive)
+	TInt drive;
+	for (drive = 0; drive < KMaxLocalDrives; drive++)
 		{
 		TBool changedFlag;
-		theInternalDrive.Connect(drive, changedFlag);
+		if (theInternalDrive.Connect(drive, changedFlag) != KErrNone)
+			continue;
 
 		TLocalDriveCapsV2 info;
 		TPckg<TLocalDriveCapsV2> infoPckg(info);
 		theInternalDrive.Caps(infoPckg);
 
 		if (info.iType == EMediaRam)
-			{
-			break;
-			}
+			break;						// found it
 
 		theInternalDrive.Disconnect();
 		}
-	test(drive < driveInfo.iTotalSupportedDrives);
+	test(drive < KMaxLocalDrives);		// iterated over all, found none
 
 	test.Next(_L("Capabilities"));
 	TLocalDriveCapsV2 info;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/pci/t_pci.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -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	Fri Apr 16 16:24:37 2010 +0300
@@ -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
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/random/d_entropysources.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,160 @@
+// 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\entropysources\d_entropysources.cpp
+// 
+//
+/**
+ @file
+ @internalComponent
+ @test
+*/
+#include <dfcs.h>
+#include <kernel/kernel.h>
+#include <kernel/kern_priv.h>
+#include "kern_test.h"
+#include "d_entropysources.h"
+
+//---------------------------------------------------------------------------------------------------------------------
+//! @SYMTestCaseID				KBASE-entropysources-2703
+//! @SYMTestType				UT
+//! @SYMTestCaseDesc			Verifies that entropy is contributed to the Secure RNG
+//! @SYMPREQ					PREQ211
+//! @SYMTestPriority			High
+//! @SYMTestActions				
+//! 	1. 	TestReseed: tests that the interval between RNG reseeds is less than KMaxReseedTime, unless the platform is 
+//!         known not to have a viable entropy source.
+//! 		
+//! 
+//! @SYMTestExpectedResults
+//! 	1.	Properties checked:
+//! 		1) checks that there is a valid entropy source contrbuting entropy data.
+//!         2) checks that the entropy collection framework is functioning correctly..
+//! 	
+//---------------------------------------------------------------------------------------------------------------------
+
+class DEntropySourcesFactory : public DLogicalDevice
+    {
+public:
+    DEntropySourcesFactory();
+    virtual TInt Install();    
+    virtual void GetCaps(TDes8 &aDes) const;
+    virtual TInt Create(DLogicalChannelBase*& aChannel); 
+    };
+
+class DEntropySources : public DLogicalChannelBase
+    {
+public:
+ 	DEntropySources();
+   ~DEntropySources();    
+    void ReseedHook();
+    
+protected:    
+	virtual TInt DoCreate(TInt aUnit, const TDesC8* anInfo, const TVersion& aVer);
+	virtual TInt Request(TInt aReqNo, TAny* a1, TAny* a2);
+
+private:
+    DThread*        iClient;
+    TClientRequest* iRequest;    
+    };
+
+// Function to be called from the kernel side code.
+void ReseedHook(TAny* aPtr)
+    {
+	((DEntropySources*)aPtr)->ReseedHook();
+    }
+
+DECLARE_STANDARD_LDD()
+    {
+     return new DEntropySourcesFactory;
+    }
+
+//
+// DEntropySourcesFactory
+//
+
+DEntropySourcesFactory::DEntropySourcesFactory()
+    {
+    // Set version number for this device
+    iVersion = TVersion(0,1,1);
+
+    // Indicate we don't support units or a PDD
+    iParseMask = 0;
+    }
+
+TInt DEntropySourcesFactory::Install()
+    {
+    return(SetName(&KEntropySourcesName));
+    }
+
+void DEntropySourcesFactory::GetCaps(TDes8& aDes) const
+    {
+    // Create a capabilities object
+    TCapsEntropySources caps;
+    caps.iVersion = iVersion;
+
+    // Write it back to user memory
+    Kern::InfoCopy(aDes,(TUint8*)&caps,sizeof(caps));
+    }
+
+TInt DEntropySourcesFactory::Create(DLogicalChannelBase*& aChannel)
+    {
+    aChannel = new DEntropySources;
+    if(!aChannel)
+        return KErrNoMemory;
+    return KErrNone;
+    }
+
+//
+// DEntropySources
+//
+
+DEntropySources::DEntropySources()
+	{
+    iClient = &Kern::CurrentThread();
+    iClient->Open();
+	}
+
+DEntropySources::~DEntropySources()
+    {
+	KernTest::Test(KernTest::ERNGReseedHook, NULL, NULL);
+    Kern::SafeClose((DObject*&)iClient, NULL);
+	Kern::DestroyClientRequest(iRequest);
+    }
+
+TInt DEntropySources::DoCreate(TInt /*aUnit*/, const TDesC8* /*aInfo*/, const TVersion& /*aVer*/)
+	{
+	return Kern::CreateClientRequest(iRequest);
+	}
+
+TInt DEntropySources::Request(TInt aReqNo, TAny* a1, TAny* a2)
+    {
+    (void)a2;
+    TInt r = KErrNotSupported;
+    switch(aReqNo)
+        {
+        case ~REntropySources::EReseedTest:
+            r = iRequest->SetStatus((TRequestStatus*)a1);
+			if (r!=KErrNone)
+				return r;
+            KernTest::Test(KernTest::ERNGReseedHook, (TAny*)&::ReseedHook, this);            
+            break;
+        }
+    return r;
+    }
+
+void DEntropySources::ReseedHook()
+    {
+	KernTest::Test(KernTest::ERNGReseedHook, NULL, NULL);
+    Kern::QueueRequestComplete(iClient, iRequest, KErrNone);
+    }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/random/d_entropysources.h	Fri Apr 16 16:24:37 2010 +0300
@@ -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:
+// e32test\entropysources\d_entropysources.h
+//
+// Test driver which notifies userspace when an RNG reseed has taken place
+// 
+//
+
+/**
+ @file
+ @internalComponent
+ @test
+*/
+
+#if !defined(__D_ENTROPYSOURCES_H__)
+#define __D_ENTROPYSOURCES_H__
+
+#include <e32cmn.h>
+#ifndef __KERNEL_MODE__
+#include <e32std.h>
+#endif
+
+_LIT(KEntropySourcesName,"D_ENTROPYSOURCES");
+
+class TCapsEntropySources
+    {
+public:
+    TVersion iVersion;
+    };
+
+class REntropySources : public RBusLogicalChannel
+    {
+public:
+  enum TRequest
+        {
+        EReseedTest,        
+        };
+    
+#ifndef __KERNEL_MODE__
+public:
+    inline TInt Open()
+        { 
+        return DoCreate(KEntropySourcesName,TVersion(0, 1, 1),KNullUnit,NULL,NULL,EOwnerThread);    
+        }
+    inline void ReseedTest(TRequestStatus& aRequestStatus)
+        {
+        DoRequest(EReseedTest, aRequestStatus);
+        }
+#endif
+    };
+
+#endif // __D_ENTROPYSOURCES_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/random/t_entropysources.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,131 @@
+// 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:
+// Test suite to check whether the device has good enough entropy sources or not.
+// More the no. of sources, high the quality of the random numbers (least predictable).
+// 
+//
+
+/**
+ @file
+ @internalTechnology
+*/
+
+#define __E32TEST_EXTENSION__
+#include <e32test.h>
+#include <hal.h>
+#include <e32math.h>
+#include "d_entropysources.h"
+
+//---------------------------------------------------------------------------------------------------------------------
+//! @SYMTestCaseID				KBASE-entropysources-2703
+//! @SYMTestType				UT
+//! @SYMTestCaseDesc			Verifies that entropy is contributed to the Secure RNG
+//! @SYMPREQ					PREQ211
+//! @SYMTestPriority			High
+//! @SYMTestActions				
+//! 	1. 	TestReseed: tests that the interval between RNG reseeds is less than KMaxReseedTime, unless the platform is 
+//!         known not to have a viable entropy source.
+//! 		
+//! 
+//! @SYMTestExpectedResults
+//! 	1.	Properties checked:
+//! 		1) checks that there is a valid entropy source contrbuting entropy data.
+//!         2) checks that the entropy collection framework is functioning correctly..
+//! 	
+//---------------------------------------------------------------------------------------------------------------------
+
+// In a worst case scenario, we expect the reseed to happen within ten minutes.
+// This is approximately 1/10 of the actual reseed intervel time (97.8 rounded to => 98).
+// ((2^24 (reseed intervel) * 350 (micro seconds per request)) / 1000000) / 60 => 97.8 minutes.
+//
+const TTimeIntervalMicroSeconds32 KMaxReseedTime = 10 * 60 * 1000000;
+
+REntropySources Ldd;
+
+LOCAL_D RTest test(_L("T_ENTROPYSOURCES"));
+
+LOCAL_C void TestReseed()
+    {    
+    test.Next(_L("Loading test driver"));
+    TInt r = User::LoadLogicalDevice(KEntropySourcesName);
+    test(r==KErrNone || r==KErrAlreadyExists);
+    
+    test.Next(_L("Opening the logical channel"));
+    test_KErrNone(Ldd.Open());
+    
+	RTimer timer;
+	test_KErrNone(timer.CreateLocal());
+
+	test.Next(_L("Testing reseed interval"));
+	// Wait for two reseeds, so we can prove the interval between them is ok
+	for (TInt i=0; i<2; ++i)
+		{
+		// Request notification of the next reseed, with a timeout
+		test.Next(_L("Requesting reseed notification"));
+		TRequestStatus reseed, timeout;
+		Ldd.ReseedTest(reseed);
+		timer.After(timeout, KMaxReseedTime);
+
+		// Prod the RNG to make sure it's not idle, then wait for an event
+		test.Next(_L("Prod RNG and wait"));
+		Math::Random();
+		User::WaitForRequest(reseed, timeout);
+
+		// Check we didn't time out and cancel the timer
+		test_Equal(KRequestPending, timeout.Int());
+		timer.Cancel();
+		User::WaitForRequest(timeout);
+		test_Equal(KErrCancel, timeout.Int());
+		test_KErrNone(reseed.Int());
+		}
+	
+	Ldd.Close();
+
+	User::FreeLogicalDevice(KEntropySourcesName);
+    }
+
+LOCAL_C TBool HardwareRNGPresent()
+    {
+    TInt muid = 0;
+    const TInt r = HAL::Get(HAL::EMachineUid, muid);
+    if (r != KErrNone) return EFalse;;
+    return ((muid != HAL::EMachineUid_X86PC) &&
+            (muid != HAL::EMachineUid_NE1_TB) &&
+            (muid != HAL::EMachineUid_OmapH6) &&
+            (muid != HAL::EMachineUid_OmapZoom) &&
+            (muid != HAL::EMachineUid_Win32Emulator));
+    }
+
+GLDEF_C TInt E32Main()
+	{
+	test.Title();
+	test.Start(_L("Test periodic entropy source"));
+
+	if(HardwareRNGPresent())	
+	    {
+	    __UHEAP_MARK;
+        
+		TestReseed();
+
+        __UHEAP_MARKEND;	    
+	    }
+	else
+	    {
+	    test.Printf(_L("Test skipped, platform is known not to have a periodic entropy source\n"));
+	    }
+	test.End();
+	test.Close();
+	
+	return 0;
+	}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/random/t_securerng.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,255 @@
+// 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\random\t_securerng.cpp
+// 
+//
+
+//system include
+#include <e32test.h>
+#include <e32math.h>
+#include <e32cmn.h>
+#include "../mmu/mmudetect.h"
+
+//---------------------------------------------------------------------------------------------------------------------
+//! @SYMTestCaseID				KBASE-securerng-2702
+//! @SYMTestType				UT
+//! @SYMTestCaseDesc			Verifies correct operation of the Secure RNG
+//! @SYMPREQ					PREQ211
+//! @SYMTestPriority			High
+//! @SYMTestActions				
+//! 	1. 	TestRandomNumberGeneration: tests that random data is generated correctly.
+//!
+//! 	2. 	SecureRNGTestWithMultiThread: tests that random data can be provided to multiple threads simultaneously
+//!
+//! 	3. 	TestSecureRNGForPanicScenarios: tests that the correct panics are issued for common error conditions
+//! 		
+//! 
+//! @SYMTestExpectedResults
+//! 	1.	Properties checked:
+//! 		1) checks that requests for random data with a buffer length of zero do not cause an error.
+//!         2) checks that requests for a large amount of random data do not cause an error.
+//!         3) checks that some random data has been returned (comparison to zero filled buffer).
+//!         4) checks that the new Math::RandomL() API either returns some random data or correctly indicates the RNG
+//!            as not secure (KErrNotReady).
+//! 	
+//! 	2. Properties checked:
+//! 		5) checks that making requests for random data from multiple threads simultaneously does not cause an error.
+//!
+//! 	3. Properties checked:
+//!         6) checks passing a user non-writable memory address to the random function through a valid pointer results
+//!            results in the correct panic.
+//!         7) checks passing a null pointer to the random function results in the correct panic.
+//!         8) checks passing a non-modifiable descriptor to the random function results in the correct panic.
+//---------------------------------------------------------------------------------------------------------------------
+
+
+// RTest for testing Secure RNG unit
+RTest test(_L("Secure RNG Unit Test"));
+
+// Threads required for multi thread testing
+RThread SecureRNGTestThread1;
+RThread SecureRNGTestThread2;
+RThread SecureRNGTestThread3;
+
+// Threads name to identify
+_LIT(KSecureRNGTestThread1, "SecureRNGTestThread1");
+_LIT(KSecureRNGTestThread2, "SecureRNGTestThread2");
+_LIT(KSecureRNGTestThread3, "SecureRNGTestThread3");
+
+//length of the buffer data
+const TInt KDataLength = 10;
+
+/*
+ *Test Secure RNG with invalid and non-writable and non modifiable descriptor type
+ */
+TInt PanicFuncForBadDesc(TAny* aDes)
+    {
+    Math::Random(*(TDes8*)aDes);
+    return KErrNone;
+    }
+
+void CreatePanicThreads(TAny* aThreadData, TInt aExpectedStatusOfThread)
+    {
+    RThread panicThread;
+    _LIT(KPanicThreadName, "SecureRNGTestPanicThread");
+        
+    test(panicThread.Create(KPanicThreadName(),PanicFuncForBadDesc,KDefaultStackSize,0x200,0x900,aThreadData) == KErrNone); 
+    TRequestStatus status;
+    panicThread.Logon(status);
+    panicThread.Resume();
+    User::WaitForRequest(status);
+    test.Printf(_L("Exit Reason %d\r\n"), status.Int());
+    test.Printf(_L("Exit Type %d\r\n"),(TInt)panicThread.ExitType());
+    //Test for expected result from thread
+    test(status.Int()== aExpectedStatusOfThread); //(status of thread = thread Exit Reason)
+    test(panicThread.ExitCategory() == _L("KERN-EXEC"));
+    test(panicThread.ExitType()==EExitPanic);
+    
+    CLOSE_AND_WAIT(panicThread);
+    }
+
+/*
+ * Panic test cases for testing Secure RNG
+ */
+void TestSecureRNGForPanicScenarios()
+    {
+    test.Printf(_L("Passing user non-writable memory address to the random function through a valid pointer \n"));
+    TPtr8 tptr(KernData(), KDataLength, KDataLength);
+    CreatePanicThreads(&tptr, 3);
+            
+    test.Printf(_L("Passing null pointer to random function \n"));
+    tptr.Set(NULL, KDataLength, KDataLength);
+    CreatePanicThreads(&tptr, 3);
+    
+    test.Printf(_L("Passing non-modifiable descriptor to the random function \n"));
+    HBufC8* randbuf =HBufC8::New(25);
+    TPtr8 ptr = randbuf->Des();
+    ptr.SetMax();
+    CreatePanicThreads(randbuf, 34);
+    delete randbuf;
+    }
+
+TInt GenerateRandomNumber(TAny*)
+    {
+    HBufC8* randbuf = HBufC8::New(3000);
+    TPtr8 ptr = randbuf->Des();
+    ptr.SetMax();
+    for(;;)
+        {
+        Math::Random(ptr);
+        }
+    }
+
+/*
+ * Test Secure RNG with multi threads requesting for random numbers
+ */
+void SecureRNGTestWithMultiThread()
+    {
+    test(SecureRNGTestThread1.Create(KSecureRNGTestThread1(),GenerateRandomNumber,KDefaultStackSize,0x200,0x900,NULL)== KErrNone);
+    SecureRNGTestThread1.SetPriority(EPriorityLess);
+    test(SecureRNGTestThread2.Create(KSecureRNGTestThread2(),GenerateRandomNumber,KDefaultStackSize,0x200,0x900,NULL)== KErrNone);
+    SecureRNGTestThread2.SetPriority(EPriorityLess);
+    test(SecureRNGTestThread3.Create(KSecureRNGTestThread3(),GenerateRandomNumber,KDefaultStackSize,0x200,0x900,NULL)== KErrNone);
+    SecureRNGTestThread3.SetPriority(EPriorityLess);
+    
+    SecureRNGTestThread1.Resume();
+    SecureRNGTestThread2.Resume();
+    SecureRNGTestThread3.Resume();
+    
+    User::After(30 * 1000 * 1000); //30 seconds
+    // After waiting for few seconds, kill the threads now.
+    SecureRNGTestThread1.Kill(KErrNone);
+    test(SecureRNGTestThread1.ExitType()==EExitKill);
+    SecureRNGTestThread2.Kill(KErrNone);
+    test(SecureRNGTestThread2.ExitType()==EExitKill);
+    SecureRNGTestThread3.Kill(KErrNone);
+    test(SecureRNGTestThread3.ExitType()==EExitKill);
+
+	CLOSE_AND_WAIT(SecureRNGTestThread1);
+	CLOSE_AND_WAIT(SecureRNGTestThread2);
+	CLOSE_AND_WAIT(SecureRNGTestThread3);
+    }
+
+const TInt KChunkLength = 2048;
+void CheckForRandomNumbers(const TUint8* aRandomNumbers, TInt aLength)
+    {
+    TBuf8<KChunkLength> buf;
+    buf.FillZ();
+    TInt bytesToCompare = aLength;
+    TInt index = 0;
+    while(bytesToCompare > 0)
+        {
+        // check there is at least some random numbers in every chunk
+        TInt newLength = bytesToCompare > KChunkLength ? KChunkLength : bytesToCompare;
+        test(memcompare(aRandomNumbers+ (index* KChunkLength), newLength, buf.Ptr(), newLength) != 0);
+        index++;
+        bytesToCompare  = bytesToCompare - KChunkLength;
+        }
+    }
+/*
+ * Functionality test for the Random APIs
+ */
+//required for testing for large number of random numbers request
+const TInt KRandomNumsRequired  = 70000;
+void TestRandomNumberGeneration()
+    {
+    test.Printf(_L(" Request for zero random numbers \n"));
+    TBuf8<KDataLength> randomBuffer;
+    randomBuffer.SetLength(0);
+    TRAPD(error, Math::RandomL(randomBuffer));
+    test(error == KErrNone);
+    
+    test.Printf(_L(" Request for huge random numbers of 70000 bytes in length \n"));
+    HBufC8* randbuf =HBufC8::New(KRandomNumsRequired);
+    TPtr8 ptr = randbuf->Des();
+    ptr.SetMax();
+    TRAP(error, Math::RandomL(ptr));
+    test(error == KErrNotReady || error == KErrNone);
+    //check we have some random numbers atleast in every chunk of large randomnumbers received
+    CheckForRandomNumbers(ptr.Ptr(), KRandomNumsRequired);
+    delete randbuf;
+            
+    test.Printf(_L(" Request for 32 bit random number using the new leaving function: Math::RandomL() api \n"));
+	for (TInt i=0; i<50; ++i)
+		{
+		// Try to prove it's working by looking for a nonzero value - 50 32-bit zero values
+		// in a row from a random source is extremely unlikely. However, if it's not ready
+		// we will get 0 every time as the return value is not set when it leaves, so we
+		// give up.
+	    TUint32 randomNumber = 0;
+	    TRAP(error ,randomNumber = Math::RandomL());
+	    test.Printf(_L("The generated four byte random number is %d \n" ), randomNumber);
+	    test(error == KErrNotReady || error == KErrNone);
+		if (error == KErrNotReady || randomNumber != 0)
+			break;
+		}
+    }
+
+/*
+ * Test Secure RNG for functionality test, multi-thread tests and panic test cases
+ */
+void SecureRNGTest()
+    {
+    test.Printf(_L("\n Functionality test for RNG \n"));
+    TestRandomNumberGeneration();
+    
+    // Test Secure RNG with multi threads
+    test.Printf(_L("Testing Secure RNG with Multithreads requesting for random numbers \n"));
+    SecureRNGTestWithMultiThread();
+        
+    //Panic test cases - check with non-writable descriptor type and null pointer
+    test.Printf(_L("\n Panic test cases for Secure RNG \n"));
+    TestSecureRNGForPanicScenarios();
+    }
+
+/*
+Gobal Entry Function
+*/
+GLDEF_C TInt E32Main()
+	{
+	test.Title();
+	test.Start(_L("\n Starting Secure RNG Unit tests \n"));
+	    
+	CTrapCleanup* cleanup=CTrapCleanup::New();
+	test(cleanup != NULL);
+	
+	__KHEAP_MARK;
+	__UHEAP_MARK;
+	SecureRNGTest();
+    __UHEAP_MARKEND;
+	__KHEAP_MARKEND;
+	
+	test.End();
+	delete cleanup;
+	return KErrNone;
+	}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/random/t_sha256.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,98 @@
+// 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/random/tsha256.cpp
+//
+
+//---------------------------------------------------------------------------------------------------------------------
+//! @SYMTestCaseID				KBASE-sha256-2701
+//! @SYMTestType				UT
+//! @SYMTestCaseDesc			Verifies the implementation of SHA256 used by the Secure RNG
+//! @SYMPREQ					PREQ211
+//! @SYMTestPriority			High
+//! @SYMTestActions				
+//! 	1. 	Tests the correct operation of the SHA256 implementation used by the Secure RNG using publically published
+//!         test vectors and corresponding outputs.
+//! 
+//! @SYMTestExpectedResults
+//! 	1.	The implementation should always return the expected outputs for the given test vectors.
+//---------------------------------------------------------------------------------------------------------------------
+
+//epoc include
+#include <e32test.h>
+//user include
+#include "sha256.h"
+
+
+//RTest for testing SHA256
+RTest test(_L("Unit Test For SHA256"));
+
+//Test data input for SHA256 taken from FIPS 180-2 and openssl
+_LIT8(KTestData1, "\x61\x62\x63");
+_LIT8(KTestData2, "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10");
+_LIT8(KTestData3, "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x01\x02\x03\x04");
+
+//Expected output for the above test data input for SHA256 taken from FIPS 180-2
+_LIT8(KTestVector1, "\xba\x78\x16\xbf\x8f\x01\xcf\xea\x41\x41\x40\xde\x5d\xae\x22\x23\xb0\x03\x61\xa3\x96\x17\x7a\x9c\xb4\x10\xff\x61\xf2\x00\x15\xad");
+_LIT8(KTestVector2, "\x91\x1B\x64\x76\x69\x49\xA2\xE8\x56\xF1\xB6\xC3\x50\x1D\x5A\x6B\xF1\x7D\xD5\x0B\x6A\x78\xD6\x09\x3A\xFC\x42\x52\xD2\xF7\x1A\x18");
+_LIT8(KTestVector3, "\x27\x53\x57\xF9\x38\x73\xAF\xFF\xF0\x0C\x4A\x83\x04\x33\xCA\x51\x37\xCC\x32\x7D\xDF\xB1\x5C\x46\xD6\xCD\x8A\x0A\x8A\x6E\x48\x3C");
+
+/*
+Functionality test for SHA256 algorithm
+*/
+void Sha256FunctionalityTest(const TDesC8& aMessageData, const TDesC8& aHashOfMessageData)
+	{
+	TBuf8<KSHA256HashSize> hash; // temp buffer
+	SHA256 sha256; 
+	sha256.Update(aMessageData.Ptr(), aMessageData.Length());
+	hash.Copy(sha256.Final().Ptr(),KSHA256HashSize);
+	TInt compareVal = aHashOfMessageData.Compare(hash);
+	test(compareVal == 0);
+	}
+
+/*
+Basic functionality test for Sha256
+*/
+void SHA2Tests()
+	{
+	//functionality test for Hash Algorithm using short message data (3 bytes in length)
+	Sha256FunctionalityTest(KTestData1(), KTestVector1());
+	
+	//functionality test for Hash Algorithm using sha256 block size message data (64 bytes)
+	Sha256FunctionalityTest(KTestData2(), KTestVector2());
+	
+	//functionality test for Hash Algorithm using long message data (68 bytes)
+	Sha256FunctionalityTest(KTestData3(), KTestVector3());
+	}
+
+/*
+Main function for sha256 algorithm testing
+*/
+GLDEF_C TInt E32Main(void)
+	{
+	test.Title();
+	test.Start(_L(" SHA256 Algorithm Test \n"));		 
+		
+	CTrapCleanup* cleanup=CTrapCleanup::New();
+	test(cleanup != NULL);
+	        
+	__UHEAP_MARK;
+	SHA2Tests();		
+	__UHEAP_MARKEND;
+
+	test.End();
+	delete cleanup;
+	return KErrNone;
+	}
+
+
+
--- a/kerneltest/e32test/resourceman/d_rescontrolcli.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kerneltest/e32test/resourceman/d_rescontrolcli.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -412,13 +412,6 @@
 	{
    	if (iOpenChannels != 0) //A Channel is already open
 		return KErrInUse;
-	//Deregister the client registered in ldd init. 
-	TInt r = PowerResourceManager::DeRegisterClient(DTestResManLddFactory::iClient.iClientId);
-	if(r != KErrNone)
-		Kern::Fault("PRM CLIENT DEREGISTER FAILED", __LINE__);
-	delete DTestResManLddFactory::iClient.pName;
-	DTestResManLddFactory::iClient.pName = NULL;
-	DTestResManLddFactory::iClient.iClientId = 0;
 	aChannel = new DTestResManLdd;
 	if(!aChannel)
 		return KErrNoMemory;
@@ -514,7 +507,17 @@
 		}
 	}
 
-
+/** 
+	Function used for polling the PostBoot Notification status. 
+*/
+TBool PollingPostBootStatus(TAny* aLddFactory)
+	{
+	if(aLddFactory)
+		if(((DTestResManLddFactory *)aLddFactory)->iPostBootNotiCount == EXPECTED_POST_NOTI_COUNT)
+			return ETrue;
+	return EFalse;
+	}
+	
 /**
   Process synchronous 'control' requests
 */
@@ -990,12 +993,9 @@
 			}
 		case RTestResMan::ECheckPostBootLevelNotifications:
 			{
-				if(DTestResManLddFactory::iPostBootNotiCount != EXPECTED_POST_NOTI_COUNT)
-				{
-				r = KErrUnderflow;
-				break;
-				}
-			r = KErrNone;
+			//aPollPeriodMs = 3ms (3rd argument)
+			//aMaxPoll = 1000 (in total ~3000 ms timeout)
+			r = Kern::PollingWait(PollingPostBootStatus, (TAny*)iDevice, 3, 1000);
 			break;
 			}
 		case RTestResMan::EGetControllerVersion:
@@ -1335,6 +1335,17 @@
 	iPostBootNotiCount++;
 	DPowerResourceNotification *ptr = (DPowerResourceNotification*)aParam;
 	TInt r = PowerResourceManager::CancelNotification(iClient.iClientId, aResId, *ptr);
-	if(r == KErrNone)
+	if(r == KErrCancel)
+		{
 		delete ptr;
+		if(iPostBootNotiCount == EXPECTED_POST_NOTI_COUNT)
+			{
+			r = PowerResourceManager::DeRegisterClient(DTestResManLddFactory::iClient.iClientId);
+			if(r != KErrNone)
+				Kern::Fault("PRM CLIENT DEREGISTER FAILED", __LINE__);
+			delete DTestResManLddFactory::iClient.pName;
+			DTestResManLddFactory::iClient.pName = NULL;
+			DTestResManLddFactory::iClient.iClientId = 0;
+			}
+		}
 	}
--- a/kerneltest/e32test/resourceman/dynamicresource.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kerneltest/e32test/resourceman/dynamicresource.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -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	Tue Feb 02 01:24:03 2010 +0200
+++ b/kerneltest/e32test/resourceman/resourceman_psl/rescontrol_extended_psl.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -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	Tue Feb 02 01:24:03 2010 +0200
+++ b/kerneltest/e32test/resourceman/resourceman_psl/rescontrol_psl.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -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
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/rm_debug/basic_tests/r_kernel_low_memory_security_svr_session.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,39 @@
+// Copyright (c) 2007-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:
+// Implementation of RKernelLowMemorySecuritySvrSession
+// 
+//
+
+#include "r_kernel_low_memory_security_svr_session.h"
+
+void RKernelLowMemorySecuritySvrSession::FailAlloc(const TInt aCount)
+	{
+	__KHEAP_FAILNEXT(aCount);
+	}
+
+void RKernelLowMemorySecuritySvrSession::HeapReset()
+	{
+	__KHEAP_RESET;
+	}
+
+void RKernelLowMemorySecuritySvrSession::MarkHeap()
+	{
+	__KHEAP_MARK;
+	}
+
+void RKernelLowMemorySecuritySvrSession::MarkHeapEnd()
+	{
+	__KHEAP_MARKEND;
+	}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/rm_debug/basic_tests/r_kernel_low_memory_security_svr_session.h	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,39 @@
+// Copyright (c) 2007-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:
+// Version of security server session to enable testing of low memory conditions on kernel side
+// 
+//
+
+/**
+ @file
+ @internalTechnology
+ @released
+*/
+
+#ifndef R_KERNEL_LOW_MEMORY_SECURITY_SVR_SESSION_H
+#define R_KERNEL_LOW_MEMORY_SECURITY_SVR_SESSION_H
+
+#include "r_low_memory_security_svr_session.h"
+
+class RKernelLowMemorySecuritySvrSession : public RLowMemorySecuritySvrSession
+	{
+protected:
+	void FailAlloc(const TInt aCount);
+	void HeapReset();
+	void MarkHeap();
+	void MarkHeapEnd();
+	};
+
+#endif //R_KERNEL_LOW_MEMORY_SECURITY_SVR_SESSION_H
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/rm_debug/basic_tests/r_low_memory_security_svr_session.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,86 @@
+// Copyright (c) 2007-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:
+// Implementation of RLowMemorySecuritySvrSession
+// 
+//
+
+#include "r_low_memory_security_svr_session.h"
+#include <e32debug.h>
+
+// test the effects of heap failure on global RSecuritySvrSession::GetList() in debug mode,
+// in release mode normal call is made (heap checking not applicable)
+TInt RLowMemorySecuritySvrSession::GetList(const Debug::TListId aListId, TDes8& aListData, TUint32& aDataSize)
+	{
+	TInt failAt = 0;
+	TInt err = KErrNoMemory;
+	while(err == KErrNoMemory)
+		{
+		failAt++;
+		FailAlloc(failAt);
+		MarkHeap();
+		err = this->RSecuritySvrSession::GetList(aListId, aListData, aDataSize);
+		if(KErrNoMemory == err)
+			{
+			MarkHeapEnd();
+			}
+		HeapReset();
+		//RDebug::Printf("Debug::RLowMemorySecuritySvrSession::GetList(): failAt: %d, err: %d", failAt, err);
+		}
+	return err;
+	}
+
+// test the effects of heap failure on thread-specific RSecuritySvrSession::GetList() in debug mode,
+// in release mode normal call is made (heap checking not applicable)
+TInt RLowMemorySecuritySvrSession::GetList(const TThreadId aThreadId, const Debug::TListId aListId, TDes8& aListData, TUint32& aDataSize)
+	{
+	TInt failAt = 0;
+	TInt err = KErrNoMemory;
+	while(err == KErrNoMemory)
+		{
+		failAt++;
+		FailAlloc(failAt);
+		MarkHeap();
+		err = this->RSecuritySvrSession::GetList(aThreadId, aListId, aListData, aDataSize);
+		if(KErrNoMemory == err)
+			{
+			MarkHeapEnd();
+			}
+		HeapReset();
+		//RDebug::Printf("Debug::RLowMemorySecuritySvrSession::GetList(TThreadId): failAt: %d, err: %d", failAt, err);
+		}
+	return err;
+	}
+
+// test the effects of heap failure on process-specific RSecuritySvrSession::GetList() in debug mode,
+// in release mode normal call is made (heap checking not applicable)
+TInt RLowMemorySecuritySvrSession::GetList(const TProcessId aProcessId, const Debug::TListId aListId, TDes8& aListData, TUint32& aDataSize)
+	{
+	TInt failAt = 0;
+	TInt err = KErrNoMemory;
+	while(err == KErrNoMemory)
+		{
+		failAt++;
+		FailAlloc(failAt);
+		MarkHeap();
+		err = this->RSecuritySvrSession::GetList(aProcessId, aListId, aListData, aDataSize);
+		if(KErrNoMemory == err)
+			{
+			MarkHeapEnd();
+			}
+		HeapReset();
+		//RDebug::Printf("Debug::RLowMemorySecuritySvrSession::GetList(TProcessId): failAt: %d, err: %d", failAt, err);
+		}
+	return err;
+	}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/rm_debug/basic_tests/r_low_memory_security_svr_session.h	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,43 @@
+// Copyright (c) 2007-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:
+// Version of security server session to enable testing of low memory conditions
+// 
+//
+
+/**
+ @file
+ @internalTechnology
+ @released
+*/
+
+#ifndef R_LOW_MEMORY_SECURITY_SVR_SESSION_H
+#define R_LOW_MEMORY_SECURITY_SVR_SESSION_H
+
+#include <rm_debug_api.h>
+
+class RLowMemorySecuritySvrSession : public Debug::RSecuritySvrSession
+	{
+public:
+	TInt GetList(const Debug::TListId aListId, TDes8& aListData, TUint32& aDataSize);
+	TInt GetList(const TThreadId aThreadId, const Debug::TListId aListId, TDes8& aListData, TUint32& aDataSize);
+	TInt GetList(const TProcessId aProcessId, const Debug::TListId aListId, TDes8& aListData, TUint32& aDataSize);
+protected:
+	virtual void FailAlloc(const TInt aCount) = 0;
+	virtual void HeapReset() = 0;
+	virtual void MarkHeap() = 0;
+	virtual void MarkHeapEnd() = 0;
+	};
+
+#endif //R_LOW_MEMORY_SECURITY_SVR_SESSION_H
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/rm_debug/basic_tests/r_user_low_memory_security_svr_session.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,54 @@
+// Copyright (c) 2007-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:
+// r_kernel_low_memory_security_svr_session.cpp
+// Implementation of RUserLowMemorySecuritySvrSession
+// 
+//
+
+#include "r_user_low_memory_security_svr_session.h"
+#include <rm_debug_api.h>
+#ifdef _DEBUG
+#include "low_mem_requests.h"
+#endif
+
+void RUserLowMemorySecuritySvrSession::FailAlloc(const TInt aCount)
+	{
+#ifdef _DEBUG
+	TIpcArgs args(aCount);
+	SendReceive(EDebugServFailAlloc, args);
+#endif
+	}
+
+void RUserLowMemorySecuritySvrSession::HeapReset()
+	{
+#ifdef _DEBUG
+	TIpcArgs args(0);
+	SendReceive(EDebugServFailAlloc, args);
+#endif
+	}
+
+void RUserLowMemorySecuritySvrSession::MarkHeap()
+	{
+#ifdef _DEBUG
+	SendReceive(EDebugServMarkHeap);
+#endif
+	}
+
+void RUserLowMemorySecuritySvrSession::MarkHeapEnd()
+	{
+#ifdef _DEBUG
+	SendReceive(EDebugServMarkEnd);
+#endif
+	}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/rm_debug/basic_tests/r_user_low_memory_security_svr_session.h	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,39 @@
+// Copyright (c) 2007-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:
+// Version of security server session to enable testing of low memory conditions on user side
+// 
+//
+
+/**
+ @file
+ @internalTechnology
+ @released
+*/
+
+#ifndef R_USER_LOW_MEMORY_SECURITY_SVR_SESSION_H
+#define R_USER_LOW_MEMORY_SECURITY_SVR_SESSION_H
+
+#include "r_low_memory_security_svr_session.h"
+
+class RUserLowMemorySecuritySvrSession : public RLowMemorySecuritySvrSession
+	{
+protected:
+	void FailAlloc(const TInt aCount);
+	void HeapReset();
+	void MarkHeap();
+	void MarkHeapEnd();
+	};
+
+#endif //R_USER_LOW_MEMORY_SECURITY_SVR_SESSION_H
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/rm_debug/basic_tests/t_rmdebug2.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,4639 @@
+// Copyright (c) 2006-2010 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 the functionality of the run mode debug device driver.
+//
+//
+
+#include <e32base.h>
+#include <e32base_private.h>
+#include <e32cons.h>
+#include <e32test.h>
+#include <e32ldr.h>
+#include <e32cmn.h>
+#include <e32cmn_private.h>
+#include <f32dbg.h>
+#include <f32file.h>
+#include <hal.h>
+#include <u32hal.h>
+#include <e32property.h>
+
+#include "t_rmdebug_dll.h"
+
+#include <rm_debug_api.h>
+#include "d_rmdebugthread2.h"
+#include "t_rmdebug2.h"
+#include "t_rmdebug_app.h"
+
+#ifdef __MARM_ARMV4__
+#include "d_rmdebug_step_test_armv4.h"
+#endif
+
+#ifdef __MARM_ARMV5__
+#include "d_rmdebug_step_test.h"
+#include "d_rmdebug_bkpt_test.h"
+#endif
+
+#include "d_demand_paging.h"
+
+#ifdef KERNEL_OOM_TESTING
+	#ifdef USER_OOM_TESTING
+		#error "Cannot define both KERNEL_OOM_TESTING and USER_OOM_TESTING"
+	#endif
+#endif
+
+_LIT8(KCrashDummyData, "This is a sample write");
+
+using namespace Debug;
+
+const TVersion securityServerVersion(0,1,1);
+
+const TVersion testVersion(2,1,0);
+
+IMPORT_C TInt StartDebugThread(RThread& aServerThread, const TDesC& aDebugThreadName);
+IMPORT_D extern TInt TestData;
+IMPORT_D extern TTestFunction FunctionChooser;
+IMPORT_D extern TBuf8<SYMBIAN_RMDBG_MEMORYSIZE> gMemoryAccessBytes;
+IMPORT_C TInt TestFunction();
+IMPORT_C void TestPagedCode();
+IMPORT_C extern TInt RMDebugDemandPagingTest();
+
+// Device driver name
+_LIT(KDebugDriverFileName,"rm_debug.ldd");
+
+#ifdef SYMBIAN_STANDARDDEBUG
+LOCAL_D RTest test(_L("T_RMDEBUG2"));
+#endif
+
+#ifdef SYMBIAN_OEMDEBUG
+LOCAL_D RTest test(_L("T_RMDEBUG2_OEM"));
+#endif
+
+#ifdef SYMBIAN_OEM2DEBUG
+LOCAL_D RTest test(_L("T_RMDEBUG2_OEM2"));
+#endif
+
+TBool gUseDelay;
+
+CRunModeAgent::CRunModeAgent()
+//
+// CRunModeAgent constructor
+//
+	{
+	FillArray();
+	RProcess thisProcess;
+	iFileName = thisProcess.FileName();
+	thisProcess.Close();
+	}
+
+CRunModeAgent* CRunModeAgent::NewL()
+//
+// CRunModeAgent::NewL
+//
+	{
+	CRunModeAgent* self = new(ELeave) CRunModeAgent();
+
+  	self->ConstructL();
+
+	return self;
+	}
+
+CRunModeAgent::~CRunModeAgent()
+//
+// CRunModeAgent destructor
+//
+	{
+	User::FreeLogicalDevice(KDebugDriverFileName);
+	iServSession.Close();
+	iDebugThread.Close();
+	}
+
+void CRunModeAgent::ConstructL()
+//
+// CRunModeAgent::ConstructL
+//
+	{
+	// nothing to do here
+	}
+
+void CRunModeAgent::SetupAndAttachToDSS()
+//
+// CRunModeAgent::SetupAndAttachToDSS
+//
+	{
+	TInt err = StartDebugThread(iDebugThread, KDebugThreadName);
+
+	// get the thread id for use in the tests
+	iThreadID = iDebugThread.Id();
+
+	if (err != KErrNone)
+		{
+		User::Panic(_L("Can't start debug thread"), err);
+		}
+
+	err = iServSession.Connect(securityServerVersion);
+	if (err != KErrNone)
+		{
+		User::Panic(_L("Can't open server session"), err);
+		}
+	}
+
+CRunModeAgent *RunModeAgent;
+
+// helper function to check whether the listing of type aListId is supported for a scope of aListScope
+TBool CRunModeAgent::ListingSupported(const TListId aListId, const TListScope aListScope)
+	{
+	TTag tag = GetTag(ETagHeaderList, aListId);
+
+	return (tag.iValue) & aListScope;
+	}
+
+//---------------------------------------------
+//! @SYMTestCaseID KBase-T-RMDEBUG2-0426
+//! @SYMTestType
+//! @SYMPREQ PREQ1426
+//! @SYMTestCaseDesc Test getting the list of XIP libraries
+//! @SYMTestActions The XIP library list should be successfully obtained
+//! @SYMTestExpectedResults The specified ldd file should be present in the obtained listing
+//! @SYMTestPriority High
+//! @SYMTestStatus Implemented
+//---------------------------------------------
+void CRunModeAgent::TestGetXipLibrariesList()
+	{
+	test.Next(_L("TestGetXipLibrariesList\n"));
+
+	test(ListingSupported(EXipLibraries, EScopeGlobal));
+	test(!ListingSupported(EXipLibraries, EScopeProcessSpecific));
+	test(!ListingSupported(EXipLibraries, EScopeThreadSpecific));
+
+	//allocate a very small buffer so the GetList call initially fails
+	RBuf8 buffer;
+	test(KErrNone == buffer.Create(1));
+	TUint32 size = 0;
+
+	//get the list data
+	DoGetList(EXipLibraries, EScopeGlobal, buffer, size);
+
+	//search the buffer for entry corresponding to the debug kernel driver
+	//which should be in the rom
+	_LIT(KRmDebugLddName, "z:\\sys\\bin\\rm_debug.ldd");
+
+	//iterate through the buffer and set found to ETrue if we find the driver
+	TBool found = EFalse;
+	TUint8* ptr = (TUint8*)buffer.Ptr();
+	const TUint8* ptrEnd = ptr + size;
+	while(ptr < ptrEnd)
+		{
+		TXipLibraryListEntry& xipLibrary = *(TXipLibraryListEntry*)ptr;
+
+		//get the name of the library
+		TPtr name(&xipLibrary.iName[0], xipLibrary.iNameLength, xipLibrary.iNameLength);
+		if(name.CompareF(KRmDebugLddName()) == 0)
+			{
+			//found the library but continue reading the rest of the buffer to
+			//check nothing bad happens towards the end
+			found = ETrue;
+			}
+		//move pointer on to next library
+		ptr += Align4(xipLibrary.GetSize());
+		}
+	test(found);
+
+	//do cleanup
+	buffer.Close();
+	}
+
+//---------------------------------------------
+//! @SYMTestCaseID KBase-T-RMDEBUG2-0427
+//! @SYMTestType
+//! @SYMPREQ PREQ1426
+//! @SYMTestCaseDesc Test getting the list of executables
+//! @SYMTestActions The list of debuggable executable files should be obtained
+//! @SYMTestExpectedResults The client exe should appear in the list
+//! @SYMTestPriority High
+//! @SYMTestStatus Implemented
+//---------------------------------------------
+void CRunModeAgent::TestGetExecutablesList()
+	{
+	test.Next(_L("TestGetExecutablesList\n"));
+
+	test(ListingSupported(EExecutables, EScopeGlobal));
+	test(!ListingSupported(EExecutables, EScopeProcessSpecific));
+	test(!ListingSupported(EExecutables, EScopeThreadSpecific));
+
+	//allocate a very small buffer so the GetList call initially fails
+	RBuf8 buffer;
+	test(KErrNone == buffer.Create(1));
+	TUint32 size = 0;
+
+	test(KErrNone == iServSession.AttachExecutable(iFileName, EFalse));
+
+	//get the list data
+	DoGetList(EExecutables, EScopeGlobal, buffer, size);
+
+	//get this process' name
+	RProcess thisProcess;
+	TFileName thisProcessName = thisProcess.FileName();
+
+	//look through the buffer and check if the target debug thread is there
+	TBool found = EFalse;
+	TUint8* ptr = (TUint8*)buffer.Ptr();
+	const TUint8* ptrEnd = ptr + size;
+	while(ptr < ptrEnd)
+		{
+		TExecutablesListEntry& entry = *(TExecutablesListEntry*)ptr;
+		//get name
+		TPtr name(&entry.iName[0], entry.iNameLength, entry.iNameLength);
+		if( (entry.iIsActivelyDebugged != 0) && (0 == thisProcessName.CompareF(name)) )
+			{
+			//found this process and asserted it is being actively debugged
+			found = ETrue;
+			}
+		//move pointer on to next entry
+		ptr += Align4(entry.GetSize());
+		}
+	test(found);
+
+	//clean up
+	buffer.Close();
+
+	test(KErrNone == iServSession.DetachExecutable(iFileName));
+	}
+
+//---------------------------------------------
+//! @SYMTestCaseID KBase-T-RMDEBUG2-0428
+//! @SYMTestType
+//! @SYMPREQ PREQ1426
+//! @SYMTestCaseDesc Test error conditions for the GetList calls
+//! @SYMTestActions Multiple calls to test calling GetList with bad arguments
+//! @SYMTestExpectedResults All tests should fail with the appropriate error codes
+//! @SYMTestPriority High
+//! @SYMTestStatus Implemented
+//---------------------------------------------
+void CRunModeAgent::TestGetListInvalidData()
+	{
+	test.Next(_L("TestGetListInvalidData\n"));
+
+	//allocate a buffer, the size should not matter as expecting all calls to fail
+	RBuf8 buffer;
+	test(KErrNone == buffer.Create(1));
+	TUint32 size = 0;
+
+	//test what happens if we ask for an unsupported list type globally
+	test(KErrNotSupported == iServSession.GetList((TListId)1234, buffer, size));
+
+	//test what happens if we ask for an unsupported list type
+	test(KErrNotSupported == iServSession.GetList(RThread().Id(), (TListId)1234, buffer, size));
+
+	//test what happens if we try to get a non-global libraries list
+	test(KErrArgument == iServSession.GetList(RThread().Id(), EXipLibraries, buffer, size));
+
+	//test what happens if we try to get a non-global executables list
+	test(KErrArgument == iServSession.GetList(RThread().Id(), EExecutables, buffer, size));
+
+	//test what happens if we try to get a non-global process list
+	test(KErrArgument == iServSession.GetList(RThread().Id(), EProcesses, buffer, size));
+
+	//check that using a process id fails
+	test(KErrArgument == iServSession.GetList(RProcess().Id(), EProcesses, buffer, size));
+
+	//check that specifying a non-existant thread id fails
+	test(KErrArgument == iServSession.GetList((TThreadId)0x12345678, EThreads, buffer, size));
+
+	//check that specifying a non-existant process id fails
+	test(KErrArgument == iServSession.GetList((TProcessId)0x12345678, EThreads, buffer, size));
+
+	//check that specifying a non-existant thread id fails
+	test(KErrArgument == iServSession.GetList((TThreadId)0x12345678, ECodeSegs, buffer, size));
+
+	//check that specifying a non-existant process id fails
+	test(KErrArgument == iServSession.GetList((TProcessId)0x12345678, ECodeSegs, buffer, size));
+
+	//cleanup
+	buffer.Close();
+	}
+
+//---------------------------------------------
+//! @SYMTestCaseID KBase-T-RMDEBUG2-0429
+//! @SYMTestType
+//! @SYMPREQ PREQ1426
+//! @SYMTestCaseDesc Test getting the process list
+//! @SYMTestActions Get the process listing
+//! @SYMTestExpectedResults The process listing should be successfully obtained and the current process should be present in the list
+//! @SYMTestPriority High
+//! @SYMTestStatus Implemented
+//---------------------------------------------
+void CRunModeAgent::TestGetProcessList()
+	{
+	test.Next(_L("TestGetProcessList\n"));
+
+	test(ListingSupported(EProcesses, EScopeGlobal));
+	test(!ListingSupported(EProcesses, EScopeProcessSpecific));
+	test(!ListingSupported(EProcesses, EScopeThreadSpecific));
+
+	//allocate a very small buffer so the GetList call fails
+	RBuf8 buffer;
+	test(KErrNone == buffer.Create(1));
+	TUint32 size = 0;
+
+	//get the list data
+	DoGetList(EProcesses, EScopeGlobal, buffer, size);
+
+	//initialise data about the target debug thread to compare the kernel's data against
+	RProcess thisProcess;
+	TFileName thisProcessName = thisProcess.FileName();
+	TUint32 processId = thisProcess.Id().Id();
+
+	//look through the buffer and check if the target debug thread is there
+	TBool found = EFalse;
+	TUint8* ptr = (TUint8*)buffer.Ptr();
+	const TUint8* ptrEnd = ptr + size;
+	while(ptr < ptrEnd)
+		{
+		TProcessListEntry& entry = *(TProcessListEntry*)ptr;
+		if( (RProcess().Id().Id() == entry.iProcessId) &&
+			(0 == thisProcessName.CompareF(TPtr(&(entry.iNames[0]), entry.iFileNameLength, entry.iFileNameLength))) &&
+		 	(0 == thisProcess.FullName().CompareF(TPtr(&(entry.iNames[0]) + entry.iFileNameLength, entry.iDynamicNameLength, entry.iDynamicNameLength))) &&
+			0x4321bbbb /* Magic */ == entry.iUid3)
+			{
+			//if all match then we've found it
+			found = ETrue;
+			}
+		ptr += Align4(entry.GetSize());
+		}
+
+	//check whether the expected result happened
+	test(found);
+
+	//clean up
+	buffer.Close();
+	}
+
+//---------------------------------------------
+//! @SYMTestCaseID KBase-T-RMDEBUG2-0430
+//! @SYMTestType
+//! @SYMPREQ PREQ1426
+//! @SYMTestCaseDesc Test getting the thread list
+//! @SYMTestActions Get the thread listing globally and for a specified thread or process
+//! @SYMTestExpectedResults The thread listings should all be successfully obtained and the current thread should be present in all listings
+//! @SYMTestPriority High
+//! @SYMTestStatus Implemented
+//---------------------------------------------
+void CRunModeAgent::TestGetThreadList()
+	{
+	test.Next(_L("TestGetThreadList\n"));
+
+	test(ListingSupported(EThreads, EScopeGlobal));
+	test(ListingSupported(EThreads, EScopeProcessSpecific));
+	test(ListingSupported(EThreads, EScopeThreadSpecific));
+
+	test(KErrNone == iServSession.AttachExecutable(iFileName, EFalse));
+	test(KErrNone == iServSession.SuspendThread(iThreadID));
+
+	//test getting the global list, ETrue as should find the target debug thread
+	DoTestGetThreadList(ETrue, EScopeGlobal);
+
+	//test getting this thread's thread list, ETrue as should find the target debug thread
+	DoTestGetThreadList(ETrue, EScopeThreadSpecific, RThread().Id().Id());
+
+	//test getting this process's thread list, ETrue as should find the target debug thread
+	DoTestGetThreadList(ETrue, EScopeProcessSpecific, RProcess().Id().Id());
+
+	test(KErrNone == iServSession.ResumeThread(iThreadID));
+	test(KErrNone == iServSession.DetachExecutable(iFileName));
+	}
+
+void CRunModeAgent::DoTestGetThreadList(const TBool aShouldPass, const TListScope aListScope, const TUint64 aTargetId)
+	{
+	test.Next(_L("DoTestGetThreadList\n"));
+
+	//create data to pass
+	RBuf8 buffer;
+	TUint32 size = 0;
+
+	//perform the call to get the Code segs
+	DoGetList(EThreads, aListScope, buffer, size, aTargetId);
+
+	//initialise data about the target debug thread to compare the kernel's data against
+	TFileName name = iDebugThread.FullName();
+	RProcess thisProcess;
+	TUint64 processId = thisProcess.Id();
+	TUint64 threadId = iDebugThread.Id();
+
+	//look through the buffer and check if the target debug thread is there
+	TBool found = EFalse;
+	TUint8* ptr = (TUint8*)buffer.Ptr();
+	const TUint8* ptrEnd = ptr + size;
+	while(ptr < ptrEnd)
+		{
+		TThreadListEntry* entry = (TThreadListEntry*)ptr;
+		TPtr entryName(&(entry->iName[0]), entry->iNameLength, entry->iNameLength);
+		if( (threadId == entry->iThreadId) && (processId == entry->iProcessId) && (0 == name.CompareF(entryName)) )
+			{
+			test(entry->iSupervisorStackBaseValid);
+			test(entry->iSupervisorStackSizeValid);
+			//if all match then we've found it
+			found = ETrue;
+			}
+
+		ptr += Align4(entry->GetSize());
+		}
+
+	//check whether the expected result happened
+	test(found == aShouldPass);
+
+	//clean up
+	buffer.Close();
+
+	}
+
+//---------------------------------------------
+//! @SYMTestCaseID KBase-T-RMDEBUG2-0431
+//! @SYMTestType
+//! @SYMPREQ PREQ1426
+//! @SYMTestCaseDesc Test getting the code segment list
+//! @SYMTestActions Get the code segment list global and for a specified thread
+//! @SYMTestExpectedResults The listings should be returned successfully
+//! @SYMTestPriority High
+//! @SYMTestStatus Implemented
+//---------------------------------------------
+void CRunModeAgent::TestGetCodeSegsList()
+	{
+	test.Next(_L("TestGetCodeSegsList\n"));
+
+	test(ListingSupported(ECodeSegs, EScopeGlobal));
+	test(ListingSupported(ECodeSegs, EScopeProcessSpecific));
+	test(ListingSupported(ECodeSegs, EScopeThreadSpecific));
+
+	// Cannot perform this test with OEM2 debug token, as the t_rmdebug2 app
+	// needs AllFiles, and the OEM2 debug token does not authorise this.
+	// It seems reasonable to suppose that it would work anyway
+
+#ifndef SYMBIAN_OEM2DEBUG
+	test(KErrNone == iServSession.AttachExecutable(iFileName, EFalse));
+
+ 	//test getting the global list, ETrue as should find this process' main codeSeg
+	DoTestGetCodeSegsList(ETrue, EScopeGlobal);
+
+	//test getting this process' codeSegs, ETrue as should find this process' main codeSeg
+	DoTestGetCodeSegsList(ETrue, EScopeProcessSpecific, RProcess().Id().Id());
+
+	//test getting this thread's codeSegs, ETrue as should find this process' main codeSeg
+	DoTestGetCodeSegsList(ETrue, EScopeThreadSpecific, RThread().Id().Id());
+
+	test(KErrNone == iServSession.DetachExecutable(iFileName));
+#endif // SYMBIAN_OEM2DEBUG
+
+	}
+
+void CRunModeAgent::DoTestGetCodeSegsList(const TBool aShouldPass, const TListScope aListScope, const TUint64 aTargetId)
+	{
+	//create data to pass
+	RBuf8 buffer;
+	TUint32 size = 0;
+
+	//perform the call to get the Code segs
+	DoGetList(ECodeSegs, aListScope, buffer, size, aTargetId);
+
+	//create memoryInfo to contain info about this process
+	RProcess thisProcess;
+	TModuleMemoryInfo memoryInfo;
+	test(KErrNone == thisProcess.GetMemoryInfo(memoryInfo));
+
+	// check whether this process came from a file in ROM so we know whether to
+	// expect the code seg to be XIP or not.
+	RFs fs;
+	test(KErrNone == fs.Connect());
+	TBool thisFileIsInRom = EFalse;
+	if(fs.IsFileInRom(iFileName))
+		{
+		thisFileIsInRom = ETrue;
+		}
+
+	//look through the buffer to find this process' main code seg
+	TBool found = EFalse;
+	TUint8* ptr = (TUint8*)buffer.Ptr();
+	const TUint8* ptrEnd = ptr + size;
+	while(ptr < ptrEnd)
+		{
+		TCodeSegListEntry* codeSeg = (TCodeSegListEntry*)ptr;
+
+		if( (codeSeg->iIsXip == thisFileIsInRom) && (0 == iFileName.CompareF(TPtr(&(codeSeg->iName[0]), codeSeg->iNameLength, codeSeg->iNameLength))) )
+			{
+			if( (memoryInfo.iCodeBase == codeSeg->iCodeBase) &&
+					(memoryInfo.iCodeSize == codeSeg->iCodeSize) &&
+					(memoryInfo.iConstDataSize == codeSeg->iConstDataSize) &&
+					(memoryInfo.iInitialisedDataBase == codeSeg->iInitialisedDataBase) &&
+					(memoryInfo.iInitialisedDataSize == codeSeg->iInitialisedDataSize) &&
+					(memoryInfo.iUninitialisedDataSize == codeSeg->iUninitialisedDataSize))
+				{
+				//all matched so means we've found the codeSeg we're looking for
+				found = ETrue;
+				}
+			}
+		ptr += Align4(codeSeg->GetSize());
+		}
+
+	//check whether the result was as expected
+	test(found == aShouldPass);
+
+	// only care about rm_debug.ldd if we have global scope (belongs to the system not this process)
+	if (aListScope == EScopeGlobal)
+	{
+		// Search for rm_debug.ldd library and check its UID3 is correct
+		found = EFalse;
+
+_LIT(KRMDebugDriverFileName,"Z:\\sys\bin\\rm_debug.ldd");
+
+		TFileName rmdebugFilename(KRMDebugDriverFileName);
+
+		// reset the Ptr
+		ptr = (TUint8*)buffer.Ptr();
+		ptrEnd = ptr+size;
+		while(ptr < ptrEnd)
+		{
+			TCodeSegListEntry* codeSeg = (TCodeSegListEntry*)ptr;
+
+			if( rmdebugFilename.CompareF(TPtr(&(codeSeg->iName[0]), codeSeg->iNameLength, codeSeg->iNameLength)))
+				{
+				if(codeSeg->iUid3 == 0x101f7157 /* Magic */)
+					{
+					//all matched so means we've found the codeSeg we're looking for
+					found = ETrue;
+					}
+				}
+			ptr += Align4(codeSeg->GetSize());
+		}
+		test((TUint32)found == (TUint32)ETrue);
+	}
+
+	//clean up
+	buffer.Close();
+
+	}
+
+void CRunModeAgent::DoGetList(const TListId aListId, const TListScope aListScope, RBuf8& aBuffer, TUint32& aSize, const TUint64 aTargetId)
+	{
+	//close the buffer in case there's stuff allocated in it
+	aBuffer.Close();
+	//initialise it to be one byte big, which will guarantee data won't fit in it
+	test(KErrNone == aBuffer.Create(1));
+	aSize = 0;
+
+	//should pass this test (assuming we've passed in sensible arguments above...)
+	if(EScopeGlobal == aListScope)
+		{
+		test(KErrTooBig == iServSession.GetList(aListId, aBuffer, aSize));
+		}
+	else if(EScopeThreadSpecific == aListScope)
+		{
+		test(KErrTooBig == iServSession.GetList((TThreadId)aTargetId, aListId, aBuffer, aSize));
+		}
+	else if(EScopeProcessSpecific == aListScope)
+		{
+		test(KErrTooBig == iServSession.GetList((TProcessId)aTargetId, aListId, aBuffer, aSize));
+		}
+	else
+		{
+		// unknown list scope
+		test(0);
+		}
+
+	//keep allocating larger buffers, beginning with the aSize returned by the above call,
+	//and hopefully we'll eventually make a large enough one
+	test(KErrNone == aBuffer.ReAlloc(aSize));
+
+	for(;;)
+		{
+		TInt err = KErrNone;
+		if(EScopeGlobal == aListScope)
+			{
+			err = iServSession.GetList(aListId, aBuffer, aSize);
+			}
+		else if(EScopeThreadSpecific == aListScope)
+			{
+			err = iServSession.GetList((TThreadId)aTargetId, aListId, aBuffer, aSize);
+			}
+		else if(EScopeProcessSpecific == aListScope)
+			{
+			err = iServSession.GetList((TProcessId)aTargetId, aListId, aBuffer, aSize);
+			}
+		else
+			{
+			// unknown list scope
+			test(0);
+			}
+		if(err == KErrTooBig)
+			{
+			//wasn't big enough so double it
+			aSize = aSize << 1;
+			err = aBuffer.ReAlloc(aSize);
+			if(err != KErrNone)
+				{
+				//print out a message if couldn't allocate memory and quit
+				test.Printf(_L("Out ot memory when attempting to allocate %d bytes."), aSize);
+				test(KErrNone == err);
+				}
+
+			//fairly arbitrary test, we don't have a max size for these calls.
+			//In reality a list would have to have many thousands of elements
+			//to break this test which shouldn't really happen
+			test(aSize <= 0x4000);
+			}
+		else
+			{
+			test(KErrNone == err);
+			test(aBuffer.Length() == aSize);
+			//break out of the loop if the list has been successfully read in
+			break;
+			}
+		}
+	}
+
+//---------------------------------------------
+//! @SYMTestCaseID KBase-T-RMDEBUG2-0432
+//! @SYMTestType
+//! @SYMPREQ PREQ1426
+//! @SYMTestCaseDesc Test reading and writing memory
+//! @SYMTestActions Multiple calls to read and write memory, with various sizes and at various locations.
+//!	Also test that bad input values cause appropriate errors to be returned.
+//! @SYMTestExpectedResults All tests should pass and the target process should be left unaffected
+//! @SYMTestPriority High
+//! @SYMTestStatus Implemented
+//---------------------------------------------
+void CRunModeAgent::TestMemoryAccess()
+{
+	TInt err;
+
+	test.Next(_L("TestMemoryAccess - Read Memory\n"));
+
+	//initialise buffer
+	gMemoryAccessBytes.SetLength(0);
+	for (TInt i=0; i<SYMBIAN_RMDBG_MEMORYSIZE; i++)
+		{
+		gMemoryAccessBytes.Append(i);
+		}
+
+	TUint32 address = (TUint32)(&gMemoryAccessBytes[0]);
+	TUint32 dataSize = SYMBIAN_RMDBG_MEMORYSIZE;
+
+	//create size for buffer that is rounded up to nearest 4 bytes if not
+	//already 4 byte aligned
+	TUint32 size = dataSize;
+	if(size % 4 != 0)
+		{
+		size += (4 - (size % 4));
+		}
+
+	RBuf8 dataBlock;
+	err = dataBlock.Create(size);
+	test(err==KErrNone);
+	test(KErrNone == iServSession.AttachExecutable(iFileName, EFalse));
+
+	//suspend the thread prior to memory operations
+	test(KErrNone == iServSession.SuspendThread(iThreadID));
+
+	err = iServSession.ReadMemory(iThreadID, address, size, dataBlock, EAccess32, EEndLE8);
+	test(err==KErrNone);
+
+	for (TInt i=0; i<dataSize; i++)
+		{
+		test(dataBlock.Ptr()[i] == gMemoryAccessBytes[i]);
+		}
+
+	test.Next(_L("TestMemoryAccess - Write Memory\n"));
+
+	// Now reset the buffer
+	for (TInt i=0; i<dataSize; i++)
+		{
+		gMemoryAccessBytes[i] = 0;
+		}
+
+	// Write our data into the buffer
+	err = iServSession.WriteMemory(iThreadID, address, size, dataBlock, EAccess32, EEndLE8);
+	test(err==KErrNone);
+
+	for (TInt i=0; i<dataSize; i++)
+		{
+		test(dataBlock.Ptr()[i] == gMemoryAccessBytes[i]);
+		}
+
+	//final test that everything's not been going wrong
+	test(gMemoryAccessBytes[5] != 0);
+
+	test.Next(_L("TestMemoryAccess - Invalid arguments\n"));
+	test.Printf(_L("This test may emit crash-like information. This is intended.\n"));
+
+	//test address that is not 32 bit aligned
+	err = iServSession.ReadMemory(iThreadID, address + 1, size, dataBlock, EAccess32, EEndLE8);
+	test(err == KErrArgument);
+
+	//test size that is not multiple of 4 bytes
+	err = iServSession.WriteMemory(iThreadID, address, size + 2, dataBlock, EAccess32, EEndLE8);
+	test(err == KErrArgument);
+
+	//test size > max block size
+	err = iServSession.ReadMemory(iThreadID, address, (1<<15), dataBlock, EAccess32, EEndLE8);
+	test(err == KErrArgument);
+
+	//test access size == 2 bytes
+	err = iServSession.ReadMemory(iThreadID, address, size, dataBlock, EAccess16, EEndLE8);
+	test(err == KErrNotSupported);
+
+	//test access size == 1 byte
+	err = iServSession.WriteMemory(iThreadID, address, size, dataBlock, EAccess8, EEndLE8);
+	test(err == KErrNotSupported);
+
+	//test endianess == EEndBE8
+	err = iServSession.ReadMemory(iThreadID, address, size, dataBlock, EAccess32, EEndBE8);
+	test(err == KErrNotSupported);
+
+	//test endianess == EEndBE32
+	err = iServSession.WriteMemory(iThreadID, address, size, dataBlock, EAccess32, EEndBE32);
+	test(err == KErrNotSupported);
+
+	//test reading off end of memory
+	err = iServSession.ReadMemory(iThreadID, 0xffffff00, 0x00000101, dataBlock, EAccess32, EEndLE8);
+	test(err == KErrArgument);
+
+	//The following three tests check that edge conditions in the range check are handled correctly.
+	err = iServSession.ReadMemory(iThreadID, 0xffffff00, 0x000000FF, dataBlock, EAccess32, EEndLE8);
+	test(err == KErrArgument);
+
+	err = iServSession.ReadMemory(iThreadID, 0xffffff00, 0x000000F0, dataBlock, EAccess32, EEndLE8);
+	test(err == KErrBadDescriptor);
+
+	//Third range check test. Check that range check is handled correctly even when base + size wraps to 0.
+	err = iServSession.ReadMemory(iThreadID, 0xffffff00, 0x00000100, dataBlock, EAccess32, EEndLE8);
+	test(err == KErrBadDescriptor);
+	//end of range check tests
+
+	//test size == 0
+	err = iServSession.WriteMemory(iThreadID, address, 0, dataBlock, EAccess32, EEndLE8);
+	test(err == KErrArgument);
+
+	//attempt to write to address outside of process data segments,
+	//this address corresponds to the vectors so shouldn't be able to write
+	err = iServSession.WriteMemory(iThreadID, 0xffff0000, size, dataBlock, EAccess32, EEndLE8);
+	test(err == KErrBadDescriptor);
+
+	//attempt to read and write to address in process code segment
+
+	//open a handle to the thread
+	RThread debugThread;
+	test(debugThread.Open(iThreadID) == KErrNone);
+
+	//get a reference to the debug process
+	RProcess debugProcess;
+	test(debugThread.Process(debugProcess) == KErrNone);
+
+	//get the memory info for the process
+	TProcessMemoryInfo info;
+	test(debugProcess.GetMemoryInfo(info) == KErrNone);
+
+	address = info.iCodeBase;
+	if(size <= info.iCodeSize)
+		{
+		test(KErrNone == iServSession.ReadMemory(iThreadID, address, size, dataBlock, EAccess32, EEndLE8));
+		test(KErrBadDescriptor == iServSession.WriteMemory(iThreadID, address, size, dataBlock, EAccess32, EEndLE8));
+		}
+
+	// Some performance tests now
+	TUint32 bytesRead = 0;
+
+	// Allocate a data buffer
+	TUint32* p = (TUint32*)User::Alloc(size);
+	test(p != 0);
+
+	TInt nanokernel_tick_period;
+	HAL::Get(HAL::ENanoTickPeriod, nanokernel_tick_period);
+	test (nanokernel_tick_period != 0);
+
+	static const TInt KOneMillion = 1000000;
+
+	TInt nkTicksPerSecond = KOneMillion/nanokernel_tick_period;
+
+	TUint32 stopTickCount = User::NTickCount() + nkTicksPerSecond;
+
+	while (User::NTickCount() < stopTickCount)
+		{
+		err = iServSession.ReadMemory(iThreadID, (TUint32)p, size, dataBlock, EAccess32, EEndLE8);
+		test(err==KErrNone);
+
+		// Increase the count of bytes read
+		bytesRead += size;
+		}
+
+	test(bytesRead != 0);
+	iMemoryReadKbytesPerSecond = bytesRead/1024;
+
+	// write memory test
+	TUint32 bytesWritten = 0;
+
+	stopTickCount = User::NTickCount() + nkTicksPerSecond;
+
+	while (User::NTickCount() < stopTickCount)
+		{
+		err = iServSession.WriteMemory(iThreadID, (TUint32)p, size, dataBlock, EAccess32, EEndLE8);
+		test(err==KErrNone);
+
+		// Increase the count of bytes read
+		bytesWritten += size;
+		}
+
+	test (bytesWritten != 0);
+	iMemoryWriteKbytesPerSecond = bytesWritten/1024;
+
+	User::Free(p);
+
+	//resume the thread
+	test(KErrNone == iServSession.ResumeThread(iThreadID));
+
+	debugThread.Close();
+	dataBlock.Close();
+
+	test(KErrNone == iServSession.DetachExecutable(iFileName));
+	}
+
+//---------------------------------------------
+//! @SYMTestCaseID KBase-T-RMDEBUG2-0433
+//! @SYMTestType
+//! @SYMPREQ PREQ1426
+//! @SYMTestCaseDesc Test suspending and resuming threads
+//! @SYMTestActions Multiple calls to suspend and resume threads with and without attaching to the thread
+//! @SYMTestExpectedResults All tests should pass and the target process should be left unaffected
+//! @SYMTestPriority High
+//! @SYMTestStatus Implemented
+//---------------------------------------------
+void CRunModeAgent::TestSuspendResume()
+	{
+	TInt err;
+
+	test.Next(_L("TestSuspendResume - Suspend\n"));
+
+	test(KErrNone == iServSession.AttachExecutable(iFileName, EFalse));
+	// Suspend the thread
+	err = iServSession.SuspendThread(iThreadID);
+	test(err==KErrNone);
+	TInt localtestdata;
+	localtestdata = TestData;
+
+	// Wait 3 seconds (suspends this thread) and hopefully resumes the
+	// thread we are controlling via the iServSession.SuspendThread request
+	User::After(3000000);
+
+	// Now check data hasnt changed
+	test(localtestdata==TestData);
+
+	// Resume the thread
+	test.Next(_L("TestSuspendResume - Resume\n"));
+	err = iServSession.ResumeThread(iThreadID);
+	test(err==KErrNone);
+
+	test(KErrNone == iServSession.DetachExecutable(iFileName));
+
+	// Wait 3 seconds (suspends this thread) and hopefully resumes the
+	// thread we are controlling via the iServSession.SuspendThread request
+	User::After(3000000);
+
+	// Now check that the thread being controlled has resumed and is
+	// updating the variable
+	test(localtestdata!=TestData);
+
+	// check that agent can resume thread which it previously detached from
+	test(KErrNone == iServSession.AttachExecutable(iFileName, EFalse));
+	test(KErrNone == iServSession.SuspendThread(iThreadID));
+	test(KErrNone == iServSession.DetachExecutable(iFileName));
+	test(KErrNone == iServSession.AttachExecutable(iFileName, EFalse));
+	test(KErrNone == iServSession.ResumeThread(iThreadID));
+	test(KErrNone == iServSession.DetachExecutable(iFileName));
+
+	// check that agent cannot suspend thread which it previously suspended and then detached from
+	test(KErrNone == iServSession.AttachExecutable(iFileName, EFalse));
+	test(KErrNone == iServSession.SuspendThread(iThreadID));
+	test(KErrNone == iServSession.DetachExecutable(iFileName));
+	test(KErrNone == iServSession.AttachExecutable(iFileName, EFalse));
+	test(KErrAlreadyExists == iServSession.SuspendThread(iThreadID));
+	test(KErrNone == iServSession.ResumeThread(iThreadID));
+	test(KErrNone == iServSession.DetachExecutable(iFileName));
+	}
+
+//---------------------------------------------
+//! @SYMTestCaseID KBase-T-RMDEBUG2-0434
+//! @SYMTestType
+//! @SYMPREQ PREQ1426
+//! @SYMTestCaseDesc Test getting the debug functionality from the driver
+//! @SYMTestActions Get the size and contents of the debug functionality block
+//! @SYMTestExpectedResults All tests should pass and the expected data should appear in the functionality block
+//! @SYMTestPriority High
+//! @SYMTestStatus Implemented
+//---------------------------------------------
+void CRunModeAgent::TestDebugFunctionality()
+	{
+
+	TInt err;
+
+	test.Next(_L("TestDebugFunctionality - GetDebugFunctionalityBufSize\n"));
+
+	TUint32 bufsize = 0;	// Safe default size
+
+	// Get functionality block size
+	err = iServSession.GetDebugFunctionalityBufSize(&bufsize);
+	test(err==KErrNone);
+	test.Next(_L("TestDebugFunctionality - GetDebugFunctionality\n"));
+
+	// Ensure we have a finite buffer size
+	test(bufsize!=0);
+
+	// Allocate space for the functionality data
+	HBufC8* dftext = HBufC8::NewLC(bufsize);
+
+	// create an empty TPtr8 refering to dftext
+	TPtr8 dftextPtr(dftext->Des());
+
+	// Get the functionality block
+	err = iServSession.GetDebugFunctionality(dftextPtr);
+	test(err==KErrNone);
+
+	// Check that the first entry is correct
+	TTagHeader RefHdr =
+	{
+		ETagHeaderIdCore,ECoreLast,
+	};
+
+	// First header passed from rm_debug.ldd
+	TTagHeader* TestHdr = (TTagHeader*)dftextPtr.Ptr();
+
+	// Check
+	test(RefHdr.iTagHdrId==TestHdr->iTagHdrId);
+	// this test might fail if the agent is used with a Debug Security Server different from
+	// the one it was compiled against. So removing it for now.
+	//test(RefHdr.iNumTags==TestHdr->iNumTags);
+
+	// read a value from the data to check it has come through as expected
+	TTagHeader* header = GetTagHdr(dftext->Des(), ETagHeaderIdApiConstants);
+	test(header != NULL);
+	TTag* tag = GetTag(header, EApiConstantsTEventInfoSize);
+	test(tag != NULL);
+	// this test might fail if the agent is used with a Debug Security Server different from
+	// the one it was compiled against. So removing it for now.
+	//test(sizeof(TEventInfo) == tag->iValue);
+
+	// Remove our temporary buffer
+	CleanupStack::PopAndDestroy(dftext);
+	}
+
+//---------------------------------------------
+//! @SYMTestCaseID KBase-T-RMDEBUG2-0435
+//! @SYMTestType
+//! @SYMPREQ PREQ1426
+//! @SYMTestCaseDesc Test setting and clearing consecutive breakpoints
+//! @SYMTestActions Set and clear consecutive breakpoints of all combinations of breakpoint types
+//! @SYMTestExpectedResults All breakpoints should be set and cleared without error
+//! @SYMTestPriority High
+//! @SYMTestStatus Implemented
+//---------------------------------------------
+void CRunModeAgent::TestConsecutiveBreakPoints()
+	{
+	test.Next(_L("TestConsecutiveBreakPoints\n"));
+
+	test(KErrNone == iServSession.SuspendThread(iThreadID));
+
+	// just a temporary structure for storing info about a breakpoint
+	struct TBreakPoint
+		{
+	public:
+		TBreakPoint()
+			:iId(0),
+			iMode((TArchitectureMode)0),
+			iAddress(0)
+			{}
+		TBreakId iId;
+		TArchitectureMode iMode;
+		TUint32 iAddress;
+		inline TInt Size() { return (EArmMode == iMode) ? 4 : 2; }
+		};
+
+	//an address in the target debug thread
+	TUint32 address = (TUint32)(&TestFunction);
+
+	// there are six orders in which three breakpoints can be set, these are looped
+	// through below to check setting and clearing consecutive breakpoints works
+	TUint8 order[6][3] =
+		{
+			{0,1,2},
+			{0,2,1},
+			{1,0,2},
+			{1,2,0},
+			{2,0,1},
+			{2,1,0}
+		};
+
+	// The following code checks that setting and clearing consecutive breakpoints works correctly:
+	// It checks that setting all combinations of three arm and thumb breakpoints succeeds, and check that the
+	// breakpoints can be set in any order, and then cleared in any order
+
+	// the 3 least significant bits of i control whether each of the three breakpoints should be arm or thumb
+	for(TInt i=0; i<8; i++)
+		{
+		// controls the order in which the breakpoints should be set
+		for(TInt j=0; j<6; j++)
+			{
+			// create the three breakpoints and set their modes
+			TBreakPoint bp[3];
+			bp[0].iMode = (i&1) ? EArmMode : EThumbMode;
+			bp[1].iMode = (i&2) ? EArmMode : EThumbMode;
+			bp[2].iMode = (i&4) ? EArmMode : EThumbMode;
+
+			// set the address of each of the breakpoints
+			bp[0].iAddress = address;
+			if(EArmMode == bp[0].iMode)
+				{ // if an arm breakpoint then must be on a four byte boundary
+				bp[0].iAddress = Align4(bp[0].iAddress);
+				}
+			bp[1].iAddress = bp[0].iAddress + bp[0].Size();
+			if(EArmMode == bp[1].iMode)
+				{ // if an arm breakpoint then must be on a four byte boundary
+				bp[1].iAddress = Align4(bp[1].iAddress);
+				}
+			bp[2].iAddress = bp[1].iAddress + bp[1].Size();
+			if(EArmMode == bp[2].iMode)
+				{ // if an arm breakpoint then must be on a four byte boundary
+				bp[2].iAddress = Align4(bp[2].iAddress);
+				}
+			for(TInt k=0; k<6; k++)
+				{
+				// set the three breakpoints in the order defined by j and then clear them in the order defined by k
+				test(KErrNone==iServSession.SetBreak(bp[order[j][0]].iId, iThreadID, bp[order[j][0]].iAddress, bp[order[j][0]].iMode));
+				test(KErrNone==iServSession.SetBreak(bp[order[j][1]].iId, iThreadID, bp[order[j][1]].iAddress, bp[order[j][1]].iMode));
+				test(KErrNone==iServSession.SetBreak(bp[order[j][2]].iId, iThreadID, bp[order[j][2]].iAddress, bp[order[j][2]].iMode));
+				test(KErrNone==iServSession.ClearBreak(bp[order[k][0]].iId));
+				test(KErrNone==iServSession.ClearBreak(bp[order[k][1]].iId));
+				test(KErrNone==iServSession.ClearBreak(bp[order[k][2]].iId));
+				}
+			}
+		}
+
+	// resume the thread
+	test(KErrNone == iServSession.ResumeThread(iThreadID));
+	}
+
+//---------------------------------------------
+//! @SYMTestCaseID KBase-T-RMDEBUG2-0436
+//! @SYMTestType
+//! @SYMPREQ PREQ1426
+//! @SYMTestCaseDesc Test breakpoint functionality
+//! @SYMTestActions Multiple calls to set and clear breakpoints. Checking bad input produces appropriate errors.
+//! @SYMTestExpectedResults All tests should pass and the target debug thread should be left unaffected
+//! @SYMTestPriority High
+//! @SYMTestStatus Implemented
+//---------------------------------------------
+void CRunModeAgent::TestBreakPoints()
+	{
+	TInt err;
+
+	test.Next(_L("TestBreakPoints - Set\n"));
+
+	test(KErrNone == iServSession.AttachExecutable(iFileName, EFalse));
+
+	TestConsecutiveBreakPoints();
+
+	//an address in the target debug thread
+	TUint32 address = (TUint32)(&TestFunction);
+
+	/*
+	 * Ensure that breakpoint operations don't
+	 * affect memory read/write by checking that reads/writes
+	 * in locations containing breakpoints don't change behaviour
+	 * because of the breakpoints.
+	 */
+
+	TUint32 size = SYMBIAN_RMDBG_MEMORYSIZE;
+
+	RBuf8 originalDataBlock;
+	err = originalDataBlock.Create(size);
+	test(err==KErrNone);
+
+	//suspend the thread
+	test(KErrNone == iServSession.SuspendThread(iThreadID));
+
+	err = iServSession.ReadMemory(iThreadID, address, size, originalDataBlock, EAccess32, EEndLE8);
+	test(err==KErrNone);
+
+	// Test data block for comparison
+	RBuf8 testDataBlock;
+	err = testDataBlock.Create(size);
+	test(err==KErrNone);
+
+	/*
+	 * set an arm breakpoint
+	 */
+	TBreakId armBreakId = 0;
+	err = iServSession.SetBreak(armBreakId, iThreadID, address, EArmMode);
+	test(err == KErrNone);
+
+	// Ensure that memory read is not corrupted
+	err = iServSession.ReadMemory(iThreadID, address, size, testDataBlock, EAccess32, EEndLE8);
+	test(err==KErrNone);
+
+	test (testDataBlock == originalDataBlock);
+
+	/*
+	 * set a thumb breakpoint
+	 */
+	TBreakId thumbBreakId = 0;
+	err = iServSession.SetBreak(thumbBreakId, iThreadID, address+4, EThumbMode);
+	test(err == KErrNone);
+
+	/*
+	 * set a thumb2EE breakpoint
+	 */
+	TBreakId thumb2EEBreakId = 0;
+	err = iServSession.SetBreak(thumb2EEBreakId, iThreadID, address+8, EThumb2EEMode);
+	test(err == KErrNotSupported);
+
+	/*
+	 * overlapping breakpoint (same address/threadId/mode)
+	 */
+	TBreakId overlapBreakId = 0;
+	err = iServSession.SetBreak(overlapBreakId, iThreadID, address, EArmMode);
+	test(err == KErrAlreadyExists);
+
+	/*
+	 * overlapping breakpoint (different address/same threadId/different mode)
+	 *
+	 * address - EArmBreakpoint
+	 * address+2 - EThumbBreakpoint
+	 */
+	TBreakId overlap2BreakId = 0;
+	err = iServSession.SetBreak(overlap2BreakId, iThreadID, address+2, EThumbMode);
+	test(err == KErrAlreadyExists);
+
+	/*
+	 * Un-aligned address (arm)
+	 */
+	TBreakId armUnalignedBreakId = 0;
+	err = iServSession.SetBreak(armUnalignedBreakId, iThreadID, address+6, EArmMode);
+	test(err == KErrArgument);
+
+	/*
+	 * Un-aligned address (thumb)
+	 */
+	TBreakId thumbUnalignedBreakId = 0;
+	err = iServSession.SetBreak(thumbUnalignedBreakId, iThreadID, address+7, EThumbMode);
+	test(err == KErrArgument);
+
+	/*
+	 * Invalid address (arm)
+	 */
+	TBreakId armBadAddressBreakId = 0;
+	err = iServSession.SetBreak(armBadAddressBreakId, iThreadID, 0 /* address */, EThumbMode);
+	test(err == KErrBadDescriptor);
+
+	/*
+	 * Different thread, same address. Should fail for the same process, but succeed
+	 * for a different process.
+	 */
+
+	/*
+	 * Invalid thread
+	 */
+	TBreakId invalidThreadBreakId = 0;
+	err = iServSession.SetBreak(invalidThreadBreakId, 0xbabababa, address, EThumbMode);
+	test(err == KErrPermissionDenied);
+
+	// Clear the ARM breakpoint
+	err = iServSession.ClearBreak(armBreakId);
+	test(err == KErrNone);
+
+	// Clear the Thumb breakpoint
+	err = iServSession.ClearBreak(thumbBreakId);
+	test(err == KErrNone);
+
+	// to do : two threads at the same address
+	// to do : two processes at the same address
+
+	// Ensure that memory read is not corrupted after clearing the breakpoints
+	err = iServSession.ReadMemory(iThreadID, address, size, testDataBlock, EAccess32, EEndLE8);
+	test(err==KErrNone);
+
+	test (testDataBlock == originalDataBlock);
+
+	/*
+	 * How fast can we set breakpoints?
+	 *
+	 * Measure the time by setting/clearing breakpoints for 1 second.
+     */
+	TInt nanokernel_tick_period;
+	HAL::Get(HAL::ENanoTickPeriod, nanokernel_tick_period);
+	test (nanokernel_tick_period != 0);
+
+	TInt nkTicksPerSecond = HelpTicksPerSecond();
+
+	TInt breaksPerSecond = 0;
+
+	TUint32 stopTickCount = User::NTickCount() + nkTicksPerSecond;
+
+	while (User::NTickCount() < stopTickCount)
+		{
+		// set the breakpoint
+		TBreakId armBreakId = 0;
+		err = iServSession.SetBreak(armBreakId, iThreadID, address, EArmMode);
+		test(err == KErrNone);
+
+		// Clear the breakpoint
+		err = iServSession.ClearBreak(armBreakId);
+		test(err == KErrNone);
+
+		// Update the count of breakpoints
+		breaksPerSecond++;
+
+		// Gone wrong if we wrap to negative breakpoints (cannot set 2billion/second!)
+		test(breaksPerSecond >0);
+		}
+
+	// Store the results for later
+	iBreakpointsPerSecond = breaksPerSecond;
+
+	/*
+	 * How many breakpoints can we set?
+	 */
+
+	TBool done = EFalse;
+
+	// We assume all the breakpoints id's are issued in ascending order
+	TInt maxBreakPoints = 0;
+
+	// Temporary buffer
+	RArray<TBreakId> breakIdList;
+
+	TUint32 testAddress = address;
+
+	while(!done)
+		{
+		TBreakId breakId = 0;
+
+		// set the breakpoint
+		testAddress += 4;	// ensure the addresses don't overlap
+
+		err = iServSession.SetBreak(breakId, iThreadID, testAddress, EArmMode);
+		test (err == KErrNone || err == KErrOverflow);
+		if (err != KErrNone)
+			{
+			// we've reached the limit of the number of breaks we can set
+			done = ETrue;
+			break;
+			}
+
+		// store the id of this breakpoint
+		breakIdList.Append(breakId);
+
+		// Increase the count of breakpoints
+		maxBreakPoints++;
+		test(maxBreakPoints > 0);
+		}
+
+	// How many breakpoints can we set?
+	iMaxBreakpoints = maxBreakPoints;
+
+	// now clear all those breakpoints again
+	while(breakIdList.Count() != 0)
+		{
+		// Place it into a TBreakId
+		TBreakId id = breakIdList[0];
+
+		err = iServSession.ClearBreak(id);
+		test(err == KErrNone);
+
+		// next id
+		breakIdList.Remove(0);
+		}
+
+	breakIdList.Close();
+
+	// close our temporary buffers
+	originalDataBlock.Close();
+	testDataBlock.Close();
+
+	err = iServSession.ResumeThread(iThreadID);
+	test (err == KErrNone);
+
+	test(KErrNone == iServSession.DetachExecutable(iFileName));
+	}
+
+//---------------------------------------------
+//! @SYMTestCaseID KBase-T-RMDEBUG2-0437
+//! @SYMTestType
+//! @SYMPREQ PREQ1426
+//! @SYMTestCaseDesc Test modifying breakpoints
+//! @SYMTestActions Several calls to modify breakpoints
+//! @SYMTestExpectedResults Valid requests should result in the breakpoints being changed, invalid requests should return errors
+//! @SYMTestPriority High
+//! @SYMTestStatus Implemented
+//---------------------------------------------
+void CRunModeAgent::TestModifyBreak()
+	{
+	test.Next(_L("TestModifyBreak\n"));
+
+	DoTestModifyBreak(ETrue);
+	DoTestModifyBreak(EFalse);
+	}
+
+void CRunModeAgent::DoTestModifyBreak(TBool aThreadSpecific)
+	{
+	test.Printf(_L("DoTestModifyBreak: aThreadSpecific: %d\n"), aThreadSpecific?1:0);
+
+	TInt err;
+
+	RProcess process;
+	TProcessId processId = process.Id();
+	process.Close();
+
+	test(KErrNone == iServSession.AttachExecutable(iFileName, EFalse));
+
+	//suspend the thread
+	test(KErrNone == iServSession.SuspendThread(iThreadID));
+
+	//an address in the target debug thread
+	TUint32 address = (TUint32)(&TestFunction);
+
+	//set an arm mode break point
+	TBreakId armBreakId = 0;
+	err = aThreadSpecific
+		? iServSession.SetBreak(armBreakId, iThreadID, address, EArmMode)
+		: iServSession.SetProcessBreak(armBreakId, processId, address, EArmMode);
+	test(err == KErrNone);
+
+	/*
+	 * Invalid thread
+	 */
+	err = aThreadSpecific
+		? iServSession.ModifyBreak(armBreakId, 0xbabababa, address, EArmMode)
+		: iServSession.ModifyProcessBreak(armBreakId, 0xbabababa, address, EArmMode);
+	test(err == KErrPermissionDenied);
+
+	/*
+	 * Valid address
+	 */
+	err = aThreadSpecific
+		? iServSession.ModifyBreak(armBreakId, iThreadID, address+4, EArmMode)
+		: iServSession.ModifyProcessBreak(armBreakId, processId, address+4, EArmMode);
+	test(err == KErrNone);
+
+	/*
+	 * Invalid address
+	 */
+	err = aThreadSpecific
+		? iServSession.ModifyBreak(armBreakId, iThreadID, 0, EArmMode)
+		: iServSession.ModifyProcessBreak(armBreakId, processId, 0, EArmMode);
+	test(err == KErrBadDescriptor);
+
+	/*
+	 * Thumb mode
+	 */
+	err = aThreadSpecific
+		? iServSession.ModifyBreak(armBreakId, iThreadID, address, EThumbMode)
+		: iServSession.ModifyProcessBreak(armBreakId, processId, address, EThumbMode);
+	test(err == KErrNone);
+
+	/*
+	 * Thumb2EE mode
+	 */
+	err = aThreadSpecific
+		? iServSession.ModifyBreak(armBreakId, iThreadID, address, EThumb2EEMode)
+		: iServSession.ModifyProcessBreak(armBreakId, processId, address, EThumb2EEMode);
+	test(err == KErrNotSupported);
+
+	/*
+	 * Arm mode
+	 */
+	err = aThreadSpecific
+		? iServSession.ModifyBreak(armBreakId, iThreadID, address, EArmMode)
+		: iServSession.ModifyProcessBreak(armBreakId, processId, address, EArmMode);
+	test(err == KErrNone);
+
+	// Finally, clear the breakpoint
+	err = iServSession.ClearBreak(armBreakId);
+	test(err == KErrNone);
+
+	//resume the thread
+	test(KErrNone == iServSession.ResumeThread(iThreadID));
+	test(KErrNone == iServSession.DetachExecutable(iFileName));
+	}
+
+//---------------------------------------------
+//! @SYMTestCaseID KBase-T-RMDEBUG2-0438
+//! @SYMTestType
+//! @SYMPREQ PREQ1426
+//! @SYMTestCaseDesc Test extracting information about breakpoints
+//! @SYMTestActions Several calls to get information about breakpoints
+//! @SYMTestExpectedResults All tests should pass and the target process should be left unaffected
+//! @SYMTestPriority High
+//! @SYMTestStatus Implemented
+//---------------------------------------------
+void CRunModeAgent::TestBreakInfo()
+	{
+	test.Next(_L("TestBreakInfo\n"));
+
+	DoTestBreakInfo(ETrue);
+	DoTestBreakInfo(EFalse);
+	}
+
+void CRunModeAgent::DoTestBreakInfo(TBool aThreadSpecific)
+	{
+	test.Printf(_L("DoTestModifyBreak: aThreadSpecific: %d\n"), aThreadSpecific?1:0);
+
+	TInt err;
+
+	RProcess process;
+	TProcessId processId = process.Id();
+	process.Close();
+
+	//an address in the target debug thread
+	TUint32 address = (TUint32)(&TestFunction);
+
+	test(KErrNone == iServSession.AttachExecutable(iFileName, EFalse));
+
+	//suspend thread
+	test(KErrNone == iServSession.SuspendThread(iThreadID));
+
+	//set an arm mode break point
+	TBreakId armBreakId = 0;
+	err = aThreadSpecific
+		? iServSession.SetBreak(armBreakId, iThreadID, address, EArmMode)
+		: iServSession.SetProcessBreak(armBreakId, processId, address, EArmMode);
+	test(err == KErrNone);
+
+	// Read back the information and check it is correct
+	TThreadId testThreadId = TThreadId(0);
+	TProcessId testProcessId = TProcessId(0);
+	TUint32 testAddress = 0;
+	TArchitectureMode testMode = EArmMode;
+
+	err = aThreadSpecific
+		? iServSession.BreakInfo(armBreakId,testThreadId,testAddress, testMode)
+		: iServSession.ProcessBreakInfo(armBreakId, testProcessId, testAddress, testMode);
+	test (err == KErrNone);
+	test (aThreadSpecific ? (testThreadId == iThreadID) : (testProcessId == processId));
+	test (testAddress == address);
+	test (testMode == EArmMode);
+
+	//change the address
+	TUint32 changeAddress = address + 64;
+	err = aThreadSpecific
+		? iServSession.ModifyBreak(armBreakId, iThreadID, changeAddress,EArmMode)
+		: iServSession.ModifyProcessBreak(armBreakId, processId, changeAddress, EArmMode);
+	test(err == KErrNone);
+
+	// Check the address has changed
+	err = aThreadSpecific
+		? iServSession.BreakInfo(armBreakId,testThreadId,testAddress, testMode)
+		: iServSession.ProcessBreakInfo(armBreakId, testProcessId, testAddress, testMode);
+	test (err == KErrNone);
+	test (testAddress == changeAddress);
+
+	// change the architecture type
+	TArchitectureMode checkMode = EThumbMode;
+	err = aThreadSpecific
+		? iServSession.ModifyBreak(armBreakId, iThreadID, address,checkMode)
+		: iServSession.ModifyProcessBreak(armBreakId, processId, address, checkMode);
+	test (err == KErrNone);
+
+	// Check the mode has changed
+	err = aThreadSpecific
+		? iServSession.BreakInfo(armBreakId,testThreadId,testAddress,testMode)
+		: iServSession.ProcessBreakInfo(armBreakId, testProcessId, testAddress, testMode);
+	test (err == KErrNone);
+	test (testMode == checkMode);
+
+	// clear the breakpoint again
+	err = iServSession.ClearBreak(armBreakId);
+	test (err == KErrNone);
+
+	//resume thread
+	test(KErrNone == iServSession.ResumeThread(iThreadID));
+	test(KErrNone == iServSession.DetachExecutable(iFileName));
+	}
+
+// Needed for the RunToBreak test
+IMPORT_C extern void RMDebug_BranchTst1();
+IMPORT_C extern void RMDebug_BranchTst2();
+
+//---------------------------------------------
+//! @SYMTestCaseID KBase-T-RMDEBUG2-0439
+//! @SYMTestType
+//! @SYMPREQ PREQ1426
+//! @SYMTestCaseDesc Test hitting various types of breakpoints
+//! @SYMTestActions Several calls to register to observe breakpoints and to hit breakpoints of different types
+//! @SYMTestExpectedResults All tests should pass and the target process should be left unaffected
+//! @SYMTestPriority High
+//! @SYMTestStatus Implemented
+//---------------------------------------------
+void CRunModeAgent::TestRunToBreak()
+	{
+	test.Next(_L("TestRunToBreak\n"));
+
+	DoTestRunToBreak(ETrue);
+	DoTestRunToBreak(EFalse);
+	}
+
+void CRunModeAgent::DoTestRunToBreak(TBool aThreadSpecific)
+	{
+	test.Printf(_L("DoTestRunToBreak: aThreadSpecific: %d\n"), aThreadSpecific?1:0);
+
+	TInt err = KErrNone;
+
+	RProcess process;
+	TProcessId processId = process.Id();
+	process.Close();
+
+	test(KErrNone == iServSession.AttachExecutable(iFileName, EFalse));
+	// we should suspend the thread first, then set the breakpoint
+	err = iServSession.SuspendThread(iThreadID);
+	test (err == KErrNone);
+
+	// Try to set the breakpoint
+	TBreakId armBreakId;
+	TUint32 address = (TUint32)(&RMDebug_BranchTst1);
+
+	err = aThreadSpecific
+		? iServSession.SetBreak(armBreakId,iThreadID,address,EArmMode)
+		: iServSession.SetProcessBreak(armBreakId, processId, address, EArmMode);
+	test(err == KErrNone);
+
+	err = aThreadSpecific
+		? iServSession.SetEventAction(iFileName,EEventsBreakPoint, EActionContinue)
+		: iServSession.SetEventAction(iFileName,EEventsProcessBreakPoint, EActionContinue);
+	test (err == KErrNone);
+
+	// Continue the thread
+	err = iServSession.ResumeThread(iThreadID);
+	test (err == KErrNone);
+
+	// wait for the breakpoint to be hit
+	TEventInfo info;
+	static TRequestStatus status;
+
+	TPtr8 infoPtr((TUint8*)&info,0,sizeof(TEventInfo));
+
+	iServSession.GetEvent(iFileName,status,infoPtr);
+
+	// Wait for notification of the breakpoint hit event
+	User::WaitForRequest(status);
+	test(status==KErrNone);
+
+	// info should now be filled with the details
+	test(info.iEventType == (aThreadSpecific ? EEventsBreakPoint : EEventsProcessBreakPoint));
+	test(info.iThreadBreakPointInfo.iRmdArmExcInfo.iR15 == address);
+	test(info.iProcessIdValid);
+	test(info.iThreadIdValid);
+
+	// Not interested in breakpoint events any more
+	err = aThreadSpecific
+		? iServSession.SetEventAction(iFileName,EEventsBreakPoint, EActionIgnore)
+		: iServSession.SetEventAction(iFileName, EEventsProcessBreakPoint, EActionIgnore);
+	test (err == KErrNone);
+
+	// Clear the breakpoint again
+	err = iServSession.ClearBreak(armBreakId);
+	test(err == KErrNone);
+
+	// continue the thread again
+	err = iServSession.ResumeThread(iThreadID);
+	test (err == KErrNone);
+	test(KErrNone == iServSession.DetachExecutable(iFileName));
+	}
+
+//---------------------------------------------
+//! @SYMTestCaseID KBASE-rmdebug2-2704
+//! @SYMTestType
+//! @SYMPREQ PREQ1426
+//! @SYMTestCaseDesc Test breakpoints in a loop
+//! @SYMTestActions Several calls to register to verify breakpoints are stopping at correct address
+//! @SYMTestExpectedResults All tests should pass and the target thread should be left unaffected
+//! @SYMTestPriority High
+//! @SYMTestStatus Implemented
+//---------------------------------------------
+void CRunModeAgent::TestBreakPointsInLoop()
+	{
+	test.Next(_L("TestBreakPointsInLoop\n"));
+
+	DoTestBreakPointsInLoop(ETrue);
+	DoTestBreakPointsInLoop(EFalse);
+	}
+
+void CRunModeAgent::DoTestBreakPointsInLoop(TBool aThreadSpecific)
+	{
+	test.Printf(_L("DoTestBreakPointsInLoop: aThreadSpecific: %d\n"), aThreadSpecific?1:0);
+
+	TInt err = KErrNone;
+	TProcessId processId = RProcess().Id(); 
+
+	test(KErrNone == iServSession.AttachExecutable(iFileName, EFalse));
+	
+	// We should suspend the thread first, then set the breakpoint
+	err = iServSession.SuspendThread(iThreadID);
+	test (err == KErrNone);
+
+	// 2 breakpoints are sufficient to find issues with hitting breakpoints in a loop
+	const TInt numOfBreakPointsInLoop = 2;
+
+	TBreakId armBreakId[numOfBreakPointsInLoop];
+	TUint32 address[numOfBreakPointsInLoop];
+   	
+	TUint32 entryAddress = (TUint32)(&RMDebug_Bkpt_Test_Entry);
+	TBreakId entryArmBreakId;
+
+	// Copy breakpoint address's in array
+	address[0] = (TUint32)(&RMDebug_Bkpt_Test_Loop_Break_1);
+	address[1] = (TUint32)(&RMDebug_Bkpt_Test_Loop_Break_2);
+
+	err = aThreadSpecific
+		? iServSession.SetBreak(entryArmBreakId,iThreadID,entryAddress,EArmMode)
+		: iServSession.SetProcessBreak(entryArmBreakId, processId, entryAddress, EArmMode);
+	test(err == KErrNone);
+
+	// Try to set the breakpoints inside loop
+	for (TInt i = 0; i < numOfBreakPointsInLoop; i++)
+		{
+		err = aThreadSpecific
+			? iServSession.SetBreak(armBreakId[i],iThreadID,address[i],EArmMode)
+			: iServSession.SetProcessBreak(armBreakId[i], processId, address[i], EArmMode);
+		test(err == KErrNone);
+		}
+
+	err = aThreadSpecific
+		? iServSession.SetEventAction(iFileName,EEventsBreakPoint, EActionContinue)
+		: iServSession.SetEventAction(iFileName,EEventsProcessBreakPoint, EActionContinue);
+	test (err == KErrNone);
+
+	// Continue the thread
+	err = iServSession.ResumeThread(iThreadID);
+	test (err == KErrNone);
+
+	// Wait for the breakpoint to be hit
+	TEventInfo info;
+	TRequestStatus status;
+
+	TPtr8 infoPtr((TUint8*)&info,0,sizeof(TEventInfo));
+	iServSession.GetEvent(iFileName,status,infoPtr);
+
+	// Wait for notification of breakpoint event
+	User::WaitForRequest(status);
+	test(status==KErrNone);
+
+	// Info should now be filled with the details
+	test(info.iEventType == (aThreadSpecific ? EEventsBreakPoint : EEventsProcessBreakPoint));
+
+	// Have we stopped at the correct breakpoint?
+	test(info.iThreadBreakPointInfo.iRmdArmExcInfo.iR15 == entryAddress);
+	test(info.iProcessIdValid);
+	test(info.iThreadIdValid);
+
+	// Don't require the entry breakpoint anymore
+	err = iServSession.ClearBreak(entryArmBreakId);
+	test(err == KErrNone);
+	
+	// Stress the system by setting loop count to 100
+	const TUint32 loopCount = 100;
+
+	for (TInt i = 0; i < loopCount; i++)
+		{
+		// Continue the thread
+		err = iServSession.ResumeThread(iThreadID);
+		test (err == KErrNone);
+
+		// Wait for the breakpoint to be hit
+		iServSession.GetEvent(iFileName,status,infoPtr);
+		
+		// Wait for notification of the breakpoint hit event
+		User::WaitForRequest(status);
+		test(status==KErrNone);
+		
+		// Info should now be filled with the details
+		test(info.iEventType == (aThreadSpecific ? EEventsBreakPoint : EEventsProcessBreakPoint));
+		
+		// Have we stopped at the correct breakpoint?
+		test(info.iThreadBreakPointInfo.iRmdArmExcInfo.iR15 == address[i%numOfBreakPointsInLoop]);
+		
+		// Check process and thread id too
+		test(info.iProcessIdValid);
+		test(info.iThreadIdValid);
+		}
+
+	// Not interested in breakpoint events any more
+	err = aThreadSpecific
+		? iServSession.SetEventAction(iFileName,EEventsBreakPoint, EActionIgnore)
+		: iServSession.SetEventAction(iFileName, EEventsProcessBreakPoint, EActionIgnore);
+	test (err == KErrNone);
+
+	// Clear breakpoints
+	for (TInt i = 0; i < numOfBreakPointsInLoop; i++)
+		{
+		err = iServSession.ClearBreak(armBreakId[i]);
+		test(err == KErrNone);
+		}
+	
+	// Continue the thread again
+	err = iServSession.ResumeThread(iThreadID);
+	test (err == KErrNone);
+	test(KErrNone == iServSession.DetachExecutable(iFileName));
+	}
+
+//----------------------------------------------------------------------------------------------
+//! @SYMTestCaseID      KBase-T-RMDEBUG2-0440
+//! @SYMTestType
+//! @SYMPREQ            PREQ1426
+//! @SYMTestCaseDesc    Test access to target user-side registers.
+//! @SYMTestActions     Suspends a target thread, and reads/writes target thread register contents
+//!
+//! @SYMTestExpectedResults KErrNone. Should access target registers without problems.
+//! @SYMTestPriority        High
+//! @SYMTestStatus          Implemented
+//----------------------------------------------------------------------------------------------
+
+void CRunModeAgent::TestRegisterAccess()
+	{
+	TInt err;
+
+	test.Next(_L("TestRegisterAccess - Read\n"));
+
+	test(KErrNone == iServSession.AttachExecutable(iFileName, EFalse));
+
+	//suspend the thread to read registers
+	err = iServSession.SuspendThread(iThreadID);
+	test(err==KErrNone);
+
+	//we'll try to read/write registers ERegisterR0 - ERegisterCPSR and ERegisterR13_IRQ
+	//this way should get valid register values back, invalid ones and not supported ones, and it
+	//means that the register IDs are not completely contiguous
+
+	TInt firstRegister = 0;
+	TInt lastRegister = 17;
+	TInt numberOfRegisters = (lastRegister - firstRegister) + 1;
+
+	RBuf8 ids;
+	err = ids.Create(numberOfRegisters * sizeof(TRegisterInfo));
+	test(err == KErrNone);
+
+	for(TInt i=0; i<numberOfRegisters - 1; i++)
+		{
+		TRegisterInfo reg = (TRegisterInfo)((i + firstRegister)<<8);
+		ids.Append(reinterpret_cast<const TUint8*>(&reg), sizeof(TRegisterInfo));
+		}
+
+	TRegisterInfo reg = ERegisterR13Irq;
+	ids.Append(reinterpret_cast<const TUint8*>(&reg), sizeof(TRegisterInfo));
+
+	//create a buffer to store the register values in
+	RBuf8 originalValues;
+	err = originalValues.Create(numberOfRegisters*sizeof(TUint32));
+	test(err == KErrNone);
+
+	//create a buffer to store the register flags in
+	RBuf8 originalFlags;
+	err = originalFlags.Create(numberOfRegisters*sizeof(TUint8));
+	test(err == KErrNone);
+
+	//read register values
+	err = iServSession.ReadRegisters(iThreadID, ids, originalValues, originalFlags);
+	test(err == KErrNone);
+
+	//create a buffer containing data to write into the registers
+	RBuf8 tempValues;
+	err = tempValues.Create(numberOfRegisters*sizeof(TUint32));
+	test(err == KErrNone);
+
+	TUint cpsrId = 16;
+	for(TUint8 i=0; i<numberOfRegisters*sizeof(TUint32); i++)
+		{
+		if(i/sizeof(TUint32) == cpsrId)
+			{
+			//For the CPSR we wish to write data that makes sense - for USR mode we are
+			//allowed change all except the mode, ie. we must stay in usr mode. We try that here
+			//(allowedCPSRValue[4:0] = 10000) thus not changing the mode.
+			TUint32 allowedCPSRValue = 0x50000010;
+			tempValues.Append((TUint8*)&allowedCPSRValue, 4);
+			i += 3;
+			}
+		else
+			{
+			tempValues.Append(&i, 1);
+			}
+		}
+
+	test.Next(_L("TestRegisterAccess - Write\n"));
+
+	//create a buffer to store the register flags in
+	RBuf8 tempWriteFlags;
+	err = tempWriteFlags.Create(numberOfRegisters*sizeof(TUint8));
+	test(err == KErrNone);
+
+	//write the temp data into the registers
+	err = iServSession.WriteRegisters(iThreadID, ids, tempValues, tempWriteFlags);
+	test(err == KErrNone);
+
+	//create another buffer to store the register flags in
+	RBuf8 tempReadFlags;
+	err = tempReadFlags.Create(numberOfRegisters*sizeof(TUint8));
+	test(err == KErrNone);
+
+	RBuf8 tempReadValues;
+	err = tempReadValues.Create(numberOfRegisters*sizeof(TUint32));
+	test(err == KErrNone);
+
+	//read the temp data out again
+	err = iServSession.ReadRegisters(iThreadID, ids, tempReadValues, tempReadFlags);
+	test(err == KErrNone);
+
+	//check values are correct
+	for(TInt i=0; i<numberOfRegisters; i++)
+		{
+		TRegisterFlag writeFlag;
+		err = GetFlag(tempWriteFlags, i, writeFlag);
+		test(err == KErrNone);
+
+		TRegisterFlag readFlag;
+		err = GetFlag(tempReadFlags, i, readFlag);
+		test(err == KErrNone);
+
+		if((writeFlag == EValid) && (readFlag == EValid))
+			{
+			TUint8 offset = i * sizeof(TUint32);
+			for(TUint j = offset; j< offset + sizeof(TUint32); j++)
+				{
+				test(tempValues.Ptr()[j] == tempReadValues.Ptr()[j]);
+				}
+			}
+		}
+
+	//write the original data into the registers
+	err = iServSession.WriteRegisters(iThreadID, ids, originalValues, originalFlags);
+	test(err == KErrNone);
+
+	//read the data out again
+	err = iServSession.ReadRegisters(iThreadID, ids, tempValues, tempReadFlags);
+	test(err == KErrNone);
+
+	//check values are correct
+	for(TInt i=0; i<numberOfRegisters; i++)
+		{
+		TRegisterFlag writeFlag;
+		err = GetFlag(originalFlags, i, writeFlag);
+		test(err == KErrNone);
+
+		TRegisterFlag readFlag;
+		err = GetFlag(tempReadFlags, i, readFlag);
+		test(err == KErrNone);
+
+		if((writeFlag == EValid) && (readFlag == EValid))
+			{
+			TUint8 offset = i * sizeof(TUint32);
+			for(TUint j = offset; j< offset + sizeof(TUint32); j++)
+				{
+				test(tempValues.Ptr()[j] == originalValues.Ptr()[j]);
+				}
+			}
+		}
+
+	test.Next(_L("TestRegisterAccess - Invalid data\n"));
+
+	//create a buffer of max size 1
+	RBuf8 emptyBuffer;
+	emptyBuffer.Create(1);
+
+	//test register IDs buffer not being a multiple of sizeof(TRegisterInfo)
+	err = iServSession.ReadRegisters(iThreadID, emptyBuffer, tempValues, tempReadFlags);
+	test(err == KErrArgument);
+
+	//test register values buffer not being a multiple of sizeof(TUint32)
+	err = iServSession.ReadRegisters(iThreadID, ids, emptyBuffer, tempReadFlags);
+	test(err == KErrArgument);
+
+	//test flags buffer being representing different number of registers from other two
+	err = iServSession.ReadRegisters(iThreadID, ids, tempValues, emptyBuffer);
+	test(err == KErrArgument);
+
+	//set max length to 0
+	emptyBuffer.ReAlloc(0);
+
+	//test ids buffer being of 0 max length
+	err = iServSession.ReadRegisters(iThreadID, emptyBuffer, tempValues, tempReadFlags);
+	test(err == KErrArgument);
+
+	//do cleanup
+	emptyBuffer.Close();
+	tempValues.Close();
+	tempWriteFlags.Close();
+	tempReadFlags.Close();
+	tempReadValues.Close();
+
+	test.Next(_L("TestRegisterAccess - Setting PC value\n"));
+
+	//create buffer containing PC register ID
+	RBuf8 pcId;
+	err = pcId.Create(sizeof(TRegisterInfo));
+	test(err == KErrNone);
+	TRegisterInfo reg1 = (TRegisterInfo)0x00000f00;
+	pcId.Append(reinterpret_cast<const TUint8*>(&reg1), sizeof(TRegisterInfo));
+
+	//create buffer containing desired PC value
+	RBuf8 pcValue;
+	err = pcValue.Create(sizeof(TUint32));
+	test(err == KErrNone);
+	TUint32 address = (TUint32)(&TestFunction);
+	pcValue.Append(reinterpret_cast<const TUint8*>(&address), sizeof(TUint32));
+
+	//craete buffer for PC flag value
+	RBuf8 pcFlag;
+	err = pcFlag.Create(sizeof(TUint8));
+
+	//write the new PC value
+	err = iServSession.WriteRegisters(iThreadID, pcId, pcValue, pcFlag);
+	test(err==KErrNone);
+
+	//get the flag and check the PC value was written ok
+	TRegisterFlag flag = ENotSupported;
+	err = GetFlag(pcFlag, 0, flag);
+	test(err==KErrNone);
+
+	if(flag == EValid)
+		{
+		/* The PC value was changed to execute the function TestFunction.
+		* TestFunction changes the value of TestData to a given value and 
+		* then calls RMDebug_BranchTst1.
+		* We place a breakpoint on RMDebug_BranchTst1 so that to we are able 
+		* to test the value of TestData.
+		*/
+
+		test(KErrNone == iServSession.SetEventAction(iFileName,EEventsBreakPoint, EActionSuspend));
+		TBreakId armBreakId;
+		TUint32 address = (TUint32)(&RMDebug_BranchTst1);
+		test(KErrNone == iServSession.SetBreak(armBreakId,iThreadID,address,EArmMode));
+
+		// Continue the thread
+		test(KErrNone == iServSession.ResumeThread(iThreadID));
+
+		// wait for the breakpoint to be hit
+		TEventInfo info;
+		static TRequestStatus status;
+
+		TPtr8 infoPtr((TUint8*)&info,0,sizeof(TEventInfo));
+		iServSession.GetEvent(iFileName,status,infoPtr);
+
+		// Wait for notification of the breakpoint hit event
+		User::WaitForRequest(status);
+		test(status==KErrNone);
+
+		// info should now be filled with the details
+		test(info.iEventType == EEventsBreakPoint);
+		test(info.iThreadBreakPointInfo.iRmdArmExcInfo.iR15 == address);
+		test(info.iProcessIdValid);
+		test(info.iThreadIdValid);
+
+		test(KErrNone == iServSession.ClearBreak(armBreakId));
+
+		// Finally test the value
+		test(TestData == 0xffeeddcc);
+		}
+
+	//Make sure we cannot change the CPSR
+	test.Next(_L("Verifying we cannot change the CPSR mode from USR Mode"));
+
+	TUint32 disallowedCpsr = 0x50000013;
+
+	RBuf8 cpsrRegId;
+	err = cpsrRegId.Create(sizeof(TUint32));
+	test(err == KErrNone);
+
+	TRegisterInfo cpsr = (TRegisterInfo)((cpsrId + firstRegister)<<8);
+	cpsrRegId.Append(reinterpret_cast<const TUint8*>(&cpsr), sizeof(TRegisterInfo));
+
+	RBuf8 cpsrRegFlags;
+	err = cpsrRegFlags.Create(sizeof(TUint8));
+	test(err == KErrNone);
+
+	RBuf8 cpsrVal;
+	err = cpsrVal.Create(sizeof(TUint32));
+	test(err == KErrNone);
+
+	cpsrVal.Append((TUint8*)&disallowedCpsr, 4);
+
+	//attempt to write disallowed CPSR in
+	err = iServSession.WriteRegisters(iThreadID, cpsrRegId, cpsrVal, cpsrRegFlags);
+	test(err == KErrNone);
+
+	RBuf8 cpsrReadVal;
+	err = cpsrReadVal.Create(sizeof(TUint32));
+	test(err == KErrNone);
+
+	//Read back the CPSR
+	err = iServSession.ReadRegisters(iThreadID, cpsrRegId, cpsrReadVal, cpsrRegFlags);
+	test(err == KErrNone);
+
+	//Make sure we havent switched modes ie. its not what we wrote
+	TUint32* readVal = (TUint32*)cpsrReadVal.Ptr();
+	test(*readVal != disallowedCpsr);
+
+	cpsrRegId.Close();
+	cpsrRegFlags.Close();
+	cpsrVal.Close();
+	cpsrReadVal.Close();
+
+	//write the original values back into here
+	err = iServSession.WriteRegisters(iThreadID, ids, originalValues, originalFlags);
+	test(err == KErrNone);
+
+	// Resume the thread
+	err = iServSession.ResumeThread(iThreadID);
+	test(err==KErrNone);
+
+	test(KErrNone == iServSession.DetachExecutable(iFileName));
+
+	//do cleanup
+	pcId.Close();
+	pcValue.Close();
+	pcFlag.Close();
+	ids.Close();
+	originalValues.Close();
+	originalFlags.Close();
+	}
+
+//----------------------------------------------------------------------------------------------
+//! @SYMTestCaseID      KBase-T-RMDEBUG2-0441
+//! @SYMTestType
+//! @SYMPREQ            PREQ1426
+//! @SYMTestCaseDesc    Test registration/de-registration of debug interest in target exe with the Debug Security Server
+//! @SYMTestActions     As per description
+//!
+//! @SYMTestExpectedResults KErrNone.
+//! @SYMTestPriority        High
+//! @SYMTestStatus          Implemented
+//----------------------------------------------------------------------------------------------
+
+void CRunModeAgent::TestAttachExecutable()
+	{
+
+	test.Next(_L("TestAttachExecutable - Attach\n"));
+
+	//attach to process passively
+	test(KErrNone == iServSession.AttachExecutable(iFileName, ETrue));
+
+	//make a thread id for a non-existent thread
+	TThreadId threadId(0x12345678);
+
+	//get a handle to the target thread
+	RThread targetThread;
+	TInt err = targetThread.Open(threadId);
+	test(err != KErrNone);
+
+	//not registered for this thread's process (as it doesn't exist)
+	//so should fail security check
+	err = iServSession.ResumeThread(threadId);
+	test(err==KErrPermissionDenied);
+
+	//try to attach to the same process (and fail)
+	test(KErrAlreadyExists == iServSession.AttachExecutable(iFileName, EFalse));
+
+	test.Next(_L("TestAttachExecutable - Detach\n"));
+
+	//detach from process
+	test(KErrNone == iServSession.DetachExecutable(iFileName));
+
+	//attach non-passively
+	test(KErrNone == iServSession.AttachExecutable(iFileName, EFalse));
+
+	//not registered for this thread's process (as it doesn't exist)
+	//so should fail security check
+	err = iServSession.ResumeThread(0x12345678);
+	test(err==KErrPermissionDenied);
+	test(KErrNone == iServSession.DetachExecutable(iFileName));
+	}
+
+//----------------------------------------------------------------------------------------------
+//! @SYMTestCaseID      KBase-T-RMDEBUG2-0442
+//! @SYMTestType
+//! @SYMPREQ            PREQ1426
+//! @SYMTestCaseDesc    Tests single-stepping target threads.
+//! @SYMTestActions     Steps target thread assembly level instructions, mainly branch/change PC
+//!
+//! @SYMTestExpectedResults KErrNone.
+//! @SYMTestPriority        High
+//! @SYMTestStatus          Implemented
+//----------------------------------------------------------------------------------------------
+
+void CRunModeAgent::TestStep()
+	{
+	test.Next(_L("TestStep\n"));
+
+	DoTestStep(EFalse);
+	DoTestStep(ETrue);
+	}
+
+void CRunModeAgent::DoTestStep(TBool aThreadSpecific)
+	{
+	test.Printf(_L("DoTestStep: aThreadSpecific: %d\n"), aThreadSpecific?1:0);
+
+	TInt err = KErrNone;
+
+	RProcess process;
+	TProcessId processId = process.Id();
+	process.Close();
+
+	test(KErrNone == iServSession.AttachExecutable(iFileName, EFalse));
+	//set the target thread to execute the stepping functions
+	test(KErrNone == SwitchTestFunction(EStepFunction));
+
+	err = iServSession.SetEventAction(iFileName,EEventsBreakPoint, EActionContinue);
+	test (err == KErrNone);
+
+	if(!aThreadSpecific)
+		{
+		err = iServSession.SetEventAction(iFileName, EEventsProcessBreakPoint, EActionContinue);
+		test (err == KErrNone);
+		}
+
+	TUint32	startAddress;
+	TUint32	endAddress;
+
+	/*
+	 * RMDebug_StepTest_Non_PC_Modifying
+	 */
+	test.Next(_L("TestStep - Non-PC modifying\n"));
+
+	startAddress = (TUint32)(&RMDebug_StepTest_Non_PC_Modifying);
+
+	endAddress = (TUint32)(&RMDebug_StepTest_Non_PC_Modifying_OK);
+
+	err = aThreadSpecific
+		? HelpTestStep(iThreadID,startAddress,endAddress,EArmMode,1)
+		: HelpTestStep(iThreadID,startAddress,endAddress,EArmMode,1, EFalse, processId);
+	test(err==KErrNone);
+
+	/*
+	 * RMDebug_StepTest_Branch
+	 */
+	test.Next(_L("TestStep - Branch\n"));
+
+	startAddress = (TUint32)(&RMDebug_StepTest_Branch);
+
+	endAddress = (TUint32)(&RMDebug_StepTest_Branch_1);
+
+	err = aThreadSpecific
+		? HelpTestStep(iThreadID,startAddress,endAddress,EArmMode,1)
+		: HelpTestStep(iThreadID,startAddress,endAddress,EArmMode,1, EFalse, processId);
+	test(err==KErrNone);
+
+	/*
+	 * RMDebug_StepTest_Branch_And_Link
+	 */
+	test.Next(_L("TestStep - Branch_And_Link\n"));
+
+	startAddress = (TUint32)(&RMDebug_StepTest_Branch_And_Link_1);
+
+	endAddress = (TUint32)(&RMDebug_StepTest_Branch_And_Link_2);
+
+	err = aThreadSpecific
+		? HelpTestStep(iThreadID,startAddress,endAddress,EArmMode,1)
+		: HelpTestStep(iThreadID,startAddress,endAddress,EArmMode,1, EFalse, processId);
+	test(err==KErrNone);
+
+	/*
+	 * RMDebug_StepTest_MOV_PC
+	 */
+	test.Next(_L("TestStep - MOV PC,X\n"));
+
+	startAddress = (TUint32)(&RMDebug_StepTest_MOV_PC_1);
+
+	endAddress = (TUint32)(&RMDebug_StepTest_MOV_PC_2);
+
+	err = aThreadSpecific
+		? HelpTestStep(iThreadID,startAddress,endAddress,EArmMode,1)
+		: HelpTestStep(iThreadID,startAddress,endAddress,EArmMode,1, EFalse, processId);
+	test(err==KErrNone);
+
+	/*
+	 * RMDebug_StepTest_LDR_PC
+	 */
+	test.Next(_L("TestStep - LDR PC\n"));
+
+	startAddress = (TUint32)(&RMDebug_StepTest_LDR_PC);
+
+	endAddress = (TUint32)(&RMDebug_StepTest_LDR_PC_1);
+
+	err = aThreadSpecific
+		? HelpTestStep(iThreadID,startAddress,endAddress,EArmMode,1)
+		: HelpTestStep(iThreadID,startAddress,endAddress,EArmMode,1, EFalse, processId);
+	test(err==KErrNone);
+
+// thumb and interworking tests are not supported on armv4
+#ifdef __MARM_ARMV5__
+
+	/*
+	 * RMDebug_StepTest_Thumb_Non_PC_Modifying
+	 */
+	test.Next(_L("TestStep - Thumb Non PC-Modifying\n"));
+
+	startAddress = (TUint32)(&RMDebug_StepTest_Thumb_Non_PC_Modifying_1);
+
+	endAddress = (TUint32)(&RMDebug_StepTest_Thumb_Non_PC_Modifying_2);
+
+	err = aThreadSpecific
+		? HelpTestStep(iThreadID,startAddress,endAddress,EThumbMode,1)
+		: HelpTestStep(iThreadID,startAddress,endAddress,EThumbMode,1, EFalse, processId);
+	test(err==KErrNone);
+
+	/*
+	 * RMDebug_StepTest_Thumb_Branch
+	 */
+	test.Next(_L("TestStep - Thumb Branch\n"));
+
+	startAddress = (TUint32)(&RMDebug_StepTest_Thumb_Branch_1);
+
+	endAddress = (TUint32)(&RMDebug_StepTest_Thumb_Branch_2);
+
+	err = aThreadSpecific
+		? HelpTestStep(iThreadID,startAddress,endAddress,EThumbMode,1)
+		: HelpTestStep(iThreadID,startAddress,endAddress,EThumbMode,1, EFalse, processId);
+	test(err==KErrNone);
+
+	/*
+	 * RMDebug_StepTest_Thumb_Branch_And_Link
+	 */
+	test.Next(_L("TestStep - Thumb Branch_And_Link\n"));
+
+	startAddress = (TUint32)(&RMDebug_StepTest_Thumb_Branch_And_Link_2);
+
+	endAddress = (TUint32)(&RMDebug_StepTest_Thumb_Branch_And_Link_3);
+
+	TInt muid=0;
+    test(HAL::Get(HAL::EMachineUid, muid)==KErrNone);
+
+	// check if running on ARMv7 core
+	if(muid==HAL::EMachineUid_OmapH6 || muid==HAL::EMachineUid_OmapZoom || muid==HAL::EMachineUid_EmuBoard)
+        {
+        // Note: ARMv7 treats BL instructions as single 32-bit instructions
+        err = aThreadSpecific
+		? HelpTestStep(iThreadID,startAddress,endAddress,EThumbMode,1)
+		: HelpTestStep(iThreadID,startAddress,endAddress,EThumbMode,1, EFalse, processId);
+        }
+    else
+	    {
+        // Note: Due to the fact that the stepper treats BL instructions
+		// as two instructions (as the hardware does), then we must step
+		// the first half instruction first)
+
+		err = aThreadSpecific
+		? HelpTestStep(iThreadID,startAddress,startAddress+2,EThumbMode,1)
+		: HelpTestStep(iThreadID,startAddress,startAddress+2,EThumbMode,1, EFalse, processId);
+		test(err==KErrNone);
+
+	// Now we actually do the BL
+	err = aThreadSpecific
+		? HelpTestStep(iThreadID,startAddress+2,endAddress,EThumbMode,1)
+		: HelpTestStep(iThreadID,startAddress+2,endAddress,EThumbMode,1, EFalse, processId);
+        }
+	test(err==KErrNone);
+
+	/*
+	 * RMDebug_StepTest_Thumb_Back_Branch_And_Link
+	 */
+	test.Next(_L("TestStep - Thumb Back_Branch_And_Link\n"));
+
+	startAddress = (TUint32)(&RMDebug_StepTest_Thumb_Back_Branch_And_Link_2);
+
+	endAddress = (TUint32)(&RMDebug_StepTest_Thumb_Back_Branch_And_Link_3);
+
+	// check if running on ARMv7 core
+	if(muid==HAL::EMachineUid_OmapH6 || muid==HAL::EMachineUid_OmapZoom || muid==HAL::EMachineUid_EmuBoard)
+		{
+		// Note: ARMv7 treats BL instructions as single 32-bit instructions
+		err = aThreadSpecific
+			? HelpTestStep(iThreadID,startAddress,endAddress,EThumbMode,1)
+			: HelpTestStep(iThreadID,startAddress,endAddress,EThumbMode,1, EFalse, processId);
+		}
+	else
+		{
+		// Note: Due to the fact that the stepper treats BL instructions
+		// as two instructions (as the hardware does), then we must step
+		// the first half instruction first)
+
+		err = aThreadSpecific
+	   		? HelpTestStep(iThreadID,startAddress,startAddress+2,EThumbMode,1)
+			: HelpTestStep(iThreadID,startAddress,startAddress+2,EThumbMode,1, EFalse, processId);
+		test(err==KErrNone);
+
+	   	// Now we actually do the BL
+		err = aThreadSpecific
+   			? HelpTestStep(iThreadID,startAddress+2,endAddress,EThumbMode,1)
+			: HelpTestStep(iThreadID,startAddress+2,endAddress,EThumbMode,1, EFalse, processId);
+		}
+	test(err==KErrNone);
+
+	/*
+	 * RMDebug_StepTest_Thumb_AddPC
+	 */
+	test.Next(_L("TestStep - Thumb ADD PC, PC, R0\n"));
+
+	startAddress = (TUint32)(&RMDebug_StepTest_Thumb_AddPC_2);
+
+	endAddress = (TUint32)(&RMDebug_StepTest_Thumb_AddPC_3);
+
+	err = aThreadSpecific
+		? HelpTestStep(iThreadID,startAddress,endAddress,EThumbMode,1)
+		: HelpTestStep(iThreadID,startAddress,endAddress,EThumbMode,1, EFalse, processId);
+	test(err==KErrNone);
+
+	/*
+	 * RMDebug_StepTest_Interwork ARM to Thumb
+	 */
+	test.Next(_L("TestStep - Interworking ARM to Thumb - BLX \n"));
+
+	startAddress = (TUint32)(&RMDebug_StepTest_Interwork_1);
+
+	endAddress = (TUint32)(&RMDebug_StepTest_Interwork_2);
+
+	err = aThreadSpecific // nb initial breakpoint in ARM code
+		? HelpTestStep(iThreadID,startAddress,endAddress,EArmMode,1)
+		: HelpTestStep(iThreadID,startAddress,endAddress,EArmMode,1, EFalse, processId);
+
+	test(err==KErrNone);
+
+	/*
+	 * RMDebug_StepTest_Interwork Thumb to ARM
+	 */
+	test.Next(_L("TestStep - Interworking Thumb to ARM - BLX\n"));
+
+	startAddress = (TUint32)(&RMDebug_StepTest_Interwork_2);
+
+	endAddress = (TUint32)(&RMDebug_StepTest_Interwork_3);
+
+	// check if running on ARMv7 core
+	if(muid==HAL::EMachineUid_OmapH6 || muid==HAL::EMachineUid_OmapZoom || muid==HAL::EMachineUid_EmuBoard)
+        {
+        // ARMv7 treats BLX instructions as single 32-bit instructions
+        err = aThreadSpecific
+		? HelpTestStep(iThreadID,startAddress,endAddress,EThumbMode,1)
+		: HelpTestStep(iThreadID,startAddress,endAddress,EThumbMode,1, EFalse, processId);
+        }
+    else
+        {
+    	// Stepper treats this as a two-stage instruction (just like the hardware)
+	err = aThreadSpecific
+		? HelpTestStep(iThreadID,startAddress,startAddress+2,EThumbMode,1)
+		: HelpTestStep(iThreadID,startAddress,startAddress+2,EThumbMode,1, EFalse, processId);
+	test(err == KErrNone);
+
+	err = aThreadSpecific
+		? HelpTestStep(iThreadID,startAddress+2,endAddress,EThumbMode,1)
+		: HelpTestStep(iThreadID,startAddress+2,endAddress,EThumbMode,1, EFalse, processId);
+        }
+	test(err == KErrNone);
+
+#endif // __MARM_ARMV5__
+
+	/*
+	 * Test multiple-step of ARM code
+	 */
+	test.Next(_L("TestStep - ARM Multiple instruction step\n"));
+
+	startAddress = (TUint32)(&RMDebug_StepTest_ARM_Step_Multiple);
+
+	endAddress = (TUint32)(&RMDebug_StepTest_ARM_Step_Multiple_1);
+
+	err = aThreadSpecific
+		? HelpTestStep(iThreadID,startAddress,endAddress,EArmMode,5)
+		: HelpTestStep(iThreadID,startAddress,endAddress,EArmMode,5, EFalse, processId);
+	test(err == KErrNone);
+	// stepping performance
+	test.Next(_L("TestStep - Steps per second\n"));
+
+	// run until we reach RMDebug_StepTest_Count_1
+	TBreakId stepBreakId;
+	startAddress = (TUint32)(&RMDebug_StepTest_Count_1);
+	endAddress = (TUint32)(&RMDebug_StepTest_Count_2);
+
+	err = aThreadSpecific
+		? HelpTestStepSetBreak(stepBreakId,iThreadID,startAddress,EArmMode)
+		: HelpTestStepSetBreak(stepBreakId,iThreadID,startAddress,EArmMode,EFalse,processId);
+	test (err == KErrNone);
+
+	// wait until we hit the breakpoint
+	TEventInfo info;
+	err = HelpTestStepWaitForBreak(iFileName,info);
+	test (err == KErrNone);
+
+	// Now clear the breakpoint
+	err = iServSession.ClearBreak(stepBreakId);
+	test(err == KErrNone);
+
+	if(aThreadSpecific)
+		{
+		// now step the code
+		TInt stepsPerSecond = 0;
+
+		TUint32 stopTickCount = User::NTickCount() + HelpTicksPerSecond();
+
+		while (User::NTickCount() < stopTickCount)
+			{
+			err = iServSession.Step(iThreadID,1);
+			test (err == KErrNone);
+
+			// we need to wait now until the step completes before asking for the next step
+				{
+				TEventInfo info;
+				static TRequestStatus status;
+
+				TPtr8 infoPtr((TUint8*)&info,0,sizeof(TEventInfo));
+
+				iServSession.GetEvent(iFileName,status,infoPtr);
+
+				// Wait for notification of the breakpoint hit event
+				User::WaitForRequest(status);
+				test(status==KErrNone);
+				}
+
+			// Update the count of steps
+			stepsPerSecond += 1;
+
+			// Gone wrong if we do too many
+			test(stepsPerSecond < 10000);
+			}
+
+		iStepsPerSecond = stepsPerSecond;
+		test(iStepsPerSecond != 0);
+		}
+
+	// finally resume the thread
+	err = iServSession.ResumeThread(iThreadID);
+	test (err == KErrNone);
+
+	err = iServSession.SetEventAction(iFileName,EEventsBreakPoint, EActionIgnore);
+	test (err == KErrNone);
+
+	if(!aThreadSpecific)
+		{
+		err = iServSession.SetEventAction(iFileName, EEventsProcessBreakPoint, EActionIgnore);
+		test (err == KErrNone);
+		}
+
+	test(KErrNone == iServSession.DetachExecutable(iFileName));
+	}
+
+//----------------------------------------------------------------------------------------------
+//! @SYMTestCaseID      KBase-T-RMDEBUG2-0443
+//! @SYMTestType
+//! @SYMPREQ            PREQ1426
+//! @SYMTestCaseDesc    Tests registration and occurrence of target thread event (in this case panic)
+//! @SYMTestActions     Registers for a panic in the target thread, causes it, and catches the panic notification.
+//!
+//! @SYMTestExpectedResults KErrNone.
+//! @SYMTestPriority        High
+//! @SYMTestStatus          Implemented
+//----------------------------------------------------------------------------------------------
+
+void CRunModeAgent::TestEvents()
+	{
+	TInt err = KErrNone;
+
+	test.Next(_L("TestEvents\n"));
+
+	TInt panicReason = 12345;
+
+	test.Printf(_L("Thread t_rmdebug.exe::DebugThread should panic with reason %d.\n"), panicReason);
+
+	//attach non-passively
+	test(KErrNone == iServSession.AttachExecutable(iFileName, EFalse));
+
+	RThread threadToPanic;
+	test(KErrNone == StartDebugThread(threadToPanic, _L("EventsThread")));
+	TThreadId threadToPanicId = threadToPanic.Id();
+	TEventInfo info;
+
+	// Set things up to wait for a thread kill event
+	err = iServSession.SetEventAction(iFileName, EEventsKillThread, EActionContinue);
+	test(err==KErrNone);
+
+	// Wait for an event to occur in this process - nothing should have happened yet.
+	static TRequestStatus status;
+
+	TPtr8 infoPtr((TUint8*)&info,0,sizeof(TEventInfo));
+
+	iServSession.GetEvent(iFileName,status,infoPtr);
+
+	// Test Request cancellation
+	err = iServSession.CancelGetEvent(iFileName);
+	test (err==KErrNone);
+
+	// Again wait for an event to occur in our process - we will provoke the
+	// thread kill event by panic'ing the test thread.
+	iServSession.GetEvent(iFileName,status,infoPtr);
+
+	// Panic the debug thread to cause a thread kill event
+	threadToPanic.Panic(_L("t_rmdebug panic thread test"), panicReason);
+
+	// Wait for notification of the Thread Kill event
+	User::WaitForRequest(status);
+	test(status==KErrNone);
+
+	// Check we are really recieving information about the panic
+	test(info.iProcessIdValid);
+	test(info.iThreadIdValid);
+	test(info.iProcessId==RProcess().Id());
+	test(info.iThreadId==threadToPanicId);
+	test(info.iEventType==EEventsKillThread);
+	test(info.iThreadKillInfo.iExitType==EExitPanic);
+
+	// Ignore other panic events
+	err = iServSession.SetEventAction(iFileName, EEventsKillThread, EActionIgnore);
+	test(err==KErrNone);
+
+	test(KErrNone == iServSession.DetachExecutable(iFileName));
+	}
+
+//----------------------------------------------------------------------------------------------
+//! @SYMTestCaseID      KBase-T-RMDEBUG2-0444
+//! @SYMTestType
+//! @SYMPREQ            PREQ1426
+//! @SYMTestCaseDesc    Tests registration and occurence of target thread events in separate process.
+//! @SYMTestActions     Registers for a hardware exception and kill thread events, and receives them.
+//!
+//! @SYMTestExpectedResults KErrNone.
+//! @SYMTestPriority        High
+//! @SYMTestStatus          Implemented
+//----------------------------------------------------------------------------------------------
+void CRunModeAgent::TestEventsForExternalProcess()
+	{
+	test.Next(_L("TestEventsForExternalProcess\n"));
+
+	for(TInt main=0; main<3; main++)
+		{
+		for(TInt extra=0; extra<3; extra++)
+			{
+			TestEventsWithExtraThreads((TKernelEventAction)main, (TKernelEventAction)extra, 0);
+			TestEventsWithExtraThreads((TKernelEventAction)main, (TKernelEventAction)extra, 2);
+			}
+		}
+	}
+
+void CRunModeAgent::TestEventsWithExtraThreads(TKernelEventAction aActionMain, TKernelEventAction aActionExtra, TUint32 aExtraThreads)
+	{
+	const TInt KNumberOfTypes = 8;
+	struct TEventStruct
+		{
+		public:
+		TDebugFunctionType iDebugFunctionType;
+		TEventType iEventType;
+		};
+
+	TEventStruct type[KNumberOfTypes] =
+		{
+			{EStackOverflowFunction, EEventsHwExc},
+			{EUserPanicFunction, EEventsKillThread},
+			{EPrefetchAbortFunction, EEventsHwExc},
+			{EDataAbortFunction, EEventsHwExc},
+			{EUndefInstructionFunction, EEventsHwExc},
+			{EDataReadErrorFunction, EEventsHwExc},
+			{EDataWriteErrorFunction, EEventsHwExc},
+			{EUserExceptionFunction, EEventsSwExc},
+		};
+
+	for(TInt j=0; j<KNumberOfTypes; j++)
+		{
+		if( gUseDelay ) User::After(500000);
+
+		RDebug::Printf("CRunModeAgent::TestEventsWithExtraThreads type: %d, main action: %d, extra action: %d, extraThreads: %d", 
+			j, (TUint32)aActionMain, (TUint32)aActionExtra, aExtraThreads);
+
+		// do this check as it seems to hard to do these cases with the current set up
+		if(EEventsKillThread == type[j].iEventType)
+			{
+			if(EActionSuspend != aActionMain)
+				{
+				if(aActionMain != aActionExtra)
+					{
+					return;
+					}
+				}
+			}
+		// attach to KRMDebugTestApplication
+		test(KErrNone == iServSession.AttachExecutable(KRMDebugTestApplication, EFalse));
+
+		// Set things up to wait for the expected exception in KRMDebugTestApplication
+		test(KErrNone == iServSession.SetEventAction(KRMDebugTestApplication, type[j].iEventType, aActionMain));
+
+		if(EActionSuspend != aActionMain)
+			{
+			test(KErrNone == iServSession.SetEventAction(KRMDebugTestApplication, EEventsKillThread, aActionExtra));
+			}
+
+		// declare a TRequestStatus object for asynchronous calls
+		TRequestStatus status;
+
+		TEventInfo info;
+		TPtr8 infoBuffer = TPtr8((TUint8*)&info,0,sizeof(TEventInfo));
+		if(EActionIgnore != aActionMain)
+			{
+			iServSession.GetEvent(KRMDebugTestApplication(), status, infoBuffer);
+			}
+
+		// launch the target process to trigger the expected exception
+		RProcess targetProcess;
+		test(KErrNone == LaunchProcess(targetProcess, KRMDebugTestApplication(), type[j].iDebugFunctionType, 0, aExtraThreads));
+		TProcessId processId(targetProcess.Id());
+		targetProcess.Close();
+
+		if(EActionIgnore != aActionMain)
+			{
+			// wait for notification of the exception
+			User::WaitForRequest(status);
+			test(KErrNone == status.Int());
+
+			// check that this is the event we were expecting
+			test(info.iProcessIdValid);
+			test(info.iThreadIdValid);
+			test(info.iProcessId==processId);
+			test(info.iEventType==type[j].iEventType);
+			}
+
+		if(EActionSuspend == aActionMain)
+			{
+			//RDebug::Printf("CRunModeAgent::TestEventsWithExtraThreads EActionSuspend == aActionMain, j=%d", j);
+			// read the thread list, partly to check the call works, and partly to check the thread still exists
+			test(ThreadExistsForProcess(info.iThreadId, info.iProcessId));
+
+			// register to catch all the thread kills which will occur
+			test(KErrNone == iServSession.SetEventAction(KRMDebugTestApplication, EEventsKillThread, aActionExtra));
+			// we specified EActionSuspend earlier so need to call resume on this thread
+			test(KErrNone == iServSession.ResumeThread(info.iThreadId));
+			}
+
+		// find out how many threads there are in the process and catch all the thread kill events,
+		// the number of kill thread events should correspond to the number of extra threads launched,
+		// plus one if the main thread panicked with a Sw/Hw exception
+		if(EActionIgnore != aActionExtra)
+			{
+			TInt dyingThreads = aExtraThreads + ( (type[j].iEventType != EEventsKillThread) ? 1 : 0);
+			for(TInt k=0; k<dyingThreads; k++)
+				{
+				//RDebug::Printf("CRunModeAgent::TestEventsWithExtraThreads dyingThreads, k=%d, j=%d", k,j);
+				iServSession.GetEvent(KRMDebugTestApplication(), status, infoBuffer);
+
+				// wait for notification of the kill thread
+				User::WaitForRequest(status);
+				test(KErrNone == status.Int());
+
+				// check that this is the event we were expecting
+				test(info.iProcessIdValid);
+				test(info.iThreadIdValid);
+				test(info.iProcessId==processId);
+				test(info.iEventType==EEventsKillThread);
+				if(EActionSuspend == aActionExtra)
+					{
+					// do some calls to check listings work ok at this stage
+					test(ProcessExists(info.iProcessId));
+					test(ThreadExistsForProcess(info.iThreadId, info.iProcessId));
+					// we specified EActionSuspend earlier so need to call resume on this thread
+					test(KErrNone == iServSession.ResumeThread(info.iThreadId));
+					}
+				}
+			}
+
+		if( gUseDelay ) User::After(500000);
+
+		// reset the thread kill event
+		test(KErrNone == iServSession.SetEventAction(KRMDebugTestApplication(), EEventsKillThread, EActionIgnore));
+
+		// reset events for KRMDebugTestApplication
+		test(KErrNone == iServSession.SetEventAction(KRMDebugTestApplication(), type[j].iEventType, EActionIgnore));
+
+		// finished debugging KRMDebugTestApplication so detach
+		test(KErrNone == iServSession.DetachExecutable(KRMDebugTestApplication()));
+	
+		// want to validate that the process has really exited, i.e. we're not accidentally keeping a handle to it...
+		TInt waitCount = 10;
+		while((waitCount-- > 0) && ProcessExists(processId))
+			{
+			/* Wait a little while and try again, just in case the process is still being removed.
+			This can happen on a very busy system or when a popup for the events is still active
+			*/
+			RDebug::Printf("CRunModeAgent::TestEventsWithExtraThreads. ProcessExists(id=%d), waiting for it to exit %d", 
+				I64LOW(processId), waitCount);
+			User::After(500);
+			}
+		test(!ProcessExists(processId));
+		}
+	}
+
+// helper function to check whether a thread with id aThreadId exists in the process with id aProcessId
+TBool CRunModeAgent::ThreadExistsForProcess(const TThreadId aThreadId, const TProcessId aProcessId)
+	{
+	TUint32 size;
+	RBuf8 buffer;
+	test(KErrNone == buffer.Create(1024));
+	TInt err = iServSession.GetList(aProcessId, EThreads, buffer, size);
+	while(KErrTooBig == err)
+		{
+		size*=2;
+		test(size<=16*1024);
+		test(KErrNone == buffer.ReAlloc(size));
+		err = iServSession.GetList(aProcessId, EThreads, buffer, size);
+		}
+	test(KErrNone == err);
+
+	//look through the buffer and check if the target debug thread is there
+	TUint8* ptr = (TUint8*)buffer.Ptr();
+	const TUint8* ptrEnd = ptr + size;
+	while(ptr < ptrEnd)
+		{
+		TThreadListEntry& entry = *(TThreadListEntry*)ptr;
+		if(aThreadId.Id() == entry.iThreadId)
+			{
+			buffer.Close();
+			return ETrue;
+			}
+		ptr += Align4(entry.GetSize());
+		}
+	buffer.Close();
+	return EFalse;
+	}
+
+// helper function to check whether a process with id aProcessId exists
+TBool CRunModeAgent::ProcessExists(const TProcessId aProcessId)
+	{
+	TUint32 size;
+	RBuf8 buffer;
+	test(KErrNone == buffer.Create(1024));
+	TInt err = iServSession.GetList(EProcesses, buffer, size);
+	while(KErrTooBig == err)
+		{
+		size*=2;
+		test(size<=16*1024);
+		test(KErrNone == buffer.ReAlloc(size));
+		err = iServSession.GetList(EProcesses, buffer, size);
+		}
+	test(KErrNone == err);
+
+	//look through the buffer and check if the target debug thread is there
+	TUint8* ptr = (TUint8*)buffer.Ptr();
+	const TUint8* ptrEnd = ptr + size;
+	while(ptr < ptrEnd)
+		{
+		TProcessListEntry& entry = *(TProcessListEntry*)ptr;
+		if(aProcessId.Id() == entry.iProcessId)
+			{
+			buffer.Close();
+			return ETrue;
+			}
+		ptr += Align4(entry.GetSize());
+		}
+	buffer.Close();
+	return EFalse;
+	}
+
+//----------------------------------------------------------------------------------------------
+//! @SYMTestCaseID      KBase-T-RMDEBUG2-0445
+//! @SYMTestType
+//! @SYMPREQ            PREQ1426
+//! @SYMTestCaseDesc    Tests basic debug functions work on demand-paged target threads
+//! @SYMTestActions     Checks it can r/w memory, set breakpoints etc in a demand paged target.
+//!
+//! @SYMTestExpectedResults KErrNone.
+//! @SYMTestPriority        High
+//! @SYMTestStatus          Implemented
+//----------------------------------------------------------------------------------------------
+
+void CRunModeAgent::TestDemandPaging(void)
+	{
+	test.Next(_L("TestDemandPaging\n"));
+
+	test(KErrNone == iServSession.AttachExecutable(iFileName, EFalse));
+	test(KErrNone == iServSession.SuspendThread(iThreadID));
+
+	// get the address of a function in code that will be paged in
+	TUint32 address = (TUint32)(&RMDebugDemandPagingTest);
+	const TUint32 armInstSize = 4;
+
+	// read the memory at &RMDebugDemandPagingTest to check that reading memory in demand paged code works
+	TUint32 demandPagedInst = 0;
+	TPtr8 demandPagedInstBuf((TUint8*)&demandPagedInst, armInstSize);
+	test(KErrNone == iServSession.ReadMemory(iThreadID, address, armInstSize, demandPagedInstBuf, EAccess32, EEndLE8));
+
+	// this is the MOVS instruction that we expect to find in RMDebugDemandPagingTest
+	TUint32 expectedDemandPagedInst = 0xe1b02000;
+
+	// check that the instruction we read is as expected
+	test(demandPagedInst == expectedDemandPagedInst);
+
+	// set event action for break points
+	test(KErrNone == iServSession.SetEventAction(RProcess().FileName(), EEventsBreakPoint, EActionContinue));
+
+	// set an arm breakpoint on RMDebugDemandPagingTest
+	TBreakId armBreakId = 0;
+	test(KErrNone == iServSession.SetBreak(armBreakId, iThreadID, address, EArmMode));
+
+	// Ensure that after setting the breakpoint the memory read returns the correct value
+	TUint32 demandPagedInstWithBreakPoint = 0;
+	TPtr8 spinForeverInstWithBreakPointBuf((TUint8*)&demandPagedInstWithBreakPoint, armInstSize);
+	test(KErrNone == iServSession.ReadMemory(iThreadID, address, armInstSize, spinForeverInstWithBreakPointBuf, EAccess32, EEndLE8));
+	test(demandPagedInst == demandPagedInstWithBreakPoint);
+
+	// switch the target thread to run the demand paging function
+	test(KErrNone == SwitchTestFunction(EDemandPagingFunction));
+
+	// set up event watcher to catch breakpoint being hit in demand paged code
+	TEventInfo info;
+	static TRequestStatus status;
+	TPtr8 infoPtr((TUint8*)&info,sizeof(TEventInfo));
+	iServSession.GetEvent(RProcess().FileName(), status, infoPtr);
+
+	// resume the thread
+	test(KErrNone == iServSession.ResumeThread(iThreadID));
+	// wait for notification of the breakpoint hit event
+	User::WaitForRequest(status);
+	test(status==KErrNone);
+
+	// info should now be filled with the details
+	test(info.iProcessIdValid);
+	test(info.iThreadIdValid);
+	test(info.iEventType == EEventsBreakPoint);
+	test(info.iThreadBreakPointInfo.iRmdArmExcInfo.iR15 == address);
+
+	// remove the break point and resume the thread
+	test(KErrNone == iServSession.ClearBreak(armBreakId));
+
+	// switch the target thread to run the default function
+	test(KErrNone == SwitchTestFunction(EDefaultFunction));
+
+	test(KErrNone == iServSession.ResumeThread(iThreadID));
+	test(KErrNone == iServSession.DetachExecutable(iFileName));
+	}
+
+// Names of some test programs used for testing security
+_LIT(KRMDebugSecurity0FileName,"z:\\sys\\bin\\t_rmdebug_security0.exe"); // Debuggable
+_LIT(KRMDebugSecurity1FileName,"z:\\sys\\bin\\t_rmdebug_security1.exe"); // Not debuggable
+_LIT(KRMDebugSecurity2FileName,"z:\\sys\\bin\\t_rmdebug_security2.exe"); // AllFiles
+_LIT(KRMDebugSecurity3FileName,"z:\\sys\\bin\\t_rmdebug_security3.exe"); // TCB AllFiles
+
+// include the test header file here
+#include "rm_debug_kerneldriver.h"
+
+//----------------------------------------------------------------------------------------------
+//! @SYMTestCaseID      KBase-T-RMDEBUG2-0446
+//! @SYMTestType
+//! @SYMPREQ            PREQ1426
+//! @SYMTestCaseDesc    Tests Debug Device Driver is locked to the SID of the Debug Security Svr.
+//! @SYMTestActions     Loads rm-debug.ldd and tries to open a handle to it. This should fail.
+//!
+//! @SYMTestExpectedResults KErrPermissionDenied.
+//! @SYMTestPriority        High
+//! @SYMTestStatus          Implemented
+//----------------------------------------------------------------------------------------------
+
+void CRunModeAgent::TestDriverSecurity(void)
+	{
+	test.Next(_L("TestDriverSecurity\n"));
+
+	RRM_DebugDriver kernelDriver;
+
+	// Load the debug device driver
+	TInt err = User::LoadLogicalDevice( KDebugDriverFileName );
+	test((KErrNone == err) || (KErrAlreadyExists == err));
+
+	// we were allowed to load the driver, or its already loaded.
+
+	// Try to open a handle to the driver - this should return KErrPermissionDenied as we don't have the DSS SID
+	TRM_DebugDriverInfo driverInfo;
+	driverInfo.iUserLibraryEnd = 0;
+	err = kernelDriver.Open(driverInfo);
+	test((err == KErrInUse) || (err == KErrPermissionDenied));
+
+	}
+
+//----------------------------------------------------------------------------------------------
+//! @SYMTestCaseID      KBase-T-RMDEBUG2-0447
+//! @SYMTestType
+//! @SYMPREQ            PREQ1426
+//! @SYMTestCaseDesc    Tests Debug driver can only be access via the DSS. Also tests DSS cannot
+//!						be subverted. Tests functionality of two representative OEM Debug Tokens.
+//! @SYMTestActions     Tries to open rm_debug.ldd (should fail). Tries to debug various processes
+//!						(only debuggable one should succeed). Checks that DSS behaves correctly
+//!						when different versions are passed in to Connect().
+//!
+//! @SYMTestExpectedResults KErrPermissionDenied.
+//! @SYMTestPriority        High
+//! @SYMTestStatus          Implemented
+//----------------------------------------------------------------------------------------------
+
+void CRunModeAgent::TestSecurity(void)
+	{
+	// Things to test
+	//
+	// try to use debug driver directly ( should have the wrong UID/SID value!)
+	test.Next(_L("TestSecurity - Bypass Debug Security Server to Debug Device Driver - DSS running\n"));
+
+	// Things to test
+	//
+	// Load the debug device driver
+	RRM_DebugDriver kernelDriver;
+	TInt err = User::LoadLogicalDevice( KDebugDriverFileName );
+	test((KErrNone == err) || (KErrAlreadyExists == err));
+
+	// we were allowed to load the driver, or its already loaded.
+
+	// Try to open handle a to the driver - this should return KErrPermission/KErrInUse as we don't have the DSS SID
+	// and we expect the DSS to already be using it.
+	TRM_DebugDriverInfo driverInfo;
+	driverInfo.iUserLibraryEnd = 0;
+	err = kernelDriver.Open(driverInfo);
+	test(err == KErrInUse);
+
+	// Try requesting an unsupported version of DSS
+	test.Next(_L("TestSecurity - requesting unsupported versions of DSS\n"));
+	RSecuritySvrSession dss;
+	err = dss.Connect(TVersion(999999, 0, 0));
+	test(err == KErrNotSupported); // Prior to DEF142018 this would crash, causing a KErrServerTerminated
+	err = dss.Connect(TVersion(KDebugServMajorVersionNumber, 999999, 0));
+	test(err == KErrNotSupported); // Explicitly asking for a minor version should give KErrNotSupported too if it's newer than what's running.
+	err = dss.Connect(TVersion(KDebugServMajorVersionNumber, 0, 0));
+	test(err == KErrNone); // But the correct major version and no explicit minor version should always succeed
+	dss.Close();
+	
+	//
+	// Attach to the Debug Security Server (passive)
+	//
+	test.Next(_L("TestSecurity - Attach to the Debug Security Server (passive)\n"));
+
+	_LIT(KSecurityServerProcessName, "z:\\sys\\bin\\rm_debug_svr.exe");
+
+	test(KErrPermissionDenied == iServSession.AttachExecutable(KSecurityServerProcessName, ETrue));
+
+	//
+	// Attach to the Debug Security Server (active)
+	//
+	test.Next(_L("TestSecurity - Attach to the Debug Security Server (active)\n"));
+
+	test(KErrPermissionDenied == iServSession.AttachExecutable(KSecurityServerProcessName, EFalse));
+
+	//
+	// Attach to Process 0
+	//
+	// Target: Debuggable
+	//
+	test.Next(_L("TestSecurity - Attach to test process 0\n"));
+
+	// Agent can debug the target app as it is marked debuggable - ie capabilities are ignored)
+	HelpTestSecurityAttachDetachExecutable(KRMDebugSecurity0FileName,ETrue);
+
+	//
+	// Attach to Process - 1
+	//
+	// Target: Non-debuggable for ordinary debug agent, debuggable for OEM/OEM2 token authorised agent
+	//
+	// Note: This target app has no PlatSec capabilities
+	//
+	// Agent cannot debug the app unless it has an OEM/OEM2 Debug Token
+	test.Next(_L("TestSecurity - Attach to test process 1\n"));
+
+#ifdef SYMBIAN_STANDARDDEBUG
+	HelpTestSecurityAttachDetachExecutable(KRMDebugSecurity1FileName,EFalse);
+#endif
+
+#ifdef SYMBIAN_OEMDEBUG
+	HelpTestSecurityAttachDetachExecutable(KRMDebugSecurity1FileName,ETrue);
+#endif
+
+#ifdef SYMBIAN_OEM2DEBUG
+	HelpTestSecurityAttachDetachExecutable(KRMDebugSecurity1FileName,ETrue);
+#endif
+
+	//
+	// Attach to Process - 2
+	//
+	// Target: Non-debuggable for ordinary debug agent, non-debuggable for OEM2 authorised agent (insufficient caps)
+	//
+	// Note: This target app has AllFiles capability
+	//
+	// Agent cannot debug the app unless it has an OEM Debug Token
+	test.Next(_L("TestSecurity - Attach to test process 2\n"));
+
+#ifdef SYMBIAN_STANDARDDEBUG
+	HelpTestSecurityAttachDetachExecutable(KRMDebugSecurity2FileName,EFalse);
+#endif
+
+#ifdef SYMBIAN_OEMDEBUG
+	HelpTestSecurityAttachDetachExecutable(KRMDebugSecurity2FileName,ETrue);
+#endif
+
+#ifdef SYMBIAN_OEM2DEBUG
+	HelpTestSecurityAttachDetachExecutable(KRMDebugSecurity2FileName,EFalse);
+#endif
+
+	//
+	// Attach to Process - 3
+	//
+	// Target: Non-debuggable for ordinary debug agent, non-debuggable for OEM authorised agent (insufficient caps)
+	//
+	// Note: This target app has AllFiles and TCB and NetworkControl capabilities
+	//
+	test.Next(_L("TestSecurity - Attach to test process 3\n"));
+
+	HelpTestSecurityAttachDetachExecutable(KRMDebugSecurity3FileName,EFalse);
+
+	}
+
+//----------------------------------------------------------------------------------------------
+//! @SYMTestCaseID      KBase-T-RMDEBUG2-0543
+//! @SYMTestType
+//! @SYMPREQ            PREQ1426
+//! @SYMTestCaseDesc    Validates that a dll can be built which #include's the rm_debug_api.h header, i.e. rm_debug_api.h contains no static data.
+//! @SYMTestActions     Calls a dummy function in t_rmdebug_dll.dll which implies the dll has been built correctly.
+//!
+//! @SYMTestExpectedResults KErrNone.
+//! @SYMTestPriority        High
+//! @SYMTestStatus          Implemented
+//----------------------------------------------------------------------------------------------
+void CRunModeAgent::TestDllUsage(void)
+	{
+	test.Next(_L("TestDllUsage\n"));
+	test(KUidDebugSecurityServer == GetDSSUid());
+	}
+
+//----------------------------------------------------------------------------------------------
+//! @SYMTestCaseID      KBase-T-RMDEBUG2-0812
+//! @SYMTestType
+//! @SYMPREQ            PREQ1700
+//! @SYMTestCaseDesc    Writes a known data to the crash flash and validates the data written
+//!						using the read operation and finally erase the data. In the absence
+//!						of an OEM debug token, access to the crash partition should not be allowed
+//! @SYMTestActions     Invoke the flash write method in DSS and call the read method in DSS
+//!						to validate the data is written correctly and then erase the written area
+//!
+//! @SYMTestExpectedResults KErrNone.
+//! @SYMTestPriority        High
+//! @SYMTestStatus          Implemented
+//----------------------------------------------------------------------------------------------
+void CRunModeAgent::TestCrashFlash(void)
+	{
+#if  defined (SYMBIAN_STANDARDDEBUG)  || defined (SYMBIAN_OEM2DEBUG)
+
+	test.Next(_L("@SYMTestCaseID:DT-debug-securityserver-006 Testing We cannot Erase the Crash Flash with insufficient privileges"));
+
+	TUint32 size = 0;
+	TInt err = iServSession.EraseCrashLog(0, 1);
+	test(KErrPermissionDenied == err);
+
+	test.Next(_L("@SYMTestCaseID:DT-debug-securityserver-005 Testing We can't Write to the Crash Flash with insufficient privileges"));
+
+	err = iServSession.WriteCrashConfig(0, KCrashDummyData, size);
+	test(KErrPermissionDenied == err);
+	test(size == 0);
+
+	test.Next(_L("@SYMTestCaseID:DT-debug-securityserver-008 Testing We can't Read from the Crash Flash with insufficient privileges"));
+
+	TUint32 readSize = 0x10;
+	RBuf8 buf;
+	buf.CleanupClosePushL();
+	err = buf.Create(readSize);
+
+	test(err == KErrNone);
+
+	err = iServSession.ReadCrashLog(0, buf, readSize);
+	test(KErrPermissionDenied == err);
+
+	test.Next(_L("@SYMTestCaseID:DT-debug-securityserver-004 Testing Writing To an invalid location"));
+
+	TUint32 writeSize = 0;
+	err = iServSession.WriteCrashConfig(0xFFFFFFFF, KCrashDummyData, writeSize);
+
+	test(err == KErrPermissionDenied);
+
+	test.Next(_L("@SYMTestCaseID:DT-debug-securityserver-003 Testing Reading from an invalid location"));
+
+	buf.FillZ();
+	err = iServSession.ReadCrashLog(0, buf, writeSize);
+
+	test(err == KErrPermissionDenied);
+
+	CleanupStack::PopAndDestroy(&buf);
+
+#endif
+
+#ifdef SYMBIAN_OEMDEBUG
+
+	TInt err = KErrNone;
+
+	test.Next(_L("@SYMTestCaseID:DT-debug-securityserver-007 Testing We can Erase the Crash Flash with sufficient privileges"));
+
+	err = iServSession.EraseCrashLog(0, 1);
+
+	// For platforms where NAND flash is not currently supported we get a KErrNotSupported - this is still a pass
+	if (KErrNotSupported == err)
+		{
+		test.Printf(_L("Nand flash not supported - continue"));
+		return;
+		}
+
+ 	//For platforms without a flash partition we get KErrNotFound - this is still a pass
+ 	if(KErrNotFound == err)
+ 		{
+ 		test.Printf(_L("Platform has no flash partition - continue"));
+ 		return;
+ 		}
+
+	test(KErrNone == err);
+
+	//Read back the start of the block to make sure its 0xFFFFFFFF
+	const TUint numBytesToCheck = 0x80;  //We dont know the block size
+	TBuf8<numBytesToCheck> eraseCheck;
+	eraseCheck.SetLength(numBytesToCheck);
+
+	err = iServSession.ReadCrashLog(0, eraseCheck, numBytesToCheck);
+	test(err == KErrNone);
+
+	TBool dataIsOk = ETrue;
+	for(TUint cnt = 0; cnt < numBytesToCheck; cnt++)
+		{
+		if(eraseCheck[cnt] != 0xFF)
+			{
+			dataIsOk = EFalse;
+			}
+		}
+
+	test(dataIsOk);
+
+	test.Next(_L("@SYMTestCaseID:DT-debug-securityserver-002 Testing We can Write to the Crash Flash with sufficient privileges"));
+
+	TUint32 writeSize = 0;
+	err = iServSession.WriteCrashConfig(0, KCrashDummyData, writeSize);
+
+	test(writeSize == KCrashDummyData().Length());
+
+	test.Next(_L("@SYMTestCaseID:DT-debug-securityserver-001 Testing We can Read from the Crash Flash with sufficient privileges"));
+
+	RBuf8 buf;
+	buf.CleanupClosePushL();
+	err = buf.Create(writeSize);
+
+	test(err == KErrNone);
+
+	buf.FillZ();
+
+	err = iServSession.ReadCrashLog(0, buf, writeSize);
+
+	test(0 == buf.Compare(KCrashDummyData));
+
+	test.Next(_L("@SYMTestCaseID:DT-debug-securityserver-004 Testing Writing To an invalid location"));
+
+	writeSize = 0;
+	err = iServSession.WriteCrashConfig(0xFFFFFFFF, KCrashDummyData, writeSize);
+
+	test(err == KErrArgument);
+
+	test.Next(_L("@SYMTestCaseID:DT-debug-securityserver-003 Testing Reading from an invalid location"));
+
+	buf.FillZ();
+	err = iServSession.ReadCrashLog(0xFFFFFFFF, buf, writeSize);
+
+	test(err == KErrArgument);
+
+	CleanupStack::PopAndDestroy(&buf);
+
+#endif
+	}
+//----------------------------------------------------------------------------------------------
+//! @SYMTestCaseID      KBase-T-RMDEBUG2-0735
+//! @SYMTestType
+//! @SYMPREQ            PREQ1426
+//! @SYMTestCaseDesc    Tests the Kill Process functionality. Only can kill a debuggable process.
+//! @SYMTestActions     Launches a debuggable and non-debuggable process and tries to kill both.
+//!
+//! @SYMTestExpectedResults KErrNone.
+//! @SYMTestPriority        High
+//! @SYMTestStatus          Implemented
+//----------------------------------------------------------------------------------------------
+void CRunModeAgent::TestKillProcess(void)
+	{
+	test.Next(_L("TestKillProcess\n"));
+
+	// Kill a debuggable process
+
+	// check that killing a process is supported
+	TTag tag = GetTag(ETagHeaderIdKillObjects, EFunctionalityKillProcess);
+	test(tag.iValue);
+	// check that killing a thread is not supported
+	tag = GetTag(ETagHeaderIdKillObjects, EFunctionalityKillThread);
+	test(!tag.iValue);
+
+	// attach first!
+	TInt err = iServSession.AttachExecutable(KRMDebugTestApplication, EFalse /* Active */);
+	test(err == KErrNone);
+
+	// first launch a debuggable process
+	RProcess process;
+	err = LaunchProcess(process, KRMDebugTestApplication(),ESpinForever, 0, 0);
+	test (err == KErrNone);
+
+	// try to find the process in the list
+_LIT(KRMDebugAppName, "t_rmdebug_app");
+
+	TBool found = ProcessExists(KRMDebugAppName);
+	test (found);
+
+	TInt processId = process.Id();
+	process.Close();
+
+	// program now running, so try to kill it
+	err = iServSession.KillProcess(processId, 0 /* kill reason */);
+	test(err == KErrNone);
+
+	User::After(2000000);	// should die within two seconds.
+
+	// can we still find it? Should be gone
+	found = ProcessExists(KRMDebugAppName);
+	test (!found);
+
+	// release the program again.
+	err = iServSession.DetachExecutable(KRMDebugTestApplication);
+	test(err == KErrNone);
+
+	// Try to kill a non-debuggable process and fail.
+
+	// first launch a non-debuggable process
+	RProcess process2;
+	err = LaunchProcess(process2, KRMDebugSecurity1FileName(),ESpinForever, 0, 0);
+	test (err == KErrNone);
+
+	// try to find the process in the list
+_LIT(KRMDebugAppName2, "t_rmdebug_security1");
+
+	TBool found2 = ProcessExists(KRMDebugAppName2);
+	test (found2);
+
+	TInt process2Id = process2.Id();
+	process2.Close();
+
+	// program now running, so try to kill it
+	err = iServSession.KillProcess(process2Id, 0 /* kill reason */);
+	test(err == KErrPermissionDenied);
+
+	User::After(2000000);	// should die within two seconds if it is going to die.
+
+	// can we still find it? Should be still around!
+	found2 = ProcessExists(KRMDebugAppName2);
+	test (found2);
+
+	}
+
+//----------------------------------------------------------------------------------------------
+//! @SYMTestCaseID      KBase-T-RMDEBUG2-1388
+//! @SYMTestType
+//! @SYMPREQ            PREQ1426
+//! @SYMTestCaseDesc    Tests the correct operation of the AddProcess and Remove Process
+//! @SYMTestActions     1. Registers for AddProcess and Remove Process events
+//!                     2. Starts a test process z:\sys\bin\t_rmdebug_security0.exe
+//!                     3. Wait for the AddProcess event to be reported
+//!                     4. Kill the newly started test process
+//!                     5. Wait for the RemoveProcess event to be reported
+//!                     6. Tell the DSS it is no longer interested in AddProcess and RemoveProcess events
+//!
+//! @SYMTestExpectedResults KErrNone.
+//! @SYMTestPriority        High
+//! @SYMTestStatus          Implemented
+//----------------------------------------------------------------------------------------------
+
+void CRunModeAgent::TestAddRemoveProcessEvents()
+	{
+	test.Next(_L("TestAddRemoveProcessEvents\n"));
+
+	// attach to a process (e.g. one of the simple security test programs)
+	// launch the security program
+	// wait for the add event
+	// continue the program.
+	// wait for the remove event
+	// detach process
+
+	test(KErrNone == iServSession.AttachExecutable(KRMDebugSecurity0FileName, EFalse));
+
+	test(KErrNone == iServSession.SetEventAction(KRMDebugSecurity0FileName,EEventsAddProcess, EActionContinue));
+
+	test(KErrNone == iServSession.SetEventAction(KRMDebugSecurity0FileName,EEventsRemoveProcess, EActionContinue));
+
+	// Creator thread ID of the current thread (to be creator of test application)
+	TInt creatorThreadId = RThread().Id();
+
+	RProcess process;
+	TInt err = process.Create(KRMDebugSecurity0FileName, KNullDesC, EOwnerProcess);
+	test (err == KErrNone);
+
+	// Rendezvous with process
+	TRequestStatus status;
+	process.Rendezvous(status);
+
+	// Start the test program
+	process.Resume();
+	User::WaitForRequest(status);
+	test(status==KErrNone);
+
+	// Wait for the addprocess event
+	TEventInfo info;
+	TPtr8 infoPtr((TUint8*)&info,0,sizeof(TEventInfo));
+
+	iServSession.GetEvent(KRMDebugSecurity0FileName,status,infoPtr);
+
+	// Wait for notification of the addprocess hit event
+	User::WaitForRequest(status);
+	test(status==KErrNone);
+
+	// Check this was the right kind of event
+	test(info.iEventType == EEventsAddProcess);
+
+	const TInt uid3offset = 2;
+
+	// Get UID3 for current process
+	TUint32 Uid3 = process.Type()[uid3offset].iUid;
+
+	// Check correct UID3 is returned from the driver
+    test(info.iAddProcessInfo.iUid3 == Uid3);
+
+    // Check correct creator ID for test application is returned from the driver
+    test(info.iAddProcessInfo.iCreatorThreadId == creatorThreadId);
+
+	// Kill the process, as we don't need it anymore
+	process.Kill(KErrNone);
+
+	// Wait for the remove process event
+	iServSession.GetEvent(KRMDebugSecurity0FileName,status,infoPtr);
+
+	// Wait for notification of the remove process hit event
+	User::WaitForRequest(status);
+	test(status==KErrNone);
+
+	// Check this was the right kind of event
+	test(info.iEventType == EEventsRemoveProcess);
+
+	test(KErrNone == iServSession.SetEventAction(KRMDebugSecurity0FileName,EEventsRemoveProcess, EActionIgnore));
+
+	test(KErrNone == iServSession.SetEventAction(KRMDebugSecurity0FileName,EEventsAddProcess, EActionIgnore));
+
+	test(KErrNone == iServSession.DetachExecutable(KRMDebugSecurity0FileName));
+
+	}
+
+//----------------------------------------------------------------------------------------------
+//! @SYMTestCaseID      KBase-T-RMDEBUG2-0736
+//! @SYMTestType
+//! @SYMPREQ            PREQ1426
+//! @SYMTestCaseDesc    Checks that process break points can be set, and that they can co-exist alongside thread breakpoints
+//! @SYMTestActions     Checks that process break points can be set, and that they can co-exist alongside thread breakpoints
+//!
+//! @SYMTestExpectedResults KErrNone.
+//! @SYMTestPriority        High
+//! @SYMTestStatus          Implemented
+//----------------------------------------------------------------------------------------------
+void CRunModeAgent::TestProcessBreakPoints(void)
+	{
+	test.Next(_L("TestProcessBreakPoints\n"));
+
+	// check that process breakpoints are supported
+	TTag tag = GetTag(ETagHeaderIdBreakpoints, EBreakpointProcess);
+	test(tag.iValue);
+
+	test(KErrNone == iServSession.AttachExecutable(iFileName, EFalse));
+	test(KErrNone == iServSession.SuspendThread(iThreadID));
+
+	// Try to set the breakpoint
+	TBreakId breakId;
+	TUint32 address = (TUint32)(&RMDebug_BranchTst1);
+	RProcess process;
+	TProcessId processId = process.Id();
+	process.Close();
+
+	test(KErrNone == iServSession.SetProcessBreak(breakId, processId, address, EArmMode));
+	test(KErrAlreadyExists == iServSession.SetBreak(breakId, iThreadID, address, EArmMode));
+	test(KErrAlreadyExists == iServSession.SetBreak(breakId, iThreadID, address, EThumbMode));
+	test(KErrAlreadyExists == iServSession.SetProcessBreak(breakId, processId, address, EArmMode));
+	test(KErrAlreadyExists == iServSession.SetProcessBreak(breakId, processId, address, EThumbMode));
+	test(KErrNone == iServSession.ClearBreak(breakId));
+
+	test(KErrNone == iServSession.SetBreak(breakId, iThreadID, address, EArmMode));
+	test(KErrAlreadyExists == iServSession.SetProcessBreak(breakId, processId, address, EArmMode));
+	test(KErrAlreadyExists == iServSession.SetProcessBreak(breakId, processId, address, EThumbMode));
+	test(KErrNone == iServSession.ClearBreak(breakId));
+
+	test(KErrNone == iServSession.ResumeThread(iThreadID));
+
+	test(KErrNone == iServSession.DetachExecutable(iFileName));
+	}
+
+//----------------------------------------------------------------------------------------------
+//! @SYMTestCaseID      KBase-T-RMDEBUG2-1309
+//! @SYMTestType
+//! @SYMPREQ            PREQ1426
+//! @SYMTestCaseDesc    Checks that in the case of multiple low priority events (user traces in this case) we can still receive higher
+//!				priority events should the buffer reach a critical level
+//! @SYMTestActions     Run to first breakpoint in our test code. Then multiple trace events are issued. We should still be able to hit
+//!				the second breakpoint
+//!
+//! @SYMTestExpectedResults KErrNone.
+//! @SYMTestPriority        High
+//! @SYMTestStatus          Implemented
+//----------------------------------------------------------------------------------------------
+
+void CRunModeAgent::TestMultipleTraceEvents(void)
+	{
+	test.Next(_L("TestMultipleTraceEvents\n"));
+
+	//attach to target debug process
+	test(KErrNone == iServSession.AttachExecutable(iFileName, EFalse));
+
+	//and suspend the thread
+	test(KErrNone == iServSession.SuspendThread(iThreadID));
+
+	//register interest in BP's & trace events and trace ignored events
+	test(KErrNone == iServSession.SetEventAction(iFileName,EEventsBreakPoint, EActionSuspend));
+	test(KErrNone == iServSession.SetEventAction(iFileName,EEventsUserTrace, EActionContinue));
+	test(KErrNone == iServSession.SetEventAction(iFileName,EEventsUserTracesLost, EActionContinue));
+
+	// Try to set the breakpoints
+	TBreakId armBreakId;
+	TBreakId armBreakId2;
+	TUint32 address = (TUint32)(&RMDebug_BranchTst1);
+	TUint32 address2 = (TUint32)(&RMDebug_StepTest_Non_PC_Modifying);
+
+	test(KErrNone == iServSession.SetBreak(armBreakId,iThreadID,address,EArmMode));
+	test(KErrNone == iServSession.SetBreak(armBreakId2,iThreadID,address2,EArmMode));
+
+	//set the target thread to execute the trace test function
+	test(KErrNone == SwitchTestFunction(EMultipleTraceCalls));
+
+	// Continue the thread
+	test(KErrNone == iServSession.ResumeThread(iThreadID));
+
+	// wait for the breakpoint to be hit
+	TEventInfo info;
+	static TRequestStatus status;
+
+	TPtr8 infoPtr((TUint8*)&info,0,sizeof(TEventInfo));
+	iServSession.GetEvent(iFileName,status,infoPtr);
+
+	// Wait for notification of the 1st breakpoint hit event
+	User::WaitForRequest(status);
+	test(status==KErrNone);
+
+	// info should now be filled with the details
+	test(info.iEventType == EEventsBreakPoint);
+	test(info.iThreadBreakPointInfo.iRmdArmExcInfo.iR15 == address);
+	test(info.iProcessIdValid);
+	test(info.iThreadIdValid);
+
+	// Continue the thread
+	test(KErrNone == iServSession.ResumeThread(iThreadID));
+
+	//Now we try to hit the second breakpoint. This will occur after a number of trace calls. If we hit this breakpoint it
+	//means many trace calls are not preventing us hitting breakpoints.
+	iServSession.GetEvent(iFileName,status,infoPtr);
+
+	// Wait for notification of the 2nd breakpoint hit event
+	User::WaitForRequest(status);
+	test(status==KErrNone);
+
+	TBool receivedTracesLost = EFalse;
+
+	while(info.iEventType == EEventsUserTrace || info.iEventType == EEventsUserTracesLost)
+		{
+		//ensure we get told traces are being thrown away - we generate enough to flood the buffer
+		if(info.iEventType == EEventsUserTracesLost)
+			{
+			receivedTracesLost = ETrue;
+
+			// Now stop the target thread from generating trace events
+			test(KErrNone == SwitchTestFunction(EDoNothing));
+			}
+		else
+			{
+			// Its EEventsUserTrace, so delay us in getting the next event so that it will be more 
+			// likely to get a EEventsUserTracesLost next time. 
+			// This is important on SMP since the platform can process lots of events, and thus
+			// withouth the delay it is difficult for this test to reproduce the abnormal situation of 
+			// lost trace packets
+			User::After(200000);
+			}
+
+		iServSession.GetEvent(iFileName,status,infoPtr);
+
+		// Wait for notification of the 2nd breakpoint hit event
+		User::WaitForRequest(status);
+		test(status==KErrNone);
+		}
+
+	//make sure we got told traces were lost
+	test(receivedTracesLost != EFalse);
+
+	// info should now be filled with the details of our breakpoint.
+	test(info.iEventType == EEventsBreakPoint);
+	test(info.iThreadBreakPointInfo.iRmdArmExcInfo.iR15 == address2);
+	test(info.iProcessIdValid);
+	test(info.iThreadIdValid);
+
+	//dont care for breakpoints or trace events no more
+	test(KErrNone == iServSession.SetEventAction(iFileName,EEventsBreakPoint, EActionIgnore));
+	test(KErrNone == iServSession.SetEventAction(iFileName,EEventsUserTrace, EActionIgnore));
+	test(KErrNone == iServSession.SetEventAction(iFileName,EEventsUserTracesLost, EActionIgnore));
+
+	//clear the breaks we set
+	test(KErrNone == iServSession.ClearBreak(armBreakId));
+	test(KErrNone == iServSession.ClearBreak(armBreakId2));
+
+	// Continue the thread
+	test(KErrNone == iServSession.ResumeThread(iThreadID));
+
+	//attach to target debug process
+	test(KErrNone == iServSession.DetachExecutable(iFileName));
+
+	}
+
+//----------------------------------------------------------------------------------------------
+//! @SYMTestCaseID KBase-T-RMDEBUG2-2441
+//! @SYMTestType
+//! @SYMPREQ PREQ1426
+//! @SYMTestCaseDesc Test clearing of a process breakpoint once the process has been killed.
+//! @SYMTestActions Creates a new process then tries to set a process breakpoint and then kills the process which should clear the previously set breakpoint. Then repeat the step once again.
+//! @SYMTestExpectedResults KErrNone
+//! @SYMTestPriority High
+//! @SYMTestStatus Implemented
+//----------------------------------------------------------------------------------------------
+
+void CRunModeAgent::TestProcessKillBreakpoint(void)
+	{
+	test.Next(_L("TestProcessKillBreakpoint\n"));
+	//SID retrieved, used in Define/Attach of the property
+	iMySid.iUid = RProcess().SecureId();
+
+	static _LIT_SECURITY_POLICY_PASS(KAllowAllPolicy);
+
+	//define a property to pass on the address from the other process we would try to debug
+	test ( KErrNone == RProperty::Define(iMySid, EMyPropertyInteger, RProperty::EInt, KAllowAllPolicy, KAllowAllPolicy));
+	    //define a global semaphore to synchronise with debuggable process publishing the property
+	test ( KErrNone == iAddressGlobSem.CreateGlobal(_L("RMDebugGlobSem"), 0) );
+
+	DoTestProcessKillBreakpoint();
+	// called once again
+	// to check if we can set the breakpoint once again after the process gets killed
+	DoTestProcessKillBreakpoint();
+
+	//delete the property
+	test ( KErrNone == RProperty::Delete(iMySid, EMyPropertyInteger));
+	//close the semaphore
+	iAddressGlobSem.Close();
+	}
+
+void CRunModeAgent::DoTestProcessKillBreakpoint()
+	{
+	test.Printf(_L("\nDoTestProcessKillBreakpoint\n"));
+
+	TInt err = KErrNone;
+
+	// check that killing a process is supported
+	TTag tag = GetTag(ETagHeaderIdKillObjects, EFunctionalityKillProcess);
+	test(tag.iValue);
+	// check that killing a thread is not supported
+	tag = GetTag(ETagHeaderIdKillObjects, EFunctionalityKillThread);
+	test(!tag.iValue);
+
+	// attach first!
+	test ( KErrNone == iServSession.AttachExecutable(KRMDebugTestApplication, EFalse/*  Active */));
+
+	// first launch a debuggable process
+	RProcess processDebug;
+	test ( KErrNone == LaunchProcess(processDebug, KRMDebugTestApplication(),ESpinForeverWithBreakPoint, 0, 0));
+
+	// try to find the process in the list
+	_LIT(KRMDebugAppName, "t_rmdebug_app");
+	TBool found = ProcessExists(KRMDebugAppName);
+	test (found);
+
+	//search for the main thread created
+   _LIT(KThreadWildCard, "t_rmdebug_app*");
+	TProcessId processDebugId = processDebug.Id();
+	TThreadId threadDebugId;
+
+   	TFindThread find(KThreadWildCard);
+	TFullName name;
+	found = EFalse;
+	while(find.Next(name)==KErrNone && !found)
+		{
+		RThread thread;
+		err = thread.Open(find);
+       	if (err == KErrNone)
+			{
+			RProcess process;
+			thread.Process(process);
+			if (((TUint32)process.Id() == processDebugId))
+				{
+				TFullName fullname = thread.FullName();
+				test.Printf(_L("Match Found Name %lS Process ID%ld Thread Id %ld"), &fullname, process.Id().Id(), thread.Id().Id());
+				found = ETrue;
+				threadDebugId = thread.Id();
+				}
+			process.Close();
+			}
+			thread.Close();
+   		}
+
+	test (found); //check if we actually found the thread we want to debug
+
+	//get the value(property) for the breakpoint address for the process to debug
+	TInt address;
+	RProperty integerProperty;
+	test ( KErrNone == integerProperty.Attach(iMySid, EMyPropertyInteger, EOwnerThread));
+
+	//waiting on semaphore to be sure that the property is set
+	iAddressGlobSem.Wait();
+
+	test ( KErrNone == integerProperty.Get(address));
+	integerProperty.Close();
+
+	test.Printf(_L("Address retrieved to set breakpoint 0x%8x"), address);
+
+	//suspend the thread before we set a breakpoint
+	test ( KErrNone == iServSession.SuspendThread(threadDebugId));
+
+	//set a process breakpoint
+	TBreakId breakId;
+	test(KErrNone == iServSession.SetProcessBreak(breakId, processDebugId, address, EArmMode));
+
+	test(KErrNone ==iServSession.SetEventAction(KRMDebugTestApplication,EEventsProcessBreakPoint, EActionContinue));
+
+	//resume the thread now
+	test(KErrNone == iServSession.ResumeThread(threadDebugId));
+
+	// wait for the breakpoint to be hit
+	static TRequestStatus status;
+	TEventInfo info;
+	TPtr8 infoPtr((TUint8*)&info,0,sizeof(TEventInfo));
+	iServSession.GetEvent(KRMDebugTestApplication,status,infoPtr);
+	// Wait for notification of the breakpoint hit event
+	User::WaitForRequest(status);
+	test(status==KErrNone);
+
+	// info should now be filled with the details
+	test(info.iEventType ==  EEventsProcessBreakPoint);
+	test(info.iThreadBreakPointInfo.iRmdArmExcInfo.iR15 == address);
+	test(info.iProcessIdValid);
+	test(info.iThreadIdValid);
+
+	// Not interested in breakpoint events any more
+	test(KErrNone == iServSession.SetEventAction(KRMDebugTestApplication, EEventsProcessBreakPoint, EActionIgnore));
+
+	// program now running, so try to kill it which should clear all the breakpoints
+	test(KErrNone == iServSession.KillProcess(processDebugId, 0  /* kill reason */ ));
+
+	processDebug.Close();
+	User::After(2000000);	// should die within two seconds.
+
+	// can we still find it? Should be gone
+	found = ProcessExists(KRMDebugAppName);
+	test (!found);
+
+	// release the program again
+	test(KErrNone == iServSession.DetachExecutable(KRMDebugTestApplication));
+
+	}
+
+void CRunModeAgent::HelpTestSecurityAttachDetachExecutable(const TDesC& aProcessName, TBool aExpectSuccess)
+	{
+	RProcess process;
+	TInt err = process.Create(aProcessName, KNullDesC, EOwnerProcess);
+	test (err == KErrNone);
+
+	// rendezvous with process
+	TRequestStatus status;
+	process.Rendezvous(status);
+
+	// start the test program
+	process.Resume();
+	User::WaitForRequest(status);
+	test(status==KErrNone);
+
+	// attach to the program (passively)
+	err = iServSession.AttachExecutable(aProcessName, EFalse);
+
+	if( gUseDelay ) User::After(500000);
+
+	// Do we expect to successfully attach
+	if (aExpectSuccess)
+	{
+		// Yes
+		test(KErrNone == err);
+
+		// Now detach again
+		test(KErrNone == iServSession.DetachExecutable(aProcessName));
+		if( gUseDelay ) User::After(500000);
+	}
+	else
+	{
+		// No
+		test(KErrPermissionDenied == err);
+
+		// Just to be sure, try active attachment
+		test(KErrPermissionDenied == iServSession.AttachExecutable(aProcessName, ETrue));
+		if( gUseDelay ) User::After(500000);
+	}
+
+	// Kill the process, as we don't need it anymore
+	process.Kill(KErrNone);
+	if( gUseDelay ) User::After(500000);
+	}
+
+void CRunModeAgent::ReportPerformance(void)
+//
+// Reports performance metrics from all the tests
+//
+	{
+	test.Printf(_L("\nPerformance\n"));
+	test.Printf(_L("========================\n"));
+
+	// Memory
+	test.Printf(_L("Memory read: %d KBytes/sec\n"),iMemoryReadKbytesPerSecond);
+	test.Printf(_L("Memory write: %d KBytes/sec\n"),iMemoryWriteKbytesPerSecond);
+
+	// Registers
+	// to do
+
+	// events
+	// to do
+
+	// Breakpoints
+	test.Printf(_L("Breakpoint set/clear: %d/sec\n"),iBreakpointsPerSecond);
+	test.Printf(_L("Maximum number of breakpoints: %d\n"),iMaxBreakpoints);
+
+	// Stepping
+	test.Printf(_L("Stepping speed: %d/sec\n"),iStepsPerSecond);
+
+	// Runtime
+	TInt ticks = HelpGetTestTicks();
+	test (ticks != 0);
+
+	TInt nkTicksPerSecond = HelpTicksPerSecond();
+	test (nkTicksPerSecond != 0);
+
+	test.Printf(_L("Total test runtime: %d seconds\n"),ticks/nkTicksPerSecond);
+
+	// Final sizes of executables/rom/ram etc
+	// to do
+
+	test.Printf(_L("\n"));
+	}
+
+/**
+ * Helper code for the stepping tests. Sets a breakpoint in a running thread.
+ * It suspends the thread, sets the breakpoint, and resumes the thread.
+ *
+ * @param aBreakId - Reference to a TBreakId which will be set when the breakpoint is set
+ * @param aThreadId - The thread id for which we should set the breakpoint.
+ * @param aBreakAddress - The address to set the breakpoint
+ * @param aMode - The architecture of the breakpoint to be set (ARM/Thumb/Thumb2EE)
+ * @return KErrNone if successful. One of the other system wide error codes otherwise.
+ */
+TInt CRunModeAgent::HelpTestStepSetBreak(TBreakId& aBreakId, TThreadId aThreadId, const TUint32 aBreakAddress, TArchitectureMode aMode, TBool aThreadSpecific, TProcessId aProcessId)
+	{
+	TInt err = KErrNone;
+
+	// Suspend the thread
+	err = iServSession.SuspendThread(aThreadId);
+	if (err != KErrNone)
+		{
+		test.Printf(_L("HelpTestStepSetBreak - Failed to suspend thread\n"));
+		return err;
+		}
+
+	// Set the breakpoint
+	err = aThreadSpecific
+		? iServSession.SetBreak(aBreakId,aThreadId,aBreakAddress,aMode)
+		: iServSession.SetProcessBreak(aBreakId, aProcessId, aBreakAddress, aMode);
+	if (err != KErrNone)
+		{
+		test.Printf(_L("HelpTestStepSetBreak - Failed to set breakpoint\n"));
+		return err;
+		}
+
+	// Continue the thread
+	err = iServSession.ResumeThread(aThreadId);
+	if (err != KErrNone)
+		{
+		test.Printf(_L("HelpTestStepSetBreak - Failed to resume thread\n"));
+		return err;
+		}
+
+	return KErrNone;
+	}
+
+/**
+ * Helper code for the stepping tests. Clears a breakpoint in a running thread.
+ * It suspends the thread, clears the breakpoint, and resumes the thread.
+ *
+ * @param aBreakId - Reference to a TBreakId which will be set when the breakpoint is set
+ * @return KErrNone if successful. One of the other system wide error codes otherwise.
+ */
+TInt CRunModeAgent::HelpTestStepClearBreak(TBreakId aBreakId, const TThreadId aThreadId, TBool aThreadSpecific)
+	{
+	TInt err = KErrNone;
+
+	// Find out what thread id we need to suspend
+	TThreadId threadId;
+	TProcessId processId;
+	TUint32 address;
+	TArchitectureMode mode;
+
+	err = aThreadSpecific
+		? iServSession.BreakInfo(aBreakId, threadId, address, mode)
+		: iServSession.ProcessBreakInfo(aBreakId, processId, address, mode);
+	if (err != KErrNone )
+		{
+		test.Printf(_L("HelpTestStepClearBreak - failed to obtain information for breakpoint\n"));
+		return err;
+		}
+	if(aThreadSpecific && aThreadId != threadId)
+		{
+		test.Printf(_L("HelpTestStepClearBreak - mismatched thread Ids\n"));
+		return KErrGeneral;
+		}
+
+	// Suspend the thread
+	err = iServSession.SuspendThread(aThreadId);
+	if (!(err == KErrNone || err == KErrAlreadyExists))
+		{
+		test.Printf(_L("HelpTestStepClearBreak - failed to suspend thread\n"));
+		return err;
+		}
+
+	// Clear the breakpoint
+	err = iServSession.ClearBreak(aBreakId);
+	if (err != KErrNone)
+		{
+		test.Printf(_L("HelpTestStepClearBreak - failed to clear breakpoint\n"));
+		return err;
+		}
+
+	// Continue the thread
+	err = iServSession.ResumeThread(aThreadId);
+	if (!(err == KErrNone || err == KErrNotFound))
+		{
+		test.Printf(_L("HelpTestStepClearBreak - failed to resume thread\n"));
+		return err;
+		}
+
+	return KErrNone;
+	}
+
+/**
+ * Helper code for the stepping tests. Waits for a previously set breakpoint to be hit.
+ *
+ * @param aProcessName - The name of the process in which the breakpoint is set. E.g. z:\sys\bin\app.exe
+ * @param aEventInfo - The event information block which is filled in when the breakpoint is hit.
+ * @return KErrNone if successful. One of the other system wide error codes otherwise.
+ */
+TInt CRunModeAgent::HelpTestStepWaitForBreak(const TDesC& aProcessName, TEventInfo& aEventInfo)
+	{
+	static TRequestStatus status;
+
+	TPtr8 infoPtr((TUint8*)&aEventInfo,0,sizeof(TEventInfo));
+
+	iServSession.GetEvent(aProcessName,status,infoPtr);
+
+	// Wait for notification of the breakpoint hit event
+	User::WaitForRequest(status);
+	if (status == KErrNone)
+		{
+		return KErrNone;
+		}
+	else
+		{
+		return KErrGeneral;
+		}
+	}
+
+/**
+ * Helper code for the stepping tests. Reads the current target PC for a given thread.
+ *
+ * @param aThreadId - Thread id for which to read the current target PC.
+ * @param aPc - Reference to a TUint32 which will be set to the current target PC.
+ * @return KErrNone if successful. One of the other system wide error codes otherwise.
+ */
+TInt CRunModeAgent::HelpTestStepReadPC(TThreadId aThreadId, TUint32& aPC)
+	{
+	TInt err = KErrNone;
+
+	//create buffer containing PC register ID
+	RBuf8 pcId;
+	err = pcId.Create(sizeof(TRegisterInfo));
+	if (err != KErrNone)
+		{
+		return err;
+		}
+
+	TRegisterInfo reg1 = (TRegisterInfo)0x00000f00;
+	pcId.Append(reinterpret_cast<const TUint8*>(&reg1), sizeof(TRegisterInfo));
+
+	//create buffer containing desired PC value
+	TPtr8 pcValue((TUint8*)&aPC,4,4);
+
+	//create buffer for PC flag value
+	RBuf8 pcFlag;
+	err = pcFlag.Create(sizeof(TUint8));
+
+	//read the new PC value
+	err = iServSession.ReadRegisters(aThreadId, pcId, pcValue, pcFlag);
+	if (err != KErrNone)
+		{
+		//delete temporary buffers
+		pcId.Close();
+		pcFlag.Close();
+		return err;
+		}
+
+	//get the flag and check the PC value was read ok
+	TRegisterFlag flag = ENotSupported;
+	err = GetFlag(pcFlag, 0, flag);
+	if (err != KErrNone)
+		{
+		//delete temporary buffers
+		pcId.Close();
+		pcFlag.Close();
+		return err;
+		}
+
+	if (flag == EValid)
+		{
+		//delete temporary buffers
+		pcId.Close();
+		pcFlag.Close();
+		return KErrNone;
+		}
+	else
+		{
+		//delete temporary buffers
+		pcId.Close();
+		pcFlag.Close();
+		return err;
+		}
+	}
+
+/**
+ * Helper code for the stepping tests. Single steps a given thread from aStartAddress to aEndAddress. Note
+ * that it reaches aStartAddress by setting a breakpoint at that address and waiting until it is hit.
+ *
+ * @param aThreadId - Thread id for which to read the current target PC.
+ * @param aStartAddress - The target address at which stepping will start.
+ * @param aEndAddress - The target address at which stepping will end.
+ * @param aMode - The architecture of the breakpoint which must be set at the start address (ARM/Thumb/Thumb2EE).
+ * @return KErrNone if successful. One of the other system wide error codes otherwise.
+ */
+TInt CRunModeAgent::HelpTestStep(TThreadId aThreadId, TUint32 aStartAddress, TUint32 aEndAddress, TArchitectureMode aMode, TUint aNumSteps, TBool aThreadSpecific, TProcessId aProcessId)
+	{
+	TInt err = KErrNone;
+
+	// Ensure that the supplied addresses are word/half-word aligned as appropriate.
+	if (aMode == EArmMode)
+		{
+		// ARM breakpoints must be word-aligned (2 lsb must be zero)
+		aStartAddress &= 0xFFFFFFFC;
+		aEndAddress &= 0xFFFFFFFC;
+		}
+	else if (aMode == EThumbMode)
+		{
+		// Thumb breakpoints must be half-word aligned (lsb must be zero)
+		aStartAddress &= 0xFFFFFFFE;
+		aEndAddress	 &= 0xFFFFFFFE;
+		}
+	else if (aMode == EThumb2EEMode)
+	{
+		// Thumb2EE breakpoints are not currently supported
+		return KErrNotSupported;
+	}
+
+	// Set breakpoint at the start address
+	TBreakId tempBreakId;
+	TEventInfo info;
+
+	err = HelpTestStepSetBreak(tempBreakId,aThreadId,aStartAddress,aMode,aThreadSpecific,aProcessId);
+	if (err != KErrNone)
+		{
+		test.Printf(_L("HelpTestStep - Failed to set breakpoint at aStartAddress 0x%08x\n"),aStartAddress);
+		return err;
+		}
+
+	// wait for the breakpoint to be hit
+	err = HelpTestStepWaitForBreak(iFileName,info);
+	if (err != KErrNone)
+		{
+		test.Printf(_L("HelpTestStep - Failed to hit the breakpoint at aStartAddress 0x%08x\n"),aStartAddress);
+		return err;
+		}
+
+	// Check the PC == aStartAddress
+	TUint32 pc = 0;
+	err = HelpTestStepReadPC(aThreadId,pc);
+	if (err != KErrNone)
+		{
+		test.Printf(_L("HelpTestStep - Failed to read the PC after hitting breakpoint at aStartAddress 0x%08x\n"),aStartAddress);
+		return err;
+		}
+
+	if (pc != aStartAddress)
+		{
+		test.Printf(_L("HelpTestStep - Incorrect PC value after hitting breakpoint (expected 0x%08x actual 0x%08x)\n"),aStartAddress,pc);
+		return KErrGeneral;
+		}
+
+	err = iServSession.Step(aThreadId,aNumSteps);
+	if (err != KErrNone)
+		{
+		test.Printf(_L("HelpTestStep - Failed to do step from 0x%08x to 0x%08x\n"),aStartAddress,aEndAddress,aNumSteps);
+		return err;
+		}
+
+	// only one 'completed step' event in the buffer.
+	err = HelpTestStepWaitForBreak(iFileName,info);
+	if (err != KErrNone)
+		{
+		test.Printf(_L("HelpTestStep - Could not read breakpoint event info after stepping"));
+		return err;
+		}
+	// end
+
+	// Check PC == aEndAddress
+	err = HelpTestStepReadPC(aThreadId,pc);
+	if (err != KErrNone)
+		{
+		test.Printf(_L("HelpTestStep - failed read the PC after stepping\n"));
+		return err;
+		}
+	if (pc != aEndAddress)
+		{
+		test.Printf(_L("HelpTestStep - Incorrect PC value after stepping (expected 0x%08x actual 0x%08x)\n"),aEndAddress,pc);
+		return KErrGeneral;
+		}
+
+	// Clear the breakpoint
+	err = HelpTestStepClearBreak(tempBreakId, aThreadId, aThreadSpecific);
+	if (err != KErrNone)
+		{
+		test.Printf(_L("HelpTestStep - failed to clear temporary breakpoint\n"));
+		return err;
+		}
+
+	return KErrNone;
+	}
+
+/**
+ * Helper code for the stepping tests. Returns the number of nanokernel ticks in one second.
+ *
+ * @return Number of nanokernel ticks. 0 if unsuccesful.
+ */
+TInt CRunModeAgent::HelpTicksPerSecond(void)
+	{
+	TInt nanokernel_tick_period;
+	HAL::Get(HAL::ENanoTickPeriod, nanokernel_tick_period);
+
+	ASSERT(nanokernel_tick_period != 0);
+
+	static const TInt KOneMillion = 1000000;
+
+	return KOneMillion/nanokernel_tick_period;
+	}
+
+/**
+  Given aTestNumber runs the appropriate test inside heap markers
+
+  @param aTestNumber test to run, corresponds to an entry in iTestArray
+
+  @panic Panic if aTestNumber is not in valid range
+  */
+void CRunModeAgent::RunTest(TInt aTestNumber)
+	{
+	if( (aTestNumber<0) || (aTestNumber>=KMaxTests) )
+		{
+		User::Panic(_L("Test number out of range"), aTestNumber);
+		}
+	__UHEAP_MARK;
+	(this->*(iTestArray[aTestNumber].iFunctionPtr))();
+	__UHEAP_MARKEND;
+	}
+
+void CRunModeAgent::PrintVersion()
+	{
+	test.Printf(_L("\nt_rmdebug2.exe\nVersion: %S\n"), &(testVersion.Name()));
+	test.Printf(_L("Press any key...\n"));
+	test.Getch();
+	}
+
+void CRunModeAgent::PrintUsage()
+	{
+	test.Printf(_L("Invoke with arguments:\n"));
+	test.Printf(_L("-r: run specified tests in reverse order\n"));
+	test.Printf(_L("-h: display usage information\n"));
+	test.Printf(_L("-v: display version\n"));
+	test.Printf(_L("-d: use delays\n"));
+	test.Printf(_L("<number>: test number to run, can specify more than one from the following list:\n"));
+	test.Printf(_L("Press any key for list...\n"));
+	test.Getch();
+	// if there are too many of these they won't fit on the screen! Stick another Getch() in if there get too many
+	for(TInt i=0; i<KMaxTests; i++)
+		{
+		test.Printf(_L("%2d: %S\n"), i, &(iTestArray[i].iFunctionName));
+		}
+	test.Printf(_L("Press any key...\n"));
+	test.Getch();
+	}
+
+/**
+  Parse the command line, see CRunModeAgent::PrintUsage for syntax
+  */
+void CRunModeAgent::ParseCommandLineL(TUint32& aMode, RArray<TInt>& aTests)
+	{
+	// get the length of the command line arguments
+	TInt argc = User::CommandLineLength();
+
+	// allocate a buffer for the command line arguments and extract the data to it
+	HBufC* commandLine = HBufC::NewLC(argc);
+	TPtr commandLineBuffer = commandLine->Des();
+	User::CommandLine(commandLineBuffer);
+
+	// reset mode
+	aMode = (TTestMode)0;
+
+	// create a lexer and read through the command line
+	TLex lex(*commandLine);
+	while (!lex.Eos())
+		{
+		// expecting the first character to be a '-'
+		if (lex.Get() == '-')
+			{
+			TChar arg = lex.Get();
+			switch (arg)
+				{
+				case 'v':
+					//print out the help
+					aMode |= EModeVersion;
+					break;
+				case 'h':
+					//print out the help
+					aMode |= EModeHelp;
+					break;
+				case 'r':
+					//store the fact that we want to run in reverse
+					aMode |= EModeReverse;
+					break;
+				case 'd':
+					//store the fact that we want to run in reverse
+					gUseDelay = EFalse;
+					RDebug::Printf("Not using delays");
+					break;
+				default:
+					// unknown argument so leave
+					User::Leave(KErrArgument);
+				}
+			}
+		else
+			{
+			lex.UnGet();
+			TInt testNumber;
+			User::LeaveIfError(lex.Val(testNumber));
+			if( (testNumber<0) || (testNumber>=KMaxTests) )
+				{
+				User::Leave(KErrArgument);
+				}
+			aTests.AppendL(testNumber);
+			}
+		lex.SkipSpace();
+		}
+	// if no tests specified then run them all
+	if(aTests.Count() == 0)
+		{
+		aMode |= EModeAll;
+		}
+
+	// do clean up
+	CleanupStack::PopAndDestroy(commandLine);
+	}
+
+void CRunModeAgent::ClientAppL()
+//
+// Performs each test in turn
+//
+	{
+	test.Start(_L("ClientAppL"));
+
+	RArray<TInt> testsToRun;
+	TUint32 testMode = 0;
+	ParseCommandLineL(testMode, testsToRun);
+
+	//if help or version mode specified then just print out the relevant stuff and quit
+	if((testMode & EModeHelp) || (testMode & EModeVersion))
+		{
+		if(testMode & EModeHelp)
+			{
+			PrintUsage();
+			}
+		if(testMode & EModeVersion)
+			{
+			PrintVersion();
+			}
+		test.End();
+		return;
+		}
+
+	if(testMode & EModeAll)
+		{
+		for(TInt i=0; i<KMaxTests; i++)
+			{
+			testsToRun.AppendL(i);
+			}
+		}
+
+	// if EModeReverse specified then reverse the array elements
+	TInt numberOfTests = testsToRun.Count();
+	if(testMode & EModeReverse)
+		{
+		for(TInt i=0; i<(numberOfTests>>1); i++)
+			{
+			TInt temp = testsToRun[i];
+			testsToRun[i] = testsToRun[numberOfTests - (i+1)];
+			testsToRun[numberOfTests - (i+1)] = temp;
+			}
+		}
+
+	__UHEAP_MARK;
+	SetupAndAttachToDSS();
+	__UHEAP_MARKEND;
+
+	HelpStartTestTimer();
+	for(TInt i=0; i<numberOfTests; i++)
+		{
+		RunTest(testsToRun[i]);
+		if( gUseDelay ) User::After(500000);
+		}
+	testsToRun.Close();
+
+	HelpStopTestTimer();
+
+	ReportPerformance();
+
+	test.End();
+	}
+
+/**
+  Fill the test array with pointers to each test.
+  */
+void CRunModeAgent::FillArray()
+	{
+	iTestArray[0].iFunctionPtr = &CRunModeAgent::TestDriverSecurity;
+	iTestArray[0].iFunctionName = _L("TestDriverSecurity");
+	iTestArray[1].iFunctionPtr = &CRunModeAgent::TestDllUsage;
+	iTestArray[1].iFunctionName = _L("TestDllUsage");
+	iTestArray[2].iFunctionPtr = &CRunModeAgent::TestSecurity;
+	iTestArray[2].iFunctionName = _L("TestSecurity");
+	iTestArray[3].iFunctionPtr = &CRunModeAgent::TestAttachExecutable;
+	iTestArray[3].iFunctionName = _L("TestAttachExecutable");
+	iTestArray[4].iFunctionPtr = &CRunModeAgent::TestGetExecutablesList;
+	iTestArray[4].iFunctionName = _L("TestGetExecutablesList");
+	iTestArray[5].iFunctionPtr = &CRunModeAgent::TestGetProcessList;
+	iTestArray[5].iFunctionName = _L("TestGetProcessList");
+	iTestArray[6].iFunctionPtr = &CRunModeAgent::TestGetXipLibrariesList;
+	iTestArray[6].iFunctionName = _L("TestGetXipLibrariesList");
+	iTestArray[7].iFunctionPtr = &CRunModeAgent::TestGetThreadList;
+	iTestArray[7].iFunctionName = _L("TestGetThreadList");
+	iTestArray[8].iFunctionPtr = &CRunModeAgent::TestGetCodeSegsList;
+	iTestArray[8].iFunctionName = _L("TestGetCodeSegsList");
+	iTestArray[9].iFunctionPtr = &CRunModeAgent::TestGetListInvalidData;
+	iTestArray[9].iFunctionName = _L("TestGetListInvalidData");
+	iTestArray[10].iFunctionPtr = &CRunModeAgent::TestMemoryAccess;
+	iTestArray[10].iFunctionName = _L("TestMemoryAccess");
+	iTestArray[11].iFunctionPtr = &CRunModeAgent::TestDebugFunctionality;
+	iTestArray[11].iFunctionName = _L("TestDebugFunctionality");
+	iTestArray[12].iFunctionPtr = &CRunModeAgent::TestSuspendResume;
+	iTestArray[12].iFunctionName = _L("TestSuspendResume");
+	iTestArray[13].iFunctionPtr = &CRunModeAgent::TestBreakPoints;
+	iTestArray[13].iFunctionName = _L("TestBreakPoints");
+	iTestArray[14].iFunctionPtr = &CRunModeAgent::TestModifyBreak;
+	iTestArray[14].iFunctionName = _L("TestModifyBreak");
+	iTestArray[15].iFunctionPtr = &CRunModeAgent::TestBreakInfo;
+	iTestArray[15].iFunctionName = _L("TestBreakInfo");
+	iTestArray[16].iFunctionPtr = &CRunModeAgent::TestRunToBreak;
+	iTestArray[16].iFunctionName = _L("TestRunToBreak");
+	iTestArray[17].iFunctionPtr = &CRunModeAgent::TestBreakPointsInLoop;
+	iTestArray[17].iFunctionName = _L("TestBreakPointsInLoop");
+	iTestArray[18].iFunctionPtr = &CRunModeAgent::TestRegisterAccess;
+	iTestArray[18].iFunctionName = _L("TestRegisterAccess");
+	iTestArray[19].iFunctionPtr = &CRunModeAgent::TestStep;
+	iTestArray[19].iFunctionName = _L("TestStep");
+	iTestArray[20].iFunctionPtr = &CRunModeAgent::TestDemandPaging;
+	iTestArray[20].iFunctionName = _L("TestDemandPaging");
+	iTestArray[21].iFunctionPtr = &CRunModeAgent::TestEventsForExternalProcess;
+	iTestArray[21].iFunctionName = _L("TestEventsForExternalProcess");
+	iTestArray[22].iFunctionPtr = &CRunModeAgent::TestEvents;
+	iTestArray[22].iFunctionName = _L("TestEvents");
+	iTestArray[23].iFunctionPtr = &CRunModeAgent::TestKillProcess;
+	iTestArray[23].iFunctionName = _L("TestKillProcess");
+	iTestArray[24].iFunctionPtr = &CRunModeAgent::TestProcessBreakPoints;
+	iTestArray[24].iFunctionName = _L("TestProcessBreakPoints");
+	iTestArray[25].iFunctionPtr = &CRunModeAgent::TestMultipleTraceEvents;
+	iTestArray[25].iFunctionName = _L("TestMultipleTraceEvents");
+	iTestArray[26].iFunctionPtr = &CRunModeAgent::TestAddRemoveProcessEvents;
+	iTestArray[26].iFunctionName = _L("TestAddRemoveProcessEvents");
+	iTestArray[27].iFunctionPtr = &CRunModeAgent::TestCrashFlash;
+	iTestArray[27].iFunctionName = _L("TestCrashFlash");
+	iTestArray[28].iFunctionPtr = &CRunModeAgent::TestProcessKillBreakpoint;
+	iTestArray[28].iFunctionName = _L("TestProcessKillBreakpoint");
+	};
+
+GLDEF_C TInt E32Main()
+//
+// Entry point for run mode debug driver test
+//
+	{
+   TInt ret = KErrNone;
+
+	// client
+	CTrapCleanup* trap = CTrapCleanup::New();
+	if (!trap)
+		return KErrNoMemory;
+   	test.Title();
+   RunModeAgent = CRunModeAgent::NewL();
+   if (RunModeAgent != NULL)
+       {
+        __UHEAP_MARK;
+	    TRAP(ret,RunModeAgent->ClientAppL());
+	    __UHEAP_MARKEND;
+
+	    delete RunModeAgent;
+       }
+
+	delete trap;
+
+	return ret;
+	}
+
+/**
+Helper function to get the aOffset'th value from aFlags
+
+@param aFlags descriptor containing TRegisterFlag type flags
+@param aOffset index of flag value to extract from aFlags
+@param aFlagValue the flag value if function returned successfully
+
+@return KErrNone if value was read successfully, KErrTooBig if aOffset is
+        greater than aFlags.Length()
+*/
+TInt CRunModeAgent::GetFlag(const TDes8& aFlags, const TUint aOffset, TRegisterFlag &aFlagValue) const
+	{
+	//get pointer to data
+	const TUint8 *ptr = aFlags.Ptr();
+
+	//check aOffset is valid
+	TUint length = aFlags.Length();
+	if(aOffset >= length)
+		return KErrTooBig;
+
+	//get flag value
+	aFlagValue = (TRegisterFlag)ptr[aOffset];
+	return KErrNone;
+	}
+
+/**
+  Helper function to set the value of FunctionChooser in the target debug thread.
+
+  @param aTestFunction TTestFunction enum to set FunctionChooser to
+
+  @return KErrNone if the value was set correctly, or one of the other system wide error codes
+  */
+TInt CRunModeAgent::SwitchTestFunction(TTestFunction aTestFunction)
+	{
+	//suspend the target thread
+	TInt suspendError = iServSession.SuspendThread(iThreadID);
+	if(! ( (suspendError == KErrNone) || (suspendError == KErrAlreadyExists) ) )
+		{
+		//the thread is not suspended so exit
+		return suspendError;
+		}
+
+	//get the address of FunctionChooser
+	TUint32 functionChooserAddress = (TUint32)&FunctionChooser;
+	//put the new value for FunctionChooser into a descriptor
+	TPtr8 functionBuf((TUint8*)&aTestFunction, sizeof(TTestFunction), sizeof(TTestFunction));
+	//write the new value into the target thread
+	TInt writeError = iServSession.WriteMemory(iThreadID, functionChooserAddress, sizeof(TTestFunction), functionBuf, EAccess32, EEndLE8);
+
+	if(KErrNone == suspendError)
+		{
+		//if this function suspended the target thread then we need to resume it
+		TInt resumeError = iServSession.ResumeThread(iThreadID);
+		if(KErrNone != resumeError)
+			{
+			//resuming failed so return the error
+			return resumeError;
+			}
+		}
+
+	//suspending and resuming was successful so return the error code from the WriteMemory call
+	return writeError;
+	}
+
+/**
+  Launch a separate process to debug.
+
+  @param aProcess the RProcess object to use to create the process
+  @param aFileName file name of the executable to create the process from
+  @param aFunctionType function that the target process should call on execution
+  @param aDelay delay before the new process should call the function represented by aFunctionType
+  @param aExtraThreads number of extra threads to create in the child process
+
+  @return KErrNone on success, or one of the other system wide error codes
+  */
+TInt CRunModeAgent::LaunchProcess(RProcess& aProcess, const TDesC& aFileName, TDebugFunctionType aFunctionType, TUint32 aDelay, TUint32 aExtraThreads)
+	{
+	// at the moment we support two arguments, this number might have to be increased to support arguments
+	const TUint KMaxCommandLineLength = 32;
+
+	// create a command line buffer
+	RBuf commandLine;
+	commandLine.Create(KMaxCommandLineLength);
+
+	// append the command line arguments to the buffer
+	_LIT(KFArg, "-f");
+	commandLine.Append(KFArg());
+	commandLine.AppendNum(aFunctionType);
+
+	_LIT(KSpace, " ");
+	commandLine.Append(KSpace());
+
+	_LIT(KDArg, "-d");
+	commandLine.Append(KDArg());
+	commandLine.AppendNum(aDelay);
+
+	commandLine.Append(KSpace());
+
+	_LIT(KEArg, "-e");
+	commandLine.Append(KEArg());
+	commandLine.AppendNum(aExtraThreads);
+
+	// create the new process, matching on file name only, not specifying uid values
+	TInt err = aProcess.Create(aFileName, commandLine);	// owned by the process
+
+	// check that there was no error raised
+	if(err != KErrNone)
+		{
+		commandLine.Close();
+		return err;
+		}
+
+	TRequestStatus status = KRequestPending;
+	aProcess.Rendezvous(status);
+
+	commandLine.Close();	// after target thread starts
+
+	if(KRequestPending != status.Int())
+		{
+		// startup failed so kill the process
+		aProcess.Kill(KErrNone);
+		return status.Int();
+		}
+	else
+		{
+		// start up succeeded so resume the process
+		aProcess.Resume();
+		User::WaitForRequest(status);
+		if(KErrNone != status.Int())
+			{
+			aProcess.Kill(KErrNone);
+			}
+		return status.Int();
+		}
+	}
+
+/**
+  Helper function to read a tag header from a debug functionality block
+
+  @param aDebugFunctionalityBlock block to read header from
+  @param aTagHdrId header type to find
+
+  @return pointer to the header, or NULL if not available
+  */
+TTagHeader* CRunModeAgent::GetTagHdr(const TDesC8& aDebugFunctionalityBlock, const TTagHeaderId aTagHdrId) const
+	{
+	TUint8* ptr = (TUint8*) aDebugFunctionalityBlock.Ptr();
+	TUint8* blockEnd = ptr + aDebugFunctionalityBlock.Size();
+
+	while(ptr < blockEnd)
+		{
+		TTagHeader* header = (TTagHeader*)ptr;
+		if(header->iTagHdrId == aTagHdrId)
+			{
+			return header;
+			}
+		ptr += sizeof(TTagHeader) + (header->iNumTags * sizeof(TTag));
+		}
+	return NULL;
+	}
+
+/**
+  Helper function to read a tag from a debug functionality block
+
+  @param aTagHdr pointer to a tag header in a debug functionality block
+  @param aElement element to return from the header's data
+
+  @return pointer to the tag, or NULL if not available
+  */
+TTag* CRunModeAgent::GetTag(const TTagHeader* aTagHdr, const TInt aElement) const
+	{
+	TUint8* ptr = (TUint8*)aTagHdr + sizeof(TTagHeader);
+	TUint8* blockEnd = ptr + (aTagHdr->iNumTags * sizeof(TTag));
+
+	while(ptr < blockEnd)
+		{
+		TTag* tag = (TTag*)ptr;
+		if(tag->iTagId == aElement)
+			{
+			return tag;
+			}
+		ptr += sizeof(TTag);
+		}
+	return NULL;
+	}
+
+TTag CRunModeAgent::GetTag(const TTagHeaderId aTagHdrId, const TInt aElement)
+	{
+	TUint32 bufsize = 0;	// Safe default size
+
+	// Get functionality block size
+	test(KErrNone == iServSession.GetDebugFunctionalityBufSize(&bufsize));
+
+	// Ensure we have a finite buffer size
+	test(bufsize!=0);
+
+	// Allocate space for the functionality data
+	HBufC8* dftext = HBufC8::NewLC(bufsize);
+
+	// create an empty TPtr8 refering to dftext
+	TPtr8 dftextPtr(dftext->Des());
+
+	// Get the functionality block
+	test(KErrNone == iServSession.GetDebugFunctionality(dftextPtr));
+
+	// read a value from the data to check it has come through as expected
+	TTagHeader* header = GetTagHdr(dftext->Des(), aTagHdrId);
+	test(header != NULL);
+	TTag* tag = GetTag(header, aElement);
+	test(tag != NULL);
+
+	TTag tagToReturn = *tag;
+
+	// Remove our temporary buffer
+	CleanupStack::PopAndDestroy(dftext);
+
+	return tagToReturn;
+	}
+
+/**
+  Helper function which returns a Boolean indicating with a process with the
+  specified name is currently running.
+
+  @param aProcessName - Name of the process to find
+  @return ETrue if found, EFalse otherwise
+  */
+TBool CRunModeAgent::ProcessExists(const TDesC& aProcessName)
+	{
+	TInt    err=KErrNone;
+	TBool	found = FALSE;
+
+_LIT(KWildCard,"*");
+
+	TFindProcess find(KWildCard);
+	TFullName name;
+	while(find.Next(name)==KErrNone)
+		{
+		RProcess process;
+		err = process.Open(find);
+		if (err == KErrNone)
+			{
+			if (name.Find(aProcessName) != KErrNotFound)
+				{
+					found = TRUE;
+				}
+			process.Close();
+			}
+	   }
+
+	return found;
+	}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/rm_debug/basic_tests/t_rmdebug2.h	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,191 @@
+// Copyright (c) 2006-2010 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:
+// Definitions for the run mode debug tests
+// 
+//
+
+/**
+ @file
+ @internalTechnology
+ @released
+*/
+
+#ifndef RMDEBUG_H
+#define RMDEBUG_H
+
+#include "t_rmdebug_app.h"
+#include "r_user_low_memory_security_svr_session.h"
+#include "r_kernel_low_memory_security_svr_session.h"
+
+
+class CRunModeAgent;
+
+// Create a pointer to function type
+typedef void (CRunModeAgent::*testFunction)();
+
+class TFunctionData
+	{
+public:
+	testFunction iFunctionPtr;
+	TBuf<40> iFunctionName;
+	};
+
+//number of test functions that we have
+const TInt KMaxTests = 29; 
+
+//
+// class CRunModeAgent
+//
+// The basic run mode agent.
+//
+class CRunModeAgent : public CBase
+	{
+public:
+	static CRunModeAgent* NewL();
+	~CRunModeAgent();
+	void ClientAppL();
+
+private:
+	CRunModeAgent();
+	void ConstructL();
+	void SetupAndAttachToDSS();
+
+	TInt TestStartup();
+	TInt TestShutdown();
+
+	void TestGetExecutablesList();
+	void TestGetProcessList();
+	void TestGetThreadList();
+	void TestGetCodeSegsList();
+	void TestGetXipLibrariesList();
+	void TestGetListInvalidData();
+
+	void DoTestGetThreadList(const TBool aShouldPass, const Debug::TListScope aListScope, const TUint64 aTargetId=0);
+	void DoTestGetCodeSegsList(const TBool aShouldPass, const Debug::TListScope aListScope, const TUint64 aTargetId=0);
+
+	void DoGetList(const Debug::TListId aListId, const Debug::TListScope aListScope, RBuf8& aBuffer, TUint32& aSize, const TUint64 aTargetId=0);
+
+	void TestMemoryAccess();
+	void TestSuspendResume();
+	void TestBreakPoints();
+	void TestConsecutiveBreakPoints();
+	void TestModifyBreak();
+	void DoTestModifyBreak(TBool aThreadSpecific);
+	void TestBreakInfo();
+	void DoTestBreakInfo(TBool aThreadSpecific);
+	void TestRunToBreak();
+	void DoTestRunToBreak(TBool aThreadSpecific);
+	void TestBreakPointsInLoop();
+	void DoTestBreakPointsInLoop(TBool aThreadSpecific);
+	void TestRegisterAccess();
+	void TestAttachExecutable();
+	void TestDebugFunctionality();
+	void TestStep();
+	void DoTestStep(TBool aThreadSpecific);
+	void TestDriverSecurity();
+	void TestSecurity();
+	void TestEvents();
+	void TestEventsForExternalProcess();
+	void TestDemandPaging();
+	void TestTraceSecurity();
+	void TestDllUsage();
+	void TestKillProcess();
+	void TestProcessBreakPoints();
+	void TestMultipleTraceEvents();
+	void TestAddRemoveProcessEvents();
+	void TestProcessKillBreakpoint();
+	void DoTestProcessKillBreakpoint();
+
+	//crash flash test functions
+	void TestCrashFlash();
+		
+	TInt GetFlag(const TDes8 &aFlags, const TUint aOffset, Debug::TRegisterFlag &aFlagValue) const;
+
+	void ReportPerformance(void);
+
+	// helper functions
+	void HelpTestSecurityAttachDetachExecutable(const TDesC& aProcessName, TBool aExpectSuccess);
+
+	TInt HelpTestStepSetBreak(Debug::TBreakId& aBreakId, TThreadId aThreadId, const TUint32 aBreakAddress, Debug::TArchitectureMode aMode, TBool aThreadSpecific=ETrue, TProcessId aProcessId=0);
+	TInt HelpTestStepClearBreak(const Debug::TBreakId aBreakId, const TThreadId aThreadId, TBool aThreadSpecific);
+	TInt HelpTestStepWaitForBreak(const TDesC& aProcessName, Debug::TEventInfo& aEventInfo);
+	TInt HelpTestStepReadPC(TThreadId aThreadId, TUint32& aPC);
+	TInt HelpTestStep(TThreadId aThreadId, TUint32 aStartAddress, TUint32 aEndAddress, Debug::TArchitectureMode aMode, TUint aNumSteps, TBool aThreadSpecific=ETrue, TProcessId=0);
+
+	TInt HelpTicksPerSecond(void);
+
+	// helper functions
+	void HelpStartTestTimer(void) { iStartTick = User::NTickCount(); iStopTick = 0; };
+	void HelpStopTestTimer(void) { iStopTick = User::NTickCount(); };
+	TInt HelpGetTestTicks(void) { return (iStopTick - iStartTick); };
+	TInt SwitchTestFunction(TTestFunction aTestFunction);
+	TInt LaunchProcess(RProcess& aProcess, const TDesC& aFileName, TDebugFunctionType aFunctionType, TUint32 aDelay=0, TUint32 aExtraThreads=0);
+	Debug::TTagHeader* GetTagHdr(const TDesC8& aDebugFunctionalityBlock, const Debug::TTagHeaderId aTagHdrId) const;
+	Debug::TTag* GetTag(const Debug::TTagHeader* aTagHdr, const TInt aElement) const;
+	Debug::TTag GetTag(const Debug::TTagHeaderId aTagHdrId, const TInt aElement);
+	TBool ProcessExists(const TProcessId aProcessId);
+	TBool ThreadExistsForProcess(const TThreadId aThreadId, const TProcessId aProcessId);
+	TBool ListingSupported(const Debug::TListId aListId, const Debug::TListScope aListScope);
+	void TestEventsWithExtraThreads(Debug::TKernelEventAction aActionMain, Debug::TKernelEventAction aActionExtra, TUint32 aExtraThreads);
+	void FillArray();
+	void PrintUsage();
+	void PrintVersion();
+
+	enum TTestMode 
+		{
+		//run all the tests
+		EModeAll = 1<<0,
+		//run the specified tests in reverse order
+		EModeReverse = 1<<1,
+		//print out help
+		EModeHelp = 1<<2,
+		//print out help
+		EModeVersion = 1<<3
+		};
+
+	void RunTest(TInt aTestNumber);
+	void ParseCommandLineL(TUint32& aMode, RArray<TInt>& aTests);
+
+	TBool ProcessExists(const TDesC& aProcessName);
+
+private:
+
+	TFunctionData iTestArray[KMaxTests];
+#if defined(KERNEL_OOM_TESTING)
+	RKernelLowMemorySecuritySvrSession iServSession;
+#elif defined (USER_OOM_TESTING)
+	RUserLowMemorySecuritySvrSession iServSession;
+#else
+	Debug::RSecuritySvrSession iServSession;
+#endif
+	RThread	iDebugThread;
+	RProcess iDSSProcess;
+	RSemaphore iAddressGlobSem;
+	TThreadId iThreadID;
+	TFileName iFileName;
+	TUid iMySid;
+
+	// Performance data
+	TInt iMemoryReadKbytesPerSecond;	
+	TInt iMemoryWriteKbytesPerSecond;	
+	TInt iBreakpointsPerSecond;
+	TInt iMaxBreakpoints;
+	TInt iStepsPerSecond;
+
+	// Timing information
+	TInt iStartTick;
+	TInt iStopTick;
+	};
+
+#endif // RMDEBUG_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/rm_debug/basic_tests/t_rmdebug2_oemtoken.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,32 @@
+// Copyright (c) 2007-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:
+//
+
+/**
+ @file
+ @internalTechnology
+ @released
+*/
+
+#include <e32base.h>
+#include <e32base_private.h>
+
+GLDEF_C TInt E32Main()
+	{
+	// No need to do anything, the only requirement is that
+	// this executable can be loaded and runs to completion
+	return 0;
+	}
+
+// End of file - t_rmdebug2_oemtoken.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/rm_debug/common/t_target_launcher.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,217 @@
+// Copyright (c) 2007-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:
+// Helper app to launch debug targets. Uses command-line parameters as follows using a + sign:
+//  +n<number of applications to launch>
+//  +m<number of times to launch each application>
+//  +o<order of launch, 1 means launch in reverse order>
+//
+
+#include <e32base.h>
+#include <e32base_private.h>
+#include <e32cons.h>
+#include <e32test.h>
+#include <e32ldr.h>
+#include <e32cmn.h>
+#include <e32cmn_private.h>
+#include <f32dbg.h>
+#include <f32file.h>
+#include <hal.h>
+#include <u32hal.h>
+#include <e32property.h>
+
+#include "t_target_launcher.h"
+
+
+/**
+  Launch a process
+
+  @param aProcess The RProcess object to use to create the process
+  @param aExeName File name of the executable to create the process from
+  @param aCommandLine The command line to pass to the new process
+  @return KErrNone on success, or one of the other system wide error codes
+  */
+TInt LaunchProcess(RProcess& aProcess, TDesC & aExeName, TPtr & aCommandLine )
+    {
+
+    TPtrC commandLine( aCommandLine );
+
+    TInt err = aProcess.Create( aExeName, commandLine );
+
+    // check that there was no error raised
+    if(err != KErrNone)
+        {
+        return err;
+        }
+
+    TRequestStatus status = KRequestPending;
+    aProcess.Rendezvous(status);
+
+    if(KRequestPending != status.Int())
+        {
+        // startup failed so kill the process
+        RDebug::Printf( "> RProcess Rendezvous() failed with %d. Killing process", status.Int() );
+        aProcess.Kill(KErrNone);
+        return status.Int();
+        }
+    else
+        {
+        // start up succeeded so resume the process
+        aProcess.Resume();
+        User::WaitForRequest(status);
+        if(KErrNone != status.Int())
+            {
+            RDebug::Printf( "> RProcess Resume() failed with %d. Killing process", status.Int() );
+            aProcess.Kill(KErrNone);
+            }
+        return status.Int();
+        }
+    }
+
+/**
+ * Read command line parameters and control the launching of targets. 
+ * Create global launch semaphore KLaunchMutexName
+ */
+void MainL()
+    {
+
+    TInt numApps = KNumApps;
+    TInt numLaunches = KNumLaunches;
+    TInt launchControl = 0;
+
+    TInt argc = User::CommandLineLength();
+    HBufC* commandLine = NULL;
+    RDebug::Printf( ">Launcher Process() argc=%d", argc );
+
+    if( argc )
+        {
+        commandLine = HBufC::NewLC(argc);
+        TPtr commandLineBuffer = commandLine->Des();
+        User::CommandLine(commandLineBuffer);
+
+        RBuf printCommandLine;
+        CleanupClosePushL( printCommandLine );
+        printCommandLine.CreateL( commandLine->Des().Length() );
+        printCommandLine.Copy( commandLine->Des() );
+        printCommandLine.Collapse();
+        RDebug::Printf( ">command line = %S", &printCommandLine );
+        CleanupStack::PopAndDestroy( &printCommandLine );
+
+        // create a lexer and read through the command line
+        TLex lex(*commandLine);
+        while (!lex.Eos())
+            {
+            // only look for options with first character '+', other switches are for the targets
+            if (lex.Get() == '+')
+                {
+                TChar arg = lex.Get();
+                switch (arg)
+                    {
+                    case 'n':
+                        lex.Val( numApps );
+                        RDebug::Printf("parsed numApps as %d", numApps);
+                        break;
+                    case 'm':
+                        lex.Val( numLaunches );
+                        RDebug::Printf("parsed numLaunches as %d", numLaunches );
+                        break;
+                    case 'o':
+                        lex.Val( launchControl );
+                        RDebug::Printf("parsed launchControl as %d", launchControl);
+                        break;
+                    default:
+                        // unknown argument ignore it
+                        break;             
+                    }//switch
+                }// if +
+            }//while
+        }//if argc
+
+   RSemaphore launchMutex;
+   TInt ret = KErrNone;
+   CleanupClosePushL( launchMutex );
+   ret = launchMutex.CreateGlobal( KLaunchMutexName, 0 );
+   RDebug::Printf( ">Target Launcher : RSemaphore.CreateGlobal ret %d", ret);
+   User::LeaveIfError( ret );
+
+   ret = launchMutex.OpenGlobal( KLaunchMutexName );
+   RDebug::Printf( ">Target Launcher : RSemaphore.OpenGlobal ret %d", ret);
+   User::LeaveIfError( ret );
+
+   //Now launch the requested number of apps for the requested number of launches
+   for( ; numLaunches > 0; numLaunches-- )
+       { 
+       for( TInt launchIndex = numApps; launchIndex > 0; launchIndex-- )  
+           {
+           RDebug::Printf( ">Target Launcher:  Mutex wait app %d, launch %d", launchIndex, numLaunches );
+           launchMutex.Wait();
+
+           RBuf targetName;
+           CleanupClosePushL( targetName );
+           RDebug::Printf( ">Target Launcher:  targetName.Create %d, launch %d", launchIndex, numLaunches );
+           targetName.Create( KTargetExe().Length() + 2 );
+
+           if( launchControl == 1 )
+               {
+               // Reverse the order of the apps launched by reversing the index in the name
+               RDebug::Printf( ">Target Launcher:  targetName.Format %d, launch %d", numApps - launchIndex + 1, numLaunches );
+               targetName.Format( KTargetExe(), numApps - launchIndex + 1 );
+               }
+           else
+               {
+               RDebug::Printf( ">Target Launcher:  targetName.Format %d, launch %d", launchIndex, numLaunches );
+               targetName.Format( KTargetExe(), launchIndex );
+               }
+
+           RProcess aProc;
+           CleanupClosePushL( aProc ); 
+    
+           RDebug::Printf( ">Target Launcher: LaunchProcess %d, launch %d", launchIndex, numLaunches );
+           RDebug::Printf( ">LaunchProcess %lS", &targetName );
+           TPtr cmdLinePtr( commandLine->Des() );
+           ret = LaunchProcess( aProc, targetName, cmdLinePtr );
+           CleanupStack::PopAndDestroy( &aProc );
+
+           RDebug::Printf( "<Target Launcher: LaunchProcess returned %d", ret );
+           CleanupStack::PopAndDestroy( &targetName );
+
+           User::LeaveIfError( ret );
+
+           //By now the add proc event should have been delivered to the
+           //test app agent.
+           }
+       }
+
+    CleanupStack::PopAndDestroy( &launchMutex );
+
+    if( commandLine )
+       CleanupStack::PopAndDestroy( commandLine );
+ 
+    }
+
+
+GLDEF_C TInt E32Main()
+	{
+	RDebug::Printf( ">Launcher Process()" );
+
+	CTrapCleanup* trap = CTrapCleanup::New();
+	if (!trap)
+		return KErrNoMemory;
+
+	TRAPD(err, MainL());
+	RDebug::Printf( "< Target launching returned %d", err);
+	
+	delete trap;
+	
+	return err;
+	}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/rm_debug/common/t_target_launcher.h	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,47 @@
+// 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:
+// Definitions for target launcher
+// 
+//
+
+/**
+ @file
+ @internalTechnology
+ @released
+*/
+
+#ifndef RMDEBUG_TARGET_LAUNCHER_H
+#define RMDEBUG_TARGET_LAUNCHER_H
+
+// Controls how many times the target applications are launched
+const TInt KNumLaunches = 3;
+
+// Controls how many applications are attached and launched
+// If changing this, need to make sure there are enough apps
+// being built. see KTargetExe and t_rmdebug_app*
+const TInt KNumApps = 4;  
+
+_LIT(KLaunchMutexName, "t_rmdebug_launch_mutex");
+_LIT(KLaunchMutexNameSearchString, "t_rmdebug_launch_mutex*");
+_LIT(KTargetExe,"z:\\sys\\bin\\t_rmdebug_app%d.exe");
+_LIT8(KTargetExeName,"t_rmdebug_app%d.exe");
+_LIT(KProcessFinder,"*t_rmdebug_app%d*");
+_LIT(KTargetOptions,"-f%d");
+
+_LIT(KZSysBin,"z:\\sys\\bin\\");
+_LIT(KLauncherExe,"z:\\sys\\bin\\t_rmdebug_target_launcher.exe");
+
+_LIT_SECURITY_POLICY_PASS(KAllowAllPolicy);
+
+#endif // RMDEBUG_TARGET_LAUNCHER_H
--- a/kerneltest/e32test/rm_debug/d_demand_paging.cia	Tue Feb 02 01:24:03 2010 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,55 +0,0 @@
-// Copyright (c) 2007-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:
-//
-
-#include <u32std.h>
-
-// unused function that contains enough padding that the test function
-// RMDebugDemandPagingTest starts in a new page.
-__NAKED__ TInt RMDebugDemandPagingPaddingBefore()
-	{
-	asm("movs       r2,r0");
-	asm("adds       r0,r2,r1");
-	asm("bx         lr");
-	// add padding to make this function 4kb in size.
-	// The 4084 corresponds to 2^12 (=4096) - 12,
-	// the 12 being the total size of the movs, adds and bx instructions.
-	asm(".space     4084");
-	}
-
-// test function which is in a page by itself
-__NAKED__ TInt RMDebugDemandPagingTest()
-	{
-	asm("movs       r2,r0");
-	asm("adds       r0,r2,r1");
-	asm("bx         lr");
-	// add padding to make this function 4kb in size.
-	// The 4084 corresponds to 2^12 (=4096) - 12,
-	// the 12 being the total size of the movs, adds and bx instructions.
-	asm(".space     4084");
-	}
-
-// unused function that contains enough padding to ensure that no used code
-// is in the same page as RMDebugDemandPagingTest
-__NAKED__ TInt RMDebugDemandPagingPaddingAfter()
-	{
-	asm("movs       r2,r0");
-	asm("adds       r0,r2,r1");
-	asm("bx         lr");
-	// add padding to make this function 4kb in size.
-	// The 4084 corresponds to 2^12 (=4096) - 12,
-	// the 12 being the total size of the movs, adds and bx instructions.
-	asm(".space     4084");
-	}
-
--- a/kerneltest/e32test/rm_debug/d_demand_paging.h	Tue Feb 02 01:24:03 2010 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,22 +0,0 @@
-// Copyright (c) 2007-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:
-// Definitions of functions in d_demand_paging.cia
-//
-
-#ifndef D_DEMAND_PAGING_H
-#define D_DEMAND_PAGING_H
-
-TInt RMDebugDemandPagingTest();
-
-#endif // D_DEMAND_PAGING_H
--- a/kerneltest/e32test/rm_debug/d_rmdebug_step_test.h	Tue Feb 02 01:24:03 2010 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,80 +0,0 @@
-// Copyright (c) 2007-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:
-// Definitions of functions in d_rmdebug_step_tests.s
-//
-
-#ifndef D_RMDEBUG_STEP_TESTS_H
-#define D_RMDEBUG_STEP_TESTS_H
-
-extern "C"
-{
-	// ARM tests
-	unsigned int RMDebug_StepTest_Non_PC_Modifying(void);
-	unsigned int RMDebug_StepTest_Non_PC_Modifying_OK(void);
-	
-	unsigned int RMDebug_StepTest_Branch(void);
-	unsigned int RMDebug_StepTest_Branch_1(void);
-
-	unsigned int RMDebug_StepTest_Branch_And_Link(void);
-	unsigned int RMDebug_StepTest_Branch_And_Link_1(void);
-	unsigned int RMDebug_StepTest_Branch_And_Link_2(void);
-	
-	unsigned int RMDebug_StepTest_MOV_PC(void);
-	unsigned int RMDebug_StepTest_MOV_PC_1(void);
-	unsigned int RMDebug_StepTest_MOV_PC_2(void);
-	
-	unsigned int RMDebug_StepTest_LDR_PC(void);
-	unsigned int RMDebug_StepTest_LDR_PC_1(void);
-
-	// Thumb tests
-	unsigned int RMDebug_StepTest_Thumb_Non_PC_Modifying(void);
-	unsigned int RMDebug_StepTest_Thumb_Non_PC_Modifying_1(void);
-	unsigned int RMDebug_StepTest_Thumb_Non_PC_Modifying_2(void);
-
-	unsigned int RMDebug_StepTest_Thumb_Branch(void);
-	unsigned int RMDebug_StepTest_Thumb_Branch_1(void);
-	unsigned int RMDebug_StepTest_Thumb_Branch_2(void);
-	
-	unsigned int RMDebug_StepTest_Thumb_Branch_And_Link(void);
-	unsigned int RMDebug_StepTest_Thumb_Branch_And_Link_1(void);
-	unsigned int RMDebug_StepTest_Thumb_Branch_And_Link_2(void);
-	unsigned int RMDebug_StepTest_Thumb_Branch_And_Link_3(void);
-
-	unsigned int RMDebug_StepTest_Thumb_Back_Branch_And_Link(void);
-	unsigned int RMDebug_StepTest_Thumb_Back_Branch_And_Link_1(void);
-	unsigned int RMDebug_StepTest_Thumb_Back_Branch_And_Link_2(void);
-	unsigned int RMDebug_StepTest_Thumb_Back_Branch_And_Link_3(void);
-
-	unsigned int RMDebug_StepTest_Thumb_AddPC(void);
-	unsigned int RMDebug_StepTest_Thumb_AddPC_1(void);
-	unsigned int RMDebug_StepTest_Thumb_AddPC_2(void);
-	unsigned int RMDebug_StepTest_Thumb_AddPC_3(void);
-
-	// ARM<->Thumb interworking tests
-	unsigned int RMDebug_StepTest_Interwork(void);
-	unsigned int RMDebug_StepTest_Interwork_1(void);
-	unsigned int RMDebug_StepTest_Interwork_2(void);
-	unsigned int RMDebug_StepTest_Interwork_3(void);
-
-	// Stepping performance test
-	unsigned int RMDebug_StepTest_Count(void);
-	unsigned int RMDebug_StepTest_Count_1(void);
-	unsigned int RMDebug_StepTest_Count_2(void);
-
-	// Multiple step test
-	unsigned int RMDebug_StepTest_ARM_Step_Multiple(void);
-	unsigned int RMDebug_StepTest_ARM_Step_Multiple_1(void);
-
-}
-#endif // D_RMDEBUG_STEP_TESTS_H
--- a/kerneltest/e32test/rm_debug/d_rmdebug_step_test.s	Tue Feb 02 01:24:03 2010 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,266 +0,0 @@
-; Copyright (c) 2007-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:
-;
-
-        AREA |d-rmdebug-bkpt$$Code|, CODE, READONLY, ALIGN=6
-
-	CODE32
-
-	; ARM tests
-	
-; 
-; Non-PC modifying
-;
-	EXPORT RMDebug_StepTest_Non_PC_Modifying
-	EXPORT RMDebug_StepTest_Non_PC_Modifying_OK
- 
-RMDebug_StepTest_Non_PC_Modifying
-	mov		r0,r0		; nop
-RMDebug_StepTest_Non_PC_Modifying_OK
-	bx		lr			; should return to normal execution of the test thread
-
-;
-; Branch
-;
-	EXPORT RMDebug_StepTest_Branch
-	EXPORT RMDebug_StepTest_Branch_1
-
-RMDebug_StepTest_Branch
-	b		RMDebug_StepTest_Branch_1		
-	mov		r0, #2		; if the pc ends up here, we know its gone wrong
-RMDebug_StepTest_Branch_1
-	bx		lr			; return
-
-;
-; Branch and Link
-;
-	EXPORT RMDebug_StepTest_Branch_And_Link
-	EXPORT RMDebug_StepTest_Branch_And_Link_1
-	EXPORT RMDebug_StepTest_Branch_And_Link_2
-
-RMDebug_StepTest_Branch_And_Link		
-	mov		r0, lr		; preserve lr for the moment
-RMDebug_StepTest_Branch_And_Link_1
-	bl		RMDebug_StepTest_Branch_And_Link_2
-	mov		r1, #1		; insert a gap in the instruction stream so we know we branched.
-RMDebug_StepTest_Branch_And_Link_2
-	mov		lr, r0		; restore lr			
-	bx		lr			; should return to normal execution of the test thread
-
-;
-; MOV PC
-;
-	EXPORT RMDebug_StepTest_MOV_PC
-	EXPORT RMDebug_StepTest_MOV_PC_1
-	EXPORT RMDebug_StepTest_MOV_PC_2
-
-RMDebug_StepTest_MOV_PC
-	mov		r0, #4
-RMDebug_StepTest_MOV_PC_1
-	add		pc, pc, r0	; should be a jump (bear in mind reading pc = current inst + 8bytes for arm)
-	mov		r0, #1		; Simple instructions which allow us to test where the PC really is
-	mov		r0, #2		; just by reading r0.
-RMDebug_StepTest_MOV_PC_2
-	mov		r0, #3		; 
-	mov		r0, #4		; 
-	bx		lr			; should return to normal execution of the test thread
-
-; 
-; LDR PC
-;
-	EXPORT RMDebug_StepTest_LDR_PC
-	EXPORT RMDebug_StepTest_LDR_PC_1
-
-RMDebug_StepTest_LDR_PC
-	ldr		pc, =RMDebug_StepTest_LDR_PC_1
-	mov		r0, #1		;  separate the branch target so we can prove it works
-RMDebug_StepTest_LDR_PC_1
-	bx		lr			; should return to normal execution of the test thread
-	
-;
-; ARM -> Thumb -> ARM interworking test
-;
-; Note: We always start and finish this test
-; in ARM mode.
-	EXPORT RMDebug_StepTest_Interwork
-	EXPORT RMDebug_StepTest_Interwork_1
-	EXPORT RMDebug_StepTest_Interwork_2
-	EXPORT RMDebug_StepTest_Interwork_3	
-RMDebug_StepTest_Interwork
-	mov		r0, lr	; preserve lr
-RMDebug_StepTest_Interwork_1
-	blx		RMDebug_StepTest_Interwork_2
-
-	CODE16
-RMDebug_StepTest_Interwork_2
-	blx		RMDebug_StepTest_Interwork_3
-
-	CODE32
-
-RMDebug_StepTest_Interwork_3
-	bx		r0
-
-;
-; Stepping performance tests
-;
-; This counts down from 100000 to 0
-; This means that for all practical purposes
-; we can single-step as much as we like
-; in less than one second and have some likelyhood
-; that we will not step too far from our loop
-
-	EXPORT RMDebug_StepTest_Count
-	EXPORT RMDebug_StepTest_Count_1
-	EXPORT RMDebug_StepTest_Count_2
-
-RMDebug_StepTest_Count
-	ldr		r2, =100000
-RMDebug_StepTest_Count_1
-	subs	r2, r2, #1
-RMDebug_StepTest_Count_2
-	bne		RMDebug_StepTest_Count_1
-	bx		lr
-
-; Thumb tests
-
-; Thumb non-pc modifying
-;
-;
-RMDebug_StepTest_Thumb_Non_PC_Modifying
-	mov		r0, lr	; preserve lr
-	blx		RMDebug_StepTest_Thumb_Non_PC_Modifying_1
-	bx		r0
-
-;
-; Thumb Branch
-;
-RMDebug_StepTest_Thumb_Branch
-	mov		r0, lr	; preserve lr
-	blx		RMDebug_StepTest_Thumb_Branch_1
-	bx		r0		
-
-;
-; Thumb Branch and link
-;
-RMDebug_StepTest_Thumb_Branch_And_Link
-	mov		r0, lr	; preserve lr
-	blx		RMDebug_StepTest_Thumb_Branch_And_Link_1
-	bx		r0 
-
-;
-; Thumb Back Branch and link
-;
-RMDebug_StepTest_Thumb_Back_Branch_And_Link
-	mov		r0, lr	; preserve lr
-	blx		RMDebug_StepTest_Thumb_Back_Branch_And_Link_1
-	bx		r0 
-
-;
-; Thumb ADD PC,PC, #0
-;
-RMDebug_StepTest_Thumb_AddPC
-	mov		r0, lr	; preserve lr
-	blx		RMDebug_StepTest_Thumb_AddPC_1
-	bx		r0 
-
-	CODE16
-
-	; Thumb tests
-	EXPORT RMDebug_StepTest_Thumb_Non_PC_Modifying
-	EXPORT RMDebug_StepTest_Thumb_Non_PC_Modifying_1
-	EXPORT RMDebug_StepTest_Thumb_Non_PC_Modifying_2
-
-	EXPORT RMDebug_StepTest_Thumb_Branch
-	EXPORT RMDebug_StepTest_Thumb_Branch_1
-	EXPORT RMDebug_StepTest_Thumb_Branch_2
-
-	EXPORT RMDebug_StepTest_Thumb_Branch_And_Link
-	EXPORT RMDebug_StepTest_Thumb_Branch_And_Link_1
-	EXPORT RMDebug_StepTest_Thumb_Branch_And_Link_2
-	EXPORT RMDebug_StepTest_Thumb_Branch_And_Link_3
-
-	EXPORT RMDebug_StepTest_Thumb_Back_Branch_And_Link
-	EXPORT RMDebug_StepTest_Thumb_Back_Branch_And_Link_1
-	EXPORT RMDebug_StepTest_Thumb_Back_Branch_And_Link_2
-	EXPORT RMDebug_StepTest_Thumb_Back_Branch_And_Link_3
-
-RMDebug_StepTest_Thumb_Non_PC_Modifying_1
-	mov		r0, r0	; nop
-RMDebug_StepTest_Thumb_Non_PC_Modifying_2
-	bx		lr	
-
-RMDebug_StepTest_Thumb_Branch_1
-	b		RMDebug_StepTest_Thumb_Branch_2
-	mov		r0, r0
-RMDebug_StepTest_Thumb_Branch_2
-	bx		lr
-
-RMDebug_StepTest_Thumb_Branch_And_Link_1
-	mov		r1, lr
-RMDebug_StepTest_Thumb_Branch_And_Link_2
-	bl		RMDebug_StepTest_Thumb_Branch_And_Link_3
-	mov		r0, r0
-RMDebug_StepTest_Thumb_Branch_And_Link_3
-	bx		r1
-
-RMDebug_StepTest_Thumb_Back_Branch_And_Link_3
-	bx		r1
-
-RMDebug_StepTest_Thumb_Back_Branch_And_Link_1
-	mov		r1, lr
-RMDebug_StepTest_Thumb_Back_Branch_And_Link_2
-	bl		RMDebug_StepTest_Thumb_Back_Branch_And_Link_3
-	bx		r1
-
-;
-; ADD PC
-;
-	EXPORT RMDebug_StepTest_Thumb_AddPC
-	EXPORT RMDebug_StepTest_Thumb_AddPC_1
-	EXPORT RMDebug_StepTest_Thumb_AddPC_2
-	EXPORT RMDebug_StepTest_Thumb_AddPC_3
-
-RMDebug_StepTest_Thumb_AddPC_1
-	mov		r1, lr
-	mov		r2, #4
-RMDebug_StepTest_Thumb_AddPC_2
-	add		pc, pc, r2	; should arrive at RMDebug_StepTest_Thumb_AddPC_3
-	mov		r0, r0
-	mov		r0, r0
-	mov		r0, r0
-RMDebug_StepTest_Thumb_AddPC_3
-	bx		r1
-
-	ALIGN 4
-
-	CODE32
-
-;
-; ARM multiple-step ( 5 steps )
-;
-	EXPORT RMDebug_StepTest_ARM_Step_Multiple
-	EXPORT RMDebug_StepTest_ARM_Step_Multiple_1
-
-RMDebug_StepTest_ARM_Step_Multiple
-	mov		r0,r0		; nop
-	mov		r0,r0		; nop
-	mov		r0,r0		; nop
-	mov		r0,r0		; nop
-	mov		r0,r0		; nop
-RMDebug_StepTest_ARM_Step_Multiple_1
-	bx		lr
-
-	END
-
-; End of file - d_rmdebug_bkpt.s
--- a/kerneltest/e32test/rm_debug/d_rmdebug_step_test_armv4.h	Tue Feb 02 01:24:03 2010 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,50 +0,0 @@
-// Copyright (c) 2007-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:
-// Definitions of functions in d_rmdebug_step_tests_armv4.s
-//
-
-#ifndef D_RMDEBUG_STEP_TESTS_H
-#define D_RMDEBUG_STEP_TESTS_H
-
-extern "C"
-{
-	// ARM tests
-	unsigned int RMDebug_StepTest_Non_PC_Modifying(void);
-	unsigned int RMDebug_StepTest_Non_PC_Modifying_OK(void);
-	
-	unsigned int RMDebug_StepTest_Branch(void);
-	unsigned int RMDebug_StepTest_Branch_1(void);
-
-	unsigned int RMDebug_StepTest_Branch_And_Link(void);
-	unsigned int RMDebug_StepTest_Branch_And_Link_1(void);
-	unsigned int RMDebug_StepTest_Branch_And_Link_2(void);
-	
-	unsigned int RMDebug_StepTest_MOV_PC(void);
-	unsigned int RMDebug_StepTest_MOV_PC_1(void);
-	unsigned int RMDebug_StepTest_MOV_PC_2(void);
-	
-	unsigned int RMDebug_StepTest_LDR_PC(void);
-	unsigned int RMDebug_StepTest_LDR_PC_1(void);
-
-	// Stepping performance test
-	unsigned int RMDebug_StepTest_Count(void);
-	unsigned int RMDebug_StepTest_Count_1(void);
-	unsigned int RMDebug_StepTest_Count_2(void);
-
-	// Multiple step test
-	unsigned int RMDebug_StepTest_ARM_Step_Multiple(void);
-	unsigned int RMDebug_StepTest_ARM_Step_Multiple_1(void);
-
-}
-#endif // D_RMDEBUG_STEP_TESTS_H
--- a/kerneltest/e32test/rm_debug/d_rmdebug_step_test_armv4.s	Tue Feb 02 01:24:03 2010 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,129 +0,0 @@
-; Copyright (c) 2007-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:
-;
-
-        AREA |d-rmdebug-bkpt$$Code|, CODE, READONLY, ALIGN=6
-
-	CODE32
-
-	; ARM tests
-	
-; 
-; Non-PC modifying
-;
-	EXPORT RMDebug_StepTest_Non_PC_Modifying
-	EXPORT RMDebug_StepTest_Non_PC_Modifying_OK
- 
-RMDebug_StepTest_Non_PC_Modifying
-	mov		r0,r0		; nop
-RMDebug_StepTest_Non_PC_Modifying_OK
-	bx		lr			; should return to normal execution of the test thread
-
-;
-; Branch
-;
-	EXPORT RMDebug_StepTest_Branch
-	EXPORT RMDebug_StepTest_Branch_1
-
-RMDebug_StepTest_Branch
-	b		RMDebug_StepTest_Branch_1		
-	mov		r0, #2		; if the pc ends up here, we know its gone wrong
-RMDebug_StepTest_Branch_1
-	bx		lr			; return
-
-;
-; Branch and Link
-;
-	EXPORT RMDebug_StepTest_Branch_And_Link
-	EXPORT RMDebug_StepTest_Branch_And_Link_1
-	EXPORT RMDebug_StepTest_Branch_And_Link_2
-
-RMDebug_StepTest_Branch_And_Link		
-	mov		r0, lr		; preserve lr for the moment
-RMDebug_StepTest_Branch_And_Link_1
-	bl		RMDebug_StepTest_Branch_And_Link_2
-	mov		r1, #1		; insert a gap in the instruction stream so we know we branched.
-RMDebug_StepTest_Branch_And_Link_2
-	mov		lr, r0		; restore lr			
-	bx		lr			; should return to normal execution of the test thread
-
-;
-; MOV PC
-;
-	EXPORT RMDebug_StepTest_MOV_PC
-	EXPORT RMDebug_StepTest_MOV_PC_1
-	EXPORT RMDebug_StepTest_MOV_PC_2
-
-RMDebug_StepTest_MOV_PC
-	mov		r0, #4
-RMDebug_StepTest_MOV_PC_1
-	add		pc, pc, r0	; should be a jump (bear in mind reading pc = current inst + 8bytes for arm)
-	mov		r0, #1		; Simple instructions which allow us to test where the PC really is
-	mov		r0, #2		; just by reading r0.
-RMDebug_StepTest_MOV_PC_2
-	mov		r0, #3		; 
-	mov		r0, #4		; 
-	bx		lr			; should return to normal execution of the test thread
-
-; 
-; LDR PC
-;
-	EXPORT RMDebug_StepTest_LDR_PC
-	EXPORT RMDebug_StepTest_LDR_PC_1
-
-RMDebug_StepTest_LDR_PC
-	ldr		pc, =RMDebug_StepTest_LDR_PC_1
-	mov		r0, #1		;  separate the branch target so we can prove it works
-RMDebug_StepTest_LDR_PC_1
-	bx		lr			; should return to normal execution of the test thread
-	
-;
-; Stepping performance tests
-;
-; This counts down from 100000 to 0
-; This means that for all practical purposes
-; we can single-step as much as we like
-; in less than one second and have some likelyhood
-; that we will not step too far from our loop
-
-	EXPORT RMDebug_StepTest_Count
-	EXPORT RMDebug_StepTest_Count_1
-	EXPORT RMDebug_StepTest_Count_2
-
-RMDebug_StepTest_Count
-	ldr		r2, =100000
-RMDebug_StepTest_Count_1
-	subs	r2, r2, #1
-RMDebug_StepTest_Count_2
-	bne		RMDebug_StepTest_Count_1
-	bx		lr
-
-;
-; ARM multiple-step ( 5 steps )
-;
-	EXPORT RMDebug_StepTest_ARM_Step_Multiple
-	EXPORT RMDebug_StepTest_ARM_Step_Multiple_1
-
-RMDebug_StepTest_ARM_Step_Multiple
-	mov		r0,r0		; nop
-	mov		r0,r0		; nop
-	mov		r0,r0		; nop
-	mov		r0,r0		; nop
-	mov		r0,r0		; nop
-RMDebug_StepTest_ARM_Step_Multiple_1
-	bx		lr
-
-	END
-
-; End of file - d_rmdebug_step_test_armv4.s
--- a/kerneltest/e32test/rm_debug/d_rmdebugclient.h	Tue Feb 02 01:24:03 2010 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,100 +0,0 @@
-// Copyright (c) 2006-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:
-// t_rmdebugclient.h
-// Definitions for the run mode debug agent client side sessions.
-// 
-//
-
-#ifndef RMDEBUGCLIENT_H
-#define RMDEBUGCLIENT_H
-
-class TProcessInfo
-	{
-	public:
-		TUint           iProcessID;
-		TInt            iAttributes;
-		TUint32         iPriority;
-		TBuf<KMaxName> 	iName;    
-	};
-
-class TThreadInfo
-	{
-	public:
-		TUint           iThreadID;
-		TUint8          iPriority;
-		TUint8          iThreadType;
-		TBuf<KMaxName>  iName;
-		TUint           iOwningProcessID;
-
-	// Probably would want a state element here, under debug control, stopped etc
-	// such that additional information could be provided which was only valid for
-	// stopped threads.
-
-	};
-
-class TExecReq
-	{
-	public:
-		TUint32 iRequest;       // Step, Step into, step threads
-		TUint32 iStartAddress;
-		TUint32 iStopAddress;
-
-	};
-
-class TMemoryInfo
-	{
-	public:
-		TUint32 iAddress;
-		TUint32	iSize;
-		TPtr8*	iDataPtr;
-	};
-
-
-// Client Side session
-class RDebugServSession : public RSessionBase
-	{
-	public:
-		RDebugServSession();
-		TVersion Version() const;
-
-		TInt Open();
-		TInt Close();
-
-		TInt ReadMemory(const TUint32 aThreadId, TMemoryInfo* aInfo);
-		TInt WriteMemory(const TUint32 aThreadId, TMemoryInfo* aInfo);
-
-//		TInt ReadThreadInfo(const TInt aIndex, const TInt aOwningProc, TThreadInfo* aInfo);
-//		TInt ReadProcessInfo(const TInt aIndex, TProcessInfo* aInfo);
-		TInt SuspendThread(const TInt ThreadID);
-		TInt ResumeThread(const TInt ThreadID);
-
-	private:
-		RThread iServerThread;       
-	};
-
-// Function codes (opcodes) used in message passing between client and server
-enum TDebugServRqst
-	{
-	EDebugServOpen = 1,
-	EDebugServClose,
-
-	EDebugServSuspendThread,
-	EDebugServResumeThread,
-//	EDebugServReadProcessInfo,
-//	EDebugServReadThreadInfo,
-	EDebugServReadMemory,
-	EDebugServWriteMemory,
-	};
-
-#endif // RMDEBUGCLIENT_H
--- a/kerneltest/e32test/rm_debug/d_rmdebugserver.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,453 +0,0 @@
-// Copyright (c) 2006-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:
-// Provides the debug agent server implementation.
-// 
-//
-
-#include <e32base.h>
-#include <e32base_private.h>
-#include <e32cons.h>
-#include <trkkerneldriver.h>
-#include "d_rmdebugserver.h"
-#include "d_rmdebugclient.h"
-#include "t_rmdebug.h"
-
-
-CDebugServServer::CDebugServServer(CActive::TPriority aActiveObjectPriority)
-   : CServer2(aActiveObjectPriority)
-//
-// Server constructor
-//
-	{
-	}
-
-CSession2* CDebugServServer::NewSessionL(const TVersion& /*aVersion*/, const RMessage2& /*aMessage*/) const
-//
-// Session constructor
-//
-	{
-	// make sure the kernel side device driver is not already loaded
-   TInt err;
-	err = User::LoadLogicalDevice(KDebugDriverFileName);
-	if ((KErrNone == err) || (KErrAlreadyExists == err))
-       {
-       return new(ELeave) CDebugServSession();
-       }
-   else
-       {
-       return (NULL);
-       }
-	}   
-
-CDebugServSession::CDebugServSession()
-// Session implementation
-	{
-   TInt err;
-	TMetroTrkDriverInfo info;
-   info.iUserLibraryEnd = 0;
-   err = iKernelDriver.Open(info);
-   if (KErrNone != err)
-		{
- 		User::Leave(err);
-		}          
-	}
-
-CDebugServSession::~CDebugServSession()
-//
-// Session destructor
-//
-	{
-	// stop the kernel side driver
-	iKernelDriver.Close();
-
-	User::FreeLogicalDevice(KDebugDriverName);
-	}
-
-
-void CDebugServSession::ServiceL(const RMessage2& aMessage)
-//
-// Session service handler
-//
-	{
-	TInt res = KErrNone;
-
-	switch(aMessage.Function())
-		{
-		case EDebugServResumeThread:
-			res = ResumeThread(aMessage);
-			break;
-
-		case EDebugServSuspendThread:
-			res = SuspendThread(aMessage);
-			break;          
-
-//		case EDebugServReadProcessInfo:
-//			res = ReadProcessInfo(aMessage);
-//			break;        
-//
-//		case EDebugServReadThreadInfo:
-//			res = ReadThreadInfo(aMessage);
-//			break;
-
-		case EDebugServReadMemory:
-			res = ReadMemory(aMessage);
-			break;        
-
-		case EDebugServWriteMemory:
-			res = WriteMemory(aMessage);
-			break;        
-
-		default:
-			User::Leave(KErrNotSupported);
-			break;
-		}
-
-	aMessage.Complete(res);
-	}
-
-
-
-TInt CDebugServSession::SuspendThread(const RMessage2& aMessage)
-//
-// Session suspend thread
-//
-	{
-	TInt err;
-
-	err = iKernelDriver.SuspendThread(aMessage.Int0());
-
-	return err;
-	}
-
-TInt CDebugServSession::ResumeThread(const RMessage2& aMessage)
-//
-// Server resume thread
-//
-	{
-	TInt err;
-
-	err = iKernelDriver.ResumeThread(aMessage.Int0());
-
-	return err;
-	}
-
-//TInt CDebugServSession::ReadProcessInfo(const RMessage2& aMessage)
-////
-//// Server read process information
-////
-//	{
-//	TInt err;
-//	TProcessInfo procinfo;
-//	TMetroTrkTaskInfo processInfo(0);
-//
-//	err = iKernelDriver.GetProcessInfo(aMessage.Int0(), processInfo);
-//
-//	if (KErrNone == err)
-//		{
-//		procinfo.iProcessID = processInfo.iId;
-//		procinfo.iPriority = processInfo.iPriority;
-//		procinfo.iName.Copy(processInfo.iName);
-//
-//		TPckgBuf<TProcessInfo> p(procinfo);
-//		aMessage.WriteL(1,p);        
-//		}
-//
-//	return err;
-//	}
-//
-//TInt CDebugServSession::ReadThreadInfo(const RMessage2& aMessage)
-////
-//// Server read thread information
-////
-//	{
-//	TInt err;
-//	TThreadInfo thrdinfo;
-//	TMetroTrkTaskInfo threadInfo(aMessage.Int1()); // Sets OtherID to the second input parameter in aMessage
-//
-//	// aMessage.Int0 is the index into the thread list for the process
-//	err = iKernelDriver.GetThreadInfo(aMessage.Int0(), threadInfo);	   
-//
-//	if (KErrNone == err)
-//		{
-//		thrdinfo.iThreadID = threadInfo.iId;
-//		thrdinfo.iPriority = threadInfo.iPriority;
-//		thrdinfo.iName.Copy(threadInfo.iName);
-//		thrdinfo.iOwningProcessID = threadInfo.iOtherId;
-//
-//		TPckgBuf<TThreadInfo> p(thrdinfo);
-//
-//		// Write out the results to the third argument passed in (pointer to the threadinfo structure)
-//		aMessage.WriteL(2,p);           
-//		}
-//
-//	return err;
-//	}
-
-TInt CDebugServSession::ReadMemory(const RMessage2& aMessage)
-//
-// Server read process memory
-//
-	{   
-	TInt err;
-	TUint32 threadId = aMessage.Int0();
-	TPckgBuf<TMemoryInfo> pckg = *(TPckgBuf<TMemoryInfo> *)(aMessage.Ptr1());
-	TMemoryInfo* InputMemoryInfo = &pckg();
-
-	TPtr8 *ptrtst = InputMemoryInfo->iDataPtr;
-
-	err = iKernelDriver.ReadMemory(threadId, InputMemoryInfo->iAddress, InputMemoryInfo->iSize, *ptrtst);
-
-	return err;
-	}
-
-TInt CDebugServSession::WriteMemory(const RMessage2& aMessage)
-//
-// Server write process memory
-//
-	{
-	TInt err;
-	TUint32 threadId = aMessage.Int0();
-	TPckgBuf<TMemoryInfo> pckg = *(TPckgBuf<TMemoryInfo> *)(aMessage.Ptr1());
-	TMemoryInfo* InputMemoryInfo = &pckg();
-
-	TPtr8 *ptrtst = InputMemoryInfo->iDataPtr;
-
-	err = iKernelDriver.WriteMemory(threadId, InputMemoryInfo->iAddress, InputMemoryInfo->iSize, *ptrtst);
-
-	return err;
-	}
-
-
-GLDEF_C TInt CDebugServServer::ThreadFunction(TAny*)
-//
-// Server thread function, continues until active scheduler stops
-//
-	{
-	CTrapCleanup* cleanup=CTrapCleanup::New();
-	if (cleanup == NULL)
-		{
-		User::Leave(KErrNoMemory);
-		}
-
-	CActiveScheduler *pA=new CActiveScheduler;
-	CDebugServServer *pS=new CDebugServServer(EPriorityStandard);
-
-	CActiveScheduler::Install(pA);
-
-	TInt err = pS->Start(KDebugServerName);
-	if (err != KErrNone)
-		{
-		User::Leave(KErrNone);
-		}
-
-	RThread::Rendezvous(KErrNone);
-
-	CActiveScheduler::Start();
-
-	delete pS;
-	delete pA;
-	delete cleanup;
-
-	return (KErrNone);
-	}
-
-
-
-EXPORT_C TInt StartThread(RThread& aServerThread)
-//
-// Start the server thread
-//
-	{
-	TInt res=KErrNone;
-
-	TFindServer finddebugserver(KDebugServerName);
-	TFullName name;
-
-	if (finddebugserver.Next(name) != KErrNone)
-		{
-		res = aServerThread.Create( KDebugServerName,
-									CDebugServServer::ThreadFunction,
-									KDefaultStackSize,
-									KDefaultHeapSize,
-									KDefaultHeapSize,
-									NULL
-									);
-
-		if (res == KErrNone)
-			{
-			TRequestStatus rendezvousStatus;
-
-			aServerThread.SetPriority(EPriorityNormal);
-			aServerThread.Rendezvous(rendezvousStatus);
-			aServerThread.Resume();
-			User::WaitForRequest(rendezvousStatus);
-			}                                 
-		else
-			{
-			aServerThread.Close();
-			}
-		}
-
-	return res;
-	}
-
-
-
-RDebugServSession::RDebugServSession()
-//
-// Server session constructor
-//
-	{
-	}
-
-TInt RDebugServSession::Open()
-//
-// Session open
-//
-	{
-	TInt r = StartThread(iServerThread);
-	if (r == KErrNone)
-		{
-		r=CreateSession(KDebugServerName, Version(), KDefaultMessageSlots);
-		}
-
-	return r;
-	}
-
-
-TVersion RDebugServSession::Version(void) const
-//
-// Session version
-//
-	{
-	return (TVersion(KDebugServMajorVersionNumber, KDebugServMinorVersionNumber, KDebugServBuildVersionNumber));
-	}
-
-TInt RDebugServSession::SuspendThread(const TInt aThreadID)
-//
-// Session suspend thread request
-//
-	{
-	TIpcArgs args(aThreadID);
-	TInt res;
-	res = SendReceive(EDebugServSuspendThread, args);
-
-	return res;
-	}
-
-TInt RDebugServSession::ResumeThread(const TInt aThreadID)
-//
-// Session resume thread request
-//
-	{
-	TIpcArgs args(aThreadID);
-	TInt res;
-	res = SendReceive(EDebugServResumeThread, args);
-
-	return res;
-	}
-
-
-//TInt RDebugServSession::ReadProcessInfo(const TInt aIndex, TProcessInfo* aInfo)
-////
-//// Session read process information request
-////
-//	{
-//	TPckgBuf<TProcessInfo> pckg;
-//	pckg = *aInfo;
-//
-//	TIpcArgs args(aIndex, &pckg);
-//
-//	TInt res;
-//
-//	res = SendReceive(EDebugServReadProcessInfo, args);
-//
-//	*aInfo = pckg();
-//
-//	return res;
-//
-//	}
-//
-//TInt RDebugServSession::ReadThreadInfo(const TInt aIndex, const TInt aProc, TThreadInfo* aInfo)
-////
-//// Session read thread information request
-////
-//	{
-//	TPckgBuf<TThreadInfo> pckg;
-//	pckg = *aInfo;
-//
-//	TIpcArgs args(aIndex, aProc, &pckg);
-//
-//	TInt res;
-//
-//	res = SendReceive(EDebugServReadThreadInfo, args);
-//
-//	*aInfo = pckg();
-//
-//	return res;
-//
-//	}
-
-
-TInt RDebugServSession::ReadMemory(const TUint32 aThreadID, TMemoryInfo* aInfo)
-//
-// Session read thread memory request
-//
-	{
-	TPckgBuf<TMemoryInfo> pckg;
-	pckg = *aInfo;
-
-	TIpcArgs args(aThreadID, &pckg);
-
-	TInt res;
-
-	res = SendReceive(EDebugServReadMemory, args);
-
-	*aInfo = pckg();
-
-	return res;
-
-	}
-
-
-TInt RDebugServSession::WriteMemory(const TUint32 aThreadID, TMemoryInfo* aInfo)
-//
-// Session write thread memory request
-//
-	{
-	TPckgBuf<TMemoryInfo> pckg;
-	pckg = *aInfo;
-
-	TIpcArgs args(aThreadID, &pckg);
-
-	TInt res;
-
-	res = SendReceive(EDebugServWriteMemory, args);
-
-	return res;
-	}
-
-
-
-TInt RDebugServSession::Close()
-//
-// Session close the session and thread
-//
-	{
-	RSessionBase::Close();
-	iServerThread.Close();
-
-	return KErrNone;
-	}
-
--- a/kerneltest/e32test/rm_debug/d_rmdebugserver.h	Tue Feb 02 01:24:03 2010 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,73 +0,0 @@
-// Copyright (c) 2006-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:
-// t_rmdebugserver.h
-// Definitions for the run mode debug agent server side session.
-// 
-//
-
-#ifndef RMDEBUGSVR_H
-#define RMDEBUGSVR_H
-
-// Server name
-_LIT(KDebugServerName,"DebugServer");
-_LIT(KDebugDriverName,"MetroTrk Driver");
-_LIT(KDebugDriverFileName,"trkdriver.ldd");
-
-// A version must be specifyed when creating a session with the server
-const TUint KDebugServMajorVersionNumber=0;
-const TUint KDebugServMinorVersionNumber=1;
-const TUint KDebugServBuildVersionNumber=1;
-const TUint KDefaultMessageSlots=4;
-const TUint KDefaultHeapSize=0x10000;
-
-class CDebugServSession;
-
-
-// Server
-class CDebugServServer : public CServer2
-	{
-	public:
-		CSession2* NewSessionL(const TVersion& aVersion, const RMessage2& aMessage) const;
-	public:
-		static TInt ThreadFunction(TAny* aStarted);
-	protected:
-		CDebugServServer(CActive::TPriority aActiveObjectPriority);
-	};
-
-// Server side session
-class CDebugServSession : public CSession2
-	{
-	public:
-		CDebugServSession();
-		~CDebugServSession();
-		void ConstructL ( void );
-		void ServiceL(const RMessage2& aMessage);
-
-		TInt ReadMemory(const RMessage2& aMessage);
-		TInt WriteMemory(const RMessage2& aMessage);
-
-//		TInt ReadProcessInfo(const RMessage2& aMessage);
-//		TInt ReadThreadInfo(const RMessage2& aMessage);
-
-		TInt ResumeThread(const RMessage2& aMessage);
-		TInt SuspendThread(const RMessage2& aMessage);
-
-	public:
-		RMetroTrkDriver iKernelDriver;	
-
-	private:
-	};
-
-
-#endif // RMDEBUGSVR_H
--- a/kerneltest/e32test/rm_debug/d_rmdebugthread.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,106 +0,0 @@
-// Copyright (c) 2006-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:
-// Implements a debug thread for testing.
-// 
-//
-
-#include <e32base.h>
-#include <e32base_private.h>
-#include <e32cons.h>
-#include "d_rmdebugthread.h"
-
-EXPORT_C TBuf8<SYMBIAN_RMDBG_MEMORYSIZE> gMemoryAccessBytes;
-extern void RMDebug_BranchTst1();
-
-EXPORT_C TInt TestData;
-
-CDebugServThread::CDebugServThread()
-//
-// Empty constructor
-//
-	{
-	}
-
-GLDEF_C TInt CDebugServThread::ThreadFunction(TAny*)
-//
-// Generic thread function for testing
-//
-	{
-	CTrapCleanup* cleanup=CTrapCleanup::New();
-	if (cleanup == NULL)
-		{
-		User::Leave(KErrNoMemory);
-		}
-
-	RThread::Rendezvous(KErrNone);
-
-	TestData = 1;
-
-	while(1)
-		{
-		RMDebug_BranchTst1();
-
-		TestData++;                   
-
-		// Wait half a second (suspends this thread)
-		User::After(500000);
-
-		if (TestData == 0xFFFFFFFF)
-			{
-			break;
-			}
-		}
-
-	delete cleanup;
-
-	return (KErrNone);
-	}
-
-EXPORT_C TInt StartDebugThread(RThread& aDebugThread)
-//
-// Starts the test thread
-//
-{
-	TInt res=KErrNone;
-
-	// Create the thread
-	res = aDebugThread.Create(	KDebugThreadName,
-								CDebugServThread::ThreadFunction,
-								KDefaultStackSize,
-								KDebugThreadDefaultHeapSize,
-								KDebugThreadDefaultHeapSize,
-								NULL
-								);
-
-	// Check that the creation worked
-	if (res == KErrNone)
-		{
-		TRequestStatus rendezvousStatus;
-
-		aDebugThread.SetPriority(EPriorityNormal);
-		// Make a request for a rendezvous
-		aDebugThread.Rendezvous(rendezvousStatus);
-		// Set the thread as ready for execution
-		aDebugThread.Resume();
-		// Wait for the resumption
-		User::WaitForRequest(rendezvousStatus);
-		}                                 
-	else
-		{
-		// Close the handle.
-		aDebugThread.Close();
-		}
-
-	return res;
-	}
--- a/kerneltest/e32test/rm_debug/d_rmdebugthread.h	Tue Feb 02 01:24:03 2010 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,38 +0,0 @@
-// Copyright (c) 2006-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:
-// t_rmdebugthread.h
-// Definitions for the run mode debug test thread.
-// 
-//
-
-#ifndef RMDEBUGSVRTHRD_H
-#define RMDEBUGSVRTHRD_H
-
-#define SYMBIAN_RMDBG_MEMORYSIZE    1024*4
-
-// Thread name
-_LIT(KDebugThreadName,"DebugThread");
-
-const TUint KDebugThreadDefaultHeapSize=0x10000;
-
-class CDebugServThread : public CBase
-	{
-	public:
-		CDebugServThread();
-		static TInt ThreadFunction(TAny* aStarted);    
-
-	public:
-	};
-
-#endif // RMDEBUGSVRTHRD_H
--- a/kerneltest/e32test/rm_debug/d_rmdebugthread2.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,205 +0,0 @@
-// Copyright (c) 2006-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:
-// Implements a debug thread for testing.
-// 
-//
-
-#include <e32base.h>
-#include <e32base_private.h>
-#include <e32cons.h>
-#include <e32debug.h>
-#include "d_rmdebugthread2.h"
-
-#include "d_rmdebug_step_test.h"
-#include "d_demand_paging.h"
-
-EXPORT_C TBuf8<SYMBIAN_RMDBG_MEMORYSIZE> gMemoryAccessBytes;
-IMPORT_C extern void RMDebug_BranchTst1();
-IMPORT_C extern TInt RMDebugDemandPagingTest();
-
-EXPORT_C TInt TestData;
-EXPORT_C TTestFunction FunctionChooser;
-
-const TInt NUMBER_TRACE_CALLS = 200;
-
-EXPORT_C TInt TestFunction()
-	{
-	//set TestData to an arbitrary value which we check for in t_rmdebug 
-	TestData = 0xffeeddcc;
-
-	User::After(3000000);	// pause three seconds.
-
-	return 0;
-	}
-
-/**
-  Wrapper around RMDebugDemandPagingTest, need to pause for a short time to
-  allow time in t_rmdebug.cpp to issue a User::WaitForRequest to catch the break point
-  */
-EXPORT_C void TestPagedCode()
-	{
-	User::After(100000);
-
-	// call the function in paged code
-	RMDebugDemandPagingTest();
-	}
-
-EXPORT_C void TestMultipleTraceCalls()
-	{
-	//arbitrary function to set a BP on
-	RMDebug_BranchTst1();
-	
-	for(TInt cnt = NUMBER_TRACE_CALLS; cnt>0; cnt--)
-		{
-		RDebug::Printf("Trace event");
-		}
-	
-	//another arbitrary function to set a BP on
-	RMDebug_StepTest_Non_PC_Modifying();
-	}
-
-CDebugServThread::CDebugServThread()
-//
-// Empty constructor
-//
-	{
-	}
-
-GLDEF_C TInt CDebugServThread::ThreadFunction(TAny*)
-//
-// Generic thread function for testing
-//
-	{
-	// set FunctionChooser to run the default function
-	FunctionChooser = EDefaultFunction;
-
-	CTrapCleanup* cleanup=CTrapCleanup::New();
-	if (cleanup == NULL)
-		{
-		User::Leave(KErrNoMemory);
-		}
-
-	RThread::Rendezvous(KErrNone);
-
-	TestData = 1;
-
-	while(TestData != 0xFFFFFFFF)
-		{
-		switch(FunctionChooser)
-			{
-			case EDemandPagingFunction:
-				TestPagedCode();
-				break;
-			case EDefaultFunction:
-				// the default function is the stepping test functions
-			case EStepFunction:
-				{
-				RMDebug_BranchTst1();
-
-				// Single stepping test support code
-
-				// ARM tests
-				RMDebug_StepTest_Non_PC_Modifying();
-
-				RMDebug_StepTest_Branch();
-
-				RMDebug_StepTest_Branch_And_Link();
-
-				RMDebug_StepTest_MOV_PC();
-
-				RMDebug_StepTest_LDR_PC();
- 
-// thumb/interworking tests not supported on armv4
-#ifdef __MARM_ARMV5__
-
-				// Thumb tests
-				RMDebug_StepTest_Thumb_Non_PC_Modifying();
-
-				RMDebug_StepTest_Thumb_Branch();
-
-				RMDebug_StepTest_Thumb_Branch_And_Link();
-
-				RMDebug_StepTest_Thumb_Back_Branch_And_Link();
-
-				// ARM <-> Thumb interworking tests
-				RMDebug_StepTest_Interwork();
-
-				RMDebug_StepTest_Thumb_AddPC();
-
-#endif	// __MARM_ARMV5__
-				
-				// Single-stepping performance
-				RMDebug_StepTest_Count();
-
-				// multiple step test
-				RMDebug_StepTest_ARM_Step_Multiple();
-
-				TestData++;
-
-				// Wait 50mSecs. // (suspends this thread)
-				User::After(50000);
-
-				break;
-				}
-			case EMultipleTraceCalls:
-				TestMultipleTraceCalls();
-				break;
-			default:
-				//do nothing
-				break;
-			}
-		}
-
-	delete cleanup;
-
-	return (KErrNone);
-	}
-
-EXPORT_C TInt StartDebugThread(RThread& aDebugThread, const TDesC& aDebugThreadName)
-//
-// Starts a test thread
-//
-{
-	TInt res=KErrNone;
-
-	// Create the thread
-	res = aDebugThread.Create(	aDebugThreadName,
-								CDebugServThread::ThreadFunction,
-								KDefaultStackSize,
-								KDebugThreadDefaultHeapSize,
-								KDebugThreadDefaultHeapSize,
-								NULL
-								);
-
-	// Check that the creation worked
-	if (res == KErrNone)
-		{
-		TRequestStatus rendezvousStatus;
-
-		aDebugThread.SetPriority(EPriorityNormal);
-		// Make a request for a rendezvous
-		aDebugThread.Rendezvous(rendezvousStatus);
-		// Set the thread as ready for execution
-		aDebugThread.Resume();
-		// Wait for the resumption
-		User::WaitForRequest(rendezvousStatus);
-		}                                 
-	else
-		{
-		// Close the handle.
-		aDebugThread.Close();
-		}
-
-	return res;
-	}
--- a/kerneltest/e32test/rm_debug/d_rmdebugthread2.h	Tue Feb 02 01:24:03 2010 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,50 +0,0 @@
-// Copyright (c) 2006-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:
-// Definitions for the run mode debug test thread.
-// 
-//
-
-#ifndef RMDEBUGSVRTHRD_H
-#define RMDEBUGSVRTHRD_H
-
-#define SYMBIAN_RMDBG_MEMORYSIZE    1024*4
-
-// Thread name
-_LIT(KDebugThreadName,"DebugThread");
-
-const TUint KDebugThreadDefaultHeapSize=0x10000;
-
-// enumeration of functions which the target debug thread can call, the
-// debugger can choose to switch the thread to a different function by
-// writing the appropriate enumeration value into FunctionChooser, the
-// target thread will finish executing the function it is currently running
-// then execute the chosen function.
-enum TTestFunction
-	{
-	EDefaultFunction = 0,
-	EStepFunction = 1,
-	EDemandPagingFunction = 2,
-	EMultipleTraceCalls = 3,
-	};
-
-class CDebugServThread : public CBase
-	{
-	public:
-		CDebugServThread();
-		static TInt ThreadFunction(TAny* aStarted);    
-
-	public:
-	};
-
-#endif // RMDEBUGSVRTHRD_H
--- a/kerneltest/e32test/rm_debug/d_rmdebugthreadasm.cia	Tue Feb 02 01:24:03 2010 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,32 +0,0 @@
-// Copyright (c) 2006-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:
-// d_rmdebugthreadasm.h
-// Assembler file for debug thread testing.
-// 
-//
-
-//#include <e32cia.h>
-//#include <e32base.h>
-//#include <e32cons.h>
-//#include "d_rmdebugthread.h"
-
-EXPORT_C __NAKED__ void RMDebug_BranchTst1( void )
-//
-// 
-//
-{
-	asm("mov r0, #0 ");			// aResult==KErrNone
-	asm("bx  lr ");             // Return
-}
-
--- a/kerneltest/e32test/rm_debug/d_rmdebugthreadasm2.cia	Tue Feb 02 01:24:03 2010 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,35 +0,0 @@
-// Copyright (c) 2006-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:
-// d_rmdebugthreadasm2.h
-// Assembler file for debug thread testing.
-// 
-//
-
-EXPORT_C __NAKED__ void RMDebug_BranchTst1( void )
-//
-// 
-//
-{
-	asm("mov r0, #0 ");			// aResult==KErrNone
-	asm("bx  lr ");             // Return
-}
-
-EXPORT_C __NAKED__ void RMDebug_BranchTst2( void )
-//
-// 
-//
-{
-	asm("mov r0, #0 ");			// aResult==KErrNone
-	asm("bx  lr ");             // Return
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/rm_debug/debug_targets/d_demand_paging.cia	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,57 @@
+// Copyright (c) 2007-2010 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:
+// 
+//
+
+
+#include <u32std.h>
+
+// unused function that contains enough padding that the test function
+// RMDebugDemandPagingTest starts in a new page.
+__NAKED__ TInt RMDebugDemandPagingPaddingBefore()
+	{
+	asm("movs       r2,r0");
+	asm("adds       r0,r2,r1");
+	asm("bx         lr");
+	// add padding to make this function 4kb in size.
+	// The 4084 corresponds to 2^12 (=4096) - 12,
+	// the 12 being the total size of the movs, adds and bx instructions.
+	asm(".space     4084");
+	}
+
+// test function which is in a page by itself
+__NAKED__ TInt RMDebugDemandPagingTest()
+	{
+	asm("movs       r2,r0");
+	asm("adds       r0,r2,r1");
+	asm("bx         lr");
+	// add padding to make this function 4kb in size.
+	// The 4084 corresponds to 2^12 (=4096) - 12,
+	// the 12 being the total size of the movs, adds and bx instructions.
+	asm(".space     4084");
+	}
+
+// unused function that contains enough padding to ensure that no used code
+// is in the same page as RMDebugDemandPagingTest
+__NAKED__ TInt RMDebugDemandPagingPaddingAfter()
+	{
+	asm("movs       r2,r0");
+	asm("adds       r0,r2,r1");
+	asm("bx         lr");
+	// add padding to make this function 4kb in size.
+	// The 4084 corresponds to 2^12 (=4096) - 12,
+	// the 12 being the total size of the movs, adds and bx instructions.
+	asm(".space     4084");
+	}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/rm_debug/debug_targets/d_demand_paging.h	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,22 @@
+// Copyright (c) 2007-2010 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:
+// definitions of functions in d_demand_paging.cia
+//
+
+#ifndef D_DEMAND_PAGING_H
+#define D_DEMAND_PAGING_H
+
+TInt RMDebugDemandPagingTest();
+
+#endif // D_DEMAND_PAGING_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/rm_debug/debug_targets/d_rmdebug_bkpt_test.h	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,28 @@
+// Copyright (c) 2010 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:
+//
+
+// definitions of functions in d_rmdebug_bkpt_test.s
+
+#ifndef D_RMDEBUG_BKPT_TESTS_H
+#define D_RMDEBUG_BKPT_TESTS_H
+
+extern "C"
+{
+	// Breakpoints in loop test
+	unsigned int RMDebug_Bkpt_Test_Entry(void);
+	unsigned int RMDebug_Bkpt_Test_Loop_Break_1(void);
+	unsigned int RMDebug_Bkpt_Test_Loop_Break_2(void);
+}
+#endif // D_RMDEBUG_BKPT_TESTS_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/rm_debug/debug_targets/d_rmdebug_bkpt_test.s	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,52 @@
+; Copyright (c) 2010 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:
+;
+
+        AREA |d-rmdebug-bkpt$$Code|, CODE, READONLY, ALIGN=6
+
+	CODE32
+
+;
+; Breakpoints in loop test
+; 
+; This function initialises some variables and then performs some basic operations 
+; within the for loop. This allows us to set multiple breakpoints within the loop 
+; to test and see whether they are being hit. 
+;
+
+	EXPORT RMDebug_Bkpt_Test_Entry
+	EXPORT RMDebug_Bkpt_Test_Loop_Break_1
+	EXPORT RMDebug_Bkpt_Test_Loop_Break_2
+	
+RMDebug_Bkpt_Test_Entry
+    mov r2,#10
+    mov r0,#20    
+    mov r3,#0
+    mov r1,#1
+    b COMPARE
+LOOP      
+    add r3,r2,r0   
+RMDebug_Bkpt_Test_Loop_Break_1    
+    mov r2,r0
+RMDebug_Bkpt_Test_Loop_Break_2  
+    mov r0,r3 
+    add r1,r1,#1
+COMPARE
+    cmp r1,#30
+    ble LOOP 
+    bx lr
+ 
+	END
+
+; End of file - d_rmdebug_bkpt_test.s
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/rm_debug/debug_targets/d_rmdebug_step_test.h	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,81 @@
+// Copyright (c) 2007-2010 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:
+// 
+// definitions of functions in d_rmdebug_step_tests.s
+//
+
+#ifndef D_RMDEBUG_STEP_TESTS_H
+#define D_RMDEBUG_STEP_TESTS_H
+
+extern "C"
+{
+	// ARM tests
+	unsigned int RMDebug_StepTest_Non_PC_Modifying(void);
+	unsigned int RMDebug_StepTest_Non_PC_Modifying_OK(void);
+	
+	unsigned int RMDebug_StepTest_Branch(void);
+	unsigned int RMDebug_StepTest_Branch_1(void);
+
+	unsigned int RMDebug_StepTest_Branch_And_Link(void);
+	unsigned int RMDebug_StepTest_Branch_And_Link_1(void);
+	unsigned int RMDebug_StepTest_Branch_And_Link_2(void);
+	
+	unsigned int RMDebug_StepTest_MOV_PC(void);
+	unsigned int RMDebug_StepTest_MOV_PC_1(void);
+	unsigned int RMDebug_StepTest_MOV_PC_2(void);
+	
+	unsigned int RMDebug_StepTest_LDR_PC(void);
+	unsigned int RMDebug_StepTest_LDR_PC_1(void);
+
+	// Thumb tests
+	unsigned int RMDebug_StepTest_Thumb_Non_PC_Modifying(void);
+	unsigned int RMDebug_StepTest_Thumb_Non_PC_Modifying_1(void);
+	unsigned int RMDebug_StepTest_Thumb_Non_PC_Modifying_2(void);
+
+	unsigned int RMDebug_StepTest_Thumb_Branch(void);
+	unsigned int RMDebug_StepTest_Thumb_Branch_1(void);
+	unsigned int RMDebug_StepTest_Thumb_Branch_2(void);
+	
+	unsigned int RMDebug_StepTest_Thumb_Branch_And_Link(void);
+	unsigned int RMDebug_StepTest_Thumb_Branch_And_Link_1(void);
+	unsigned int RMDebug_StepTest_Thumb_Branch_And_Link_2(void);
+	unsigned int RMDebug_StepTest_Thumb_Branch_And_Link_3(void);
+
+	unsigned int RMDebug_StepTest_Thumb_Back_Branch_And_Link(void);
+	unsigned int RMDebug_StepTest_Thumb_Back_Branch_And_Link_1(void);
+	unsigned int RMDebug_StepTest_Thumb_Back_Branch_And_Link_2(void);
+	unsigned int RMDebug_StepTest_Thumb_Back_Branch_And_Link_3(void);
+
+	unsigned int RMDebug_StepTest_Thumb_AddPC(void);
+	unsigned int RMDebug_StepTest_Thumb_AddPC_1(void);
+	unsigned int RMDebug_StepTest_Thumb_AddPC_2(void);
+	unsigned int RMDebug_StepTest_Thumb_AddPC_3(void);
+
+	// ARM<->Thumb interworking tests
+	unsigned int RMDebug_StepTest_Interwork(void);
+	unsigned int RMDebug_StepTest_Interwork_1(void);
+	unsigned int RMDebug_StepTest_Interwork_2(void);
+	unsigned int RMDebug_StepTest_Interwork_3(void);
+
+	// Stepping performance test
+	unsigned int RMDebug_StepTest_Count(void);
+	unsigned int RMDebug_StepTest_Count_1(void);
+	unsigned int RMDebug_StepTest_Count_2(void);
+
+	// Multiple step test
+	unsigned int RMDebug_StepTest_ARM_Step_Multiple(void);
+	unsigned int RMDebug_StepTest_ARM_Step_Multiple_1(void);
+
+}
+#endif // D_RMDEBUG_STEP_TESTS_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/rm_debug/debug_targets/d_rmdebug_step_test.s	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,268 @@
+; Copyright (c) 2007-2010 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:
+; 
+;
+
+        
+		AREA |d-rmdebug-step$$Code|, CODE, READONLY, ALIGN=6
+
+	CODE32
+
+	; ARM tests
+	
+; 
+; Non-PC modifying
+;
+	EXPORT RMDebug_StepTest_Non_PC_Modifying
+	EXPORT RMDebug_StepTest_Non_PC_Modifying_OK
+ 
+RMDebug_StepTest_Non_PC_Modifying
+	mov		r0,r0		; nop
+RMDebug_StepTest_Non_PC_Modifying_OK
+	bx		lr			; should return to normal execution of the test thread
+
+;
+; Branch
+;
+	EXPORT RMDebug_StepTest_Branch
+	EXPORT RMDebug_StepTest_Branch_1
+
+RMDebug_StepTest_Branch
+	b		RMDebug_StepTest_Branch_1		
+	mov		r0, #2		; if the pc ends up here, we know its gone wrong
+RMDebug_StepTest_Branch_1
+	bx		lr			; return
+
+;
+; Branch and Link
+;
+	EXPORT RMDebug_StepTest_Branch_And_Link
+	EXPORT RMDebug_StepTest_Branch_And_Link_1
+	EXPORT RMDebug_StepTest_Branch_And_Link_2
+
+RMDebug_StepTest_Branch_And_Link		
+	mov		r0, lr		; preserve lr for the moment
+RMDebug_StepTest_Branch_And_Link_1
+	bl		RMDebug_StepTest_Branch_And_Link_2
+	mov		r1, #1		; insert a gap in the instruction stream so we know we branched.
+RMDebug_StepTest_Branch_And_Link_2
+	mov		lr, r0		; restore lr			
+	bx		lr			; should return to normal execution of the test thread
+
+;
+; MOV PC
+;
+	EXPORT RMDebug_StepTest_MOV_PC
+	EXPORT RMDebug_StepTest_MOV_PC_1
+	EXPORT RMDebug_StepTest_MOV_PC_2
+
+RMDebug_StepTest_MOV_PC
+	mov		r0, #4
+RMDebug_StepTest_MOV_PC_1
+	add		pc, pc, r0	; should be a jump (bear in mind reading pc = current inst + 8bytes for arm)
+	mov		r0, #1		; Simple instructions which allow us to test where the PC really is
+	mov		r0, #2		; just by reading r0.
+RMDebug_StepTest_MOV_PC_2
+	mov		r0, #3		; 
+	mov		r0, #4		; 
+	bx		lr			; should return to normal execution of the test thread
+
+; 
+; LDR PC
+;
+	EXPORT RMDebug_StepTest_LDR_PC
+	EXPORT RMDebug_StepTest_LDR_PC_1
+
+RMDebug_StepTest_LDR_PC
+	ldr		pc, =RMDebug_StepTest_LDR_PC_1
+	mov		r0, #1		;  separate the branch target so we can prove it works
+RMDebug_StepTest_LDR_PC_1
+	bx		lr			; should return to normal execution of the test thread
+	
+;
+; ARM -> Thumb -> ARM interworking test
+;
+; Note: We always start and finish this test
+; in ARM mode.
+	EXPORT RMDebug_StepTest_Interwork
+	EXPORT RMDebug_StepTest_Interwork_1
+	EXPORT RMDebug_StepTest_Interwork_2
+	EXPORT RMDebug_StepTest_Interwork_3	
+RMDebug_StepTest_Interwork
+	mov		r0, lr	; preserve lr
+RMDebug_StepTest_Interwork_1
+	blx		RMDebug_StepTest_Interwork_2
+
+	CODE16
+RMDebug_StepTest_Interwork_2
+	blx		RMDebug_StepTest_Interwork_3
+
+	CODE32
+
+RMDebug_StepTest_Interwork_3
+	bx		r0
+
+;
+; Stepping performance tests
+;
+; This counts down from 100000 to 0
+; This means that for all practical purposes
+; we can single-step as much as we like
+; in less than one second and have some likelyhood
+; that we will not step too far from our loop
+
+	EXPORT RMDebug_StepTest_Count
+	EXPORT RMDebug_StepTest_Count_1
+	EXPORT RMDebug_StepTest_Count_2
+
+RMDebug_StepTest_Count
+	ldr		r2, =100000
+RMDebug_StepTest_Count_1
+	subs	r2, r2, #1
+RMDebug_StepTest_Count_2
+	bne		RMDebug_StepTest_Count_1
+	bx		lr
+
+; Thumb tests
+
+; Thumb non-pc modifying
+;
+;
+RMDebug_StepTest_Thumb_Non_PC_Modifying
+	mov		r0, lr	; preserve lr
+	blx		RMDebug_StepTest_Thumb_Non_PC_Modifying_1
+	bx		r0
+
+;
+; Thumb Branch
+;
+RMDebug_StepTest_Thumb_Branch
+	mov		r0, lr	; preserve lr
+	blx		RMDebug_StepTest_Thumb_Branch_1
+	bx		r0		
+
+;
+; Thumb Branch and link
+;
+RMDebug_StepTest_Thumb_Branch_And_Link
+	mov		r0, lr	; preserve lr
+	blx		RMDebug_StepTest_Thumb_Branch_And_Link_1
+	bx		r0 
+
+;
+; Thumb Back Branch and link
+;
+RMDebug_StepTest_Thumb_Back_Branch_And_Link
+	mov		r0, lr	; preserve lr
+	blx		RMDebug_StepTest_Thumb_Back_Branch_And_Link_1
+	bx		r0 
+
+;
+; Thumb ADD PC,PC, #0
+;
+RMDebug_StepTest_Thumb_AddPC
+	mov		r0, lr	; preserve lr
+	blx		RMDebug_StepTest_Thumb_AddPC_1
+	bx		r0 
+
+	CODE16
+
+	; Thumb tests
+	EXPORT RMDebug_StepTest_Thumb_Non_PC_Modifying
+	EXPORT RMDebug_StepTest_Thumb_Non_PC_Modifying_1
+	EXPORT RMDebug_StepTest_Thumb_Non_PC_Modifying_2
+
+	EXPORT RMDebug_StepTest_Thumb_Branch
+	EXPORT RMDebug_StepTest_Thumb_Branch_1
+	EXPORT RMDebug_StepTest_Thumb_Branch_2
+
+	EXPORT RMDebug_StepTest_Thumb_Branch_And_Link
+	EXPORT RMDebug_StepTest_Thumb_Branch_And_Link_1
+	EXPORT RMDebug_StepTest_Thumb_Branch_And_Link_2
+	EXPORT RMDebug_StepTest_Thumb_Branch_And_Link_3
+
+	EXPORT RMDebug_StepTest_Thumb_Back_Branch_And_Link
+	EXPORT RMDebug_StepTest_Thumb_Back_Branch_And_Link_1
+	EXPORT RMDebug_StepTest_Thumb_Back_Branch_And_Link_2
+	EXPORT RMDebug_StepTest_Thumb_Back_Branch_And_Link_3
+
+RMDebug_StepTest_Thumb_Non_PC_Modifying_1
+	mov		r0, r0	; nop
+RMDebug_StepTest_Thumb_Non_PC_Modifying_2
+	bx		lr	
+
+RMDebug_StepTest_Thumb_Branch_1
+	b		RMDebug_StepTest_Thumb_Branch_2
+	mov		r0, r0
+RMDebug_StepTest_Thumb_Branch_2
+	bx		lr
+
+RMDebug_StepTest_Thumb_Branch_And_Link_1
+	mov		r1, lr
+RMDebug_StepTest_Thumb_Branch_And_Link_2
+	bl		RMDebug_StepTest_Thumb_Branch_And_Link_3
+	mov		r0, r0
+RMDebug_StepTest_Thumb_Branch_And_Link_3
+	bx		r1
+
+RMDebug_StepTest_Thumb_Back_Branch_And_Link_3
+	bx		r1
+
+RMDebug_StepTest_Thumb_Back_Branch_And_Link_1
+	mov		r1, lr
+RMDebug_StepTest_Thumb_Back_Branch_And_Link_2
+	bl		RMDebug_StepTest_Thumb_Back_Branch_And_Link_3
+	bx		r1
+
+;
+; ADD PC
+;
+	EXPORT RMDebug_StepTest_Thumb_AddPC
+	EXPORT RMDebug_StepTest_Thumb_AddPC_1
+	EXPORT RMDebug_StepTest_Thumb_AddPC_2
+	EXPORT RMDebug_StepTest_Thumb_AddPC_3
+
+RMDebug_StepTest_Thumb_AddPC_1
+	mov		r1, lr
+	mov		r2, #4
+RMDebug_StepTest_Thumb_AddPC_2
+	add		pc, pc, r2	; should arrive at RMDebug_StepTest_Thumb_AddPC_3
+	mov		r0, r0
+	mov		r0, r0
+	mov		r0, r0
+RMDebug_StepTest_Thumb_AddPC_3
+	bx		r1
+
+	ALIGN 4
+
+	CODE32
+
+;
+; ARM multiple-step ( 5 steps )
+;
+	EXPORT RMDebug_StepTest_ARM_Step_Multiple
+	EXPORT RMDebug_StepTest_ARM_Step_Multiple_1
+
+RMDebug_StepTest_ARM_Step_Multiple
+	mov		r0,r0		; nop
+	mov		r0,r0		; nop
+	mov		r0,r0		; nop
+	mov		r0,r0		; nop
+	mov		r0,r0		; nop
+RMDebug_StepTest_ARM_Step_Multiple_1
+	bx		lr
+
+	END
+
+; End of file - d_rmdebug_step_test.s
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/rm_debug/debug_targets/d_rmdebug_step_test_armv4.h	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,50 @@
+// Copyright (c) 2007-2010 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:
+// definitions of functions in d_rmdebug_step_tests_armv4.s
+//
+
+#ifndef D_RMDEBUG_STEP_TESTS_H
+#define D_RMDEBUG_STEP_TESTS_H
+
+extern "C"
+{
+	// ARM tests
+	unsigned int RMDebug_StepTest_Non_PC_Modifying(void);
+	unsigned int RMDebug_StepTest_Non_PC_Modifying_OK(void);
+	
+	unsigned int RMDebug_StepTest_Branch(void);
+	unsigned int RMDebug_StepTest_Branch_1(void);
+
+	unsigned int RMDebug_StepTest_Branch_And_Link(void);
+	unsigned int RMDebug_StepTest_Branch_And_Link_1(void);
+	unsigned int RMDebug_StepTest_Branch_And_Link_2(void);
+	
+	unsigned int RMDebug_StepTest_MOV_PC(void);
+	unsigned int RMDebug_StepTest_MOV_PC_1(void);
+	unsigned int RMDebug_StepTest_MOV_PC_2(void);
+	
+	unsigned int RMDebug_StepTest_LDR_PC(void);
+	unsigned int RMDebug_StepTest_LDR_PC_1(void);
+
+	// Stepping performance test
+	unsigned int RMDebug_StepTest_Count(void);
+	unsigned int RMDebug_StepTest_Count_1(void);
+	unsigned int RMDebug_StepTest_Count_2(void);
+
+	// Multiple step test
+	unsigned int RMDebug_StepTest_ARM_Step_Multiple(void);
+	unsigned int RMDebug_StepTest_ARM_Step_Multiple_1(void);
+
+}
+#endif // D_RMDEBUG_STEP_TESTS_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/rm_debug/debug_targets/d_rmdebug_step_test_armv4.s	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,130 @@
+; Copyright (c) 2007-2010 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:
+; 
+;
+
+        AREA |d-rmdebug-bkpt$$Code|, CODE, READONLY, ALIGN=6
+
+	CODE32
+
+	; ARM tests
+	
+; 
+; Non-PC modifying
+;
+	EXPORT RMDebug_StepTest_Non_PC_Modifying
+	EXPORT RMDebug_StepTest_Non_PC_Modifying_OK
+ 
+RMDebug_StepTest_Non_PC_Modifying
+	mov		r0,r0		; nop
+RMDebug_StepTest_Non_PC_Modifying_OK
+	bx		lr			; should return to normal execution of the test thread
+
+;
+; Branch
+;
+	EXPORT RMDebug_StepTest_Branch
+	EXPORT RMDebug_StepTest_Branch_1
+
+RMDebug_StepTest_Branch
+	b		RMDebug_StepTest_Branch_1		
+	mov		r0, #2		; if the pc ends up here, we know its gone wrong
+RMDebug_StepTest_Branch_1
+	bx		lr			; return
+
+;
+; Branch and Link
+;
+	EXPORT RMDebug_StepTest_Branch_And_Link
+	EXPORT RMDebug_StepTest_Branch_And_Link_1
+	EXPORT RMDebug_StepTest_Branch_And_Link_2
+
+RMDebug_StepTest_Branch_And_Link		
+	mov		r0, lr		; preserve lr for the moment
+RMDebug_StepTest_Branch_And_Link_1
+	bl		RMDebug_StepTest_Branch_And_Link_2
+	mov		r1, #1		; insert a gap in the instruction stream so we know we branched.
+RMDebug_StepTest_Branch_And_Link_2
+	mov		lr, r0		; restore lr			
+	bx		lr			; should return to normal execution of the test thread
+
+;
+; MOV PC
+;
+	EXPORT RMDebug_StepTest_MOV_PC
+	EXPORT RMDebug_StepTest_MOV_PC_1
+	EXPORT RMDebug_StepTest_MOV_PC_2
+
+RMDebug_StepTest_MOV_PC
+	mov		r0, #4
+RMDebug_StepTest_MOV_PC_1
+	add		pc, pc, r0	; should be a jump (bear in mind reading pc = current inst + 8bytes for arm)
+	mov		r0, #1		; Simple instructions which allow us to test where the PC really is
+	mov		r0, #2		; just by reading r0.
+RMDebug_StepTest_MOV_PC_2
+	mov		r0, #3		; 
+	mov		r0, #4		; 
+	bx		lr			; should return to normal execution of the test thread
+
+; 
+; LDR PC
+;
+	EXPORT RMDebug_StepTest_LDR_PC
+	EXPORT RMDebug_StepTest_LDR_PC_1
+
+RMDebug_StepTest_LDR_PC
+	ldr		pc, =RMDebug_StepTest_LDR_PC_1
+	mov		r0, #1		;  separate the branch target so we can prove it works
+RMDebug_StepTest_LDR_PC_1
+	bx		lr			; should return to normal execution of the test thread
+	
+;
+; Stepping performance tests
+;
+; This counts down from 100000 to 0
+; This means that for all practical purposes
+; we can single-step as much as we like
+; in less than one second and have some likelyhood
+; that we will not step too far from our loop
+
+	EXPORT RMDebug_StepTest_Count
+	EXPORT RMDebug_StepTest_Count_1
+	EXPORT RMDebug_StepTest_Count_2
+
+RMDebug_StepTest_Count
+	ldr		r2, =100000
+RMDebug_StepTest_Count_1
+	subs	r2, r2, #1
+RMDebug_StepTest_Count_2
+	bne		RMDebug_StepTest_Count_1
+	bx		lr
+
+;
+; ARM multiple-step ( 5 steps )
+;
+	EXPORT RMDebug_StepTest_ARM_Step_Multiple
+	EXPORT RMDebug_StepTest_ARM_Step_Multiple_1
+
+RMDebug_StepTest_ARM_Step_Multiple
+	mov		r0,r0		; nop
+	mov		r0,r0		; nop
+	mov		r0,r0		; nop
+	mov		r0,r0		; nop
+	mov		r0,r0		; nop
+RMDebug_StepTest_ARM_Step_Multiple_1
+	bx		lr
+
+	END
+
+; End of file - d_rmdebug_step_test_armv4.s
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/rm_debug/debug_targets/d_rmdebugthread.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,106 @@
+// Copyright (c) 2006-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:
+// Implements a debug thread for testing.
+// 
+//
+
+#include <e32base.h>
+#include <e32base_private.h>
+#include <e32cons.h>
+#include "d_rmdebugthread.h"
+
+EXPORT_C TBuf8<SYMBIAN_RMDBG_MEMORYSIZE> gMemoryAccessBytes;
+extern void RMDebug_BranchTst1();
+
+EXPORT_C TInt TestData;
+
+CDebugServThread::CDebugServThread()
+//
+// Empty constructor
+//
+	{
+	}
+
+GLDEF_C TInt CDebugServThread::ThreadFunction(TAny*)
+//
+// Generic thread function for testing
+//
+	{
+	CTrapCleanup* cleanup=CTrapCleanup::New();
+	if (cleanup == NULL)
+		{
+		User::Leave(KErrNoMemory);
+		}
+
+	RThread::Rendezvous(KErrNone);
+
+	TestData = 1;
+
+	while(1)
+		{
+		RMDebug_BranchTst1();
+
+		TestData++;                   
+
+		// Wait half a second (suspends this thread)
+		User::After(500000);
+
+		if (TestData == 0xFFFFFFFF)
+			{
+			break;
+			}
+		}
+
+	delete cleanup;
+
+	return (KErrNone);
+	}
+
+EXPORT_C TInt StartDebugThread(RThread& aDebugThread)
+//
+// Starts the test thread
+//
+{
+	TInt res=KErrNone;
+
+	// Create the thread
+	res = aDebugThread.Create(	KDebugThreadName,
+								CDebugServThread::ThreadFunction,
+								KDefaultStackSize,
+								KDebugThreadDefaultHeapSize,
+								KDebugThreadDefaultHeapSize,
+								NULL
+								);
+
+	// Check that the creation worked
+	if (res == KErrNone)
+		{
+		TRequestStatus rendezvousStatus;
+
+		aDebugThread.SetPriority(EPriorityNormal);
+		// Make a request for a rendezvous
+		aDebugThread.Rendezvous(rendezvousStatus);
+		// Set the thread as ready for execution
+		aDebugThread.Resume();
+		// Wait for the resumption
+		User::WaitForRequest(rendezvousStatus);
+		}                                 
+	else
+		{
+		// Close the handle.
+		aDebugThread.Close();
+		}
+
+	return res;
+	}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/rm_debug/debug_targets/d_rmdebugthread.h	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,38 @@
+// Copyright (c) 2006-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:
+// t_rmdebugthread.h
+// Definitions for the run mode debug test thread.
+// 
+//
+
+#ifndef RMDEBUGSVRTHRD_H
+#define RMDEBUGSVRTHRD_H
+
+#define SYMBIAN_RMDBG_MEMORYSIZE    1024*4
+
+// Thread name
+_LIT(KDebugThreadName,"DebugThread");
+
+const TUint KDebugThreadDefaultHeapSize=0x10000;
+
+class CDebugServThread : public CBase
+	{
+	public:
+		CDebugServThread();
+		static TInt ThreadFunction(TAny* aStarted);    
+
+	public:
+	};
+
+#endif // RMDEBUGSVRTHRD_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/rm_debug/debug_targets/d_rmdebugthread2.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,218 @@
+// Copyright (c) 2006-2010 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:
+// Implements a debug thread for testing.
+// 
+//
+
+#include <e32base.h>
+#include <e32base_private.h>
+#include <e32cons.h>
+#include <e32debug.h>
+#include "d_rmdebugthread2.h"
+
+#include "d_rmdebug_step_test.h"
+#include "d_rmdebug_bkpt_test.h"
+#include "d_demand_paging.h"
+
+EXPORT_C TBuf8<SYMBIAN_RMDBG_MEMORYSIZE> gMemoryAccessBytes;
+IMPORT_C extern void RMDebug_BranchTst1();
+IMPORT_C extern TInt RMDebugDemandPagingTest();
+
+EXPORT_C TInt TestData;
+EXPORT_C TTestFunction FunctionChooser;
+
+const TInt 	KNumberOfTraceCalls = 50;
+
+EXPORT_C TInt TestFunction()
+	{
+	// Set TestData to an arbitrary value that can be checked by a tester
+	TestData = 0xffeeddcc;
+	RMDebug_BranchTst1();
+	
+	// Code here may not be executed because tests can change the PC value
+	// at any time, typically once the test passes
+	return 0;
+	}
+
+/**
+  Wrapper around RMDebugDemandPagingTest, need to pause for a short time to
+  allow time in t_rmdebug.cpp to issue a User::WaitForRequest to catch the break point
+  */
+EXPORT_C void TestPagedCode()
+	{
+	User::After(100000);
+
+	// call the function in paged code
+	RMDebugDemandPagingTest();
+	}
+
+EXPORT_C void TestMultipleTraceCalls()
+	{
+	//arbitrary function to set a BP on
+	RMDebug_BranchTst1();
+
+	// The tester will change FunctionChooser once it gets what it needs out of the test
+	for(TInt cnt = KNumberOfTraceCalls; cnt>0 && (FunctionChooser==EMultipleTraceCalls); cnt--)
+		{
+		RDebug::Printf("T");
+		RDebug::Printf("R");
+		RDebug::Printf("A");
+		RDebug::Printf("C");
+		RDebug::Printf("E");
+		}
+	
+	//another arbitrary function to set a BP on
+	RMDebug_StepTest_Non_PC_Modifying();
+	}
+
+CDebugServThread::CDebugServThread()
+//
+// Empty constructor
+//
+	{
+	}
+
+GLDEF_C TInt CDebugServThread::ThreadFunction(TAny*)
+//
+// Generic thread function for testing
+//
+	{
+	// set FunctionChooser to run the default function
+	FunctionChooser = EDefaultFunction;
+
+	CTrapCleanup* cleanup=CTrapCleanup::New();
+	if (cleanup == NULL)
+		{
+		User::Leave(KErrNoMemory);
+		}
+
+	RThread::Rendezvous(KErrNone);
+
+	TestData = 1;
+
+	/* Beware of adding printf or other debug-generating events in this loop because
+	* they interfere with the tests
+	*/
+	while(TestData != 0xFFFFFFFF)
+		{
+		switch(FunctionChooser)
+			{
+			case EDemandPagingFunction:
+				TestPagedCode();
+				break;
+			case EDefaultFunction:
+				// the default function is the stepping test functions
+			case EStepFunction:
+				{
+				RMDebug_BranchTst1();
+
+				// Single stepping test support code
+
+				// ARM tests
+				RMDebug_StepTest_Non_PC_Modifying();
+
+				RMDebug_StepTest_Branch();
+
+				RMDebug_StepTest_Branch_And_Link();
+
+				RMDebug_StepTest_MOV_PC();
+
+				RMDebug_StepTest_LDR_PC();
+ 
+// thumb/interworking tests not supported on armv4
+#ifdef __MARM_ARMV5__
+
+				// Thumb tests
+				RMDebug_StepTest_Thumb_Non_PC_Modifying();
+
+				RMDebug_StepTest_Thumb_Branch();
+
+				RMDebug_StepTest_Thumb_Branch_And_Link();
+
+				RMDebug_StepTest_Thumb_Back_Branch_And_Link();
+
+				// ARM <-> Thumb interworking tests
+				RMDebug_StepTest_Interwork();
+
+				RMDebug_StepTest_Thumb_AddPC();
+
+#endif	// __MARM_ARMV5__
+				
+				// Single-stepping performance
+				RMDebug_StepTest_Count();
+
+				// multiple step test
+				RMDebug_StepTest_ARM_Step_Multiple();
+
+				// Breakpoints in loop test
+				RMDebug_Bkpt_Test_Entry();
+
+				TestData++;
+
+				// Wait 50mSecs. // (suspends this thread)
+				User::After(50000);
+
+				break;
+				}
+			case EMultipleTraceCalls:
+				TestMultipleTraceCalls();
+				break;
+			default:
+				//do nothing
+				break;
+			}
+		}
+
+	delete cleanup;
+
+	return (KErrNone);
+	}
+
+EXPORT_C TInt StartDebugThread(RThread& aDebugThread, const TDesC& aDebugThreadName)
+//
+// Starts a test thread
+//
+{
+	TInt res=KErrNone;
+
+	// Create the thread
+	res = aDebugThread.Create(	aDebugThreadName,
+								CDebugServThread::ThreadFunction,
+								KDefaultStackSize,
+								KDebugThreadDefaultHeapSize,
+								KDebugThreadDefaultHeapSize,
+								NULL
+								);
+
+	// Check that the creation worked
+	if (res == KErrNone)
+		{
+		TRequestStatus rendezvousStatus;
+
+		aDebugThread.SetPriority(EPriorityNormal);
+		// Make a request for a rendezvous
+		aDebugThread.Rendezvous(rendezvousStatus);
+		// Set the thread as ready for execution
+		aDebugThread.Resume();
+		// Wait for the resumption
+		User::WaitForRequest(rendezvousStatus);
+		}                                 
+	else
+		{
+		// Close the handle.
+		aDebugThread.Close();
+		}
+
+	return res;
+	}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/rm_debug/debug_targets/d_rmdebugthread2.h	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,51 @@
+// Copyright (c) 2006-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:
+// Definitions for the run mode debug test thread.
+// 
+//
+
+#ifndef RMDEBUGSVRTHRD_H
+#define RMDEBUGSVRTHRD_H
+
+#define SYMBIAN_RMDBG_MEMORYSIZE    1024*4
+
+// Thread name
+_LIT(KDebugThreadName,"DebugThread");
+
+const TUint KDebugThreadDefaultHeapSize=0x10000;
+
+// enumeration of functions which the target debug thread can call, the
+// debugger can choose to switch the thread to a different function by
+// writing the appropriate enumeration value into FunctionChooser, the
+// target thread will finish executing the function it is currently running
+// then execute the chosen function.
+enum TTestFunction
+	{
+	EDefaultFunction = 0,
+	EStepFunction = 1,
+	EDemandPagingFunction = 2,
+	EMultipleTraceCalls = 3,
+	EDoNothing = 4
+	};
+
+class CDebugServThread : public CBase
+	{
+	public:
+		CDebugServThread();
+		static TInt ThreadFunction(TAny* aStarted);    
+
+	public:
+	};
+
+#endif // RMDEBUGSVRTHRD_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/rm_debug/debug_targets/d_rmdebugthreadasm.cia	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,32 @@
+// Copyright (c) 2006-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:
+// d_rmdebugthreadasm.h
+// Assembler file for debug thread testing.
+// 
+//
+
+//#include <e32cia.h>
+//#include <e32base.h>
+//#include <e32cons.h>
+//#include "d_rmdebugthread.h"
+
+EXPORT_C __NAKED__ void RMDebug_BranchTst1( void )
+//
+// 
+//
+{
+	asm("mov r0, #0 ");			// aResult==KErrNone
+	asm("bx  lr ");             // Return
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/rm_debug/debug_targets/d_rmdebugthreadasm2.cia	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,35 @@
+// Copyright (c) 2006-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:
+// d_rmdebugthreadasm2.h
+// Assembler file for debug thread testing.
+// 
+//
+
+EXPORT_C __NAKED__ void RMDebug_BranchTst1( void )
+//
+// 
+//
+{
+	asm("mov r0, #0 ");			// aResult==KErrNone
+	asm("bx  lr ");             // Return
+}
+
+EXPORT_C __NAKED__ void RMDebug_BranchTst2( void )
+//
+// 
+//
+{
+	asm("mov r0, #0 ");			// aResult==KErrNone
+	asm("bx  lr ");             // Return
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/rm_debug/debug_targets/t_rmdebug_app.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,380 @@
+// Copyright (c) 2007-2010 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:
+//
+
+#include <e32base.h>
+#include <e32base_private.h>
+#include <e32cmn.h>
+#include <e32cmn_private.h>
+#include <e32debug.h>
+#include <e32property.h> 
+#include <u32hal.h>
+#include <f32file.h>
+
+
+
+#include "t_rmdebug_app.h"
+
+IMPORT_C extern void RMDebug_BranchTst2();
+
+LOCAL_C void ParseCommandLineL(TInt32& aFunctionType, TUint& aDelay, TUint& aExtraThreads, TInt32& aCpuNumber)
+	{
+	// get the length of the command line arguments
+	TInt argc = User::CommandLineLength();
+	RDebug::Printf(" t_rmdebug_app: ParseCommandLineL argc=%d", argc);
+
+	// allocate a buffer for the command line arguments and extract the data to it
+	HBufC* commandLine = HBufC::NewLC(argc);
+	TPtr commandLineBuffer = commandLine->Des();
+	User::CommandLine(commandLineBuffer);
+
+	// create a lexer and read through the command line
+	TLex lex(*commandLine);
+	while (!lex.Eos())
+		{
+		// expecting the first character to be a '-'
+		if (lex.Get() == '-')
+			{
+			TChar arg = lex.Get();
+			switch (arg)
+				{
+				case 'f':
+					// the digits following '-f' give the function type
+					User::LeaveIfError(lex.Val(aFunctionType));
+					RDebug::Printf(" t_rmdebug_app: setting aFunctionType=%d", aFunctionType);
+					break;
+				case 'd':
+					// the digits following '-d' give the delay
+					User::LeaveIfError(lex.Val(aDelay));
+					RDebug::Printf(" t_rmdebug_app: setting aDelay=%d", aDelay);
+					break;
+				case 'e':
+					// the digits following '-e' give the number of extra threads to launch
+					User::LeaveIfError(lex.Val(aExtraThreads));
+					RDebug::Printf(" t_rmdebug_app: setting aExtraThreads=%d", aExtraThreads);
+					break;
+
+				case 'a':
+						// the digits following '-a' gives the cpu on which this thread will execute on
+					User::LeaveIfError(lex.Val(aCpuNumber));
+					RDebug::Printf(" t_rmdebug_app: CPU Number=%d", aCpuNumber);
+					break;
+
+				default:
+					// unknown argument so leave
+					User::Leave(KErrArgument);
+				}
+			lex.SkipSpace();
+			}
+		else
+			{
+			// unknown argument so leave
+			User::Leave(KErrArgument);
+			}
+		}
+
+	// do clean up
+	CleanupStack::PopAndDestroy(commandLine);
+	}
+
+typedef void (*TPfun)();
+
+// test function to call corresponding to EPrefetchAbortFunction
+void PrefetchAbort()
+	{
+	TPfun f = NULL;
+	f();
+	}
+
+// test function to call corresponding to EUserPanicFunction
+void UserPanic()
+	{
+	User::Panic(KUserPanic, KUserPanicCode);
+	}
+
+// calls self repeatedly until stack is used up. Slightly convoluted to prevent UREL optimising this out...
+TUint32 StackOverFlowFunction(TUint32 aInt=0)
+	{
+	TUint32 unusedArray[150];
+	for(TInt i=0; i<150; i++)
+		{
+		unusedArray[i] = StackOverFlowFunction(i);
+		}
+	return unusedArray[0];
+	}
+
+void DataAbort()
+	{
+	TInt* r = (TInt*) 0x1000;
+	*r = 0x42;              
+	}
+
+void UndefInstruction()
+	{
+	TUint32 undef = 0xE6000010;
+	TPfun f = (TPfun) &undef;
+	f();
+	}
+
+TInt DataRead()
+	{
+	TInt* r = (TInt*) 0x1000;
+	TInt rr = (TInt)*r;
+	//include the following line to ensure that rr doesn't get optimised out
+	RDebug::Printf("Shouldn't see this being printed out: %d", rr);
+
+	// Stop compilation warning. Should not get here anyway.
+	rr++;
+	return rr;
+	}
+
+void DataWrite()
+	{
+	TInt* r = (TInt*) 0x1000;
+	*r = 0x42;                
+	}
+
+void UserException()
+	{
+	User::RaiseException(EExcGeneral);
+	}
+
+void SpinForeverWithBreakPoint()
+	{
+
+    // finding the process t_rmdebug2/t_rmdebug2_oem/t_rmdebug2_oem2
+    // we find the process.SID to attach to the property
+	_LIT(KThreadWildCard, "t_rmdebug2*");
+
+	TInt err = KErrNone;
+	TUid propertySid = KNullUid;
+	TFindThread find(KThreadWildCard);
+	TFullName name;
+	TBool found = EFalse;
+	while(find.Next(name)==KErrNone && !found)
+		{
+		RThread thread;
+		err = thread.Open(find);
+		if (err == KErrNone)
+			{
+			RProcess process;
+			thread.Process(process);
+			TFullName fullname = thread.FullName();
+		    //RDebug::Printf("SID Search Match Found Name %lS Process ID%ld Thread Id %ld", &fullname, process.Id().Id(), thread.Id().Id());
+			found = ETrue;
+			//SID saved so that the property can be attached to
+			propertySid = process.SecureId();
+			process.Close();
+			}
+		thread.Close();
+	}
+
+    //attach to the property to publish the address of the RMDebug_BranchTst2 with the correct SID value
+	RProperty integerProperty;
+	err = integerProperty.Attach(propertySid, EMyPropertyInteger, EOwnerThread);
+	if(KErrNone != err)
+		RDebug::Printf("Error Attach to the property %d", err);
+
+	TInt address = (TInt)&RMDebug_BranchTst2;
+	
+	// publish the address where the breakpoint would be set
+	err = integerProperty.Set(address);
+	if(KErrNone != err)
+		RDebug::Printf("Error Set of the property %d", err);
+	integerProperty.Close();
+	
+	//open semaphore to signal the fact we have reached the point where we have to set the property
+	RSemaphore globsem;
+	globsem.OpenGlobal(_L("RMDebugGlobSem"));
+	globsem.Signal();
+	globsem.Close();
+
+	RProcess thisProcess;
+	TFileName thisProcessName = thisProcess.FileName();
+	RDebug::Printf("App Process Name %lS process id %ld thread id %ld", &thisProcessName, thisProcess.Id().Id(), RThread().Id().Id());
+
+	TInt i=0;
+	RThread::Rendezvous(KErrNone);
+	while(i<0xffffffff)
+		{
+		RMDebug_BranchTst2();
+		User::After(10000);
+		}
+	}
+
+void SpinForever()
+	{
+	TInt i=0;
+	RThread::Rendezvous(KErrNone);
+	while(i<0xffffffff)
+		{
+		User::After(10000);
+		}
+	}
+
+void NormalExit()
+    {
+    RDebug::Printf("Target app: NormalExit() function. Returning to MainL" );
+    }
+
+void LaunchThreads(TUint aNumber)
+	{
+	_LIT(KDebugThreadName, "DebugThread");
+	const TUint KDebugThreadDefaultHeapSize=0x10000;
+	for(TInt i=0; i<aNumber; i++)
+		{
+		RThread thread;
+		RBuf threadName;
+		threadName.Create(KDebugThreadName().Length()+10); // the 10 is for appending i to the end of the name
+		threadName.Append(KDebugThreadName());
+		threadName.AppendNum(i);
+		TInt err = thread.Create(threadName, (TThreadFunction)SpinForever, KDefaultStackSize, KDebugThreadDefaultHeapSize, KDebugThreadDefaultHeapSize, NULL);
+		if(err != KErrNone)
+			{
+			RDebug::Printf("Couldn't create thread %d", err);
+			threadName.Close();
+			thread.Close();
+			break;
+			}
+		thread.SetPriority(EPriorityNormal);
+		TRequestStatus status;
+		thread.Rendezvous(status);
+		thread.Resume();
+		User::WaitForRequest(status);
+		thread.Close();
+		threadName.Close();
+		}
+	}
+
+void WaitFiveSecondsThenExit(void)
+	{
+	// wait for 5 seconds
+	User::After(5000000);
+	}
+
+TInt NumberOfCpus()
+	{
+	TInt r = UserSvr::HalFunction(EHalGroupKernel, EKernelHalNumLogicalCpus, 0, 0);
+	return r;
+	}
+
+TInt SetCpuAffinity(TInt aCpuNumber)
+	{
+    TInt TestCpuCount = NumberOfCpus();
+	RDebug::Printf("SetCpuAffinity --> TestCpuCount = %d\n", TestCpuCount);		
+	TUint32 cpu = 0;
+
+	if ((aCpuNumber % TestCpuCount) != 0)
+	cpu = (TUint32)(aCpuNumber % TestCpuCount);
+
+	RDebug::Printf("SetCpuAffinity --> Setting cpu %3d\n", cpu);
+	TInt r = UserSvr::HalFunction(EHalGroupKernel, EKernelHalLockThreadToCpu, (TAny *)cpu, 0);
+	return r;
+	}
+
+// call the function corresponding to aFunctionType
+LOCAL_C void CallFunction(TDebugFunctionType aFunctionType, TUint aDelay, TUint aExtraThreads, TInt32 aCpuNumber)
+	{
+	// pause for aDelay microseconds
+	User::After(aDelay);
+
+	// set cpu on which this thread should execute on
+	if (aCpuNumber)
+		SetCpuAffinity(aCpuNumber);
+
+	// launch the extra threads
+	LaunchThreads(aExtraThreads);
+
+	// call appropriate function
+	switch( aFunctionType )
+		{
+		case EPrefetchAbortFunction:
+			PrefetchAbort();
+			break;
+		case EUserPanicFunction:
+			UserPanic();
+			break;
+		case EStackOverflowFunction:
+			StackOverFlowFunction();
+			break;
+		case EDataAbortFunction:
+			DataAbort();
+			break;
+		case EUndefInstructionFunction:
+			UndefInstruction();
+			break;
+		case EDataReadErrorFunction:
+			DataRead();
+			break;
+		case EDataWriteErrorFunction:
+			DataWrite();
+			break;
+		case EUserExceptionFunction:
+			UserException();
+			break;
+		case EWaitFiveSecondsThenExit:
+			WaitFiveSecondsThenExit();
+			break;
+		case ESpinForever:
+			SpinForever();
+			break;
+		case ESpinForeverWithBreakPoint:
+			SpinForeverWithBreakPoint();
+			break;
+        case ENormalExit:
+            NormalExit();
+            break;			
+		case EDefaultDebugFunction:
+		default:
+			break;
+		}
+	}
+
+void PrintHelp()
+	{
+	RDebug::Printf("Invoke with arguments:\n");
+	RDebug::Printf("\t-d<delay>\n\t: delay in microseconds before calling target function\n");
+	RDebug::Printf("\t-f<function-number>\n\t: enumerator from TDebugFunctionType representing function to call\n");
+	RDebug::Printf("\t-e<number>\n\t: number of extra threads to launch, these threads run endlessly\n");
+	}
+
+
+TInt E32Main()
+	{
+	// setup heap checking and clean up trap
+	__UHEAP_MARK;
+	CTrapCleanup* cleanup=CTrapCleanup::New();
+	RThread().SetPriority(EPriorityNormal);
+	RProcess::Rendezvous(KErrNone);
+
+	// read arguments from command line
+	TUint delay = 0;
+	TInt32 functionTypeAsTInt32 = (TInt32)EDefaultDebugFunction;
+	TUint extraThreads = 0;
+	TInt32 aCpuNumber = -1;
+
+	TRAPD(err, ParseCommandLineL(functionTypeAsTInt32, delay, extraThreads, aCpuNumber));
+
+	if(KErrNone == err)
+		{
+		// if the command line arguments were successfully read then call the appropriate function
+		CallFunction((TDebugFunctionType)functionTypeAsTInt32, delay, extraThreads, aCpuNumber);
+		}
+
+	// perform clean up and return any error which was recorded
+	delete cleanup;
+	__UHEAP_MARKEND;
+	return err;
+	}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/rm_debug/debug_targets/t_rmdebug_app.h	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,44 @@
+// Copyright (c) 2007-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:
+//
+
+#ifndef T_RMDEBUG_APP_H
+#define T_RMDEBUG_APP_H
+
+_LIT(KRMDebugTestApplication, "z:\\sys\\bin\\t_rmdebug_app.exe");
+_LIT(KUserPanic, "UserPanic");
+const TInt KUserPanicCode = 0x1234ABCD;
+enum TMyPropertyKeys {EMyPropertyInteger};
+
+
+// enumeration of functions to call in test debug application
+enum TDebugFunctionType
+	{
+	EDefaultDebugFunction,
+	EPrefetchAbortFunction,
+	EUserPanicFunction,
+	EStackOverflowFunction,
+	EDataAbortFunction,
+	EUndefInstructionFunction,
+	EDataReadErrorFunction,
+	EDataWriteErrorFunction,
+	EUserExceptionFunction,
+	EWaitFiveSecondsThenExit,
+	ESpinForever,
+	ESpinForeverWithBreakPoint,
+	ENormalExit
+	};
+
+#endif //T_RMDEBUG_APP_H
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/rm_debug/debug_targets/t_rmdebug_dll.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,25 @@
+// Copyright (c) 2007-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:
+//
+
+#include <e32std.h>
+#include <e32std_private.h>
+#include <rm_debug_api.h>
+#include "t_rmdebug_dll.h"
+
+EXPORT_C TUid GetDSSUid()
+	{
+	return Debug::KUidDebugSecurityServer;
+	}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/rm_debug/debug_targets/t_rmdebug_dll.h	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,23 @@
+// Copyright (c) 2007-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:
+//
+
+#include <e32std.h>
+
+/**
+  This is a simple function that uses an element from rm_debug_api.h.
+  If the e32tests can be built and run then this is 'proof' that the
+  rm_debug_api.h header file can be #include'd into a dll
+  */
+IMPORT_C TUid GetDSSUid();
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/rm_debug/debug_targets/t_rmdebug_security.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,100 @@
+// Copyright (c) 2006-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 application to be debugged by t_rmdebug.exe when testing
+// security restrictions. This application is built with various
+// capabilities by the t_rmdebug_securityX.mmp files. This allows
+// the t_rmdebug2 program to ensure that security restrictions are
+// properly enforced by the DSS/DDD subsystem.
+// 
+//
+
+#include <e32base.h>
+#include <e32base_private.h>
+#include <e32cons.h>
+#include <e32test.h>
+#include <e32ldr.h>
+#include <e32cmn.h>
+#include <e32cmn_private.h>
+#include "t_rmdebug_security.h"
+
+CRunModeApp* CRunModeApp::NewL()
+//
+// CRunModeApp::NewL
+//
+	{
+	CRunModeApp* self = new(ELeave) CRunModeApp();
+
+  	self->ConstructL();
+   
+	return self;
+	}
+
+CRunModeApp::CRunModeApp()
+//
+// CRunModeApp constructor
+//
+	{
+	}
+
+CRunModeApp::~CRunModeApp()
+//
+// CRunModeApp destructor
+//
+	{
+	}
+
+void CRunModeApp::ConstructL()
+//
+// CRunModeApp::ConstructL
+//
+	{
+	}
+
+void CRunModeApp::TestWaitDebug()
+//
+// CRunModeApp::TestWaitDebug
+//
+	{
+	RProcess::Rendezvous(KErrNone);
+
+	// Wait a 3secs then quit (long enough to test, but not hang around forever)
+	User::After(3000000);
+	}
+
+GLDEF_C TInt E32Main()
+//
+// Entry point for run mode debug app test program
+//
+	{
+   TInt ret = KErrNone;
+   
+	// client
+	CTrapCleanup* trap = CTrapCleanup::New();
+	if (!trap)
+		return KErrNoMemory;
+
+   CRunModeApp* myApp = CRunModeApp::NewL();
+   if (myApp != NULL)
+       {
+        __UHEAP_MARK;
+	    TRAP(ret,myApp->TestWaitDebug());
+	    __UHEAP_MARKEND;
+
+	    delete myApp;
+       }
+       
+	delete trap;
+
+	return ret;
+	}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/rm_debug/debug_targets/t_rmdebug_security.h	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,44 @@
+// Copyright (c) 2006-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 application to be debugged by t_rmdebug2.exe when testing
+// security restrictions. This application is built with various
+// capabilities by the t_rmdebug_securityX.mmp files. This allows
+// the t_rmdebug2 program to ensure that security restrictions are
+// properly enforced by the DSS/DDD subsystem.
+// 
+//
+
+/**
+ @file
+ @internalTechnology
+ @released
+*/
+
+#ifndef T_RMDEBUG_SECURITY_H
+#define T_RMDEBUG_SECURITY_H
+
+class CRunModeApp : public CBase
+{
+public:
+	static CRunModeApp* NewL();
+	~CRunModeApp();
+
+	void TestWaitDebug();
+
+private:
+	CRunModeApp();
+	void ConstructL();
+};
+
+#endif // T_RMDEBUG_SECURITY_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/rm_debug/group/t_crashmonitor_lib.mmp	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,44 @@
+// Copyright (c) 2008-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 the functionality of the System Crash Monitor libraries
+//
+
+ALWAYS_BUILD_AS_ARM
+
+targettype     exe
+ 
+SYMBIAN_BASE_SYSTEMINCLUDE(nkern)
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN
+
+userinclude    ../../../../kernel/eka/debug/crashMonitor/inc
+sourcepath	   	../crashmonitor
+
+source        	t_crashmonitor.cpp
+
+library	euser.lib
+library hal.lib
+staticlibrary scmusr_lib.lib
+
+target         t_crashmonitor_lib.exe
+
+UID            0x0 0x4321bbbc
+SECUREID       0x2000B26F
+
+capability		none
+
+VENDORID       0x70000001
+
+DEBUGGABLE
+
+SMPSAFE
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/rm_debug/group/t_multi_agent_launcher.mmp	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,41 @@
+// Copyright (c) 2006-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:
+// Application that launches multiple agents which in-turn test the ability of 
+// the run mode debug component to debug several targets
+// 
+//
+
+targettype     exe
+target         t_multi_agent_launcher.exe
+
+library		euser.lib hal.lib
+
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN
+
+userinclude    ../debug_targets
+userinclude    ../common
+userinclude    ../multi_agent_tests
+
+sourcepath	   ../multi_agent_tests
+source         t_multi_agent_launcher.cpp 
+
+UID            0x0 0x4321bbbc
+SECUREID       0x1234aaab
+VENDORID       0x70000001
+
+DEBUGGABLE
+
+macro SYMBIAN_STANDARDDEBUG
+
+SMPSAFE
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/rm_debug/group/t_rmdebug.mmp	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,40 @@
+// Copyright (c) 2006-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:
+// 
+//
+
+ALWAYS_BUILD_AS_ARM
+
+target         t_rmdebug.exe
+targettype     exe
+
+sourcepath	   	../metro_trk
+source        	d_rmdebugserver.cpp 
+source        	d_rmdebugthread.cpp 
+source        	t_rmdebug.cpp 
+sourcepath	   	../common
+source			d_rmdebugthreadasm.cia
+
+library		euser.lib
+               
+SYMBIAN_BASE_SYSTEMINCLUDE(nkern)
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN
+
+UID            0x100039CE 0x101F7159
+SECUREID       0x101F7159
+VENDORID       0x70000001
+
+CAPABILITY 	ALL -TCB
+
+SMPSAFE
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/rm_debug/group/t_rmdebug2.mmh	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,66 @@
+// Copyright (c) 2006-2010 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:
+// 
+//
+
+ALWAYS_BUILD_AS_ARM
+
+targettype     exe
+
+sourcepath	   	..\debug_targets
+
+source        	d_rmdebugthread2.cpp 
+source			d_rmdebugthreadasm2.cia
+
+#if defined(MARM_ARMV5)
+source			d_rmdebug_step_test.s
+source			d_rmdebug_bkpt_test.s
+#endif
+
+#if defined(MARM_ARMV4)
+source			d_rmdebug_step_test_armv4.s
+#endif
+
+source			d_demand_paging.cia
+
+library		euser.lib
+library         hal.lib
+library         efsrv.lib
+library         t_rmdebug_dll.lib
+
+userinclude    ..\..\..\..\kernel\eka\include\drivers
+userinclude    ..\..\..\..\kernel\eka\debug\securityserver\inc
+userinclude    ..\debug_targets
+
+
+#ifdef SYMBIAN_OLD_EXPORT_LOCATION
+SYMBIAN_BASE_SYSTEMINCLUDE(drivers)
+SYMBIAN_BASE_SYSTEMINCLUDE(kernel)
+#endif
+SYMBIAN_BASE_SYSTEMINCLUDE(nkern)
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN
+
+PAGED
+
+// To test heap allocation failure uncomment one or other of the following macros.
+// NOTE: Do not uncomment both, the tests will panic if both are defined!
+
+// To test heap allocation failure in the Debug Device Driver uncomment this macro
+//macro KERNEL_OOM_TESTING
+
+// To test heap allocation failure in the Debug Security Server uncomment this macro
+//macro USER_OOM_TESTING
+
+
+SMPSAFE
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/rm_debug/group/t_rmdebug2.mmp	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,35 @@
+// Copyright (c) 2006-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:
+// 
+//
+
+#include "t_rmdebug2.mmh"
+
+target         t_rmdebug2.exe
+
+sourcepath	   	../basic_tests
+source        	t_rmdebug2.cpp 
+source		r_low_memory_security_svr_session.cpp
+source		r_kernel_low_memory_security_svr_session.cpp
+source		r_user_low_memory_security_svr_session.cpp
+
+UID            0x0 0x4321bbbb
+SECUREID       0x1234aaaa
+VENDORID       0x70000001
+
+CAPABILITY 	READUSERDATA POWERMGMT ALLFILES
+
+DEBUGGABLE
+
+macro SYMBIAN_STANDARDDEBUG
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/rm_debug/group/t_rmdebug2_oem.mmp	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,38 @@
+// Copyright (c) 2006-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:
+// Same tests as t_rmdebug2.mmp but with OEM rights conferred
+// by the OEMDebug_F123ABCD.exe token file.
+// 
+//
+
+#include "t_rmdebug2.mmh"
+
+target         t_rmdebug2_oem.exe
+
+sourcepath	   	../basic_tests
+source        	t_rmdebug2.cpp 
+source		r_low_memory_security_svr_session.cpp
+source		r_kernel_low_memory_security_svr_session.cpp
+source		r_user_low_memory_security_svr_session.cpp
+
+UID            0x0 0x4321bbbb
+SECUREID       0xF123abcd
+VENDORID       0x70000001
+
+CAPABILITY 	READUSERDATA POWERMGMT ALLFILES
+
+// Used when compiling tests to work in the presence of an
+// OEM Debug Token
+macro SYMBIAN_OEMDEBUG
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/rm_debug/group/t_rmdebug2_oem2.mmp	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,38 @@
+// Copyright (c) 2006-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:
+// Same tests as t_rmdebug2.mmp but with some OEM rights conferred
+// by the OEMDebug_F1234567.exe token file.
+// 
+//
+
+#include "t_rmdebug2.mmh"
+
+target         t_rmdebug2_oem2.exe
+
+sourcepath	   	../basic_tests
+source        	t_rmdebug2.cpp 
+source		r_low_memory_security_svr_session.cpp
+source		r_kernel_low_memory_security_svr_session.cpp
+source		r_user_low_memory_security_svr_session.cpp
+
+UID            0x0 0x4321bbbb
+SECUREID       0xF1234567
+VENDORID       0x70000001
+
+CAPABILITY 	READUSERDATA POWERMGMT
+
+// Used when compiling tests to work in the presence of an
+// OEM Debug Token with AllFiles only capability
+macro SYMBIAN_OEM2DEBUG
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/rm_debug/group/t_rmdebug2_oemtoken.mmp	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,36 @@
+// Copyright (c) 2007-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:
+// 
+//
+
+ALWAYS_BUILD_AS_ARM
+
+target         OEMDebug_F123ABCD.exe
+targettype     exe
+
+sourcepath	   	../basic_tests
+
+source        	t_rmdebug2_oemtoken.cpp 
+
+library		euser.lib
+
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN
+
+capability PowerMgmt AllFiles Tcb ReadUserData WriteUserData
+
+UID            0x0 0x0
+SECUREID       0x0
+VENDORID       0x70000001
+
+SMPSAFE
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/rm_debug/group/t_rmdebug2_oemtoken2.mmp	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,37 @@
+// Copyright (c) 2007-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:
+// 
+//
+
+ALWAYS_BUILD_AS_ARM
+
+target         OEMDebug_F1234567.exe
+targettype     exe
+
+sourcepath	   	../basic_tests
+
+source        	t_rmdebug2_oemtoken.cpp 
+
+library		euser.lib
+
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN
+
+// Token requires AllFiles
+capability AllFiles ReadUserData PowerMgmt
+
+UID            0x0 0x0
+SECUREID       0x0
+VENDORID       0x70000001
+
+SMPSAFE
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/rm_debug/group/t_rmdebug_app.mmp	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,35 @@
+// Copyright (c) 2007-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             t_rmdebug_app.exe
+targettype         exe
+
+sourcepath         ../debug_targets
+source             t_rmdebug_app.cpp 
+source			   d_rmdebugthreadasm2.cia
+
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN
+library            euser.lib hal.lib
+
+uid                0x0 0x0
+capability         none
+
+always_build_as_arm
+pagedcode
+
+DEBUGGABLE
+
+SMPSAFE
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/rm_debug/group/t_rmdebug_app1.mmp	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,36 @@
+// Copyright (c) 2007-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 application to be debugged
+// 
+//
+
+target             t_rmdebug_app1.exe
+targettype         exe
+
+sourcepath         ../debug_targets
+source             t_rmdebug_app.cpp 
+source             d_rmdebugthreadasm2.cia
+
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN
+library            euser.lib hal.lib
+
+uid                0x0 0x0
+capability         none
+
+always_build_as_arm
+pagedcode
+
+DEBUGGABLE
+
+SMPSAFE
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/rm_debug/group/t_rmdebug_app10.mmp	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,36 @@
+// Copyright (c) 2007-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 application to be debugged
+// 
+//
+
+target             t_rmdebug_app10.exe
+targettype         exe
+
+sourcepath         ../debug_targets
+source             t_rmdebug_app.cpp 
+source             d_rmdebugthreadasm2.cia
+
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN
+library            euser.lib hal.lib
+
+uid                0x0 0x0
+capability         none
+
+always_build_as_arm
+pagedcode
+
+DEBUGGABLE
+
+SMPSAFE
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/rm_debug/group/t_rmdebug_app2.mmp	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,36 @@
+// Copyright (c) 2007-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 application to be debugged
+// 
+//
+
+target             t_rmdebug_app2.exe
+targettype         exe
+
+sourcepath         ../debug_targets
+source             t_rmdebug_app.cpp 
+source             d_rmdebugthreadasm2.cia
+
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN
+library            euser.lib hal.lib
+
+uid                0x0 0x0
+capability         none
+
+always_build_as_arm
+pagedcode
+
+DEBUGGABLE
+
+SMPSAFE
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/rm_debug/group/t_rmdebug_app3.mmp	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,36 @@
+// Copyright (c) 2007-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 application to be debugged
+// 
+//
+
+target             t_rmdebug_app3.exe
+targettype         exe
+
+sourcepath         ../debug_targets
+source             t_rmdebug_app.cpp 
+source             d_rmdebugthreadasm2.cia
+
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN
+library            euser.lib hal.lib
+
+uid                0x0 0x0
+capability         none
+
+always_build_as_arm
+pagedcode
+
+DEBUGGABLE
+
+SMPSAFE
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/rm_debug/group/t_rmdebug_app4.mmp	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,36 @@
+// Copyright (c) 2007-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 application to be debugged
+// 
+//
+
+target             t_rmdebug_app4.exe
+targettype         exe
+
+sourcepath         ../debug_targets
+source             t_rmdebug_app.cpp 
+source             d_rmdebugthreadasm2.cia
+
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN
+library            euser.lib hal.lib
+
+uid                0x0 0x0
+capability         none
+
+always_build_as_arm
+pagedcode
+
+DEBUGGABLE
+
+SMPSAFE
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/rm_debug/group/t_rmdebug_app5.mmp	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,36 @@
+// Copyright (c) 2007-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 application to be debugged
+// 
+//
+
+target             t_rmdebug_app5.exe
+targettype         exe
+
+sourcepath         ../debug_targets
+source             t_rmdebug_app.cpp 
+source             d_rmdebugthreadasm2.cia
+
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN
+library            euser.lib hal.lib
+
+uid                0x0 0x0
+capability         none
+
+always_build_as_arm
+pagedcode
+
+DEBUGGABLE
+
+SMPSAFE
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/rm_debug/group/t_rmdebug_app6.mmp	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,36 @@
+// Copyright (c) 2007-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 application to be debugged
+// 
+//
+
+target             t_rmdebug_app6.exe
+targettype         exe
+
+sourcepath         ../debug_targets
+source             t_rmdebug_app.cpp 
+source             d_rmdebugthreadasm2.cia
+
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN
+library            euser.lib hal.lib
+
+uid                0x0 0x0
+capability         none
+
+always_build_as_arm
+pagedcode
+
+DEBUGGABLE
+
+SMPSAFE
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/rm_debug/group/t_rmdebug_app7.mmp	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,36 @@
+// Copyright (c) 2007-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 application to be debugged
+// 
+//
+
+target             t_rmdebug_app7.exe
+targettype         exe
+
+sourcepath         ../debug_targets
+source             t_rmdebug_app.cpp 
+source             d_rmdebugthreadasm2.cia
+
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN
+library            euser.lib hal.lib
+
+uid                0x0 0x0
+capability         none
+
+always_build_as_arm
+pagedcode
+
+DEBUGGABLE
+
+SMPSAFE
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/rm_debug/group/t_rmdebug_app8.mmp	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,36 @@
+// Copyright (c) 2007-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 application to be debugged
+// 
+//
+
+target             t_rmdebug_app8.exe
+targettype         exe
+
+sourcepath         ../debug_targets
+source             t_rmdebug_app.cpp 
+source             d_rmdebugthreadasm2.cia
+
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN
+library            euser.lib hal.lib
+
+uid                0x0 0x0
+capability         none
+
+always_build_as_arm
+pagedcode
+
+DEBUGGABLE
+
+SMPSAFE
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/rm_debug/group/t_rmdebug_app9.mmp	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,36 @@
+// Copyright (c) 2007-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 application to be debugged
+// 
+//
+
+target             t_rmdebug_app9.exe
+targettype         exe
+
+sourcepath         ../debug_targets
+source             t_rmdebug_app.cpp 
+source             d_rmdebugthreadasm2.cia
+
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN
+library            euser.lib hal.lib
+
+uid                0x0 0x0
+capability         none
+
+always_build_as_arm
+pagedcode
+
+DEBUGGABLE
+
+SMPSAFE
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/rm_debug/group/t_rmdebug_dll.mmp	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,38 @@
+// Copyright (c) 2007-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:
+// 
+//
+
+ALWAYS_BUILD_AS_ARM
+
+target         t_rmdebug_dll.dll
+targettype     dll
+
+DEFFILE        ../../~/t_rmdebug_dll.def
+
+sourcepath	   	../debug_targets
+
+source        	t_rmdebug_dll.cpp 
+
+library		euser.lib
+
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN
+
+capability PowerMgmt AllFiles ReadUserData
+
+UID            0x0 0x0
+SECUREID       0x0
+VENDORID       0x70000001
+
+SMPSAFE
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/rm_debug/group/t_rmdebug_multi_agent.mmp	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,41 @@
+// Copyright (c) 2006-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:
+// Application that tests the ability of the run mode debug component 
+// to debug multiple targets 
+// 
+//
+
+targettype     exe
+target         t_rmdebug_multi_agent.exe
+
+library		euser.lib hal.lib
+
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN
+
+userinclude    ../debug_targets
+userinclude    ../common
+userinclude    ../multi_agent_tests
+
+sourcepath	   ../multi_agent_tests
+source         t_multi_agent.cpp t_agent_eventhandler.cpp 
+
+UID            0x0 0x4321bbbc
+SECUREID       0x1234aaab
+VENDORID       0x70000001
+
+DEBUGGABLE
+
+macro SYMBIAN_STANDARDDEBUG
+
+SMPSAFE
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/rm_debug/group/t_rmdebug_multi_target.mmp	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,43 @@
+// Copyright (c) 2006-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:
+// Application that tests the ability of the run mode debug component 
+// to debug several targets
+// 
+//
+
+ALWAYS_BUILD_AS_ARM
+
+targettype     exe
+target         t_rmdebug_multi_target.exe
+
+library		euser.lib hal.lib
+
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN
+
+userinclude    ../debug_targets
+userinclude    ../common
+userinclude    ../multi_target_tests
+
+sourcepath	   ../multi_target_tests
+source         t_multi_target.cpp 
+
+UID            0x0 0x4321bbbc
+SECUREID       0x1234aaab
+VENDORID       0x70000001
+
+DEBUGGABLE
+
+macro SYMBIAN_STANDARDDEBUG
+
+SMPSAFE
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/rm_debug/group/t_rmdebug_security0.mmp	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,36 @@
+// Copyright (c) 2006-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:
+// 
+//
+
+ALWAYS_BUILD_AS_ARM
+
+target         t_rmdebug_security0.exe
+targettype     exe
+
+sourcepath	   	../debug_targets
+source        	t_rmdebug_security.cpp 
+
+library		euser.lib hal.lib
+               
+SYMBIAN_BASE_SYSTEMINCLUDE(nkern)
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN
+
+UID            0x100039CE 0xbaaaf00d
+SECUREID       0x101F7159
+VENDORID       0x70000001
+
+DEBUGGABLE
+
+SMPSAFE
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/rm_debug/group/t_rmdebug_security1.mmp	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,35 @@
+// Copyright (c) 2006-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:
+// 
+//
+
+ALWAYS_BUILD_AS_ARM
+
+target         t_rmdebug_security1.exe
+targettype     exe
+
+sourcepath	   	../debug_targets
+source        	t_rmdebug_security.cpp 
+
+library		euser.lib hal.lib
+               
+SYMBIAN_BASE_SYSTEMINCLUDE(nkern)
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN
+
+UID            0x100039CE 0xdeadbaaa
+SECUREID       0x101F7159
+VENDORID       0x70000001
+
+
+SMPSAFE
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/rm_debug/group/t_rmdebug_security2.mmp	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,37 @@
+// Copyright (c) 2006-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:
+// 
+//
+
+ALWAYS_BUILD_AS_ARM
+
+target         t_rmdebug_security2.exe
+targettype     exe
+
+sourcepath	   	../debug_targets
+source        	t_rmdebug_security.cpp 
+
+library		euser.lib hal.lib
+               
+SYMBIAN_BASE_SYSTEMINCLUDE(nkern)
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN
+
+capability AllFiles
+
+UID            0x100039CE 0xdeadbaaa
+SECUREID       0x101F7159
+VENDORID       0x70000001
+
+
+SMPSAFE
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/rm_debug/group/t_rmdebug_security3.mmp	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,37 @@
+// Copyright (c) 2006-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:
+// 
+//
+
+ALWAYS_BUILD_AS_ARM
+
+target         t_rmdebug_security3.exe
+targettype     exe
+
+sourcepath	   	../debug_targets
+source        	t_rmdebug_security.cpp 
+
+library		euser.lib hal.lib
+               
+SYMBIAN_BASE_SYSTEMINCLUDE(nkern)
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN
+
+capability TCB AllFiles NetworkControl
+
+UID            0x100039CE 0xdeadbaaa
+SECUREID       0x101F7159
+VENDORID       0x70000001
+
+
+SMPSAFE
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/rm_debug/group/t_rmdebug_target_launcher.mmp	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,38 @@
+// Copyright (c) 2006-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:
+// Application that test the ability of the run mode debug component 
+// to handle several target applications
+// 
+//
+
+target         t_rmdebug_target_launcher.exe
+targettype     exe
+
+library		     euser.lib
+
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN
+
+userinclude    ../common
+sourcepath	   ../common
+source         t_target_launcher.cpp 
+
+UID            0x0 0x4321bbbd
+SECUREID       0x1234aaac
+VENDORID       0x70000001
+
+DEBUGGABLE
+
+macro SYMBIAN_STANDARDDEBUG
+
+SMPSAFE
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/rm_debug/group/t_trkdummyapp.mmp	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,44 @@
+// Copyright (c) 2008-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:
+// t_trkdummyapp.mmp
+// 
+//
+
+ALWAYS_BUILD_AS_ARM
+
+target         t_trkdummyapp.exe
+targettype     exe
+
+sourcepath	   	../trk_blocking
+
+source        	t_trkdummyapp.cpp 
+
+library		euser.lib
+library         hal.lib
+library         efsrv.lib
+library         t_rmdebug_dll.lib
+
+SYMBIAN_BASE_SYSTEMINCLUDE(nkern)
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN
+
+UID            0x0 0x0
+SECUREID       0x0
+VENDORID       0x70000001
+
+CAPABILITY 	none
+
+
+
+
+SMPSAFE
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/rm_debug/metro_trk/d_rmdebugclient.h	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,100 @@
+// Copyright (c) 2006-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:
+// t_rmdebugclient.h
+// Definitions for the run mode debug agent client side sessions.
+// 
+//
+
+#ifndef RMDEBUGCLIENT_H
+#define RMDEBUGCLIENT_H
+
+class TProcessInfo
+	{
+	public:
+		TUint           iProcessID;
+		TInt            iAttributes;
+		TUint32         iPriority;
+		TBuf<KMaxName> 	iName;    
+	};
+
+class TThreadInfo
+	{
+	public:
+		TUint           iThreadID;
+		TUint8          iPriority;
+		TUint8          iThreadType;
+		TBuf<KMaxName>  iName;
+		TUint           iOwningProcessID;
+
+	// Probably would want a state element here, under debug control, stopped etc
+	// such that additional information could be provided which was only valid for
+	// stopped threads.
+
+	};
+
+class TExecReq
+	{
+	public:
+		TUint32 iRequest;       // Step, Step into, step threads
+		TUint32 iStartAddress;
+		TUint32 iStopAddress;
+
+	};
+
+class TMemoryInfo
+	{
+	public:
+		TUint32 iAddress;
+		TUint32	iSize;
+		TPtr8*	iDataPtr;
+	};
+
+
+// Client Side session
+class RDebugServSession : public RSessionBase
+	{
+	public:
+		RDebugServSession();
+		TVersion Version() const;
+
+		TInt Open();
+		TInt Close();
+
+		TInt ReadMemory(const TUint32 aThreadId, TMemoryInfo* aInfo);
+		TInt WriteMemory(const TUint32 aThreadId, TMemoryInfo* aInfo);
+
+//		TInt ReadThreadInfo(const TInt aIndex, const TInt aOwningProc, TThreadInfo* aInfo);
+//		TInt ReadProcessInfo(const TInt aIndex, TProcessInfo* aInfo);
+		TInt SuspendThread(const TInt ThreadID);
+		TInt ResumeThread(const TInt ThreadID);
+
+	private:
+		RThread iServerThread;       
+	};
+
+// Function codes (opcodes) used in message passing between client and server
+enum TDebugServRqst
+	{
+	EDebugServOpen = 1,
+	EDebugServClose,
+
+	EDebugServSuspendThread,
+	EDebugServResumeThread,
+//	EDebugServReadProcessInfo,
+//	EDebugServReadThreadInfo,
+	EDebugServReadMemory,
+	EDebugServWriteMemory,
+	};
+
+#endif // RMDEBUGCLIENT_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/rm_debug/metro_trk/d_rmdebugserver.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,453 @@
+// Copyright (c) 2006-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:
+// Provides the debug agent server implementation.
+// 
+//
+
+#include <e32base.h>
+#include <e32base_private.h>
+#include <e32cons.h>
+#include <trkkerneldriver.h>
+#include "d_rmdebugserver.h"
+#include "d_rmdebugclient.h"
+#include "t_rmdebug.h"
+
+
+CDebugServServer::CDebugServServer(CActive::TPriority aActiveObjectPriority)
+   : CServer2(aActiveObjectPriority)
+//
+// Server constructor
+//
+	{
+	}
+
+CSession2* CDebugServServer::NewSessionL(const TVersion& /*aVersion*/, const RMessage2& /*aMessage*/) const
+//
+// Session constructor
+//
+	{
+	// make sure the kernel side device driver is not already loaded
+   TInt err;
+	err = User::LoadLogicalDevice(KDebugDriverFileName);
+	if ((KErrNone == err) || (KErrAlreadyExists == err))
+       {
+       return new(ELeave) CDebugServSession();
+       }
+   else
+       {
+       return (NULL);
+       }
+	}   
+
+CDebugServSession::CDebugServSession()
+// Session implementation
+	{
+   TInt err;
+	TMetroTrkDriverInfo info;
+   info.iUserLibraryEnd = 0;
+   err = iKernelDriver.Open(info);
+   if (KErrNone != err)
+		{
+ 		User::Leave(err);
+		}          
+	}
+
+CDebugServSession::~CDebugServSession()
+//
+// Session destructor
+//
+	{
+	// stop the kernel side driver
+	iKernelDriver.Close();
+
+	User::FreeLogicalDevice(KDebugDriverName);
+	}
+
+
+void CDebugServSession::ServiceL(const RMessage2& aMessage)
+//
+// Session service handler
+//
+	{
+	TInt res = KErrNone;
+
+	switch(aMessage.Function())
+		{
+		case EDebugServResumeThread:
+			res = ResumeThread(aMessage);
+			break;
+
+		case EDebugServSuspendThread:
+			res = SuspendThread(aMessage);
+			break;          
+
+//		case EDebugServReadProcessInfo:
+//			res = ReadProcessInfo(aMessage);
+//			break;        
+//
+//		case EDebugServReadThreadInfo:
+//			res = ReadThreadInfo(aMessage);
+//			break;
+
+		case EDebugServReadMemory:
+			res = ReadMemory(aMessage);
+			break;        
+
+		case EDebugServWriteMemory:
+			res = WriteMemory(aMessage);
+			break;        
+
+		default:
+			User::Leave(KErrNotSupported);
+			break;
+		}
+
+	aMessage.Complete(res);
+	}
+
+
+
+TInt CDebugServSession::SuspendThread(const RMessage2& aMessage)
+//
+// Session suspend thread
+//
+	{
+	TInt err;
+
+	err = iKernelDriver.SuspendThread(aMessage.Int0());
+
+	return err;
+	}
+
+TInt CDebugServSession::ResumeThread(const RMessage2& aMessage)
+//
+// Server resume thread
+//
+	{
+	TInt err;
+
+	err = iKernelDriver.ResumeThread(aMessage.Int0());
+
+	return err;
+	}
+
+//TInt CDebugServSession::ReadProcessInfo(const RMessage2& aMessage)
+////
+//// Server read process information
+////
+//	{
+//	TInt err;
+//	TProcessInfo procinfo;
+//	TMetroTrkTaskInfo processInfo(0);
+//
+//	err = iKernelDriver.GetProcessInfo(aMessage.Int0(), processInfo);
+//
+//	if (KErrNone == err)
+//		{
+//		procinfo.iProcessID = processInfo.iId;
+//		procinfo.iPriority = processInfo.iPriority;
+//		procinfo.iName.Copy(processInfo.iName);
+//
+//		TPckgBuf<TProcessInfo> p(procinfo);
+//		aMessage.WriteL(1,p);        
+//		}
+//
+//	return err;
+//	}
+//
+//TInt CDebugServSession::ReadThreadInfo(const RMessage2& aMessage)
+////
+//// Server read thread information
+////
+//	{
+//	TInt err;
+//	TThreadInfo thrdinfo;
+//	TMetroTrkTaskInfo threadInfo(aMessage.Int1()); // Sets OtherID to the second input parameter in aMessage
+//
+//	// aMessage.Int0 is the index into the thread list for the process
+//	err = iKernelDriver.GetThreadInfo(aMessage.Int0(), threadInfo);	   
+//
+//	if (KErrNone == err)
+//		{
+//		thrdinfo.iThreadID = threadInfo.iId;
+//		thrdinfo.iPriority = threadInfo.iPriority;
+//		thrdinfo.iName.Copy(threadInfo.iName);
+//		thrdinfo.iOwningProcessID = threadInfo.iOtherId;
+//
+//		TPckgBuf<TThreadInfo> p(thrdinfo);
+//
+//		// Write out the results to the third argument passed in (pointer to the threadinfo structure)
+//		aMessage.WriteL(2,p);           
+//		}
+//
+//	return err;
+//	}
+
+TInt CDebugServSession::ReadMemory(const RMessage2& aMessage)
+//
+// Server read process memory
+//
+	{   
+	TInt err;
+	TUint32 threadId = aMessage.Int0();
+	TPckgBuf<TMemoryInfo> pckg = *(TPckgBuf<TMemoryInfo> *)(aMessage.Ptr1());
+	TMemoryInfo* InputMemoryInfo = &pckg();
+
+	TPtr8 *ptrtst = InputMemoryInfo->iDataPtr;
+
+	err = iKernelDriver.ReadMemory(threadId, InputMemoryInfo->iAddress, InputMemoryInfo->iSize, *ptrtst);
+
+	return err;
+	}
+
+TInt CDebugServSession::WriteMemory(const RMessage2& aMessage)
+//
+// Server write process memory
+//
+	{
+	TInt err;
+	TUint32 threadId = aMessage.Int0();
+	TPckgBuf<TMemoryInfo> pckg = *(TPckgBuf<TMemoryInfo> *)(aMessage.Ptr1());
+	TMemoryInfo* InputMemoryInfo = &pckg();
+
+	TPtr8 *ptrtst = InputMemoryInfo->iDataPtr;
+
+	err = iKernelDriver.WriteMemory(threadId, InputMemoryInfo->iAddress, InputMemoryInfo->iSize, *ptrtst);
+
+	return err;
+	}
+
+
+GLDEF_C TInt CDebugServServer::ThreadFunction(TAny*)
+//
+// Server thread function, continues until active scheduler stops
+//
+	{
+	CTrapCleanup* cleanup=CTrapCleanup::New();
+	if (cleanup == NULL)
+		{
+		User::Leave(KErrNoMemory);
+		}
+
+	CActiveScheduler *pA=new CActiveScheduler;
+	CDebugServServer *pS=new CDebugServServer(EPriorityStandard);
+
+	CActiveScheduler::Install(pA);
+
+	TInt err = pS->Start(KDebugServerName);
+	if (err != KErrNone)
+		{
+		User::Leave(KErrNone);
+		}
+
+	RThread::Rendezvous(KErrNone);
+
+	CActiveScheduler::Start();
+
+	delete pS;
+	delete pA;
+	delete cleanup;
+
+	return (KErrNone);
+	}
+
+
+
+EXPORT_C TInt StartThread(RThread& aServerThread)
+//
+// Start the server thread
+//
+	{
+	TInt res=KErrNone;
+
+	TFindServer finddebugserver(KDebugServerName);
+	TFullName name;
+
+	if (finddebugserver.Next(name) != KErrNone)
+		{
+		res = aServerThread.Create( KDebugServerName,
+									CDebugServServer::ThreadFunction,
+									KDefaultStackSize,
+									KDefaultHeapSize,
+									KDefaultHeapSize,
+									NULL
+									);
+
+		if (res == KErrNone)
+			{
+			TRequestStatus rendezvousStatus;
+
+			aServerThread.SetPriority(EPriorityNormal);
+			aServerThread.Rendezvous(rendezvousStatus);
+			aServerThread.Resume();
+			User::WaitForRequest(rendezvousStatus);
+			}                                 
+		else
+			{
+			aServerThread.Close();
+			}
+		}
+
+	return res;
+	}
+
+
+
+RDebugServSession::RDebugServSession()
+//
+// Server session constructor
+//
+	{
+	}
+
+TInt RDebugServSession::Open()
+//
+// Session open
+//
+	{
+	TInt r = StartThread(iServerThread);
+	if (r == KErrNone)
+		{
+		r=CreateSession(KDebugServerName, Version(), KDefaultMessageSlots);
+		}
+
+	return r;
+	}
+
+
+TVersion RDebugServSession::Version(void) const
+//
+// Session version
+//
+	{
+	return (TVersion(KDebugServMajorVersionNumber, KDebugServMinorVersionNumber, KDebugServBuildVersionNumber));
+	}
+
+TInt RDebugServSession::SuspendThread(const TInt aThreadID)
+//
+// Session suspend thread request
+//
+	{
+	TIpcArgs args(aThreadID);
+	TInt res;
+	res = SendReceive(EDebugServSuspendThread, args);
+
+	return res;
+	}
+
+TInt RDebugServSession::ResumeThread(const TInt aThreadID)
+//
+// Session resume thread request
+//
+	{
+	TIpcArgs args(aThreadID);
+	TInt res;
+	res = SendReceive(EDebugServResumeThread, args);
+
+	return res;
+	}
+
+
+//TInt RDebugServSession::ReadProcessInfo(const TInt aIndex, TProcessInfo* aInfo)
+////
+//// Session read process information request
+////
+//	{
+//	TPckgBuf<TProcessInfo> pckg;
+//	pckg = *aInfo;
+//
+//	TIpcArgs args(aIndex, &pckg);
+//
+//	TInt res;
+//
+//	res = SendReceive(EDebugServReadProcessInfo, args);
+//
+//	*aInfo = pckg();
+//
+//	return res;
+//
+//	}
+//
+//TInt RDebugServSession::ReadThreadInfo(const TInt aIndex, const TInt aProc, TThreadInfo* aInfo)
+////
+//// Session read thread information request
+////
+//	{
+//	TPckgBuf<TThreadInfo> pckg;
+//	pckg = *aInfo;
+//
+//	TIpcArgs args(aIndex, aProc, &pckg);
+//
+//	TInt res;
+//
+//	res = SendReceive(EDebugServReadThreadInfo, args);
+//
+//	*aInfo = pckg();
+//
+//	return res;
+//
+//	}
+
+
+TInt RDebugServSession::ReadMemory(const TUint32 aThreadID, TMemoryInfo* aInfo)
+//
+// Session read thread memory request
+//
+	{
+	TPckgBuf<TMemoryInfo> pckg;
+	pckg = *aInfo;
+
+	TIpcArgs args(aThreadID, &pckg);
+
+	TInt res;
+
+	res = SendReceive(EDebugServReadMemory, args);
+
+	*aInfo = pckg();
+
+	return res;
+
+	}
+
+
+TInt RDebugServSession::WriteMemory(const TUint32 aThreadID, TMemoryInfo* aInfo)
+//
+// Session write thread memory request
+//
+	{
+	TPckgBuf<TMemoryInfo> pckg;
+	pckg = *aInfo;
+
+	TIpcArgs args(aThreadID, &pckg);
+
+	TInt res;
+
+	res = SendReceive(EDebugServWriteMemory, args);
+
+	return res;
+	}
+
+
+
+TInt RDebugServSession::Close()
+//
+// Session close the session and thread
+//
+	{
+	RSessionBase::Close();
+	iServerThread.Close();
+
+	return KErrNone;
+	}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/rm_debug/metro_trk/d_rmdebugserver.h	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,73 @@
+// Copyright (c) 2006-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:
+// t_rmdebugserver.h
+// Definitions for the run mode debug agent server side session.
+// 
+//
+
+#ifndef RMDEBUGSVR_H
+#define RMDEBUGSVR_H
+
+// Server name
+_LIT(KDebugServerName,"DebugServer");
+_LIT(KDebugDriverName,"MetroTrk Driver");
+_LIT(KDebugDriverFileName,"trkdriver.ldd");
+
+// A version must be specifyed when creating a session with the server
+const TUint KDebugServMajorVersionNumber=0;
+const TUint KDebugServMinorVersionNumber=1;
+const TUint KDebugServBuildVersionNumber=1;
+const TUint KDefaultMessageSlots=4;
+const TUint KDefaultHeapSize=0x10000;
+
+class CDebugServSession;
+
+
+// Server
+class CDebugServServer : public CServer2
+	{
+	public:
+		CSession2* NewSessionL(const TVersion& aVersion, const RMessage2& aMessage) const;
+	public:
+		static TInt ThreadFunction(TAny* aStarted);
+	protected:
+		CDebugServServer(CActive::TPriority aActiveObjectPriority);
+	};
+
+// Server side session
+class CDebugServSession : public CSession2
+	{
+	public:
+		CDebugServSession();
+		~CDebugServSession();
+		void ConstructL ( void );
+		void ServiceL(const RMessage2& aMessage);
+
+		TInt ReadMemory(const RMessage2& aMessage);
+		TInt WriteMemory(const RMessage2& aMessage);
+
+//		TInt ReadProcessInfo(const RMessage2& aMessage);
+//		TInt ReadThreadInfo(const RMessage2& aMessage);
+
+		TInt ResumeThread(const RMessage2& aMessage);
+		TInt SuspendThread(const RMessage2& aMessage);
+
+	public:
+		RMetroTrkDriver iKernelDriver;	
+
+	private:
+	};
+
+
+#endif // RMDEBUGSVR_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/rm_debug/metro_trk/t_rmdebug.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,347 @@
+// Copyright (c) 2006-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 the functionality of the run mode debug device driver.
+// 
+//
+
+#include <e32base.h>
+#include <e32base_private.h>
+#include <e32cons.h>
+#include <e32test.h>
+#include <e32ldr.h>
+#include <f32dbg.h>
+#include "d_rmdebugclient.h"
+#include "d_rmdebugthread.h"
+#include "t_rmdebug.h"
+
+IMPORT_C TInt StartDebugThread(RThread& aServerThread);
+IMPORT_D extern TInt TestData;
+IMPORT_D extern TBuf8<SYMBIAN_RMDBG_MEMORYSIZE> gMemoryAccessBytes;
+
+LOCAL_D RTest test(_L("T_RMDEBUG"));
+
+CRunModeAgent::CRunModeAgent()
+//
+// CRunModeAgent constructor
+//
+	{
+	}
+
+CRunModeAgent* CRunModeAgent::NewL()
+//
+// CRunModeAgent::NewL
+//
+	{
+	CRunModeAgent* self = new(ELeave) CRunModeAgent();
+
+  	self->ConstructL();
+
+   if (self->iState != ERunModeAgentRunning)
+       {
+       delete self;
+       self = NULL;
+       }       
+	return self;
+	}
+
+CRunModeAgent::~CRunModeAgent()
+//
+// CRunModeAgent destructor
+//
+	{
+	iServSession.Close();
+	iDebugThread.Close();
+   iState = ERunModeAgentUnInit;
+	}
+
+void CRunModeAgent::ConstructL()
+//
+// CRunModeAgent::ConstructL
+//
+	{
+	TInt err;
+	err = StartDebugThread(iDebugThread);
+
+	if (err == KErrNone)
+		{
+		if (iServSession.Open() == KErrNone)
+           {
+           iState = ERunModeAgentRunning;
+           }
+       else
+           {
+           iState = ERunModeAgentUnInit;
+           }
+		}
+	else
+		{
+		User::Panic(_L("Can't start debug thread"), err);
+		}
+}
+
+
+
+CRunModeAgent *RunModeAgent;
+
+// Test process names
+_LIT(ProcessName1,"T_RMDEBUG");
+_LIT(ProcessName1a,"t_rmdebug");
+//_LIT(ProcessName2,"ekern");
+//_LIT(ProcessName3,"efile");
+_LIT(KWildCard,"*");
+
+
+//---------------------------------------------
+//! @SYMTestCaseID KBase-0185
+//! @SYMTestType 
+//! @SYMPREQ PREQ1426
+//! @SYMTestCaseDesc Test reading process list
+//! @SYMTestActions Several calls to read the process list
+//! @SYMTestExpectedResults KErrNone and the owning process ID set
+//! @SYMTestPriority High
+//! @SYMTestStatus Implemented
+//---------------------------------------------
+void CRunModeAgent::TestProcessList()
+	{
+	TInt    err=KErrNone;
+	TBool	found = FALSE;
+
+	test.Next(_L("TestProcessList - Read Process List\n"));
+
+	TFindProcess find(KWildCard);
+	TFullName name;
+	while(find.Next(name)==KErrNone)
+		{
+		RProcess process;
+		err = process.Open(find);
+		if (err == KErrNone)
+			{
+			if ((name.Find(ProcessName1) != KErrNotFound) ||
+				(name.Find(ProcessName1a) != KErrNotFound))
+				{				
+					iProcessID = process.Id();
+					found = TRUE;				
+				}
+			process.Close();				
+			}
+	   }   
+	test(found== TRUE);   
+	}
+
+// Test thread name
+_LIT(ThreadName1,"DebugThread");
+
+//---------------------------------------------
+//! @SYMTestCaseID KBase-0186
+//! @SYMTestType 
+//! @SYMPREQ PREQ1426
+//! @SYMTestCaseDesc Test reading thread list
+//! @SYMTestActions Several calls to read the thread list
+//! @SYMTestExpectedResults KErrNone and the debug thread ID set
+//! @SYMTestPriority High
+//! @SYMTestStatus Implemented
+//---------------------------------------------
+void CRunModeAgent::TestThreadList()
+	{
+	TInt        err=KErrNone;
+	TBool       found = FALSE;
+
+	test.Next(_L("TestThreadList - Read Thread List\n"));
+
+   	TFindThread find(KWildCard);
+	TFullName name;
+	while(find.Next(name)==KErrNone)
+		{
+		RThread thread;
+		err = thread.Open(find);
+       	if (err == KErrNone)
+			{
+			RProcess process;
+			thread.Process(process);
+			if (((TUint32)process.Id() == iProcessID) &&
+				(name.Find(ThreadName1) != KErrNotFound))
+				{
+				found = TRUE;           
+				iThreadID = thread.Id();
+				}
+			}
+			thread.Close();
+   		}   
+
+	test(found==TRUE);   
+	}
+
+   
+//---------------------------------------------
+//! @SYMTestCaseID KBase-0187
+//! @SYMTestType 
+//! @SYMPREQ PREQ1426
+//! @SYMTestCaseDesc Test reading and writing thread memory
+//! @SYMTestActions Several call to read and write blocks of thread memory
+//! @SYMTestExpectedResults KErrNone
+//! @SYMTestPriority High
+//! @SYMTestStatus Implemented
+//---------------------------------------------
+void CRunModeAgent::TestMemoryAccess()
+{
+	TInt err=KErrNone;
+	TMemoryInfo MemoryInfo;
+	TInt i;
+
+	test.Next(_L("TestMemoryAccess - Read Memory\n"));     
+
+	for (i = 0; i < SYMBIAN_RMDBG_MEMORYSIZE; i++)
+		{
+		gMemoryAccessBytes.Append(i);
+		}
+
+	MemoryInfo.iAddress = (TUint32)(&gMemoryAccessBytes[0]);
+	MemoryInfo.iSize = SYMBIAN_RMDBG_MEMORYSIZE;
+
+	HBufC8 *data = HBufC8::NewLC(SYMBIAN_RMDBG_MEMORYSIZE);
+	TPtr8 ptr_memread(data->Des());   
+	MemoryInfo.iDataPtr = &ptr_memread;
+
+//	test.Printf(_L("Read address = 0x%x Read size = 0x%x\n"),MemoryInfo.iAddress,MemoryInfo.iSize);
+
+	err = iServSession.ReadMemory(iThreadID, &MemoryInfo);
+
+	for (i = 0; i < MemoryInfo.iSize; i++)
+		{
+		if (ptr_memread.Ptr()[i] != gMemoryAccessBytes[i])
+			{
+			err = KErrCorrupt;       		
+			}
+		}
+
+
+	// Test out writing memory.   
+	test.Next(_L("TestMemoryAccess - Write Memory\n"));
+//	test.Printf(_L("Write address = 0x%x Write size = 0x%x\n"),MemoryInfo.iAddress,MemoryInfo.iSize);
+	if (err== KErrNone)
+		{
+		// Now reset the buffer
+		for (i = 0; i < SYMBIAN_RMDBG_MEMORYSIZE; i++)
+			{
+			gMemoryAccessBytes[i] = 0;
+			}      
+
+		// Write our data into the buffer
+		err = iServSession.WriteMemory(iThreadID, &MemoryInfo);
+
+		for (i = 0; i < MemoryInfo.iSize; i++)
+			{
+			if (ptr_memread.Ptr()[i] != gMemoryAccessBytes[i])
+				{
+				err = KErrCorrupt;       		
+				}
+			}
+
+		}
+
+	if (gMemoryAccessBytes[5] == 0)
+		{
+		err = KErrCorrupt;
+		}
+
+	CleanupStack::PopAndDestroy(data);       
+	test(err==KErrNone);   
+	}
+
+
+//---------------------------------------------
+//! @SYMTestCaseID KBase-0188
+//! @SYMTestType 
+//! @SYMPREQ PREQ1426
+//! @SYMTestCaseDesc Test suspending and resuming a task
+//! @SYMTestActions Suspends a thread checks the contents of a variable then waits and tests it hasnt changed
+//! @SYMTestExpectedResults KErrNone
+//! @SYMTestPriority High
+//! @SYMTestStatus Implemented
+//---------------------------------------------
+void CRunModeAgent::TestSuspendResume()
+	{
+	TInt err;
+
+	test.Next(_L("TestSuspendResume - Suspend\n"));
+	// Suspend the thread
+	err = iServSession.SuspendThread(iThreadID);
+	test(err==KErrNone);
+	TInt localtestdata;
+	localtestdata = TestData;
+
+	// Wait 3 seconds (suspends this thread) and hopefully resumes the
+	// thread we are controlling via the iServSession.SuspendThread request
+	User::After(3000000);
+
+	// Now check data hasnt changed
+	test(localtestdata==TestData);
+
+	// Resume the thread
+	test.Next(_L("TestSuspendResume - Resume\n"));
+	err = iServSession.ResumeThread(iThreadID);
+	test(err==KErrNone);
+
+	// Wait 3 seconds (suspends this thread) and hopefully resumes the
+	// thread we are controlling via the iServSession.SuspendThread request
+	User::After(3000000);
+
+	// Now check that the thread being controlled has resumed and is
+	// updating the variable
+	test(localtestdata!=TestData);
+	}
+   
+void CRunModeAgent::ClientAppL()
+//
+// Performs each test in turn
+//
+	{
+	test.Start(_L("ClientAppL"));
+
+	TestProcessList();
+	TestThreadList();
+	TestMemoryAccess();
+	TestSuspendResume();
+	test.End();   
+	}
+
+GLDEF_C TInt E32Main()
+//
+// Entry point for run mode debug driver test
+//
+	{
+   TInt ret = KErrNone;
+   
+	// client
+	CTrapCleanup* trap = CTrapCleanup::New();
+	if (!trap)
+		return KErrNoMemory;
+
+   RunModeAgent = CRunModeAgent::NewL();
+   if (RunModeAgent != NULL)
+       {
+   	test.Title();
+
+        __UHEAP_MARK;
+	    TRAPD(r,RunModeAgent->ClientAppL());
+       ret = r;
+	    __UHEAP_MARKEND;
+
+	    delete RunModeAgent;
+       }
+       
+	delete trap;
+
+	return ret;
+	}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/rm_debug/metro_trk/t_rmdebug.h	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,61 @@
+// Copyright (c) 2006-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:
+// Definitions for the run mode debug tests
+// 
+//
+
+#ifndef RMDEBUG_H
+#define RMDEBUG_H
+
+// Function codes (opcodes) used in message passing between client and server
+enum TRunModeAgentState
+	{
+	ERunModeAgentUnInit,
+    ERunModeAgentRunning,
+	};
+
+
+//
+// class CRunModeAgent
+//
+// The basic run mode agent.
+//
+class CRunModeAgent : public CBase
+	{
+	public:
+		static CRunModeAgent* NewL();
+		~CRunModeAgent();
+		void ClientAppL();
+
+	private:
+		CRunModeAgent();
+		void ConstructL();
+
+		TInt TestStartup();
+		TInt TestShutdown();
+
+		void TestProcessList();
+		void TestThreadList();
+		void TestMemoryAccess();
+		void TestSuspendResume();
+
+	private:
+		RDebugServSession	iServSession;
+		RThread				iDebugThread;
+		TInt				iProcessID;
+		TInt				iThreadID;
+        TInt                iState;
+	};
+
+#endif // RMDEBUG_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/rm_debug/multi_agent_tests/t_agent_eventhandler.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,124 @@
+// Copyright (c) 2007-2010 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:
+// Implements the handling of run mode events for a particular target executable
+// 
+
+#include <e32base.h>
+#include <e32property.h>
+#include <e32test.h>
+
+#include "t_rmdebug_app.h"
+#include "t_agent_eventhandler.h"
+#include "t_multi_agent.h"
+#include "t_debug_logging.h" 
+
+using namespace Debug;
+
+CAgentAsyncEvent::CAgentAsyncEvent(CMultiAgent& aDriver, const TDesC& aExeName, const TDesC& aExeConfig):
+	CActive(EPriorityStandard), iDriver(aDriver)
+	{
+	}
+
+CAgentAsyncEvent* CAgentAsyncEvent::NewLC(CMultiAgent& aDriver, const TDesC& aExeName, const TDesC& aExeConfig)
+	{
+	CAgentAsyncEvent* self = new(ELeave) CAgentAsyncEvent(aDriver, aExeName, aExeConfig);
+	CleanupStack::PushL(self);
+	self->ConstructL(aExeName, aExeConfig);
+	return self;
+	}
+
+CAgentAsyncEvent* CAgentAsyncEvent::NewL(CMultiAgent& aDriver, const TDesC& aExeName, const TDesC& aExeConfig)
+	{
+	CAgentAsyncEvent* self = CAgentAsyncEvent::NewLC(aDriver, aExeName, aExeConfig);
+	CleanupStack::Pop(); // self
+	return self;
+	}
+
+void CAgentAsyncEvent::ConstructL(const TDesC& aExeName, const TDesC& aExeConfig)
+	{
+	iExeName.CreateL(aExeName);
+	iExeConfig.CreateL(aExeConfig);
+	CActiveScheduler::Add(this);
+	}
+
+CAgentAsyncEvent::~CAgentAsyncEvent()
+	{
+	LOG_MSG2("~CAgentAsyncEvent(), this = 0x%08x", this);
+
+	iSEventInfo.iEventInfoBuf.Delete(0, sizeof(TEventInfo));
+	iExeName.Close();
+	iExeConfig.Close();
+	iProc.Close();
+	Cancel(); // Cancel any request, if outstanding
+	}
+
+/*
+ * Issue request to DSS and notify the active scheduler
+ */
+void CAgentAsyncEvent::Watch()
+	{
+	LOG_MSG2("ENTER: CAgentAsyncEvent::Watch, this = 0x%08x", this);
+	iDriver.DebugDriver().GetEvent(GetExecutable(), iStatus, iSEventInfo.iEventInfoBuf);
+
+	if (!IsActive())
+		{
+		LOG_MSG("CAgentAsyncEvent::Watch(): SetActive()");
+		SetActive();
+		}
+
+	LOG_MSG("EXIT: CAgentAsyncEvent::Watch");
+	}
+
+void CAgentAsyncEvent::RunL()
+	{
+	LOG_MSG4("ENTER: CAgentAsyncEvent::RunL iDebugType=%d, iStatus.Int() %d, this 0x%x08", 
+			 iSEventInfo.iEventInfo.iEventType, iStatus.Int(), this);
+	
+    LOG_MSG2("%S", &TPtr8((TUint8*)GetExecutable().Ptr(), 2*GetExecutable().Length(), 2*GetExecutable().Length()));	
+	iDriver.HandleEvent(iSEventInfo.iEventInfo);
+
+	LOG_MSG2("iDriver.GetNumApps() %d: ", iDriver.GetNumApps());
+	LOG_MSG2("iDriver.iLaunchCompleted  %d: ", iDriver.GetLaunchCompleted());
+
+	if (iDriver.GetLaunchCompleted() < iDriver.GetNumApps())
+		{
+		// Do not call Watch() if target has run to completion but test is still on going
+		if (iSEventInfo.iEventInfo.iEventType != EEventsRemoveProcess)
+			{
+			LOG_MSG("CAgentAsyncEvent::RunL Setting Watch()");
+			Watch();
+			}
+		}
+	else
+		{
+		// Stop event handling for all targets
+		LOG_MSG("CAgentAsyncEvent::RunL CActiveScheduler::Stop() & Cancel");
+		CActiveScheduler::Stop();
+		}
+
+	LOG_MSG2("EXIT: CAgentAsyncEvent::RunL", KNullDesC);
+	}
+
+void CAgentAsyncEvent::DoCancel()
+	{
+	LOG_MSG("CAgentAsyncEvent::DoCancel");
+	}
+
+TInt CAgentAsyncEvent::RunError(TInt aError)
+	{
+	LOG_MSG3(" RunL() has left with error %d, this 0x%08X", aError, this);
+	return aError; 
+	// Can we handle this error? Not at the moment!
+	}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/rm_debug/multi_agent_tests/t_agent_eventhandler.h	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,90 @@
+// Copyright (c) 2007-2010 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:
+// Definitions for event handling via the DSS and target specific information
+//
+//
+
+#ifndef RMDEBUG_AGENT_EVENTHANDLER_H
+#define RMDEBUG_AGENT_EVENTHANDLER_H
+
+#include "t_multi_agent.h"
+
+using namespace Debug;
+
+class CMultiAgent;
+
+/**
+ Class for gathering event data from the run-mode driver
+ */
+class TAgentEventInfo
+{
+public:
+	TAgentEventInfo() : 
+	iEventInfoBuf((TUint8*)&iEventInfo, sizeof(TEventInfo), sizeof(TEventInfo))
+	{ 	
+	}
+
+public:
+	// This is the underlying class for event interaction with the Run Mode debug API 
+	TEventInfo			iEventInfo;
+	
+	// A convenience handle for iEventInfo used across the Debug::GetEvent() method 
+	TPtr8				iEventInfoBuf;
+};
+
+/**
+  Active object class used to trap asynchronous events
+  Also, contains target specific parameters
+  */
+class CAgentAsyncEvent : public CActive
+	{
+public:
+	// Close buffers and Cancel and destroy
+	~CAgentAsyncEvent();	
+
+	// Two-phased constructor
+	static CAgentAsyncEvent* NewLC(CMultiAgent& aDriver, const TDesC& aExeName, const TDesC& aExeConfig);
+
+	// Two-phased constructor
+	static CAgentAsyncEvent* NewL(CMultiAgent& aDriver, const TDesC& aExeName, const TDesC& aExeConfig);
+
+	// set up ASP and issue another request	
+	void Watch();
+
+	TDesC& GetExecutable() { return iExeName; }
+ 	TDesC& GetExeConfig() { return iExeConfig; }
+	RProcess& GetProcHandle() { return iProc; }
+
+protected:
+	// from CActive
+	virtual void RunL();
+	virtual void DoCancel();
+	virtual TInt RunError(TInt aError);
+
+private:
+	CAgentAsyncEvent(CMultiAgent& aDriver, const TDesC& aExeName, const TDesC& aExeConfig);
+	void ConstructL(const TDesC& aExeName, const TDesC& aExeConfig);
+
+private:
+	RBuf iExeName;
+	RBuf iExeConfig;
+	RProcess iProc;
+
+	CMultiAgent& iDriver;
+	TAgentEventInfo iSEventInfo;
+	};
+
+#endif // RMDEBUG_AGENT_EVENTHANDLER_H
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/rm_debug/multi_agent_tests/t_debug_logging.h	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,52 @@
+// Copyright (c) 2006-2010 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:
+// Logging macros for use in debug subsystem
+// 
+//
+
+#ifndef RMDEBUG_MULTI_AGENT_LOGGING_H
+#define RMDEBUG_MULTI_AGENT_LOGGING_H
+
+/* Debug messages
+ * 
+ * Debug messages are only generated for debug builds.
+ * 
+ * As user mode use RDebug::Printf(). 
+ * 
+ */
+
+// Uncomment if logging of multi agent test required
+// #define MULTI_AGENT_DEBUG_LOGGING 
+
+#ifdef MULTI_AGENT_DEBUG_LOGGING
+
+    #include <e32debug.h>
+
+    #define LOG_MSG( a )              RDebug::Printf( a )
+    #define LOG_MSG2( a, b )          RDebug::Printf( a, b )
+    #define LOG_MSG3( a, b, c )       RDebug::Printf( a, b, c )
+    #define LOG_MSG4( a, b, c, d )    RDebug::Printf( a, b, c, d )
+    #define LOG_MSG5( a, b, c, d, e )    RDebug::Printf( a, b, c, d, e )
+
+#else
+
+  #define LOG_MSG( a )
+  #define LOG_MSG2( a, b )
+  #define LOG_MSG3( a, b, c )
+  #define LOG_MSG4( a, b, c, d )
+  #define LOG_MSG5( a, b, c, d, e )
+
+#endif
+
+#endif //RMDEBUG_MULTI_AGENT_LOGGING_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/rm_debug/multi_agent_tests/t_multi_agent.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,432 @@
+// Copyright (c) 2007-2010 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 the run mode debug device component by launching multiple targets 
+// on different CPUs. On a single core the targets run on the same CPU.  
+//
+
+#include <e32base.h>
+#include <e32property.h>
+#include <hal.h>
+#include <e32test.h>
+#include <e32def.h>
+
+#include "t_rmdebug_app.h"
+#include "t_multi_agent.h"
+#include "t_agent_eventhandler.h"
+#include "t_debug_logging.h"
+
+const TVersion securityServerVersion(0,1,1);
+
+/**
+ * First phase constructor
+ */
+CMultiAgent* CMultiAgent::NewL()
+	{
+	CMultiAgent* self = new(ELeave) CMultiAgent();
+	self->ConstructL();
+	return self;
+	}
+
+/**
+  * Destructor
+  */
+CMultiAgent::~CMultiAgent()
+	{
+	LOG_MSG("~CMultiTargetAgent\n");
+	iServSession.Close();
+	}
+
+/**
+ * Constructor
+ */
+CMultiAgent::CMultiAgent() 
+	{
+	}
+
+/**
+ * Second phase constructor
+ */
+void CMultiAgent::ConstructL()
+	{
+	}
+
+/**
+  Parse the command line, set agent cpu affinity and call main test function
+  */
+void CMultiAgent::ClientAppL()
+	{
+	LOG_MSG("ENTER: CMultiTargetAgent::ClientAppL"); 
+
+	iNumApps = KNumApps;
+	iAgentCpuNo = KAgentCpu;
+	iTargetNameOffset = KTargetOffset;
+
+	TInt argc = User::CommandLineLength();
+	HBufC* commandLine = NULL;
+	LOG_MSG2(">Launcher Process() argc=%d", argc);
+	
+	if(argc)
+		{
+		commandLine = HBufC::NewLC(argc);
+		TPtr commandLineBuffer = commandLine->Des();
+		User::CommandLine(commandLineBuffer);
+
+		RBuf printCommandLine;
+		CleanupClosePushL(printCommandLine);
+		printCommandLine.CreateL(commandLine->Des().Length());
+		printCommandLine.Copy(commandLine->Des());
+		printCommandLine.Collapse();
+		LOG_MSG2(">command line = %S", &printCommandLine );
+		CleanupStack::PopAndDestroy( &printCommandLine );
+
+		// create a lexer and read through the command line
+		TLex lex(*commandLine);
+	
+		while (!lex.Eos())
+		{
+			// only look for options with first character '-'
+			if (lex.Get() == '-')
+			{
+			TChar arg = lex.Get();
+			
+				switch ( arg )
+				{
+				case 'n':
+					lex.Val( iNumApps );
+					LOG_MSG2("parsed numApps as %d", iNumApps); 
+					break;
+		
+				case 'a':
+					lex.Val( iAgentCpuNo );
+					LOG_MSG2("parsed agentCpuNo as %d", iAgentCpuNo);                        
+					break;
+
+				case 'o':
+					lex.Val( iTargetNameOffset );
+					LOG_MSG2("parsed iTargetNameOffset as %d", iTargetNameOffset);        
+					break;
+
+				default:
+					LOG_MSG("Bad argument from user"); 
+					break;                 
+				}
+			}
+		}
+	}
+	// Create active scheduler (to run active objects)
+	CActiveScheduler* scheduler = new (ELeave) CActiveScheduler();
+	CleanupStack::PushL(scheduler);
+	CActiveScheduler::Install(scheduler);
+	
+	if (iAgentCpuNo)
+		{
+		LOG_MSG2("CMultiAgent::ClientAppL() - setting agent to cpu %d", iAgentCpuNo);
+		UserSvr::HalFunction(EHalGroupKernel, EKernelHalLockThreadToCpu, (TAny *)iAgentCpuNo, 0);
+		}
+
+	TInt err = iServSession.Connect(securityServerVersion);
+	
+	if (err != KErrNone)
+		{
+		User::Panic(_L("Can't open server session"), err);
+		}
+
+	StartTest();
+
+	// Note: below is a workaround to overcome an issue with RTest server crashing 
+	// when writing to the windows console from different agents (on different CPUs 
+	// at the same time). To overcome this we signal the launcher using a global 
+	// semaphore to indicate a RTest complete instead
+	RSemaphore launchSemaphore;
+	CleanupClosePushL(launchSemaphore);
+            
+	TFindSemaphore launchSemFinder(KLaunchSemaphoreSearchString);
+	TFullName semaphoreResult;
+	TInt ret = launchSemFinder.Next(semaphoreResult);
+	LOG_MSG3( "> Find Launch Semaphote.Next ret=%d, %lS", ret, &semaphoreResult);
+         
+	ret = launchSemaphore.OpenGlobal(semaphoreResult);
+	LOG_MSG2( ">OpenGlobal semaphore ret=%d", ret );         
+    
+	LOG_MSG( ">Signalling semaphore" );
+	launchSemaphore.Signal();
+	CleanupStack::PopAndDestroy(&launchSemaphore); // launchSemaphore
+
+	// Delete active scheduler
+	CleanupStack::PopAndDestroy(scheduler);
+
+	if (commandLine)
+	CleanupStack::PopAndDestroy(commandLine);
+	
+	LOG_MSG( "EXIT: CMultiTargetAgent::ClientAppL"); 
+	}
+
+/**
+  Launch a process
+  @param aProcess the RProcess object used to create the process
+  @param aFileName file name of the executable used to create the process
+  @return KErrNone on success, or one of the other system wide error codes
+  */
+TInt CMultiAgent::LaunchProcess(RProcess& aProcess, const TDesC& aExeName, const TDesC& aCommandLine)    
+	{
+	LOG_MSG( "ENTER: CMultiAgent::LaunchProcess");
+    LOG_MSG2("%S", &TPtr8((TUint8*)aExeName.Ptr(), 2*aExeName.Length(), 2*aExeName.Length()));	
+	
+	// wait for 0.5 seconds due to issue with creating several processes in smp quickly
+	User::After(500000);
+	
+	TInt err = aProcess.Create( aExeName, aCommandLine );
+	LOG_MSG2( "CMultiAgent::LaunchProcess, aProcess.Create err = %d", err); 
+
+	// check that there was no error raised
+	if (err != KErrNone)
+		return err;
+	
+	// rendezvous with process
+	TRequestStatus status = KRequestPending;
+	aProcess.Rendezvous(status);
+
+	if (KRequestPending != status.Int())
+		{
+		// startup failed so kill the process
+		LOG_MSG2( "> RProcess Rendezvous() failed with %d. Killing process", status.Int() );
+		aProcess.Kill(KErrNone);
+		LOG_MSG( "EXIT: CMultiAgent::LaunchProcess");
+		return status.Int();
+		}
+	else
+		{
+		// start the test target
+		aProcess.Resume();
+		User::WaitForRequest(status);
+	
+		LOG_MSG2( "> CMultiAgent::LaunchProcess: RProcess Resume() Rendezvous successful %d: ", status.Int() );
+
+		if(KErrNone != status.Int())
+			{
+			LOG_MSG2( "> RProcess Resume() failed with %d. Killing process", status.Int() );
+			aProcess.Kill(KErrNone);
+			}
+
+		LOG_MSG( "EXIT: CMultiAgent::LaunchProcess");
+		return status.Int();
+		}
+	}
+
+/**
+  Handle Event
+  @param aEventInfo object containing event information from the DSS 
+  */
+void CMultiAgent::HandleEvent(TEventInfo& aEventInfo)
+	{
+	LOG_MSG( "ENTER: CMultiAgent::HandleEvent" ); 
+	TInt ret = KErrNone;
+	const TInt idValid = 1;
+	
+	switch ( aEventInfo.iEventType )
+		{
+		case EEventsAddProcess:
+			{
+			LOG_MSG(">> EEventsAddProcess");                        
+			TPtrC8 exeNamePtr8(aEventInfo.iAddProcessInfo.iFileName, aEventInfo.iAddProcessInfo.iFileNameLength);
+	
+			RBuf8 exeName8;
+			CleanupClosePushL(exeName8);
+			exeName8.CreateL(exeNamePtr8);
+			LOG_MSG2("From event: exeName8=%S", &exeName8);
+			CleanupStack::PopAndDestroy(&exeName8);
+			LOG_MSG("Testing if event process id is valid");
+
+			LOG_MSG2("Got aEventInfo.iProcessId=%d", I64LOW( aEventInfo.iProcessId));
+			__ASSERT_ALWAYS((aEventInfo.iProcessIdValid==idValid), User::Panic(_L("ProcessId Invalid"), aEventInfo.iProcessIdValid));
+	
+			RProcess targetProc;
+			ret = targetProc.Open(TProcessId(aEventInfo.iProcessId));
+			LOG_MSG2("RProcess open ret=%d", ret);
+			targetProc.Close();
+
+			__ASSERT_ALWAYS((ret == KErrNone), User::Panic(_L("ProcessId Invalid"), aEventInfo.iProcessIdValid));
+			break;
+			}
+	
+		case EEventsStartThread:
+			{
+			LOG_MSG(">> EEventsStartThread");                
+			TPtrC8 exeNamePtr8(aEventInfo.iStartThreadInfo.iFileName, aEventInfo.iStartThreadInfo.iFileNameLength);
+			RBuf8 exe8Name;
+			CleanupClosePushL(exe8Name);
+			exe8Name.CreateL(exeNamePtr8);
+			LOG_MSG2("From event: exeName8=%S", &exe8Name);
+			CleanupStack::PopAndDestroy(&exe8Name);
+	
+			LOG_MSG("Testing if event process id is valid" );
+
+			__ASSERT_ALWAYS((aEventInfo.iProcessIdValid==idValid), User::Panic(_L("ProcessId Invalid"), aEventInfo.iProcessIdValid));
+
+			LOG_MSG2("Got aEventInfo.iProcessId=%d", I64LOW(aEventInfo.iProcessId));
+
+			LOG_MSG("Testing if event thread id is valid");
+
+			__ASSERT_ALWAYS((aEventInfo.iThreadIdValid==idValid), User::Panic(_L("ThreadId Invalid"), aEventInfo.iThreadIdValid));
+
+			LOG_MSG2("Got aEventInfo.iThreadId=%d", I64LOW(aEventInfo.iThreadId));
+			break;                    
+			}                       
+
+		case EEventsUserTrace:
+			{
+			LOG_MSG(">> EEventsUserTrace");  
+			break;
+			}
+
+		case EEventsRemoveProcess:
+			{
+			LOG_MSG( ">> EEventsRemoveProcess");                        
+			iLaunchCompleted++; 
+			break;
+			}
+	
+		default:   
+			{
+			LOG_MSG( ">> Unknown event - probably due to DSS busy?");
+			break;
+			}	
+		}
+ 	 
+	LOG_MSG("EXIT: CMultiAgent::HandleEvent"); 
+	}
+
+/**
+ * Main test function which launches several targets and stresses the DSS 
+ */
+TInt CMultiAgent::StartTest()
+	{
+	LOG_MSG("ENTER: CMultiTargetAgent::StartTest");
+
+	for( TInt i = 0; i < iNumApps; i++ )
+		{
+		RBuf targetName;
+		RBuf launcherOptions;
+
+		CleanupClosePushL(targetName); 
+		CleanupClosePushL(launcherOptions); 
+
+		targetName.CreateL( KTargetExe().Length() + 2 );
+		targetName.Format( KTargetExe(), i + iTargetNameOffset + 1 );
+
+		LOG_MSG2("App %d: ", i+1);
+		LOG_MSG2("%S", &TPtr8((TUint8*)targetName.Ptr(), 2*targetName.Length(), 2*targetName.Length()));	
+
+		launcherOptions.CreateL( KTargetOptions().Length() + 2 );
+		launcherOptions.Format( KTargetOptions(), (TUint)ENormalExit, (i+1) );
+
+		LOG_MSG( "AppOptions : ");
+		LOG_MSG2("%S", &TPtr8((TUint8*)launcherOptions.Ptr(), 2*launcherOptions.Length(), 2*launcherOptions.Length()));	
+		
+		// Add each test target to array
+		iTargetList.AppendL(CAgentAsyncEvent::NewL(*this, targetName, launcherOptions));
+		CleanupStack::PopAndDestroy(2, &targetName );
+		}
+	
+	iLaunchCompleted = 0;
+	TInt err = KErrNone;
+		
+	for (TInt i = 0; i < iNumApps; i++)
+		{
+		// Attach to process non-passively
+		LOG_MSG2( ">AttachExecutable app %d ", i + iTargetNameOffset + 1 );
+		LOG_MSG2("%S", &TPtr8((TUint8*)iTargetList[i]->GetExecutable().Ptr(), 2*iTargetList[i]->GetExecutable().Length(), 
+					2*iTargetList[i]->GetExecutable().Length()));
+
+		err = iServSession.AttachExecutable( iTargetList[i]->GetExecutable(), EFalse);
+		__ASSERT_ALWAYS((err == KErrNone), User::Panic(_L("DSS Attach failed"), err));
+
+		// Continue on interested event actions
+		LOG_MSG2( ">SetEventAction app %d,  EEventsStartThread EAcionContinue", i + iTargetNameOffset + 1);
+
+		err = iServSession.SetEventAction( iTargetList[i]->GetExecutable(), EEventsStartThread, EActionContinue);
+		__ASSERT_ALWAYS((err==KErrNone), User::Panic(_L("SetEventAction Error"), err));
+	
+		LOG_MSG2(">SetEventAction app %d,  EEventsAddProcess EActionContinue", i + iTargetNameOffset + 1);
+		err = iServSession.SetEventAction( iTargetList[i]->GetExecutable(), EEventsAddProcess, EActionContinue);
+		__ASSERT_ALWAYS((err==KErrNone), User::Panic(_L("SetEventAction Error"), err));
+
+		LOG_MSG2(">SetEventAction app %d,  EEventsUserTrace EActionContinue", i + iTargetNameOffset + 1);
+		err = iServSession.SetEventAction( iTargetList[i]->GetExecutable(), EEventsUserTrace, EActionContinue);
+		__ASSERT_ALWAYS((err==KErrNone), User::Panic(_L("SetEventAction Error"), err));
+	
+		LOG_MSG2(">SetEventAction app %d,  EEventsRemoveProcess EActionContinue", i + iTargetNameOffset + 1);
+		err = iServSession.SetEventAction( iTargetList[i]->GetExecutable(), EEventsRemoveProcess, EActionContinue);
+		__ASSERT_ALWAYS((err==KErrNone), User::Panic(_L("SetEventAction Error"), err));
+
+		// Add target object to active schedular
+		iTargetList[i]->Watch();
+		}
+
+	for (TInt i= 0; i< iNumApps; i++)
+		{
+		LOG_MSG( ">Calling LaunchProcess function");
+		err = LaunchProcess(iTargetList[i]->GetProcHandle(), iTargetList[i]->GetExecutable(), iTargetList[i]->GetExeConfig());
+		__ASSERT_ALWAYS((err==KErrNone), User::Panic(_L("LaunchProcess failed"), err));
+		}
+
+	LOG_MSG( ">CActiveScheduler::Start()");
+	CActiveScheduler::Start();
+
+	for (TInt i= 0; i < iNumApps; i++)
+		{
+		// Now detach again
+		LOG_MSG( "Before iServSession.DetachExecutable" );
+		err = iServSession.DetachExecutable(iTargetList[i]->GetExecutable());
+		__ASSERT_ALWAYS((err==KErrNone), User::Panic(_L("DetachExecutable failed"), err));
+		}
+	
+	// Free all the memory
+	iTargetList.ResetAndDestroy();
+	LOG_MSG( "EXIT: CMultiTargetAgent::StartTest" );
+
+	return KErrNone;
+	}
+
+/**
+  * Entry point for run mode debug driver test
+  */
+GLDEF_C TInt E32Main()
+	{
+	LOG_MSG( "ENTER: Multi_agent E32Main ");
+	__UHEAP_MARK;
+
+	TInt ret = KErrNone;
+	RProcess::Rendezvous(KErrNone);
+	
+	CTrapCleanup* trap = CTrapCleanup::New();
+		
+	if (!trap)
+		return KErrNoMemory;
+	
+	CMultiAgent *runModeAgent = CMultiAgent::NewL();
+
+	if (runModeAgent != NULL)
+		{
+		TRAP(ret,runModeAgent->ClientAppL());
+		LOG_MSG2( "ClientAppL returned %d", ret );
+		delete runModeAgent;
+		}
+
+	delete trap;
+	__UHEAP_MARKEND;
+	LOG_MSG( "EXIT: Multi_agent E32Main ");
+	return ret;
+	}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/rm_debug/multi_agent_tests/t_multi_agent.h	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,110 @@
+// Copyright (c) 2006-2010 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:
+// Definitions for the run mode debug tests
+// 
+//
+
+/**
+ @file
+ @internalTechnology
+ @released
+*/
+
+#ifndef RMDEBUG_MULTI_AGENT_H
+#define RMDEBUG_MULTI_AGENT_H
+
+#include <u32hal.h>
+#include <f32file.h>
+#include <rm_debug_api.h>
+
+using namespace Debug;
+
+_LIT(KLaunchSemaphoreName, "t_rmdebug_launch_semaphore");
+_LIT(KLaunchSemaphoreSearchString, "t_rmdebug_launch_semaphore*");
+
+// Currently the targets are instances of t_rmdebug_app.exe
+_LIT(KTargetExe,"z:\\sys\\bin\\t_rmdebug_app%d.exe");
+
+_LIT(KTargetOptions,"-f%d -a%d");
+
+// If changing this, make sure there are enough apps built/in the rom 
+const TInt KNumApps = 5;
+
+// Default CPU execution for Agent
+const TInt KAgentCpu = 0;
+
+// Workaround to ensure we have the same agent binary when running multiple agents
+const TInt KTargetOffset = 0;
+
+class CAgentAsyncEvent;
+
+/**
+  @Class CRunModeAgent
+  
+  The basic run mode agent
+  */
+class CMultiAgent : public CBase
+	{
+	public:
+	static CMultiAgent* NewL();
+	~CMultiAgent();
+	void ClientAppL();  
+	RSecuritySvrSession&  DebugDriver() { return iServSession; };	
+	void HandleEvent(TEventInfo& aSEventInfo);
+
+	public:
+	TInt GetLaunchCompleted() const { return iLaunchCompleted; }
+	TInt GetNumApps() const { return iNumApps; }
+	TInt GetTargetOffset() const { return iTargetNameOffset; }
+
+	private:
+	CMultiAgent();
+	void ConstructL();
+	TInt StartTest();
+	TInt LaunchProcess(RProcess& aProcess, const TDesC& aExeName, const TDesC& aCommandLine);
+	
+	private:
+
+	/**
+	 * CPU agent executes on; by default this is 0 
+	 */
+	TInt iAgentCpuNo;
+
+	/*
+	 * Offset for running multiple targets using the same agent
+	 */
+	TInt iTargetNameOffset;
+
+	/** 
+	 * Number of applications/targets per agent
+	 */
+	TInt iNumApps;
+
+	/**
+	 * Flag used for terminating the event handling for a target 
+	 */	
+	TInt iLaunchCompleted;
+
+	/*
+	 * Handle to DSS
+	 */
+	RSecuritySvrSession iServSession;
+	
+	/**
+	 * Array to target parameters required by the agent
+	 */	
+	RPointerArray<CAgentAsyncEvent> iTargetList;
+	};
+
+#endif // RMDEBUG_MULTI_AGENT_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/rm_debug/multi_agent_tests/t_multi_agent_launcher.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,229 @@
+// Copyright (c) 2007-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:
+// Helper app to launch debug targets
+//
+//
+
+#include "t_multi_agent_launcher.h"
+
+#include "t_debug_logging.h"
+
+/**
+ * Launch a process
+ * @param aProcess the RProcess object used for creating the process
+ * @param aExeName the name of the executable to run 
+ * @param aCommandLine command line parameters to pass when creating the process 
+ * @return KErrNone on success, or one of the other system wide error codes
+ */
+TInt LaunchProcess(RProcess& aProcess, TDesC& aExeName, TDesC& aCommandLine )    
+	{
+	LOG_MSG("ENTER: t_multi_agent_launcher: launchProcess"); 
+
+	LOG_MSG2("aExeName %S ", &TPtr8((TUint8*)aExeName.Ptr(), 2*aExeName.Length(), 2*aExeName.Length()));
+	LOG_MSG2("aCommandLine %S", &TPtr8((TUint8*)aCommandLine.Ptr(), 2*aCommandLine.Length(), 2*aCommandLine.Length()));
+
+	TInt err = aProcess.Create( aExeName, aCommandLine );
+	LOG_MSG2("t_multi_agent_launcher launchProcess, aProcess.Create err = %d", err); 
+
+	// check that there was no error raised
+	if(err != KErrNone)
+		{
+		return err;
+		}
+
+	// rendezvous with process
+	TRequestStatus status = KRequestPending;
+	aProcess.Rendezvous(status);
+
+	if(KRequestPending != status.Int())
+		{
+		// startup failed so kill the process
+		LOG_MSG2("t_multi_agent_launcher: launchProcess: RProcess Rendezvous() failed with %d. Killing process", status.Int());
+		aProcess.Kill(KErrNone);
+		return status.Int();
+		}
+	else
+		{
+		aProcess.Resume();
+		User::WaitForRequest(status);
+
+		LOG_MSG2("t_multi_agent_launcher: launchProcess: RProcess Resume() Rendezvous successful %d: ", status.Int());
+
+		if(KErrNone != status.Int())
+			{
+			LOG_MSG2("t_multi_agent_launcher: RProcess Resume() failed with %d. Killing process", status.Int());
+			aProcess.Kill(KErrNone);
+			}
+
+		LOG_MSG("EXIT: t_multi_agent_launcher launchProcess");
+		return status.Int();
+		}
+	}
+
+/**
+ * Read command line parameters and control the launching of the agents. 
+ */
+void MainL()
+	{	
+	LOG_MSG( "ENTER: t_multi_agent_launcher MainL()");
+
+	TInt ret = KErrNone;
+	TInt numAgents = KNumAgents;
+	TInt numTargets = KNumTargets;
+	TInt numTestRuns = KNumTestRuns;
+
+	TInt argc = User::CommandLineLength();
+	HBufC* commandLine = NULL;
+	LOG_MSG2("t_multi_agent_launcher: MainL(): argc=%d", argc);
+    
+	if(argc)
+		{
+		commandLine = HBufC::NewLC(argc);
+		TPtr commandLineBuffer = commandLine->Des();
+		User::CommandLine(commandLineBuffer);
+
+		RBuf printCommandLine;
+		CleanupClosePushL( printCommandLine );
+		printCommandLine.CreateL( commandLine->Des().Length() );
+		printCommandLine.Copy( commandLine->Des() );
+		printCommandLine.Collapse();
+		LOG_MSG2("t_multi_agent_launcher: command line = %S", &printCommandLine);
+		CleanupStack::PopAndDestroy( &printCommandLine );
+ 
+		// create a lexer and read through the command line
+		TLex lex(*commandLine);
+		while (!lex.Eos())
+			{
+			// only look for options with first character '-'
+			if (lex.Get() == '-')
+				{
+					TChar arg = lex.Get();
+					switch ( arg )
+						{
+						case 'n':
+							lex.Val( numAgents );
+							LOG_MSG2("t_multi_agent_launcher: parsed numAgents as %d", numAgents);
+							break;
+						case 'm':
+							lex.Val( numTargets );
+							LOG_MSG2("t_multi_agent_launcher: parsed numTargets as %d", numTargets);                        
+							break;  
+						case 't':
+							lex.Val( numTestRuns );
+							LOG_MSG2("t_multi_agent_launcher: parsed numTestRuns as %d", numTestRuns);                        
+							break;                    
+						default:
+							LOG_MSG("t_multi_agent_launcher: unknown argument ignoring it");
+							break;                 
+						}
+				}
+			}
+		}
+
+	// Note: below is a workaround to overcome an issue with RTest server crashing 
+	// when writing to the windows console from different agents (on different CPUs 
+	// at the same time). To overcome this we get signaled by the agents when they have 
+	// completed their tests so that we can do a RTest complete
+	RSemaphore launchSemaphore;
+	CleanupClosePushL(launchSemaphore);
+	ret = launchSemaphore.CreateGlobal(KLaunchSemaphoreName, 0);
+	LOG_MSG2( ">Target Launcher : RSemaphore.CreateGlobal ret %d", ret);
+	User::LeaveIfError( ret );
+
+	ret = launchSemaphore.OpenGlobal(KLaunchSemaphoreName);
+	LOG_MSG2( ">Target Launcher : RSemaphore.OpenGlobal ret %d", ret);
+	User::LeaveIfError( ret );
+
+	//Now launch the requested number of apps for the requested number of test runs
+	for( TInt j = 0; j < numTestRuns; j++ )
+		{ 
+			for( TInt i = 0; i < numAgents; i++ )  
+				{
+					RBuf targetName;
+					targetName.CleanupClosePushL();
+					targetName.CreateL(KAgentExe());
+
+					RProcess aProc;
+					CleanupClosePushL(aProc); 
+					RBuf launcherOptions;
+					CleanupClosePushL(launcherOptions);
+				    const TInt additionalWords = 2;	
+					launcherOptions.CreateL( KAgentOptions().Length() + additionalWords );
+		
+					// Apply offset: launcherOptions.Format( .., .., i * numTargets, ..)
+					// workaround to ensure we have the same binary for multiple agents. 
+					// e.g. So if offset = 0, agent attaches to app1, app2, app3, app4, app5
+					// if offset = 5, agent attached to app6, app7, app8, app9, app10 etc.
+					// Note: apps need to be in rom otherwise the agent will fail on an assert 
+					// (with KErrNotFound)
+					launcherOptions.Format( KAgentOptions(), (TUint)numTargets, i * numTargets, 0);
+			
+					ret = LaunchProcess( aProc, targetName, launcherOptions );	
+					CleanupStack::PopAndDestroy(3,&targetName);
+					User::LeaveIfError(ret);
+				}
+		}
+
+	// Wait for all agents to do their testing before checking the semaphore
+	User::After(12000000);
+
+	LOG_MSG( ">Target Launcher:  Semaphore wait");
+
+	for (TInt i = 0; i < numAgents; i ++)
+		{
+		//We need this delay just in case an agent crashes and never signals the sem
+		ret = launchSemaphore.Wait(100000);
+		if( ret != KErrNone )
+			{
+			LOG_MSG3("launchSemaphore.Wait ret %d for agent %d", ret, i);
+			break;
+			}
+		}
+
+	LOG_MSG2( "testing for Semaphore ret %d", ret);
+
+	// We only want to have one RTest instance at any one time since otherwise RTest can panic
+	RTest test(_L("T_MULTI_AGENT_LAUNCHER"));
+	test.Start(_L("t_multi_agent_launcher Check for agents finishing correctly"));
+	test(ret == KErrNone);
+	test.End();
+	test.Close();
+
+	CleanupStack::PopAndDestroy(&launchSemaphore); // launchSemaphore
+
+	if( commandLine )
+	CleanupStack::PopAndDestroy(commandLine);
+	
+	LOG_MSG("EXIT: t_multi_agent_launcher MainL()");
+	}
+ 
+GLDEF_C TInt E32Main()
+	{
+	LOG_MSG("ENTER: Multi_agent_launcher E32Main()");
+	__UHEAP_MARK;
+
+	CTrapCleanup* trap = CTrapCleanup::New();
+	if (!trap)
+		return KErrNoMemory;
+
+	TRAPD(err, MainL());
+	LOG_MSG2("Multi_agent_launcher: returning from MainL(), err = %d", err);
+	
+	delete trap;
+	LOG_MSG("EXIT: Multi_agent_launcher E32Main()");
+	__UHEAP_MARKEND;
+
+	return err;
+	}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/rm_debug/multi_agent_tests/t_multi_agent_launcher.h	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,45 @@
+// 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:
+// Definitions for agent launcher
+// 
+//
+
+/**
+ @file
+ @internalTechnology
+ @released
+*/
+
+#ifndef RMDEBUG_MULTI_AGENT_LAUNCHER_H
+#define RMDEBUG_MULTI_AGENT_LAUNCHER_H
+
+#include <e32test.h>
+
+// Default test runs
+const TInt KNumTestRuns = 1; 
+
+// Default number of targets per agent
+const TInt KNumTargets = 5;
+
+// Default number of agents, if changing this make sure there are enough apps being built 
+const TInt KNumAgents = 2; 
+
+_LIT(KAgentExe,"z:\\sys\\bin\\t_rmdebug_multi_agent.exe");
+_LIT(KAgentOptions,"-n%d -o%d -a%d");
+
+_LIT(KLaunchSemaphoreName, "t_rmdebug_launch_semaphore");
+_LIT(KLaunchSemaphoreSearchString, "t_rmdebug_launch_semaphore*");
+
+#endif // RMDEBUG_MULTI_AGENT_LAUNCHER_H
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/rm_debug/multi_target_tests/t_multi_target.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,402 @@
+// Copyright (c) 2006-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:
+// Test the ability of the debug system to handle events from several debug targets
+//
+//
+
+#include <e32base.h>
+#include <e32property.h>
+
+#include <hal.h>
+#include <e32test.h>
+
+#include "t_multi_target.h"
+#include "t_target_launcher.h"
+#include "t_rmdebug_app.h"
+
+#ifdef KERNEL_OOM_TESTING
+  #ifdef USER_OOM_TESTING
+    #error "Cannot define both KERNEL_OOM_TESTING and USER_OOM_TESTING"
+  #endif
+#endif
+
+
+using namespace Debug;
+
+const TVersion securityServerVersion(0,1,1);
+
+const TVersion testVersion(2,1,0);
+
+#ifdef SYMBIAN_STANDARDDEBUG
+LOCAL_D RTest test(_L("T_RMDEBUG_MULTI_TARGET"));
+#endif
+
+#ifdef SYMBIAN_OEMDEBUG
+LOCAL_D RTest test(_L("T_RMDEBUG_MULTI_TARGET_OEM"));
+#endif
+
+#ifdef SYMBIAN_OEM2DEBUG
+LOCAL_D RTest test(_L("T_RMDEBUG_MULTI_TARGET_OEM2"));
+#endif
+
+
+
+CMultiTargetAgent* CMultiTargetAgent::NewL()
+//
+// CMultiTargetAgent::NewL
+//
+  {
+  CMultiTargetAgent* self = new(ELeave) CMultiTargetAgent();
+
+  self->ConstructL();
+
+  return self;
+  }
+
+
+CMultiTargetAgent::~CMultiTargetAgent()
+//
+// CMultiTargetAgent destructor
+//
+    {
+    RDebug::Printf("~CMultiTargetAgent\n");
+    iServSession.Close();
+    }
+
+
+CMultiTargetAgent::CMultiTargetAgent() : 
+    iEventPtr( (TUint8*)&iEventInfo, sizeof(TEventInfo) )
+    {
+    }
+
+
+void CMultiTargetAgent::ConstructL()
+//
+// CMultiTargetAgent::ConstructL
+//
+  {
+  }
+
+/**
+ * Helper code for the stepping tests. Returns the number of nanokernel ticks in one second.
+ *
+ * @return Number of nanokernel ticks. 0 if unsuccesful.
+ */
+TInt CMultiTargetAgent::HelpTicksPerSecond(void)
+  {
+  TInt nanokernel_tick_period;
+  HAL::Get(HAL::ENanoTickPeriod, nanokernel_tick_period);
+
+  ASSERT(nanokernel_tick_period != 0);
+
+  static const TInt KOneMillion = 1000000;
+
+  return KOneMillion/nanokernel_tick_period;
+  }
+
+void CMultiTargetAgent::ClientAppL()
+//
+// Performs each test in turn
+//
+  {
+  TInt err = iServSession.Connect(securityServerVersion);
+  if (err != KErrNone)
+      {
+      User::Panic(_L("Can't open server session"), err);
+      }
+
+  LaunchTargetsInOrderL();
+  RDebug::Printf( "returning from CMultiTargetAgent::ClientAppL" );
+  }
+
+/**
+  Launch a process
+
+  @param aProcess The RProcess object to use to create the process
+  @param aExeName File name of the executable to create the process from
+  @param aCommandLine The command line to pass to the new process
+  @return KErrNone on success, or one of the other system wide error codes
+  */
+TInt CMultiTargetAgent::LaunchProcess(RProcess& aProcess, TDesC & aExeName, TDesC & aCommandLine )
+    {    
+    TInt err = aProcess.Create( aExeName, aCommandLine );    
+    if(err != KErrNone)
+        {
+        RDebug::Printf( "aProcess.Create ret %d", err);
+        return err;
+        }
+
+    TRequestStatus status = KRequestPending;
+    aProcess.Rendezvous(status);
+    if(KRequestPending != status.Int())
+        {
+        // startup failed so kill the process
+        aProcess.Kill(KErrNone);
+        return status.Int();
+        }
+    else
+        {
+        // start up succeeded so resume the process
+        aProcess.Resume();
+        // Give the process a chance to run
+        User::After( 500000 );
+        return KErrNone;
+        }
+    }
+
+void CMultiTargetAgent::SetupDebugServerL()
+    {
+    RDebug::Printf( "CMultiTargetAgent::SetupDebugServerL" );
+
+    iTargets.ReserveL( KNumApps );
+
+    RBuf targetName;
+    CleanupClosePushL( targetName );
+
+    for( TInt numApps = 0; numApps < KNumApps; numApps++ )
+        {
+        iTargets.AppendL( targetName );
+        RDebug::Printf( "Attach to DSS for app %d ", numApps );
+
+        iTargets[numApps].CreateL( KTargetExe().Length() + 2 );
+        iTargets[numApps].Format( KTargetExe(), numApps+1 );
+
+        TInt ret = iServSession.AttachExecutable( iTargets[numApps], EFalse );
+        test( ret == KErrNone );
+
+        RDebug::Printf( ">SetEventAction app %d,  EEventsStartThread EActionSuspend", numApps );
+        ret = iServSession.SetEventAction( iTargets[numApps], EEventsStartThread, EActionSuspend );
+        test( ret == KErrNone );
+
+        RDebug::Printf( ">SetEventAction app %d,  EEventsAddProcess EActionContinue", numApps );
+        ret = iServSession.SetEventAction( iTargets[numApps], EEventsAddProcess, EActionContinue );
+        test( ret == KErrNone );
+
+        RDebug::Printf( ">SetEventAction app %d,  EEventsRemoveProcess EActionContinue", numApps );
+        ret = iServSession.SetEventAction( iTargets[numApps], EEventsRemoveProcess, EActionContinue );
+        test( ret == KErrNone );
+        }
+
+    CleanupStack::PopAndDestroy( &targetName ); // targetName
+
+    }
+
+
+
+TInt CMultiTargetAgent::LaunchTargetsInOrderL()
+    {
+    RDebug::Printf( "CMultiTargetAgent::LaunchTargetsInOrderL" );
+    
+    RBuf launcher;
+    CleanupClosePushL( launcher );
+    launcher.CreateL( KLauncherExe() );
+    
+    RBuf launcherOptions;
+    CleanupClosePushL( launcherOptions ); 
+    launcherOptions.CreateL( KTargetOptions().Length() + 2 );
+    launcherOptions.Format( KTargetOptions(), (TUint)ENormalExit );
+
+    RDebug::Printf( ">LaunchProcess()" );
+    RProcess launcherProc; 
+    CleanupClosePushL( launcherProc );
+    
+    TInt ret = LaunchProcess( launcherProc, launcher, launcherOptions );
+    RDebug::Printf( "<LaunchProcess() ret %d", ret );
+    
+    CleanupStack::PopAndDestroy( &launcherProc ); // launcherProc
+    CleanupStack::PopAndDestroy( &launcherOptions ); // launcherOptions
+    CleanupStack::PopAndDestroy( &launcher ); //launcher 
+
+    test( ret == KErrNone );
+    
+    RSemaphore launchSemaphore;   
+    CleanupClosePushL( launchSemaphore );
+            
+    TFindSemaphore launchSemFinder( KLaunchMutexNameSearchString );
+    TFullName mutexResult;
+    ret = launchSemFinder.Next(mutexResult);
+    RDebug::Printf( ">  Find Launch Semaphote.Next ret=%d, %lS", ret, &mutexResult );
+    test( ret == KErrNone );   
+     
+    ret = launchSemaphore.OpenGlobal( mutexResult );
+    RDebug::Printf( "> OpenGlobal mutex ret=%d", ret );         
+    test( ret == KErrNone );    
+    
+    TBool thisLaunchCompleted; 
+
+    SetupDebugServerL();
+   
+    for( TInt numLaunches = KNumLaunches; numLaunches > 0; numLaunches-- )
+        {
+        for( TInt numApps = KNumApps; numApps > 0; numApps-- )
+            {
+            thisLaunchCompleted = EFalse;
+            // This will trigger the launcher app to launch the next target
+            RDebug::Printf( " >Mutex.Signal app=%d, launch=%d", numApps, numLaunches);
+            launchSemaphore.Signal();
+            
+            RBuf8 tgt8Name; 
+            CleanupClosePushL( tgt8Name );
+           
+            RBuf tgtCollapseName;
+            CleanupClosePushL( tgtCollapseName );
+                    
+            tgtCollapseName.CreateL( iTargets[numApps-1] );
+            tgt8Name.CreateL( tgtCollapseName.Collapse() );
+            
+
+            while( ! thisLaunchCompleted )
+                {
+                RDebug::Printf( ">GetEvent app %d for %S", numApps, &tgt8Name );
+                iServSession.GetEvent( iTargets[numApps-1], iStatus, iEventPtr );
+          
+                // Wait for the target to get started.
+                RDebug::Printf( " >Wait for event from target app=%d, launch=%d\n", numApps, numLaunches);
+                User::WaitForRequest( iStatus );
+                RDebug::Printf( " <Wait for request returned with status %d", iStatus.Int() );
+                test( iStatus==KErrNone );
+    
+                RDebug::Printf( " > Got iEventType =%d, app=%d", iEventInfo.iEventType, numApps );
+                switch( iEventInfo.iEventType )
+                    {
+                    case EEventsAddProcess:
+                        {
+                        RDebug::Printf( "Got EEventsAddProcess" );                        
+                        TPtrC8 exeNamePtr8( iEventInfo.iAddProcessInfo.iFileName, iEventInfo.iAddProcessInfo.iFileNameLength );
+                        
+                        RBuf8 exeName8;
+                        CleanupClosePushL( exeName8 );
+                        exeName8.CreateL( exeNamePtr8 );
+                        RDebug::Printf( " from event: exeName8=%S", &exeName8 );
+                        CleanupStack::PopAndDestroy( &exeName8 );
+                        
+                        RBuf8 compareName8;
+                        CleanupClosePushL( compareName8 );
+                        compareName8.CreateL( KTargetExeName().Length() + 10 );
+                        compareName8.Format( KTargetExeName(), numApps );
+                        RDebug::Printf( " comparing to: compareName8=%S", &compareName8 );
+                        
+                        test( compareName8.CompareC( exeNamePtr8 ) == 0 );
+                        CleanupStack::PopAndDestroy( &compareName8 );
+
+                        RDebug::Printf( "Testing if event process id is valid" );
+                        test( iEventInfo.iProcessIdValid );
+                        RDebug::Printf( "Got iEventInfo.iProcessId=%d", I64LOW( iEventInfo.iProcessId ) );
+                        
+                        RProcess targetProc;
+                        ret = targetProc.Open( TProcessId( iEventInfo.iProcessId ) );
+                        RDebug::Printf( "RProcess open ret=%d",ret );
+                        targetProc.Close();
+                        test( ret == KErrNone );
+                        
+                        break;
+                        }//EEventsAddProcess
+                        
+                    case EEventsStartThread:
+                        {
+                        RDebug::Printf( "Got EEventsStartThread" );
+                         
+                        TPtrC8 exeNamePtr8( iEventInfo.iStartThreadInfo.iFileName, iEventInfo.iStartThreadInfo.iFileNameLength );
+                        RBuf8 exe8Name;
+                        CleanupClosePushL( exe8Name );
+                        exe8Name.CreateL( exeNamePtr8 );
+                        RDebug::Printf( " from event: exeName8=%S", &exe8Name );
+                        CleanupStack::PopAndDestroy( &exe8Name );
+                        
+                        test( tgt8Name.CompareC( exeNamePtr8 ) == 0 );
+                        
+                        RDebug::Printf( "Testing if event process id is valid" );
+                        test( iEventInfo.iProcessIdValid );
+                        RDebug::Printf( "Got iEventInfo.iProcessId=%d", I64LOW( iEventInfo.iProcessId ) );
+                         
+                        RDebug::Printf( "Testing if event thread id is valid" );
+                        test( iEventInfo.iThreadIdValid );
+                        RDebug::Printf( "Got iEventInfo.iThreadId=%d", I64LOW( iEventInfo.iThreadId ) );
+                        
+                        RThread targetThread;
+                        CleanupClosePushL( targetThread );
+                        
+                        ret = targetThread.Open( TThreadId( iEventInfo.iThreadId ) );
+                        RDebug::Printf( "RThread open ret=%d", ret );
+                        test( ret == KErrNone ); 
+                         
+                        test( iEventInfo.iThreadId == targetThread.Id() );  
+
+                        RDebug::Printf( "Resuming thread for app=%d, id=%d", numApps, I64LOW( targetThread.Id() ));
+                        ret = iServSession.ResumeThread( iEventInfo.iThreadId );
+                        CleanupStack::PopAndDestroy( &targetThread );
+                        
+                        test( ret == KErrNone );
+                        
+                        ret = iServSession.ResumeThread( iEventInfo.iThreadId );
+                        break;                    
+                        }//case EEventsStartThread                        
+
+                    case ( EEventsRemoveProcess ):
+                        {
+                        RDebug::Printf( "*** Got EEventsRemoveProcess. app%d has exited. Moving on to next app", numApps );                        
+                        thisLaunchCompleted = ETrue;
+                        break;
+                        }
+                        
+                    default :   
+                        RDebug::Printf( "Got unknown event" );
+                        test( EFalse );
+                        break;
+                    }
+                }//while
+
+            CleanupStack::PopAndDestroy( &tgtCollapseName ); // tgtCollapseName
+            CleanupStack::PopAndDestroy( &tgt8Name ); // tgt8Name 
+            }
+        }    
+
+        CleanupStack::PopAndDestroy( &launchSemaphore ); // launchSemaphore
+      
+        for( TInt i = iTargets.Count()-1; i>=0; i-- )
+            {
+            RDebug::Printf( "Closing target %d", i );
+            iTargets[ i ].Close();
+            }
+
+        iTargets.Close();
+        
+        return KErrNone;
+    }
+
+
+GLDEF_C TInt E32Main()
+    {
+    TInt ret = KErrNone;
+   
+  
+    CTrapCleanup* trap = CTrapCleanup::New();
+    if (!trap)
+      return KErrNoMemory;
+    test.Title();
+   
+    CMultiTargetAgent *runModeAgent = CMultiTargetAgent::NewL();
+    if (runModeAgent != NULL)
+        {
+        __UHEAP_MARK;
+        TRAP(ret,runModeAgent->ClientAppL());
+        __UHEAP_MARKEND;
+        
+        RDebug::Printf( "ClientAppL returned %d", ret );
+        delete runModeAgent;
+        }
+
+    delete trap;
+    return ret;
+    }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/rm_debug/multi_target_tests/t_multi_target.h	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,93 @@
+// Copyright (c) 2006-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:
+// Definitions for the run mode debug tests
+// 
+//
+
+/**
+ @file
+ @internalTechnology
+ @released
+*/
+
+#ifndef RMDEBUG_MULTI_TARGET_H
+#define RMDEBUG_MULTI_TARGET_H
+
+#include "t_rmdebug_app.h"
+
+#include <rm_debug_api.h>
+
+class CMultiTargetAgent;
+
+//
+// class CRunModeAgent
+//
+// The basic run mode agent.
+//
+class CMultiTargetAgent : public CBase
+	{
+public:
+	static CMultiTargetAgent* NewL();
+	~CMultiTargetAgent();
+	void ClientAppL();
+	
+    TInt LaunchProcess(RProcess& aProcess, TDesC & aExeName, TDesC & aCommandLine );
+    
+private:
+	CMultiTargetAgent();
+	void ConstructL();
+
+	void ReportPerformance(void);
+
+	TInt HelpTicksPerSecond(void);
+
+	enum TTestMode 
+		{
+		//run all the tests
+		EModeAll = 1<<0,
+		//run the specified tests in reverse order
+		EModeReverse = 1<<1,
+		//print out help
+		EModeHelp = 1<<2,
+		//print out help
+		EModeVersion = 1<<3
+		};
+	
+	TInt LaunchTargetsInOrderL();
+	void SetupDebugServerL();
+
+private:
+
+#if defined(KERNEL_OOM_TESTING)
+	RKernelLowMemorySecuritySvrSession iServSession;
+#elif defined (USER_OOM_TESTING)
+	RUserLowMemorySecuritySvrSession iServSession;
+#else
+	Debug::RSecuritySvrSession iServSession;
+#endif
+	RSemaphore iAddressGlobSem;
+
+	TUid iMySid;
+
+	// Timing information
+	TInt iStartTick;
+	TInt iStopTick;
+
+	RArray<RBuf> iTargets;
+  TRequestStatus iStatus;
+  Debug::TEventInfo iEventInfo;
+  TPtr8 iEventPtr;
+	};
+
+#endif // RMDEBUG_MULTI_TARGET_H
--- a/kerneltest/e32test/rm_debug/r_kernel_low_memory_security_svr_session.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,39 +0,0 @@
-// Copyright (c) 2007-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:
-// Implementation of RKernelLowMemorySecuritySvrSession
-// 
-//
-
-#include "r_kernel_low_memory_security_svr_session.h"
-
-void RKernelLowMemorySecuritySvrSession::FailAlloc(const TInt aCount)
-	{
-	__KHEAP_FAILNEXT(aCount);
-	}
-
-void RKernelLowMemorySecuritySvrSession::HeapReset()
-	{
-	__KHEAP_RESET;
-	}
-
-void RKernelLowMemorySecuritySvrSession::MarkHeap()
-	{
-	__KHEAP_MARK;
-	}
-
-void RKernelLowMemorySecuritySvrSession::MarkHeapEnd()
-	{
-	__KHEAP_MARKEND;
-	}
-
--- a/kerneltest/e32test/rm_debug/r_kernel_low_memory_security_svr_session.h	Tue Feb 02 01:24:03 2010 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,39 +0,0 @@
-// Copyright (c) 2007-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:
-// Version of security server session to enable testing of low memory conditions on kernel side
-// 
-//
-
-/**
- @file
- @internalTechnology
- @released
-*/
-
-#ifndef R_KERNEL_LOW_MEMORY_SECURITY_SVR_SESSION_H
-#define R_KERNEL_LOW_MEMORY_SECURITY_SVR_SESSION_H
-
-#include "r_low_memory_security_svr_session.h"
-
-class RKernelLowMemorySecuritySvrSession : public RLowMemorySecuritySvrSession
-	{
-protected:
-	void FailAlloc(const TInt aCount);
-	void HeapReset();
-	void MarkHeap();
-	void MarkHeapEnd();
-	};
-
-#endif //R_KERNEL_LOW_MEMORY_SECURITY_SVR_SESSION_H
-
--- a/kerneltest/e32test/rm_debug/r_low_memory_security_svr_session.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,86 +0,0 @@
-// Copyright (c) 2007-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:
-// Implementation of RLowMemorySecuritySvrSession
-// 
-//
-
-#include "r_low_memory_security_svr_session.h"
-#include <e32debug.h>
-
-// test the effects of heap failure on global RSecuritySvrSession::GetList() in debug mode,
-// in release mode normal call is made (heap checking not applicable)
-TInt RLowMemorySecuritySvrSession::GetList(const Debug::TListId aListId, TDes8& aListData, TUint32& aDataSize)
-	{
-	TInt failAt = 0;
-	TInt err = KErrNoMemory;
-	while(err == KErrNoMemory)
-		{
-		failAt++;
-		FailAlloc(failAt);
-		MarkHeap();
-		err = this->RSecuritySvrSession::GetList(aListId, aListData, aDataSize);
-		if(KErrNoMemory == err)
-			{
-			MarkHeapEnd();
-			}
-		HeapReset();
-		//RDebug::Printf("Debug::RLowMemorySecuritySvrSession::GetList(): failAt: %d, err: %d", failAt, err);
-		}
-	return err;
-	}
-
-// test the effects of heap failure on thread-specific RSecuritySvrSession::GetList() in debug mode,
-// in release mode normal call is made (heap checking not applicable)
-TInt RLowMemorySecuritySvrSession::GetList(const TThreadId aThreadId, const Debug::TListId aListId, TDes8& aListData, TUint32& aDataSize)
-	{
-	TInt failAt = 0;
-	TInt err = KErrNoMemory;
-	while(err == KErrNoMemory)
-		{
-		failAt++;
-		FailAlloc(failAt);
-		MarkHeap();
-		err = this->RSecuritySvrSession::GetList(aThreadId, aListId, aListData, aDataSize);
-		if(KErrNoMemory == err)
-			{
-			MarkHeapEnd();
-			}
-		HeapReset();
-		//RDebug::Printf("Debug::RLowMemorySecuritySvrSession::GetList(TThreadId): failAt: %d, err: %d", failAt, err);
-		}
-	return err;
-	}
-
-// test the effects of heap failure on process-specific RSecuritySvrSession::GetList() in debug mode,
-// in release mode normal call is made (heap checking not applicable)
-TInt RLowMemorySecuritySvrSession::GetList(const TProcessId aProcessId, const Debug::TListId aListId, TDes8& aListData, TUint32& aDataSize)
-	{
-	TInt failAt = 0;
-	TInt err = KErrNoMemory;
-	while(err == KErrNoMemory)
-		{
-		failAt++;
-		FailAlloc(failAt);
-		MarkHeap();
-		err = this->RSecuritySvrSession::GetList(aProcessId, aListId, aListData, aDataSize);
-		if(KErrNoMemory == err)
-			{
-			MarkHeapEnd();
-			}
-		HeapReset();
-		//RDebug::Printf("Debug::RLowMemorySecuritySvrSession::GetList(TProcessId): failAt: %d, err: %d", failAt, err);
-		}
-	return err;
-	}
-
--- a/kerneltest/e32test/rm_debug/r_low_memory_security_svr_session.h	Tue Feb 02 01:24:03 2010 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,43 +0,0 @@
-// Copyright (c) 2007-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:
-// Version of security server session to enable testing of low memory conditions
-// 
-//
-
-/**
- @file
- @internalTechnology
- @released
-*/
-
-#ifndef R_LOW_MEMORY_SECURITY_SVR_SESSION_H
-#define R_LOW_MEMORY_SECURITY_SVR_SESSION_H
-
-#include <rm_debug_api.h>
-
-class RLowMemorySecuritySvrSession : public Debug::RSecuritySvrSession
-	{
-public:
-	TInt GetList(const Debug::TListId aListId, TDes8& aListData, TUint32& aDataSize);
-	TInt GetList(const TThreadId aThreadId, const Debug::TListId aListId, TDes8& aListData, TUint32& aDataSize);
-	TInt GetList(const TProcessId aProcessId, const Debug::TListId aListId, TDes8& aListData, TUint32& aDataSize);
-protected:
-	virtual void FailAlloc(const TInt aCount) = 0;
-	virtual void HeapReset() = 0;
-	virtual void MarkHeap() = 0;
-	virtual void MarkHeapEnd() = 0;
-	};
-
-#endif //R_LOW_MEMORY_SECURITY_SVR_SESSION_H
-
--- a/kerneltest/e32test/rm_debug/r_user_low_memory_security_svr_session.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,54 +0,0 @@
-// Copyright (c) 2007-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:
-// r_kernel_low_memory_security_svr_session.cpp
-// Implementation of RUserLowMemorySecuritySvrSession
-// 
-//
-
-#include "r_user_low_memory_security_svr_session.h"
-#include <rm_debug_api.h>
-#ifdef _DEBUG
-#include "low_mem_requests.h"
-#endif
-
-void RUserLowMemorySecuritySvrSession::FailAlloc(const TInt aCount)
-	{
-#ifdef _DEBUG
-	TIpcArgs args(aCount);
-	SendReceive(EDebugServFailAlloc, args);
-#endif
-	}
-
-void RUserLowMemorySecuritySvrSession::HeapReset()
-	{
-#ifdef _DEBUG
-	TIpcArgs args(0);
-	SendReceive(EDebugServFailAlloc, args);
-#endif
-	}
-
-void RUserLowMemorySecuritySvrSession::MarkHeap()
-	{
-#ifdef _DEBUG
-	SendReceive(EDebugServMarkHeap);
-#endif
-	}
-
-void RUserLowMemorySecuritySvrSession::MarkHeapEnd()
-	{
-#ifdef _DEBUG
-	SendReceive(EDebugServMarkEnd);
-#endif
-	}
-
--- a/kerneltest/e32test/rm_debug/r_user_low_memory_security_svr_session.h	Tue Feb 02 01:24:03 2010 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,39 +0,0 @@
-// Copyright (c) 2007-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:
-// Version of security server session to enable testing of low memory conditions on user side
-// 
-//
-
-/**
- @file
- @internalTechnology
- @released
-*/
-
-#ifndef R_USER_LOW_MEMORY_SECURITY_SVR_SESSION_H
-#define R_USER_LOW_MEMORY_SECURITY_SVR_SESSION_H
-
-#include "r_low_memory_security_svr_session.h"
-
-class RUserLowMemorySecuritySvrSession : public RLowMemorySecuritySvrSession
-	{
-protected:
-	void FailAlloc(const TInt aCount);
-	void HeapReset();
-	void MarkHeap();
-	void MarkHeapEnd();
-	};
-
-#endif //R_USER_LOW_MEMORY_SECURITY_SVR_SESSION_H
-
--- a/kerneltest/e32test/rm_debug/t_rmdebug.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,347 +0,0 @@
-// Copyright (c) 2006-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 the functionality of the run mode debug device driver.
-// 
-//
-
-#include <e32base.h>
-#include <e32base_private.h>
-#include <e32cons.h>
-#include <e32test.h>
-#include <e32ldr.h>
-#include <f32dbg.h>
-#include "d_rmdebugclient.h"
-#include "d_rmdebugthread.h"
-#include "t_rmdebug.h"
-
-IMPORT_C TInt StartDebugThread(RThread& aServerThread);
-IMPORT_D extern TInt TestData;
-IMPORT_D extern TBuf8<SYMBIAN_RMDBG_MEMORYSIZE> gMemoryAccessBytes;
-
-LOCAL_D RTest test(_L("T_RMDEBUG"));
-
-CRunModeAgent::CRunModeAgent()
-//
-// CRunModeAgent constructor
-//
-	{
-	}
-
-CRunModeAgent* CRunModeAgent::NewL()
-//
-// CRunModeAgent::NewL
-//
-	{
-	CRunModeAgent* self = new(ELeave) CRunModeAgent();
-
-  	self->ConstructL();
-
-   if (self->iState != ERunModeAgentRunning)
-       {
-       delete self;
-       self = NULL;
-       }       
-	return self;
-	}
-
-CRunModeAgent::~CRunModeAgent()
-//
-// CRunModeAgent destructor
-//
-	{
-	iServSession.Close();
-	iDebugThread.Close();
-   iState = ERunModeAgentUnInit;
-	}
-
-void CRunModeAgent::ConstructL()
-//
-// CRunModeAgent::ConstructL
-//
-	{
-	TInt err;
-	err = StartDebugThread(iDebugThread);
-
-	if (err == KErrNone)
-		{
-		if (iServSession.Open() == KErrNone)
-           {
-           iState = ERunModeAgentRunning;
-           }
-       else
-           {
-           iState = ERunModeAgentUnInit;
-           }
-		}
-	else
-		{
-		User::Panic(_L("Can't start debug thread"), err);
-		}
-}
-
-
-
-CRunModeAgent *RunModeAgent;
-
-// Test process names
-_LIT(ProcessName1,"T_RMDEBUG");
-_LIT(ProcessName1a,"t_rmdebug");
-//_LIT(ProcessName2,"ekern");
-//_LIT(ProcessName3,"efile");
-_LIT(KWildCard,"*");
-
-
-//---------------------------------------------
-//! @SYMTestCaseID KBase-0185
-//! @SYMTestType 
-//! @SYMPREQ PREQ1426
-//! @SYMTestCaseDesc Test reading process list
-//! @SYMTestActions Several calls to read the process list
-//! @SYMTestExpectedResults KErrNone and the owning process ID set
-//! @SYMTestPriority High
-//! @SYMTestStatus Implemented
-//---------------------------------------------
-void CRunModeAgent::TestProcessList()
-	{
-	TInt    err=KErrNone;
-	TBool	found = FALSE;
-
-	test.Next(_L("TestProcessList - Read Process List\n"));
-
-	TFindProcess find(KWildCard);
-	TFullName name;
-	while(find.Next(name)==KErrNone)
-		{
-		RProcess process;
-		err = process.Open(find);
-		if (err == KErrNone)
-			{
-			if ((name.Find(ProcessName1) != KErrNotFound) ||
-				(name.Find(ProcessName1a) != KErrNotFound))
-				{				
-					iProcessID = process.Id();
-					found = TRUE;				
-				}
-			process.Close();				
-			}
-	   }   
-	test(found== TRUE);   
-	}
-
-// Test thread name
-_LIT(ThreadName1,"DebugThread");
-
-//---------------------------------------------
-//! @SYMTestCaseID KBase-0186
-//! @SYMTestType 
-//! @SYMPREQ PREQ1426
-//! @SYMTestCaseDesc Test reading thread list
-//! @SYMTestActions Several calls to read the thread list
-//! @SYMTestExpectedResults KErrNone and the debug thread ID set
-//! @SYMTestPriority High
-//! @SYMTestStatus Implemented
-//---------------------------------------------
-void CRunModeAgent::TestThreadList()
-	{
-	TInt        err=KErrNone;
-	TBool       found = FALSE;
-
-	test.Next(_L("TestThreadList - Read Thread List\n"));
-
-   	TFindThread find(KWildCard);
-	TFullName name;
-	while(find.Next(name)==KErrNone)
-		{
-		RThread thread;
-		err = thread.Open(find);
-       	if (err == KErrNone)
-			{
-			RProcess process;
-			thread.Process(process);
-			if (((TUint32)process.Id() == iProcessID) &&
-				(name.Find(ThreadName1) != KErrNotFound))
-				{
-				found = TRUE;           
-				iThreadID = thread.Id();
-				}
-			}
-			thread.Close();
-   		}   
-
-	test(found==TRUE);   
-	}
-
-   
-//---------------------------------------------
-//! @SYMTestCaseID KBase-0187
-//! @SYMTestType 
-//! @SYMPREQ PREQ1426
-//! @SYMTestCaseDesc Test reading and writing thread memory
-//! @SYMTestActions Several call to read and write blocks of thread memory
-//! @SYMTestExpectedResults KErrNone
-//! @SYMTestPriority High
-//! @SYMTestStatus Implemented
-//---------------------------------------------
-void CRunModeAgent::TestMemoryAccess()
-{
-	TInt err=KErrNone;
-	TMemoryInfo MemoryInfo;
-	TInt i;
-
-	test.Next(_L("TestMemoryAccess - Read Memory\n"));     
-
-	for (i = 0; i < SYMBIAN_RMDBG_MEMORYSIZE; i++)
-		{
-		gMemoryAccessBytes.Append(i);
-		}
-
-	MemoryInfo.iAddress = (TUint32)(&gMemoryAccessBytes[0]);
-	MemoryInfo.iSize = SYMBIAN_RMDBG_MEMORYSIZE;
-
-	HBufC8 *data = HBufC8::NewLC(SYMBIAN_RMDBG_MEMORYSIZE);
-	TPtr8 ptr_memread(data->Des());   
-	MemoryInfo.iDataPtr = &ptr_memread;
-
-//	test.Printf(_L("Read address = 0x%x Read size = 0x%x\n"),MemoryInfo.iAddress,MemoryInfo.iSize);
-
-	err = iServSession.ReadMemory(iThreadID, &MemoryInfo);
-
-	for (i = 0; i < MemoryInfo.iSize; i++)
-		{
-		if (ptr_memread.Ptr()[i] != gMemoryAccessBytes[i])
-			{
-			err = KErrCorrupt;       		
-			}
-		}
-
-
-	// Test out writing memory.   
-	test.Next(_L("TestMemoryAccess - Write Memory\n"));
-//	test.Printf(_L("Write address = 0x%x Write size = 0x%x\n"),MemoryInfo.iAddress,MemoryInfo.iSize);
-	if (err== KErrNone)
-		{
-		// Now reset the buffer
-		for (i = 0; i < SYMBIAN_RMDBG_MEMORYSIZE; i++)
-			{
-			gMemoryAccessBytes[i] = 0;
-			}      
-
-		// Write our data into the buffer
-		err = iServSession.WriteMemory(iThreadID, &MemoryInfo);
-
-		for (i = 0; i < MemoryInfo.iSize; i++)
-			{
-			if (ptr_memread.Ptr()[i] != gMemoryAccessBytes[i])
-				{
-				err = KErrCorrupt;       		
-				}
-			}
-
-		}
-
-	if (gMemoryAccessBytes[5] == 0)
-		{
-		err = KErrCorrupt;
-		}
-
-	CleanupStack::PopAndDestroy(data);       
-	test(err==KErrNone);   
-	}
-
-
-//---------------------------------------------
-//! @SYMTestCaseID KBase-0188
-//! @SYMTestType 
-//! @SYMPREQ PREQ1426
-//! @SYMTestCaseDesc Test suspending and resuming a task
-//! @SYMTestActions Suspends a thread checks the contents of a variable then waits and tests it hasnt changed
-//! @SYMTestExpectedResults KErrNone
-//! @SYMTestPriority High
-//! @SYMTestStatus Implemented
-//---------------------------------------------
-void CRunModeAgent::TestSuspendResume()
-	{
-	TInt err;
-
-	test.Next(_L("TestSuspendResume - Suspend\n"));
-	// Suspend the thread
-	err = iServSession.SuspendThread(iThreadID);
-	test(err==KErrNone);
-	TInt localtestdata;
-	localtestdata = TestData;
-
-	// Wait 3 seconds (suspends this thread) and hopefully resumes the
-	// thread we are controlling via the iServSession.SuspendThread request
-	User::After(3000000);
-
-	// Now check data hasnt changed
-	test(localtestdata==TestData);
-
-	// Resume the thread
-	test.Next(_L("TestSuspendResume - Resume\n"));
-	err = iServSession.ResumeThread(iThreadID);
-	test(err==KErrNone);
-
-	// Wait 3 seconds (suspends this thread) and hopefully resumes the
-	// thread we are controlling via the iServSession.SuspendThread request
-	User::After(3000000);
-
-	// Now check that the thread being controlled has resumed and is
-	// updating the variable
-	test(localtestdata!=TestData);
-	}
-   
-void CRunModeAgent::ClientAppL()
-//
-// Performs each test in turn
-//
-	{
-	test.Start(_L("ClientAppL"));
-
-	TestProcessList();
-	TestThreadList();
-	TestMemoryAccess();
-	TestSuspendResume();
-	test.End();   
-	}
-
-GLDEF_C TInt E32Main()
-//
-// Entry point for run mode debug driver test
-//
-	{
-   TInt ret = KErrNone;
-   
-	// client
-	CTrapCleanup* trap = CTrapCleanup::New();
-	if (!trap)
-		return KErrNoMemory;
-
-   RunModeAgent = CRunModeAgent::NewL();
-   if (RunModeAgent != NULL)
-       {
-   	test.Title();
-
-        __UHEAP_MARK;
-	    TRAPD(r,RunModeAgent->ClientAppL());
-       ret = r;
-	    __UHEAP_MARKEND;
-
-	    delete RunModeAgent;
-       }
-       
-	delete trap;
-
-	return ret;
-	}
--- a/kerneltest/e32test/rm_debug/t_rmdebug.h	Tue Feb 02 01:24:03 2010 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,61 +0,0 @@
-// Copyright (c) 2006-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:
-// Definitions for the run mode debug tests
-// 
-//
-
-#ifndef RMDEBUG_H
-#define RMDEBUG_H
-
-// Function codes (opcodes) used in message passing between client and server
-enum TRunModeAgentState
-	{
-	ERunModeAgentUnInit,
-    ERunModeAgentRunning,
-	};
-
-
-//
-// class CRunModeAgent
-//
-// The basic run mode agent.
-//
-class CRunModeAgent : public CBase
-	{
-	public:
-		static CRunModeAgent* NewL();
-		~CRunModeAgent();
-		void ClientAppL();
-
-	private:
-		CRunModeAgent();
-		void ConstructL();
-
-		TInt TestStartup();
-		TInt TestShutdown();
-
-		void TestProcessList();
-		void TestThreadList();
-		void TestMemoryAccess();
-		void TestSuspendResume();
-
-	private:
-		RDebugServSession	iServSession;
-		RThread				iDebugThread;
-		TInt				iProcessID;
-		TInt				iThreadID;
-        TInt                iState;
-	};
-
-#endif // RMDEBUG_H
--- a/kerneltest/e32test/rm_debug/t_rmdebug2.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,4432 +0,0 @@
-// Copyright (c) 2006-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 the functionality of the run mode debug device driver.
-//
-//
-
-#include <e32base.h>
-#include <e32base_private.h>
-#include <e32cons.h>
-#include <e32test.h>
-#include <e32ldr.h>
-#include <e32svr.h>
-#include <e32cmn.h>
-#include <e32cmn_private.h>
-#include <f32dbg.h>
-#include <f32file.h>
-#include <hal.h>
-#include <u32hal.h>
-#include <e32property.h>
-
-#include "t_rmdebug_dll.h"
-
-#include <rm_debug_api.h>
-#include "d_rmdebugthread2.h"
-#include "t_rmdebug2.h"
-#include "t_rmdebug_app.h"
-
-#ifdef __MARM_ARMV4__
-#include "d_rmdebug_step_test_armv4.h"
-#endif
-
-#ifdef __MARM_ARMV5__
-#include "d_rmdebug_step_test.h"
-#endif
-
-#include "d_demand_paging.h"
-
-#ifdef KERNEL_OOM_TESTING
-	#ifdef USER_OOM_TESTING
-		#error "Cannot define both KERNEL_OOM_TESTING and USER_OOM_TESTING"
-	#endif
-#endif
-
-_LIT8(KCrashDummyData, "This is a sample write");
-
-using namespace Debug;
-
-const TVersion securityServerVersion(0,1,1);
-
-const TVersion testVersion(2,1,0);
-
-IMPORT_C TInt StartDebugThread(RThread& aServerThread, const TDesC& aDebugThreadName);
-IMPORT_D extern TInt TestData;
-IMPORT_D extern TTestFunction FunctionChooser;
-IMPORT_D extern TBuf8<SYMBIAN_RMDBG_MEMORYSIZE> gMemoryAccessBytes;
-IMPORT_C TInt TestFunction();
-IMPORT_C void TestPagedCode();
-IMPORT_C extern TInt RMDebugDemandPagingTest();
-
-// Device driver name
-_LIT(KDebugDriverFileName,"rm_debug.ldd");
-
-#ifdef SYMBIAN_STANDARDDEBUG
-LOCAL_D RTest test(_L("T_RMDEBUG2"));
-#endif
-
-#ifdef SYMBIAN_OEMDEBUG
-LOCAL_D RTest test(_L("T_RMDEBUG2_OEM"));
-#endif
-
-#ifdef SYMBIAN_OEM2DEBUG
-LOCAL_D RTest test(_L("T_RMDEBUG2_OEM2"));
-#endif
-
-CRunModeAgent::CRunModeAgent()
-//
-// CRunModeAgent constructor
-//
-	{
-	FillArray();
-	RProcess thisProcess;
-	iFileName = thisProcess.FileName();
-	thisProcess.Close();
-	}
-
-CRunModeAgent* CRunModeAgent::NewL()
-//
-// CRunModeAgent::NewL
-//
-	{
-	CRunModeAgent* self = new(ELeave) CRunModeAgent();
-
-  	self->ConstructL();
-
-	return self;
-	}
-
-CRunModeAgent::~CRunModeAgent()
-//
-// CRunModeAgent destructor
-//
-	{
-	User::FreeLogicalDevice(KDebugDriverFileName);
-	iServSession.Close();
-	iDebugThread.Close();
-	}
-
-void CRunModeAgent::ConstructL()
-//
-// CRunModeAgent::ConstructL
-//
-	{
-	// nothing to do here
-	}
-
-void CRunModeAgent::SetupAndAttachToDSS()
-//
-// CRunModeAgent::SetupAndAttachToDSS
-//
-	{
-	TInt err = StartDebugThread(iDebugThread, KDebugThreadName);
-
-	// get the thread id for use in the tests
-	iThreadID = iDebugThread.Id();
-
-	if (err != KErrNone)
-		{
-		User::Panic(_L("Can't start debug thread"), err);
-		}
-
-	err = iServSession.Connect(securityServerVersion);
-	if (err != KErrNone)
-		{
-		User::Panic(_L("Can't open server session"), err);
-		}
-	}
-
-CRunModeAgent *RunModeAgent;
-
-// helper function to check whether the listing of type aListId is supported for a scope of aListScope
-TBool CRunModeAgent::ListingSupported(const TListId aListId, const TListScope aListScope)
-	{
-	TTag tag = GetTag(ETagHeaderList, aListId);
-
-	return (tag.iValue) & aListScope;
-	}
-
-//---------------------------------------------
-//! @SYMTestCaseID KBase-T-RMDEBUG2-0426
-//! @SYMTestType
-//! @SYMPREQ PREQ1426
-//! @SYMTestCaseDesc Test getting the list of XIP libraries
-//! @SYMTestActions The XIP library list should be successfully obtained
-//! @SYMTestExpectedResults The specified ldd file should be present in the obtained listing
-//! @SYMTestPriority High
-//! @SYMTestStatus Implemented
-//---------------------------------------------
-void CRunModeAgent::TestGetXipLibrariesList()
-	{
-	test.Next(_L("TestGetXipLibrariesList\n"));
-
-	test(ListingSupported(EXipLibraries, EScopeGlobal));
-	test(!ListingSupported(EXipLibraries, EScopeProcessSpecific));
-	test(!ListingSupported(EXipLibraries, EScopeThreadSpecific));
-
-	//allocate a very small buffer so the GetList call initially fails
-	RBuf8 buffer;
-	test(KErrNone == buffer.Create(1));
-	TUint32 size = 0;
-
-	//get the list data
-	DoGetList(EXipLibraries, EScopeGlobal, buffer, size);
-
-	//search the buffer for entry corresponding to the debug kernel driver
-	//which should be in the rom
-	_LIT(KRmDebugLddName, "z:\\sys\\bin\\rm_debug.ldd");
-
-	//iterate through the buffer and set found to ETrue if we find the driver
-	TBool found = EFalse;
-	TUint8* ptr = (TUint8*)buffer.Ptr();
-	const TUint8* ptrEnd = ptr + size;
-	while(ptr < ptrEnd)
-		{
-		TXipLibraryListEntry& xipLibrary = *(TXipLibraryListEntry*)ptr;
-
-		//get the name of the library
-		TPtr name(&xipLibrary.iName[0], xipLibrary.iNameLength, xipLibrary.iNameLength);
-		if(name.CompareF(KRmDebugLddName()) == 0)
-			{
-			//found the library but continue reading the rest of the buffer to
-			//check nothing bad happens towards the end
-			found = ETrue;
-			}
-		//move pointer on to next library
-		ptr += Align4(xipLibrary.GetSize());
-		}
-	test(found);
-
-	//do cleanup
-	buffer.Close();
-	}
-
-//---------------------------------------------
-//! @SYMTestCaseID KBase-T-RMDEBUG2-0427
-//! @SYMTestType
-//! @SYMPREQ PREQ1426
-//! @SYMTestCaseDesc Test getting the list of executables
-//! @SYMTestActions The list of debuggable executable files should be obtained
-//! @SYMTestExpectedResults The client exe should appear in the list
-//! @SYMTestPriority High
-//! @SYMTestStatus Implemented
-//---------------------------------------------
-void CRunModeAgent::TestGetExecutablesList()
-	{
-	test.Next(_L("TestGetExecutablesList\n"));
-
-	test(ListingSupported(EExecutables, EScopeGlobal));
-	test(!ListingSupported(EExecutables, EScopeProcessSpecific));
-	test(!ListingSupported(EExecutables, EScopeThreadSpecific));
-
-	//allocate a very small buffer so the GetList call initially fails
-	RBuf8 buffer;
-	test(KErrNone == buffer.Create(1));
-	TUint32 size = 0;
-
-	test(KErrNone == iServSession.AttachExecutable(iFileName, EFalse));
-
-	//get the list data
-	DoGetList(EExecutables, EScopeGlobal, buffer, size);
-
-	//get this process' name
-	RProcess thisProcess;
-	TFileName thisProcessName = thisProcess.FileName();
-
-	//look through the buffer and check if the target debug thread is there
-	TBool found = EFalse;
-	TUint8* ptr = (TUint8*)buffer.Ptr();
-	const TUint8* ptrEnd = ptr + size;
-	while(ptr < ptrEnd)
-		{
-		TExecutablesListEntry& entry = *(TExecutablesListEntry*)ptr;
-		//get name
-		TPtr name(&entry.iName[0], entry.iNameLength, entry.iNameLength);
-		if( (entry.iIsActivelyDebugged != 0) && (0 == thisProcessName.CompareF(name)) )
-			{
-			//found this process and asserted it is being actively debugged
-			found = ETrue;
-			}
-		//move pointer on to next entry
-		ptr += Align4(entry.GetSize());
-		}
-	test(found);
-
-	//clean up
-	buffer.Close();
-
-	test(KErrNone == iServSession.DetachExecutable(iFileName));
-	}
-
-//---------------------------------------------
-//! @SYMTestCaseID KBase-T-RMDEBUG2-0428
-//! @SYMTestType
-//! @SYMPREQ PREQ1426
-//! @SYMTestCaseDesc Test error conditions for the GetList calls
-//! @SYMTestActions Multiple calls to test calling GetList with bad arguments
-//! @SYMTestExpectedResults All tests should fail with the appropriate error codes
-//! @SYMTestPriority High
-//! @SYMTestStatus Implemented
-//---------------------------------------------
-void CRunModeAgent::TestGetListInvalidData()
-	{
-	test.Next(_L("TestGetListInvalidData\n"));
-
-	//allocate a buffer, the size should not matter as expecting all calls to fail
-	RBuf8 buffer;
-	test(KErrNone == buffer.Create(1));
-	TUint32 size = 0;
-
-	//test what happens if we ask for an unsupported list type globally
-	test(KErrNotSupported == iServSession.GetList((TListId)1234, buffer, size));
-
-	//test what happens if we ask for an unsupported list type
-	test(KErrNotSupported == iServSession.GetList(RThread().Id(), (TListId)1234, buffer, size));
-
-	//test what happens if we try to get a non-global libraries list
-	test(KErrArgument == iServSession.GetList(RThread().Id(), EXipLibraries, buffer, size));
-
-	//test what happens if we try to get a non-global executables list
-	test(KErrArgument == iServSession.GetList(RThread().Id(), EExecutables, buffer, size));
-
-	//test what happens if we try to get a non-global process list
-	test(KErrArgument == iServSession.GetList(RThread().Id(), EProcesses, buffer, size));
-
-	//check that using a process id fails
-	test(KErrArgument == iServSession.GetList(RProcess().Id(), EProcesses, buffer, size));
-
-	//check that specifying a non-existant thread id fails
-	test(KErrArgument == iServSession.GetList((TThreadId)0x12345678, EThreads, buffer, size));
-
-	//check that specifying a non-existant process id fails
-	test(KErrArgument == iServSession.GetList((TProcessId)0x12345678, EThreads, buffer, size));
-
-	//check that specifying a non-existant thread id fails
-	test(KErrArgument == iServSession.GetList((TThreadId)0x12345678, ECodeSegs, buffer, size));
-
-	//check that specifying a non-existant process id fails
-	test(KErrArgument == iServSession.GetList((TProcessId)0x12345678, ECodeSegs, buffer, size));
-
-	//cleanup
-	buffer.Close();
-	}
-
-//---------------------------------------------
-//! @SYMTestCaseID KBase-T-RMDEBUG2-0429
-//! @SYMTestType
-//! @SYMPREQ PREQ1426
-//! @SYMTestCaseDesc Test getting the process list
-//! @SYMTestActions Get the process listing
-//! @SYMTestExpectedResults The process listing should be successfully obtained and the current process should be present in the list
-//! @SYMTestPriority High
-//! @SYMTestStatus Implemented
-//---------------------------------------------
-void CRunModeAgent::TestGetProcessList()
-	{
-	test.Next(_L("TestGetProcessList\n"));
-
-	test(ListingSupported(EProcesses, EScopeGlobal));
-	test(!ListingSupported(EProcesses, EScopeProcessSpecific));
-	test(!ListingSupported(EProcesses, EScopeThreadSpecific));
-
-	//allocate a very small buffer so the GetList call fails
-	RBuf8 buffer;
-	test(KErrNone == buffer.Create(1));
-	TUint32 size = 0;
-
-	//get the list data
-	DoGetList(EProcesses, EScopeGlobal, buffer, size);
-
-	//initialise data about the target debug thread to compare the kernel's data against
-	RProcess thisProcess;
-	TFileName thisProcessName = thisProcess.FileName();
-	TUint32 processId = thisProcess.Id().Id();
-
-	//look through the buffer and check if the target debug thread is there
-	TBool found = EFalse;
-	TUint8* ptr = (TUint8*)buffer.Ptr();
-	const TUint8* ptrEnd = ptr + size;
-	while(ptr < ptrEnd)
-		{
-		TProcessListEntry& entry = *(TProcessListEntry*)ptr;
-		if( (RProcess().Id().Id() == entry.iProcessId) &&
-			(0 == thisProcessName.CompareF(TPtr(&(entry.iNames[0]), entry.iFileNameLength, entry.iFileNameLength))) &&
-		 	(0 == thisProcess.FullName().CompareF(TPtr(&(entry.iNames[0]) + entry.iFileNameLength, entry.iDynamicNameLength, entry.iDynamicNameLength))) &&
-			0x4321bbbb /* Magic */ == entry.iUid3)
-			{
-			//if all match then we've found it
-			found = ETrue;
-			}
-		ptr += Align4(entry.GetSize());
-		}
-
-	//check whether the expected result happened
-	test(found);
-
-	//clean up
-	buffer.Close();
-	}
-
-//---------------------------------------------
-//! @SYMTestCaseID KBase-T-RMDEBUG2-0430
-//! @SYMTestType
-//! @SYMPREQ PREQ1426
-//! @SYMTestCaseDesc Test getting the thread list
-//! @SYMTestActions Get the thread listing globally and for a specified thread or process
-//! @SYMTestExpectedResults The thread listings should all be successfully obtained and the current thread should be present in all listings
-//! @SYMTestPriority High
-//! @SYMTestStatus Implemented
-//---------------------------------------------
-void CRunModeAgent::TestGetThreadList()
-	{
-	test.Next(_L("TestGetThreadList\n"));
-
-	test(ListingSupported(EThreads, EScopeGlobal));
-	test(ListingSupported(EThreads, EScopeProcessSpecific));
-	test(ListingSupported(EThreads, EScopeThreadSpecific));
-
-	test(KErrNone == iServSession.AttachExecutable(iFileName, EFalse));
-	test(KErrNone == iServSession.SuspendThread(iThreadID));
-
-	//test getting the global list, ETrue as should find the target debug thread
-	DoTestGetThreadList(ETrue, EScopeGlobal);
-
-	//test getting this thread's thread list, ETrue as should find the target debug thread
-	DoTestGetThreadList(ETrue, EScopeThreadSpecific, RThread().Id().Id());
-
-	//test getting this process's thread list, ETrue as should find the target debug thread
-	DoTestGetThreadList(ETrue, EScopeProcessSpecific, RProcess().Id().Id());
-
-	test(KErrNone == iServSession.ResumeThread(iThreadID));
-	test(KErrNone == iServSession.DetachExecutable(iFileName));
-	}
-
-void CRunModeAgent::DoTestGetThreadList(const TBool aShouldPass, const TListScope aListScope, const TUint64 aTargetId)
-	{
-	test.Next(_L("DoTestGetThreadList\n"));
-
-	//create data to pass
-	RBuf8 buffer;
-	TUint32 size = 0;
-
-	//perform the call to get the Code segs
-	DoGetList(EThreads, aListScope, buffer, size, aTargetId);
-
-	//initialise data about the target debug thread to compare the kernel's data against
-	TFileName name = iDebugThread.FullName();
-	RProcess thisProcess;
-	TUint64 processId = thisProcess.Id();
-	TUint64 threadId = iDebugThread.Id();
-
-	//look through the buffer and check if the target debug thread is there
-	TBool found = EFalse;
-	TUint8* ptr = (TUint8*)buffer.Ptr();
-	const TUint8* ptrEnd = ptr + size;
-	while(ptr < ptrEnd)
-		{
-		TThreadListEntry* entry = (TThreadListEntry*)ptr;
-		TPtr entryName(&(entry->iName[0]), entry->iNameLength, entry->iNameLength);
-		if( (threadId == entry->iThreadId) && (processId == entry->iProcessId) && (0 == name.CompareF(entryName)) )
-			{
-			test(entry->iSupervisorStackBaseValid);
-			test(entry->iSupervisorStackSizeValid);
-			//if all match then we've found it
-			found = ETrue;
-			}
-
-		ptr += Align4(entry->GetSize());
-		}
-
-	//check whether the expected result happened
-	test(found == aShouldPass);
-
-	//clean up
-	buffer.Close();
-
-	}
-
-//---------------------------------------------
-//! @SYMTestCaseID KBase-T-RMDEBUG2-0431
-//! @SYMTestType
-//! @SYMPREQ PREQ1426
-//! @SYMTestCaseDesc Test getting the code segment list
-//! @SYMTestActions Get the code segment list global and for a specified thread
-//! @SYMTestExpectedResults The listings should be returned successfully
-//! @SYMTestPriority High
-//! @SYMTestStatus Implemented
-//---------------------------------------------
-void CRunModeAgent::TestGetCodeSegsList()
-	{
-	test.Next(_L("TestGetCodeSegsList\n"));
-
-	test(ListingSupported(ECodeSegs, EScopeGlobal));
-	test(ListingSupported(ECodeSegs, EScopeProcessSpecific));
-	test(ListingSupported(ECodeSegs, EScopeThreadSpecific));
-
-	// Cannot perform this test with OEM2 debug token, as the t_rmdebug2 app
-	// needs AllFiles, and the OEM2 debug token does not authorise this.
-	// It seems reasonable to suppose that it would work anyway
-
-#ifndef SYMBIAN_OEM2DEBUG
-	test(KErrNone == iServSession.AttachExecutable(iFileName, EFalse));
-
- 	//test getting the global list, ETrue as should find this process' main codeSeg
-	DoTestGetCodeSegsList(ETrue, EScopeGlobal);
-
-	//test getting this process' codeSegs, ETrue as should find this process' main codeSeg
-	DoTestGetCodeSegsList(ETrue, EScopeProcessSpecific, RProcess().Id().Id());
-
-	//test getting this thread's codeSegs, ETrue as should find this process' main codeSeg
-	DoTestGetCodeSegsList(ETrue, EScopeThreadSpecific, RThread().Id().Id());
-
-	test(KErrNone == iServSession.DetachExecutable(iFileName));
-#endif // SYMBIAN_OEM2DEBUG
-
-	}
-
-void CRunModeAgent::DoTestGetCodeSegsList(const TBool aShouldPass, const TListScope aListScope, const TUint64 aTargetId)
-	{
-	//create data to pass
-	RBuf8 buffer;
-	TUint32 size = 0;
-
-	//perform the call to get the Code segs
-	DoGetList(ECodeSegs, aListScope, buffer, size, aTargetId);
-
-	//create memoryInfo to contain info about this process
-	RProcess thisProcess;
-	TModuleMemoryInfo memoryInfo;
-	test(KErrNone == thisProcess.GetMemoryInfo(memoryInfo));
-
-	// check whether this process came from a file in ROM so we know whether to
-	// expect the code seg to be XIP or not.
-	RFs fs;
-	test(KErrNone == fs.Connect());
-	TBool thisFileIsInRom = EFalse;
-	if(fs.IsFileInRom(iFileName))
-		{
-		thisFileIsInRom = ETrue;
-		}
-
-	//look through the buffer to find this process' main code seg
-	TBool found = EFalse;
-	TUint8* ptr = (TUint8*)buffer.Ptr();
-	const TUint8* ptrEnd = ptr + size;
-	while(ptr < ptrEnd)
-		{
-		TCodeSegListEntry* codeSeg = (TCodeSegListEntry*)ptr;
-
-		if( (codeSeg->iIsXip == thisFileIsInRom) && (0 == iFileName.CompareF(TPtr(&(codeSeg->iName[0]), codeSeg->iNameLength, codeSeg->iNameLength))) )
-			{
-			if( (memoryInfo.iCodeBase == codeSeg->iCodeBase) &&
-					(memoryInfo.iCodeSize == codeSeg->iCodeSize) &&
-					(memoryInfo.iConstDataSize == codeSeg->iConstDataSize) &&
-					(memoryInfo.iInitialisedDataBase == codeSeg->iInitialisedDataBase) &&
-					(memoryInfo.iInitialisedDataSize == codeSeg->iInitialisedDataSize) &&
-					(memoryInfo.iUninitialisedDataSize == codeSeg->iUninitialisedDataSize))
-				{
-				//all matched so means we've found the codeSeg we're looking for
-				found = ETrue;
-				}
-			}
-		ptr += Align4(codeSeg->GetSize());
-		}
-
-	//check whether the result was as expected
-	test(found == aShouldPass);
-
-	// only care about rm_debug.ldd if we have global scope (belongs to the system not this process)
-	if (aListScope == EScopeGlobal)
-	{
-		// Search for rm_debug.ldd library and check its UID3 is correct
-		found = EFalse;
-
-_LIT(KRMDebugDriverFileName,"Z:\\sys\bin\\rm_debug.ldd");
-
-		TFileName rmdebugFilename(KRMDebugDriverFileName);
-
-		// reset the Ptr
-		ptr = (TUint8*)buffer.Ptr();
-		ptrEnd = ptr+size;
-		while(ptr < ptrEnd)
-		{
-			TCodeSegListEntry* codeSeg = (TCodeSegListEntry*)ptr;
-
-			if( rmdebugFilename.CompareF(TPtr(&(codeSeg->iName[0]), codeSeg->iNameLength, codeSeg->iNameLength)))
-				{
-				if(codeSeg->iUid3 == 0x101f7157 /* Magic */)
-					{
-					//all matched so means we've found the codeSeg we're looking for
-					found = ETrue;
-					}
-				}
-			ptr += Align4(codeSeg->GetSize());
-		}
-		test((TUint32)found == (TUint32)ETrue);
-	}
-
-	//clean up
-	buffer.Close();
-
-	}
-
-void CRunModeAgent::DoGetList(const TListId aListId, const TListScope aListScope, RBuf8& aBuffer, TUint32& aSize, const TUint64 aTargetId)
-	{
-	//close the buffer in case there's stuff allocated in it
-	aBuffer.Close();
-	//initialise it to be one byte big, which will guarantee data won't fit in it
-	test(KErrNone == aBuffer.Create(1));
-	aSize = 0;
-
-	//should pass this test (assuming we've passed in sensible arguments above...)
-	if(EScopeGlobal == aListScope)
-		{
-		test(KErrTooBig == iServSession.GetList(aListId, aBuffer, aSize));
-		}
-	else if(EScopeThreadSpecific == aListScope)
-		{
-		test(KErrTooBig == iServSession.GetList((TThreadId)aTargetId, aListId, aBuffer, aSize));
-		}
-	else if(EScopeProcessSpecific == aListScope)
-		{
-		test(KErrTooBig == iServSession.GetList((TProcessId)aTargetId, aListId, aBuffer, aSize));
-		}
-	else
-		{
-		// unknown list scope
-		test(0);
-		}
-
-	//keep allocating larger buffers, beginning with the aSize returned by the above call,
-	//and hopefully we'll eventually make a large enough one
-	test(KErrNone == aBuffer.ReAlloc(aSize));
-
-	for(;;)
-		{
-		TInt err = KErrNone;
-		if(EScopeGlobal == aListScope)
-			{
-			err = iServSession.GetList(aListId, aBuffer, aSize);
-			}
-		else if(EScopeThreadSpecific == aListScope)
-			{
-			err = iServSession.GetList((TThreadId)aTargetId, aListId, aBuffer, aSize);
-			}
-		else if(EScopeProcessSpecific == aListScope)
-			{
-			err = iServSession.GetList((TProcessId)aTargetId, aListId, aBuffer, aSize);
-			}
-		else
-			{
-			// unknown list scope
-			test(0);
-			}
-		if(err == KErrTooBig)
-			{
-			//wasn't big enough so double it
-			aSize = aSize << 1;
-			err = aBuffer.ReAlloc(aSize);
-			if(err != KErrNone)
-				{
-				//print out a message if couldn't allocate memory and quit
-				test.Printf(_L("Out ot memory when attempting to allocate %d bytes."), aSize);
-				test(KErrNone == err);
-				}
-
-			//fairly arbitrary test, we don't have a max size for these calls.
-			//In reality a list would have to have many thousands of elements
-			//to break this test which shouldn't really happen
-			test(aSize <= 0x4000);
-			}
-		else
-			{
-			test(KErrNone == err);
-			test(aBuffer.Length() == aSize);
-			//break out of the loop if the list has been successfully read in
-			break;
-			}
-		}
-	}
-
-//---------------------------------------------
-//! @SYMTestCaseID KBase-T-RMDEBUG2-0432
-//! @SYMTestType
-//! @SYMPREQ PREQ1426
-//! @SYMTestCaseDesc Test reading and writing memory
-//! @SYMTestActions Multiple calls to read and write memory, with various sizes and at various locations.
-//!	Also test that bad input values cause appropriate errors to be returned.
-//! @SYMTestExpectedResults All tests should pass and the target process should be left unaffected
-//! @SYMTestPriority High
-//! @SYMTestStatus Implemented
-//---------------------------------------------
-void CRunModeAgent::TestMemoryAccess()
-{
-	TInt err;
-
-	test.Next(_L("TestMemoryAccess - Read Memory\n"));
-
-	//initialise buffer
-	gMemoryAccessBytes.SetLength(0);
-	for (TInt i=0; i<SYMBIAN_RMDBG_MEMORYSIZE; i++)
-		{
-		gMemoryAccessBytes.Append(i);
-		}
-
-	TUint32 address = (TUint32)(&gMemoryAccessBytes[0]);
-	TUint32 dataSize = SYMBIAN_RMDBG_MEMORYSIZE;
-
-	//create size for buffer that is rounded up to nearest 4 bytes if not
-	//already 4 byte aligned
-	TUint32 size = dataSize;
-	if(size % 4 != 0)
-		{
-		size += (4 - (size % 4));
-		}
-
-	RBuf8 dataBlock;
-	err = dataBlock.Create(size);
-	test(err==KErrNone);
-	test(KErrNone == iServSession.AttachExecutable(iFileName, EFalse));
-
-	//suspend the thread prior to memory operations
-	test(KErrNone == iServSession.SuspendThread(iThreadID));
-
-	err = iServSession.ReadMemory(iThreadID, address, size, dataBlock, EAccess32, EEndLE8);
-	test(err==KErrNone);
-
-	for (TInt i=0; i<dataSize; i++)
-		{
-		test(dataBlock.Ptr()[i] == gMemoryAccessBytes[i]);
-		}
-
-	test.Next(_L("TestMemoryAccess - Write Memory\n"));
-
-	// Now reset the buffer
-	for (TInt i=0; i<dataSize; i++)
-		{
-		gMemoryAccessBytes[i] = 0;
-		}
-
-	// Write our data into the buffer
-	err = iServSession.WriteMemory(iThreadID, address, size, dataBlock, EAccess32, EEndLE8);
-	test(err==KErrNone);
-
-	for (TInt i=0; i<dataSize; i++)
-		{
-		test(dataBlock.Ptr()[i] == gMemoryAccessBytes[i]);
-		}
-
-	//final test that everything's not been going wrong
-	test(gMemoryAccessBytes[5] != 0);
-
-	test.Next(_L("TestMemoryAccess - Invalid arguments\n"));
-	test.Printf(_L("This test may emit crash-like information. This is intended.\n"));
-
-	//test address that is not 32 bit aligned
-	err = iServSession.ReadMemory(iThreadID, address + 1, size, dataBlock, EAccess32, EEndLE8);
-	test(err == KErrArgument);
-
-	//test size that is not multiple of 4 bytes
-	err = iServSession.WriteMemory(iThreadID, address, size + 2, dataBlock, EAccess32, EEndLE8);
-	test(err == KErrArgument);
-
-	//test size > max block size
-	err = iServSession.ReadMemory(iThreadID, address, (1<<15), dataBlock, EAccess32, EEndLE8);
-	test(err == KErrArgument);
-
-	//test access size == 2 bytes
-	err = iServSession.ReadMemory(iThreadID, address, size, dataBlock, EAccess16, EEndLE8);
-	test(err == KErrNotSupported);
-
-	//test access size == 1 byte
-	err = iServSession.WriteMemory(iThreadID, address, size, dataBlock, EAccess8, EEndLE8);
-	test(err == KErrNotSupported);
-
-	//test endianess == EEndBE8
-	err = iServSession.ReadMemory(iThreadID, address, size, dataBlock, EAccess32, EEndBE8);
-	test(err == KErrNotSupported);
-
-	//test endianess == EEndBE32
-	err = iServSession.WriteMemory(iThreadID, address, size, dataBlock, EAccess32, EEndBE32);
-	test(err == KErrNotSupported);
-
-	//test reading off end of memory
-	err = iServSession.ReadMemory(iThreadID, 0xffffff00, 0x00000101, dataBlock, EAccess32, EEndLE8);
-	test(err == KErrArgument);
-
-	//The following three tests check that edge conditions in the range check are handled correctly.
-	err = iServSession.ReadMemory(iThreadID, 0xffffff00, 0x000000FF, dataBlock, EAccess32, EEndLE8);
-	test(err == KErrArgument);
-
-	err = iServSession.ReadMemory(iThreadID, 0xffffff00, 0x000000F0, dataBlock, EAccess32, EEndLE8);
-	test(err == KErrBadDescriptor);
-
-	//Third range check test. Check that range check is handled correctly even when base + size wraps to 0.
-	err = iServSession.ReadMemory(iThreadID, 0xffffff00, 0x00000100, dataBlock, EAccess32, EEndLE8);
-	test(err == KErrBadDescriptor);
-	//end of range check tests
-
-	//test size == 0
-	err = iServSession.WriteMemory(iThreadID, address, 0, dataBlock, EAccess32, EEndLE8);
-	test(err == KErrArgument);
-
-	//attempt to write to address outside of process data segments,
-	//this address corresponds to the vectors so shouldn't be able to write
-	err = iServSession.WriteMemory(iThreadID, 0xffff0000, size, dataBlock, EAccess32, EEndLE8);
-	test(err == KErrBadDescriptor);
-
-	//attempt to read and write to address in process code segment
-
-	//open a handle to the thread
-	RThread debugThread;
-	test(debugThread.Open(iThreadID) == KErrNone);
-
-	//get a reference to the debug process
-	RProcess debugProcess;
-	test(debugThread.Process(debugProcess) == KErrNone);
-
-	//get the memory info for the process
-	TProcessMemoryInfo info;
-	test(debugProcess.GetMemoryInfo(info) == KErrNone);
-
-	address = info.iCodeBase;
-	if(size <= info.iCodeSize)
-		{
-		test(KErrNone == iServSession.ReadMemory(iThreadID, address, size, dataBlock, EAccess32, EEndLE8));
-		test(KErrBadDescriptor == iServSession.WriteMemory(iThreadID, address, size, dataBlock, EAccess32, EEndLE8));
-		}
-
-	// Some performance tests now
-	TUint32 bytesRead = 0;
-
-	// Allocate a data buffer
-	TUint32* p = (TUint32*)User::Alloc(size);
-	test(p != 0);
-
-	TInt nanokernel_tick_period;
-	HAL::Get(HAL::ENanoTickPeriod, nanokernel_tick_period);
-	test (nanokernel_tick_period != 0);
-
-	static const TInt KOneMillion = 1000000;
-
-	TInt nkTicksPerSecond = KOneMillion/nanokernel_tick_period;
-
-	TUint32 stopTickCount = User::NTickCount() + nkTicksPerSecond;
-
-	while (User::NTickCount() < stopTickCount)
-		{
-		err = iServSession.ReadMemory(iThreadID, (TUint32)p, size, dataBlock, EAccess32, EEndLE8);
-		test(err==KErrNone);
-
-		// Increase the count of bytes read
-		bytesRead += size;
-		}
-
-	test(bytesRead != 0);
-	iMemoryReadKbytesPerSecond = bytesRead/1024;
-
-	// write memory test
-	TUint32 bytesWritten = 0;
-
-	stopTickCount = User::NTickCount() + nkTicksPerSecond;
-
-	while (User::NTickCount() < stopTickCount)
-		{
-		err = iServSession.WriteMemory(iThreadID, (TUint32)p, size, dataBlock, EAccess32, EEndLE8);
-		test(err==KErrNone);
-
-		// Increase the count of bytes read
-		bytesWritten += size;
-		}
-
-	test (bytesWritten != 0);
-	iMemoryWriteKbytesPerSecond = bytesWritten/1024;
-
-	User::Free(p);
-
-	//resume the thread
-	test(KErrNone == iServSession.ResumeThread(iThreadID));
-
-	debugThread.Close();
-	dataBlock.Close();
-
-	test(KErrNone == iServSession.DetachExecutable(iFileName));
-	}
-
-//---------------------------------------------
-//! @SYMTestCaseID KBase-T-RMDEBUG2-0433
-//! @SYMTestType
-//! @SYMPREQ PREQ1426
-//! @SYMTestCaseDesc Test suspending and resuming threads
-//! @SYMTestActions Multiple calls to suspend and resume threads with and without attaching to the thread
-//! @SYMTestExpectedResults All tests should pass and the target process should be left unaffected
-//! @SYMTestPriority High
-//! @SYMTestStatus Implemented
-//---------------------------------------------
-void CRunModeAgent::TestSuspendResume()
-	{
-	TInt err;
-
-	test.Next(_L("TestSuspendResume - Suspend\n"));
-
-	test(KErrNone == iServSession.AttachExecutable(iFileName, EFalse));
-	// Suspend the thread
-	err = iServSession.SuspendThread(iThreadID);
-	test(err==KErrNone);
-	TInt localtestdata;
-	localtestdata = TestData;
-
-	// Wait 3 seconds (suspends this thread) and hopefully resumes the
-	// thread we are controlling via the iServSession.SuspendThread request
-	User::After(3000000);
-
-	// Now check data hasnt changed
-	test(localtestdata==TestData);
-
-	// Resume the thread
-	test.Next(_L("TestSuspendResume - Resume\n"));
-	err = iServSession.ResumeThread(iThreadID);
-	test(err==KErrNone);
-
-	test(KErrNone == iServSession.DetachExecutable(iFileName));
-
-	// Wait 3 seconds (suspends this thread) and hopefully resumes the
-	// thread we are controlling via the iServSession.SuspendThread request
-	User::After(3000000);
-
-	// Now check that the thread being controlled has resumed and is
-	// updating the variable
-	test(localtestdata!=TestData);
-
-	// check that agent can resume thread which it previously detached from
-	test(KErrNone == iServSession.AttachExecutable(iFileName, EFalse));
-	test(KErrNone == iServSession.SuspendThread(iThreadID));
-	test(KErrNone == iServSession.DetachExecutable(iFileName));
-	test(KErrNone == iServSession.AttachExecutable(iFileName, EFalse));
-	test(KErrNone == iServSession.ResumeThread(iThreadID));
-	test(KErrNone == iServSession.DetachExecutable(iFileName));
-
-	// check that agent cannot suspend thread which it previously suspended and then detached from
-	test(KErrNone == iServSession.AttachExecutable(iFileName, EFalse));
-	test(KErrNone == iServSession.SuspendThread(iThreadID));
-	test(KErrNone == iServSession.DetachExecutable(iFileName));
-	test(KErrNone == iServSession.AttachExecutable(iFileName, EFalse));
-	test(KErrAlreadyExists == iServSession.SuspendThread(iThreadID));
-	test(KErrNone == iServSession.ResumeThread(iThreadID));
-	test(KErrNone == iServSession.DetachExecutable(iFileName));
-	}
-
-//---------------------------------------------
-//! @SYMTestCaseID KBase-T-RMDEBUG2-0434
-//! @SYMTestType
-//! @SYMPREQ PREQ1426
-//! @SYMTestCaseDesc Test getting the debug functionality from the driver
-//! @SYMTestActions Get the size and contents of the debug functionality block
-//! @SYMTestExpectedResults All tests should pass and the expected data should appear in the functionality block
-//! @SYMTestPriority High
-//! @SYMTestStatus Implemented
-//---------------------------------------------
-void CRunModeAgent::TestDebugFunctionality()
-	{
-
-	TInt err;
-
-	test.Next(_L("TestDebugFunctionality - GetDebugFunctionalityBufSize\n"));
-
-	TUint32 bufsize = 0;	// Safe default size
-
-	// Get functionality block size
-	err = iServSession.GetDebugFunctionalityBufSize(&bufsize);
-	test(err==KErrNone);
-	test.Next(_L("TestDebugFunctionality - GetDebugFunctionality\n"));
-
-	// Ensure we have a finite buffer size
-	test(bufsize!=0);
-
-	// Allocate space for the functionality data
-	HBufC8* dftext = HBufC8::NewLC(bufsize);
-
-	// create an empty TPtr8 refering to dftext
-	TPtr8 dftextPtr(dftext->Des());
-
-	// Get the functionality block
-	err = iServSession.GetDebugFunctionality(dftextPtr);
-	test(err==KErrNone);
-
-	// Check that the first entry is correct
-	TTagHeader RefHdr =
-	{
-		ETagHeaderIdCore,ECoreLast,
-	};
-
-	// First header passed from rm_debug.ldd
-	TTagHeader* TestHdr = (TTagHeader*)dftextPtr.Ptr();
-
-	// Check
-	test(RefHdr.iTagHdrId==TestHdr->iTagHdrId);
-	// this test might fail if the agent is used with a Debug Security Server different from
-	// the one it was compiled against. So removing it for now.
-	//test(RefHdr.iNumTags==TestHdr->iNumTags);
-
-	// read a value from the data to check it has come through as expected
-	TTagHeader* header = GetTagHdr(dftext->Des(), ETagHeaderIdApiConstants);
-	test(header != NULL);
-	TTag* tag = GetTag(header, EApiConstantsTEventInfoSize);
-	test(tag != NULL);
-	// this test might fail if the agent is used with a Debug Security Server different from
-	// the one it was compiled against. So removing it for now.
-	//test(sizeof(TEventInfo) == tag->iValue);
-
-	// Remove our temporary buffer
-	CleanupStack::PopAndDestroy(dftext);
-	}
-
-//---------------------------------------------
-//! @SYMTestCaseID KBase-T-RMDEBUG2-0435
-//! @SYMTestType
-//! @SYMPREQ PREQ1426
-//! @SYMTestCaseDesc Test setting and clearing consecutive breakpoints
-//! @SYMTestActions Set and clear consecutive breakpoints of all combinations of breakpoint types
-//! @SYMTestExpectedResults All breakpoints should be set and cleared without error
-//! @SYMTestPriority High
-//! @SYMTestStatus Implemented
-//---------------------------------------------
-void CRunModeAgent::TestConsecutiveBreakPoints()
-	{
-	test.Next(_L("TestConsecutiveBreakPoints\n"));
-
-	test(KErrNone == iServSession.SuspendThread(iThreadID));
-
-	// just a temporary structure for storing info about a breakpoint
-	struct TBreakPoint
-		{
-	public:
-		TBreakPoint()
-			:iId(0),
-			iMode((TArchitectureMode)0),
-			iAddress(0)
-			{}
-		TBreakId iId;
-		TArchitectureMode iMode;
-		TUint32 iAddress;
-		inline TInt Size() { return (EArmMode == iMode) ? 4 : 2; }
-		};
-
-	//an address in the target debug thread
-	TUint32 address = (TUint32)(&TestFunction);
-
-	// there are six orders in which three breakpoints can be set, these are looped
-	// through below to check setting and clearing consecutive breakpoints works
-	TUint8 order[6][3] =
-		{
-			{0,1,2},
-			{0,2,1},
-			{1,0,2},
-			{1,2,0},
-			{2,0,1},
-			{2,1,0}
-		};
-
-	// The following code checks that setting and clearing consecutive breakpoints works correctly:
-	// It checks that setting all combinations of three arm and thumb breakpoints succeeds, and check that the
-	// breakpoints can be set in any order, and then cleared in any order
-
-	// the 3 least significant bits of i control whether each of the three breakpoints should be arm or thumb
-	for(TInt i=0; i<8; i++)
-		{
-		// controls the order in which the breakpoints should be set
-		for(TInt j=0; j<6; j++)
-			{
-			// create the three breakpoints and set their modes
-			TBreakPoint bp[3];
-			bp[0].iMode = (i&1) ? EArmMode : EThumbMode;
-			bp[1].iMode = (i&2) ? EArmMode : EThumbMode;
-			bp[2].iMode = (i&4) ? EArmMode : EThumbMode;
-
-			// set the address of each of the breakpoints
-			bp[0].iAddress = address;
-			if(EArmMode == bp[0].iMode)
-				{ // if an arm breakpoint then must be on a four byte boundary
-				bp[0].iAddress = Align4(bp[0].iAddress);
-				}
-			bp[1].iAddress = bp[0].iAddress + bp[0].Size();
-			if(EArmMode == bp[1].iMode)
-				{ // if an arm breakpoint then must be on a four byte boundary
-				bp[1].iAddress = Align4(bp[1].iAddress);
-				}
-			bp[2].iAddress = bp[1].iAddress + bp[1].Size();
-			if(EArmMode == bp[2].iMode)
-				{ // if an arm breakpoint then must be on a four byte boundary
-				bp[2].iAddress = Align4(bp[2].iAddress);
-				}
-			for(TInt k=0; k<6; k++)
-				{
-				// set the three breakpoints in the order defined by j and then clear them in the order defined by k
-				test(KErrNone==iServSession.SetBreak(bp[order[j][0]].iId, iThreadID, bp[order[j][0]].iAddress, bp[order[j][0]].iMode));
-				test(KErrNone==iServSession.SetBreak(bp[order[j][1]].iId, iThreadID, bp[order[j][1]].iAddress, bp[order[j][1]].iMode));
-				test(KErrNone==iServSession.SetBreak(bp[order[j][2]].iId, iThreadID, bp[order[j][2]].iAddress, bp[order[j][2]].iMode));
-				test(KErrNone==iServSession.ClearBreak(bp[order[k][0]].iId));
-				test(KErrNone==iServSession.ClearBreak(bp[order[k][1]].iId));
-				test(KErrNone==iServSession.ClearBreak(bp[order[k][2]].iId));
-				}
-			}
-		}
-
-	// resume the thread
-	test(KErrNone == iServSession.ResumeThread(iThreadID));
-	}
-
-//---------------------------------------------
-//! @SYMTestCaseID KBase-T-RMDEBUG2-0436
-//! @SYMTestType
-//! @SYMPREQ PREQ1426
-//! @SYMTestCaseDesc Test breakpoint functionality
-//! @SYMTestActions Multiple calls to set and clear breakpoints. Checking bad input produces appropriate errors.
-//! @SYMTestExpectedResults All tests should pass and the target debug thread should be left unaffected
-//! @SYMTestPriority High
-//! @SYMTestStatus Implemented
-//---------------------------------------------
-void CRunModeAgent::TestBreakPoints()
-	{
-	TInt err;
-
-	test.Next(_L("TestBreakPoints - Set\n"));
-
-	test(KErrNone == iServSession.AttachExecutable(iFileName, EFalse));
-
-	TestConsecutiveBreakPoints();
-
-	//an address in the target debug thread
-	TUint32 address = (TUint32)(&TestFunction);
-
-	/*
-	 * Ensure that breakpoint operations don't
-	 * affect memory read/write by checking that reads/writes
-	 * in locations containing breakpoints don't change behaviour
-	 * because of the breakpoints.
-	 */
-
-	TUint32 size = SYMBIAN_RMDBG_MEMORYSIZE;
-
-	RBuf8 originalDataBlock;
-	err = originalDataBlock.Create(size);
-	test(err==KErrNone);
-
-	//suspend the thread
-	test(KErrNone == iServSession.SuspendThread(iThreadID));
-
-	err = iServSession.ReadMemory(iThreadID, address, size, originalDataBlock, EAccess32, EEndLE8);
-	test(err==KErrNone);
-
-	// Test data block for comparison
-	RBuf8 testDataBlock;
-	err = testDataBlock.Create(size);
-	test(err==KErrNone);
-
-	/*
-	 * set an arm breakpoint
-	 */
-	TBreakId armBreakId = 0;
-	err = iServSession.SetBreak(armBreakId, iThreadID, address, EArmMode);
-	test(err == KErrNone);
-
-	// Ensure that memory read is not corrupted
-	err = iServSession.ReadMemory(iThreadID, address, size, testDataBlock, EAccess32, EEndLE8);
-	test(err==KErrNone);
-
-	test (testDataBlock == originalDataBlock);
-
-	/*
-	 * set a thumb breakpoint
-	 */
-	TBreakId thumbBreakId = 0;
-	err = iServSession.SetBreak(thumbBreakId, iThreadID, address+4, EThumbMode);
-	test(err == KErrNone);
-
-	/*
-	 * set a thumb2EE breakpoint
-	 */
-	TBreakId thumb2EEBreakId = 0;
-	err = iServSession.SetBreak(thumb2EEBreakId, iThreadID, address+8, EThumb2EEMode);
-	test(err == KErrNotSupported);
-
-	/*
-	 * overlapping breakpoint (same address/threadId/mode)
-	 */
-	TBreakId overlapBreakId = 0;
-	err = iServSession.SetBreak(overlapBreakId, iThreadID, address, EArmMode);
-	test(err == KErrAlreadyExists);
-
-	/*
-	 * overlapping breakpoint (different address/same threadId/different mode)
-	 *
-	 * address - EArmBreakpoint
-	 * address+2 - EThumbBreakpoint
-	 */
-	TBreakId overlap2BreakId = 0;
-	err = iServSession.SetBreak(overlap2BreakId, iThreadID, address+2, EThumbMode);
-	test(err == KErrAlreadyExists);
-
-	/*
-	 * Un-aligned address (arm)
-	 */
-	TBreakId armUnalignedBreakId = 0;
-	err = iServSession.SetBreak(armUnalignedBreakId, iThreadID, address+6, EArmMode);
-	test(err == KErrArgument);
-
-	/*
-	 * Un-aligned address (thumb)
-	 */
-	TBreakId thumbUnalignedBreakId = 0;
-	err = iServSession.SetBreak(thumbUnalignedBreakId, iThreadID, address+7, EThumbMode);
-	test(err == KErrArgument);
-
-	/*
-	 * Invalid address (arm)
-	 */
-	TBreakId armBadAddressBreakId = 0;
-	err = iServSession.SetBreak(armBadAddressBreakId, iThreadID, 0 /* address */, EThumbMode);
-	test(err == KErrBadDescriptor);
-
-	/*
-	 * Different thread, same address. Should fail for the same process, but succeed
-	 * for a different process.
-	 */
-
-	/*
-	 * Invalid thread
-	 */
-	TBreakId invalidThreadBreakId = 0;
-	err = iServSession.SetBreak(invalidThreadBreakId, 0xbabababa, address, EThumbMode);
-	test(err == KErrPermissionDenied);
-
-	// Clear the ARM breakpoint
-	err = iServSession.ClearBreak(armBreakId);
-	test(err == KErrNone);
-
-	// Clear the Thumb breakpoint
-	err = iServSession.ClearBreak(thumbBreakId);
-	test(err == KErrNone);
-
-	// to do : two threads at the same address
-	// to do : two processes at the same address
-
-	// Ensure that memory read is not corrupted after clearing the breakpoints
-	err = iServSession.ReadMemory(iThreadID, address, size, testDataBlock, EAccess32, EEndLE8);
-	test(err==KErrNone);
-
-	test (testDataBlock == originalDataBlock);
-
-	/*
-	 * How fast can we set breakpoints?
-	 *
-	 * Measure the time by setting/clearing breakpoints for 1 second.
-     */
-	TInt nanokernel_tick_period;
-	HAL::Get(HAL::ENanoTickPeriod, nanokernel_tick_period);
-	test (nanokernel_tick_period != 0);
-
-	TInt nkTicksPerSecond = HelpTicksPerSecond();
-
-	TInt breaksPerSecond = 0;
-
-	TUint32 stopTickCount = User::NTickCount() + nkTicksPerSecond;
-
-	while (User::NTickCount() < stopTickCount)
-		{
-		// set the breakpoint
-		TBreakId armBreakId = 0;
-		err = iServSession.SetBreak(armBreakId, iThreadID, address, EArmMode);
-		test(err == KErrNone);
-
-		// Clear the breakpoint
-		err = iServSession.ClearBreak(armBreakId);
-		test(err == KErrNone);
-
-		// Update the count of breakpoints
-		breaksPerSecond++;
-
-		// Gone wrong if we wrap to negative breakpoints (cannot set 2billion/second!)
-		test(breaksPerSecond >0);
-		}
-
-	// Store the results for later
-	iBreakpointsPerSecond = breaksPerSecond;
-
-	/*
-	 * How many breakpoints can we set?
-	 */
-
-	TBool done = EFalse;
-
-	// We assume all the breakpoints id's are issued in ascending order
-	TInt maxBreakPoints = 0;
-
-	// Temporary buffer
-	RArray<TBreakId> breakIdList;
-
-	TUint32 testAddress = address;
-
-	while(!done)
-		{
-		TBreakId breakId = 0;
-
-		// set the breakpoint
-		testAddress += 4;	// ensure the addresses don't overlap
-
-		err = iServSession.SetBreak(breakId, iThreadID, testAddress, EArmMode);
-		test (err == KErrNone || err == KErrOverflow);
-		if (err != KErrNone)
-			{
-			// we've reached the limit of the number of breaks we can set
-			done = ETrue;
-			break;
-			}
-
-		// store the id of this breakpoint
-		breakIdList.Append(breakId);
-
-		// Increase the count of breakpoints
-		maxBreakPoints++;
-		test(maxBreakPoints > 0);
-		}
-
-	// How many breakpoints can we set?
-	iMaxBreakpoints = maxBreakPoints;
-
-	// now clear all those breakpoints again
-	while(breakIdList.Count() != 0)
-		{
-		// Place it into a TBreakId
-		TBreakId id = breakIdList[0];
-
-		err = iServSession.ClearBreak(id);
-		test(err == KErrNone);
-
-		// next id
-		breakIdList.Remove(0);
-		}
-
-	breakIdList.Close();
-
-	// close our temporary buffers
-	originalDataBlock.Close();
-	testDataBlock.Close();
-
-	err = iServSession.ResumeThread(iThreadID);
-	test (err == KErrNone);
-
-	test(KErrNone == iServSession.DetachExecutable(iFileName));
-	}
-
-//---------------------------------------------
-//! @SYMTestCaseID KBase-T-RMDEBUG2-0437
-//! @SYMTestType
-//! @SYMPREQ PREQ1426
-//! @SYMTestCaseDesc Test modifying breakpoints
-//! @SYMTestActions Several calls to modify breakpoints
-//! @SYMTestExpectedResults Valid requests should result in the breakpoints being changed, invalid requests should return errors
-//! @SYMTestPriority High
-//! @SYMTestStatus Implemented
-//---------------------------------------------
-void CRunModeAgent::TestModifyBreak()
-	{
-	test.Next(_L("TestModifyBreak\n"));
-
-	DoTestModifyBreak(ETrue);
-	DoTestModifyBreak(EFalse);
-	}
-
-void CRunModeAgent::DoTestModifyBreak(TBool aThreadSpecific)
-	{
-	test.Printf(_L("DoTestModifyBreak: aThreadSpecific: %d\n"), aThreadSpecific?1:0);
-
-	TInt err;
-
-	RProcess process;
-	TProcessId processId = process.Id();
-	process.Close();
-
-	test(KErrNone == iServSession.AttachExecutable(iFileName, EFalse));
-
-	//suspend the thread
-	test(KErrNone == iServSession.SuspendThread(iThreadID));
-
-	//an address in the target debug thread
-	TUint32 address = (TUint32)(&TestFunction);
-
-	//set an arm mode break point
-	TBreakId armBreakId = 0;
-	err = aThreadSpecific
-		? iServSession.SetBreak(armBreakId, iThreadID, address, EArmMode)
-		: iServSession.SetProcessBreak(armBreakId, processId, address, EArmMode);
-	test(err == KErrNone);
-
-	/*
-	 * Invalid thread
-	 */
-	err = aThreadSpecific
-		? iServSession.ModifyBreak(armBreakId, 0xbabababa, address, EArmMode)
-		: iServSession.ModifyProcessBreak(armBreakId, 0xbabababa, address, EArmMode);
-	test(err == KErrPermissionDenied);
-
-	/*
-	 * Valid address
-	 */
-	err = aThreadSpecific
-		? iServSession.ModifyBreak(armBreakId, iThreadID, address+4, EArmMode)
-		: iServSession.ModifyProcessBreak(armBreakId, processId, address+4, EArmMode);
-	test(err == KErrNone);
-
-	/*
-	 * Invalid address
-	 */
-	err = aThreadSpecific
-		? iServSession.ModifyBreak(armBreakId, iThreadID, 0, EArmMode)
-		: iServSession.ModifyProcessBreak(armBreakId, processId, 0, EArmMode);
-	test(err == KErrBadDescriptor);
-
-	/*
-	 * Thumb mode
-	 */
-	err = aThreadSpecific
-		? iServSession.ModifyBreak(armBreakId, iThreadID, address, EThumbMode)
-		: iServSession.ModifyProcessBreak(armBreakId, processId, address, EThumbMode);
-	test(err == KErrNone);
-
-	/*
-	 * Thumb2EE mode
-	 */
-	err = aThreadSpecific
-		? iServSession.ModifyBreak(armBreakId, iThreadID, address, EThumb2EEMode)
-		: iServSession.ModifyProcessBreak(armBreakId, processId, address, EThumb2EEMode);
-	test(err == KErrNotSupported);
-
-	/*
-	 * Arm mode
-	 */
-	err = aThreadSpecific
-		? iServSession.ModifyBreak(armBreakId, iThreadID, address, EArmMode)
-		: iServSession.ModifyProcessBreak(armBreakId, processId, address, EArmMode);
-	test(err == KErrNone);
-
-	// Finally, clear the breakpoint
-	err = iServSession.ClearBreak(armBreakId);
-	test(err == KErrNone);
-
-	//resume the thread
-	test(KErrNone == iServSession.ResumeThread(iThreadID));
-	test(KErrNone == iServSession.DetachExecutable(iFileName));
-	}
-
-//---------------------------------------------
-//! @SYMTestCaseID KBase-T-RMDEBUG2-0438
-//! @SYMTestType
-//! @SYMPREQ PREQ1426
-//! @SYMTestCaseDesc Test extracting information about breakpoints
-//! @SYMTestActions Several calls to get information about breakpoints
-//! @SYMTestExpectedResults All tests should pass and the target process should be left unaffected
-//! @SYMTestPriority High
-//! @SYMTestStatus Implemented
-//---------------------------------------------
-void CRunModeAgent::TestBreakInfo()
-	{
-	test.Next(_L("TestBreakInfo\n"));
-
-	DoTestBreakInfo(ETrue);
-	DoTestBreakInfo(EFalse);
-	}
-
-void CRunModeAgent::DoTestBreakInfo(TBool aThreadSpecific)
-	{
-	test.Printf(_L("DoTestModifyBreak: aThreadSpecific: %d\n"), aThreadSpecific?1:0);
-
-	TInt err;
-
-	RProcess process;
-	TProcessId processId = process.Id();
-	process.Close();
-
-	//an address in the target debug thread
-	TUint32 address = (TUint32)(&TestFunction);
-
-	test(KErrNone == iServSession.AttachExecutable(iFileName, EFalse));
-
-	//suspend thread
-	test(KErrNone == iServSession.SuspendThread(iThreadID));
-
-	//set an arm mode break point
-	TBreakId armBreakId = 0;
-	err = aThreadSpecific
-		? iServSession.SetBreak(armBreakId, iThreadID, address, EArmMode)
-		: iServSession.SetProcessBreak(armBreakId, processId, address, EArmMode);
-	test(err == KErrNone);
-
-	// Read back the information and check it is correct
-	TThreadId testThreadId = TThreadId(0);
-	TProcessId testProcessId = TProcessId(0);
-	TUint32 testAddress = 0;
-	TArchitectureMode testMode = EArmMode;
-
-	err = aThreadSpecific
-		? iServSession.BreakInfo(armBreakId,testThreadId,testAddress, testMode)
-		: iServSession.ProcessBreakInfo(armBreakId, testProcessId, testAddress, testMode);
-	test (err == KErrNone);
-	test (aThreadSpecific ? (testThreadId == iThreadID) : (testProcessId == processId));
-	test (testAddress == address);
-	test (testMode == EArmMode);
-
-	//change the address
-	TUint32 changeAddress = address + 64;
-	err = aThreadSpecific
-		? iServSession.ModifyBreak(armBreakId, iThreadID, changeAddress,EArmMode)
-		: iServSession.ModifyProcessBreak(armBreakId, processId, changeAddress, EArmMode);
-	test(err == KErrNone);
-
-	// Check the address has changed
-	err = aThreadSpecific
-		? iServSession.BreakInfo(armBreakId,testThreadId,testAddress, testMode)
-		: iServSession.ProcessBreakInfo(armBreakId, testProcessId, testAddress, testMode);
-	test (err == KErrNone);
-	test (testAddress == changeAddress);
-
-	// change the architecture type
-	TArchitectureMode checkMode = EThumbMode;
-	err = aThreadSpecific
-		? iServSession.ModifyBreak(armBreakId, iThreadID, address,checkMode)
-		: iServSession.ModifyProcessBreak(armBreakId, processId, address, checkMode);
-	test (err == KErrNone);
-
-	// Check the mode has changed
-	err = aThreadSpecific
-		? iServSession.BreakInfo(armBreakId,testThreadId,testAddress,testMode)
-		: iServSession.ProcessBreakInfo(armBreakId, testProcessId, testAddress, testMode);
-	test (err == KErrNone);
-	test (testMode == checkMode);
-
-	// clear the breakpoint again
-	err = iServSession.ClearBreak(armBreakId);
-	test (err == KErrNone);
-
-	//resume thread
-	test(KErrNone == iServSession.ResumeThread(iThreadID));
-	test(KErrNone == iServSession.DetachExecutable(iFileName));
-	}
-
-// Needed for the RunToBreak test
-IMPORT_C extern void RMDebug_BranchTst1();
-IMPORT_C extern void RMDebug_BranchTst2();
-
-//---------------------------------------------
-//! @SYMTestCaseID KBase-T-RMDEBUG2-0439
-//! @SYMTestType
-//! @SYMPREQ PREQ1426
-//! @SYMTestCaseDesc Test hitting various types of breakpoints
-//! @SYMTestActions Several calls to register to observe breakpoints and to hit breakpoints of different types
-//! @SYMTestExpectedResults All tests should pass and the target process should be left unaffected
-//! @SYMTestPriority High
-//! @SYMTestStatus Implemented
-//---------------------------------------------
-void CRunModeAgent::TestRunToBreak()
-	{
-	test.Next(_L("TestRunToBreak\n"));
-
-	DoTestRunToBreak(ETrue);
-	DoTestRunToBreak(EFalse);
-	}
-
-void CRunModeAgent::DoTestRunToBreak(TBool aThreadSpecific)
-	{
-	test.Printf(_L("DoTestRunToBreak: aThreadSpecific: %d\n"), aThreadSpecific?1:0);
-
-	TInt err = KErrNone;
-
-	RProcess process;
-	TProcessId processId = process.Id();
-	process.Close();
-
-	test(KErrNone == iServSession.AttachExecutable(iFileName, EFalse));
-	// we should suspend the thread first, then set the breakpoint
-	err = iServSession.SuspendThread(iThreadID);
-	test (err == KErrNone);
-
-	// Try to set the breakpoint
-	TBreakId armBreakId;
-	TUint32 address = (TUint32)(&RMDebug_BranchTst1);
-
-	err = aThreadSpecific
-		? iServSession.SetBreak(armBreakId,iThreadID,address,EArmMode)
-		: iServSession.SetProcessBreak(armBreakId, processId, address, EArmMode);
-	test(err == KErrNone);
-
-	err = aThreadSpecific
-		? iServSession.SetEventAction(iFileName,EEventsBreakPoint, EActionContinue)
-		: iServSession.SetEventAction(iFileName,EEventsProcessBreakPoint, EActionContinue);
-	test (err == KErrNone);
-
-	// Continue the thread
-	err = iServSession.ResumeThread(iThreadID);
-	test (err == KErrNone);
-
-	// wait for the breakpoint to be hit
-	TEventInfo info;
-	static TRequestStatus status;
-
-	TPtr8 infoPtr((TUint8*)&info,0,sizeof(TEventInfo));
-
-	iServSession.GetEvent(iFileName,status,infoPtr);
-
-	// Wait for notification of the breakpoint hit event
-	User::WaitForRequest(status);
-	test(status==KErrNone);
-
-	// info should now be filled with the details
-	test(info.iEventType == (aThreadSpecific ? EEventsBreakPoint : EEventsProcessBreakPoint));
-	test(info.iThreadBreakPointInfo.iRmdArmExcInfo.iR15 == address);
-	test(info.iProcessIdValid);
-	test(info.iThreadIdValid);
-
-	// Not interested in breakpoint events any more
-	err = aThreadSpecific
-		? iServSession.SetEventAction(iFileName,EEventsBreakPoint, EActionIgnore)
-		: iServSession.SetEventAction(iFileName, EEventsProcessBreakPoint, EActionIgnore);
-	test (err == KErrNone);
-
-	// Clear the breakpoint again
-	err = iServSession.ClearBreak(armBreakId);
-	test(err == KErrNone);
-
-	// continue the thread again
-	err = iServSession.ResumeThread(iThreadID);
-	test (err == KErrNone);
-	test(KErrNone == iServSession.DetachExecutable(iFileName));
-	}
-
-//----------------------------------------------------------------------------------------------
-//! @SYMTestCaseID      KBase-T-RMDEBUG2-0440
-//! @SYMTestType
-//! @SYMPREQ            PREQ1426
-//! @SYMTestCaseDesc    Test access to target user-side registers.
-//! @SYMTestActions     Suspends a target thread, and reads/writes target thread register contents
-//!
-//! @SYMTestExpectedResults KErrNone. Should access target registers without problems.
-//! @SYMTestPriority        High
-//! @SYMTestStatus          Implemented
-//----------------------------------------------------------------------------------------------
-
-void CRunModeAgent::TestRegisterAccess()
-	{
-	TInt err;
-
-	test.Next(_L("TestRegisterAccess - Read\n"));
-
-	test(KErrNone == iServSession.AttachExecutable(iFileName, EFalse));
-
-	//suspend the thread to read registers
-	err = iServSession.SuspendThread(iThreadID);
-	test(err==KErrNone);
-
-	//we'll try to read/write registers ERegisterR0 - ERegisterCPSR and ERegisterR13_IRQ
-	//this way should get valid register values back, invalid ones and not supported ones, and it
-	//means that the register IDs are not completely contiguous
-
-	TInt firstRegister = 0;
-	TInt lastRegister = 17;
-	TInt numberOfRegisters = (lastRegister - firstRegister) + 1;
-
-	RBuf8 ids;
-	err = ids.Create(numberOfRegisters * sizeof(TRegisterInfo));
-	test(err == KErrNone);
-
-	for(TInt i=0; i<numberOfRegisters - 1; i++)
-		{
-		TRegisterInfo reg = (TRegisterInfo)((i + firstRegister)<<8);
-		ids.Append(reinterpret_cast<const TUint8*>(&reg), sizeof(TRegisterInfo));
-		}
-
-	TRegisterInfo reg = ERegisterR13Irq;
-	ids.Append(reinterpret_cast<const TUint8*>(&reg), sizeof(TRegisterInfo));
-
-	//create a buffer to store the register values in
-	RBuf8 originalValues;
-	err = originalValues.Create(numberOfRegisters*sizeof(TUint32));
-	test(err == KErrNone);
-
-	//create a buffer to store the register flags in
-	RBuf8 originalFlags;
-	err = originalFlags.Create(numberOfRegisters*sizeof(TUint8));
-	test(err == KErrNone);
-
-	//read register values
-	err = iServSession.ReadRegisters(iThreadID, ids, originalValues, originalFlags);
-	test(err == KErrNone);
-
-	//create a buffer containing data to write into the registers
-	RBuf8 tempValues;
-	err = tempValues.Create(numberOfRegisters*sizeof(TUint32));
-	test(err == KErrNone);
-
-	TUint cpsrId = 16;
-	for(TUint8 i=0; i<numberOfRegisters*sizeof(TUint32); i++)
-		{
-		if(i/sizeof(TUint32) == cpsrId)
-			{
-			//For the CPSR we wish to write data that makes sense - for USR mode we are
-			//allowed change all except the mode, ie. we must stay in usr mode. We try that here
-			//(allowedCPSRValue[4:0] = 10000) thus not changing the mode.
-			TUint32 allowedCPSRValue = 0x50000010;
-			tempValues.Append((TUint8*)&allowedCPSRValue, 4);
-			i += 3;
-			}
-		else
-			{
-			tempValues.Append(&i, 1);
-			}
-		}
-
-	test.Next(_L("TestRegisterAccess - Write\n"));
-
-	//create a buffer to store the register flags in
-	RBuf8 tempWriteFlags;
-	err = tempWriteFlags.Create(numberOfRegisters*sizeof(TUint8));
-	test(err == KErrNone);
-
-	//write the temp data into the registers
-	err = iServSession.WriteRegisters(iThreadID, ids, tempValues, tempWriteFlags);
-	test(err == KErrNone);
-
-	//create another buffer to store the register flags in
-	RBuf8 tempReadFlags;
-	err = tempReadFlags.Create(numberOfRegisters*sizeof(TUint8));
-	test(err == KErrNone);
-
-	RBuf8 tempReadValues;
-	err = tempReadValues.Create(numberOfRegisters*sizeof(TUint32));
-	test(err == KErrNone);
-
-	//read the temp data out again
-	err = iServSession.ReadRegisters(iThreadID, ids, tempReadValues, tempReadFlags);
-	test(err == KErrNone);
-
-	//check values are correct
-	for(TInt i=0; i<numberOfRegisters; i++)
-		{
-		TRegisterFlag writeFlag;
-		err = GetFlag(tempWriteFlags, i, writeFlag);
-		test(err == KErrNone);
-
-		TRegisterFlag readFlag;
-		err = GetFlag(tempReadFlags, i, readFlag);
-		test(err == KErrNone);
-
-		if((writeFlag == EValid) && (readFlag == EValid))
-			{
-			TUint8 offset = i * sizeof(TUint32);
-			for(TUint j = offset; j< offset + sizeof(TUint32); j++)
-				{
-				test(tempValues.Ptr()[j] == tempReadValues.Ptr()[j]);
-				}
-			}
-		}
-
-	//write the original data into the registers
-	err = iServSession.WriteRegisters(iThreadID, ids, originalValues, originalFlags);
-	test(err == KErrNone);
-
-	//read the data out again
-	err = iServSession.ReadRegisters(iThreadID, ids, tempValues, tempReadFlags);
-	test(err == KErrNone);
-
-	//check values are correct
-	for(TInt i=0; i<numberOfRegisters; i++)
-		{
-		TRegisterFlag writeFlag;
-		err = GetFlag(originalFlags, i, writeFlag);
-		test(err == KErrNone);
-
-		TRegisterFlag readFlag;
-		err = GetFlag(tempReadFlags, i, readFlag);
-		test(err == KErrNone);
-
-		if((writeFlag == EValid) && (readFlag == EValid))
-			{
-			TUint8 offset = i * sizeof(TUint32);
-			for(TUint j = offset; j< offset + sizeof(TUint32); j++)
-				{
-				test(tempValues.Ptr()[j] == originalValues.Ptr()[j]);
-				}
-			}
-		}
-
-	test.Next(_L("TestRegisterAccess - Invalid data\n"));
-
-	//create a buffer of max size 1
-	RBuf8 emptyBuffer;
-	emptyBuffer.Create(1);
-
-	//test register IDs buffer not being a multiple of sizeof(TRegisterInfo)
-	err = iServSession.ReadRegisters(iThreadID, emptyBuffer, tempValues, tempReadFlags);
-	test(err == KErrArgument);
-
-	//test register values buffer not being a multiple of sizeof(TUint32)
-	err = iServSession.ReadRegisters(iThreadID, ids, emptyBuffer, tempReadFlags);
-	test(err == KErrArgument);
-
-	//test flags buffer being representing different number of registers from other two
-	err = iServSession.ReadRegisters(iThreadID, ids, tempValues, emptyBuffer);
-	test(err == KErrArgument);
-
-	//set max length to 0
-	emptyBuffer.ReAlloc(0);
-
-	//test ids buffer being of 0 max length
-	err = iServSession.ReadRegisters(iThreadID, emptyBuffer, tempValues, tempReadFlags);
-	test(err == KErrArgument);
-
-	//do cleanup
-	emptyBuffer.Close();
-	tempValues.Close();
-	tempWriteFlags.Close();
-	tempReadFlags.Close();
-	tempReadValues.Close();
-
-	test.Next(_L("TestRegisterAccess - Setting PC value\n"));
-
-	//create buffer containing PC register ID
-	RBuf8 pcId;
-	err = pcId.Create(sizeof(TRegisterInfo));
-	test(err == KErrNone);
-	TRegisterInfo reg1 = (TRegisterInfo)0x00000f00;
-	pcId.Append(reinterpret_cast<const TUint8*>(&reg1), sizeof(TRegisterInfo));
-
-	//create buffer containing desired PC value
-	RBuf8 pcValue;
-	err = pcValue.Create(sizeof(TUint32));
-	test(err == KErrNone);
-	TUint32 address = (TUint32)(&TestFunction);
-	pcValue.Append(reinterpret_cast<const TUint8*>(&address), sizeof(TUint32));
-
-	//craete buffer for PC flag value
-	RBuf8 pcFlag;
-	err = pcFlag.Create(sizeof(TUint8));
-
-	//write the new PC value
-	err = iServSession.WriteRegisters(iThreadID, pcId, pcValue, pcFlag);
-	test(err==KErrNone);
-
-	//get the flag and check the PC value was written ok
-	TRegisterFlag flag = ENotSupported;
-	err = GetFlag(pcFlag, 0, flag);
-	test(err==KErrNone);
-
-	//if the PC value was successfully changed then resume the thread and
-	//the value of TestData will hopefully be changed to our specified
-	//value
-	if(flag == EValid)
-		{
-		err = iServSession.ResumeThread(iThreadID);
-		test(err==KErrNone);
-
-		User::After(500000);
-
-		err = iServSession.SuspendThread(iThreadID);
-		test(err==KErrNone);
-
-		test(TestData == 0xffeeddcc);
-		}
-
-	//Make sure we cannot change the CPSR
-	test.Next(_L("Verifying we cannot change the CPSR mode from USR Mode"));
-
-	TUint32 disallowedCpsr = 0x50000013;
-
-	RBuf8 cpsrRegId;
-	err = cpsrRegId.Create(sizeof(TUint32));
-	test(err == KErrNone);
-
-	TRegisterInfo cpsr = (TRegisterInfo)((cpsrId + firstRegister)<<8);
-	cpsrRegId.Append(reinterpret_cast<const TUint8*>(&cpsr), sizeof(TRegisterInfo));
-
-	RBuf8 cpsrRegFlags;
-	err = cpsrRegFlags.Create(sizeof(TUint8));
-	test(err == KErrNone);
-
-	RBuf8 cpsrVal;
-	err = cpsrVal.Create(sizeof(TUint32));
-	test(err == KErrNone);
-
-	cpsrVal.Append((TUint8*)&disallowedCpsr, 4);
-
-	//attempt to write disallowed CPSR in
-	err = iServSession.WriteRegisters(iThreadID, cpsrRegId, cpsrVal, cpsrRegFlags);
-	test(err == KErrNone);
-
-	RBuf8 cpsrReadVal;
-	err = cpsrReadVal.Create(sizeof(TUint32));
-	test(err == KErrNone);
-
-	//Read back the CPSR
-	err = iServSession.ReadRegisters(iThreadID, cpsrRegId, cpsrReadVal, cpsrRegFlags);
-	test(err == KErrNone);
-
-	//Make sure we havent switched modes ie. its not what we wrote
-	TUint32* readVal = (TUint32*)cpsrReadVal.Ptr();
-	test(*readVal != disallowedCpsr);
-
-	cpsrRegId.Close();
-	cpsrRegFlags.Close();
-	cpsrVal.Close();
-	cpsrReadVal.Close();
-
-	//write the original values back into here
-	err = iServSession.WriteRegisters(iThreadID, ids, originalValues, originalFlags);
-	test(err == KErrNone);
-
-	// Resume the thread
-	err = iServSession.ResumeThread(iThreadID);
-	test(err==KErrNone);
-
-	test(KErrNone == iServSession.DetachExecutable(iFileName));
-
-	//do cleanup
-	pcId.Close();
-	pcValue.Close();
-	pcFlag.Close();
-	ids.Close();
-	originalValues.Close();
-	originalFlags.Close();
-	}
-
-//----------------------------------------------------------------------------------------------
-//! @SYMTestCaseID      KBase-T-RMDEBUG2-0441
-//! @SYMTestType
-//! @SYMPREQ            PREQ1426
-//! @SYMTestCaseDesc    Test registration/de-registration of debug interest in target exe with the Debug Security Server
-//! @SYMTestActions     As per description
-//!
-//! @SYMTestExpectedResults KErrNone.
-//! @SYMTestPriority        High
-//! @SYMTestStatus          Implemented
-//----------------------------------------------------------------------------------------------
-
-void CRunModeAgent::TestAttachExecutable()
-	{
-
-	test.Next(_L("TestAttachExecutable - Attach\n"));
-
-	//attach to process passively
-	test(KErrNone == iServSession.AttachExecutable(iFileName, ETrue));
-
-	//make a thread id for a non-existent thread
-	TThreadId threadId(0x12345678);
-
-	//get a handle to the target thread
-	RThread targetThread;
-	TInt err = targetThread.Open(threadId);
-	test(err != KErrNone);
-
-	//not registered for this thread's process (as it doesn't exist)
-	//so should fail security check
-	err = iServSession.ResumeThread(threadId);
-	test(err==KErrPermissionDenied);
-
-	//try to attach to the same process (and fail)
-	test(KErrAlreadyExists == iServSession.AttachExecutable(iFileName, EFalse));
-
-	test.Next(_L("TestAttachExecutable - Detach\n"));
-
-	//detach from process
-	test(KErrNone == iServSession.DetachExecutable(iFileName));
-
-	//attach non-passively
-	test(KErrNone == iServSession.AttachExecutable(iFileName, EFalse));
-
-	//not registered for this thread's process (as it doesn't exist)
-	//so should fail security check
-	err = iServSession.ResumeThread(0x12345678);
-	test(err==KErrPermissionDenied);
-	test(KErrNone == iServSession.DetachExecutable(iFileName));
-	}
-
-//----------------------------------------------------------------------------------------------
-//! @SYMTestCaseID      KBase-T-RMDEBUG2-0442
-//! @SYMTestType
-//! @SYMPREQ            PREQ1426
-//! @SYMTestCaseDesc    Tests single-stepping target threads.
-//! @SYMTestActions     Steps target thread assembly level instructions, mainly branch/change PC
-//!
-//! @SYMTestExpectedResults KErrNone.
-//! @SYMTestPriority        High
-//! @SYMTestStatus          Implemented
-//----------------------------------------------------------------------------------------------
-
-void CRunModeAgent::TestStep()
-	{
-	//Dont run the test for an SMP System
-	if (UserSvr::HalFunction(EHalGroupKernel, EKernelHalSmpSupported, 0, 0) == KErrNone)
-		return;
-
-	test.Next(_L("TestStep\n"));
-
-	DoTestStep(EFalse);
-	DoTestStep(ETrue);
-	}
-
-void CRunModeAgent::DoTestStep(TBool aThreadSpecific)
-	{
-	test.Printf(_L("DoTestStep: aThreadSpecific: %d\n"), aThreadSpecific?1:0);
-
-	TInt err = KErrNone;
-
-	RProcess process;
-	TProcessId processId = process.Id();
-	process.Close();
-
-	test(KErrNone == iServSession.AttachExecutable(iFileName, EFalse));
-	//set the target thread to execute the stepping functions
-	test(KErrNone == SwitchTestFunction(EStepFunction));
-
-	err = iServSession.SetEventAction(iFileName,EEventsBreakPoint, EActionContinue);
-	test (err == KErrNone);
-
-	if(!aThreadSpecific)
-		{
-		err = iServSession.SetEventAction(iFileName, EEventsProcessBreakPoint, EActionContinue);
-		test (err == KErrNone);
-		}
-
-	TUint32	startAddress;
-	TUint32	endAddress;
-
-	/*
-	 * RMDebug_StepTest_Non_PC_Modifying
-	 */
-	test.Next(_L("TestStep - Non-PC modifying\n"));
-
-	startAddress = (TUint32)(&RMDebug_StepTest_Non_PC_Modifying);
-
-	endAddress = (TUint32)(&RMDebug_StepTest_Non_PC_Modifying_OK);
-
-	err = aThreadSpecific
-		? HelpTestStep(iThreadID,startAddress,endAddress,EArmMode,1)
-		: HelpTestStep(iThreadID,startAddress,endAddress,EArmMode,1, EFalse, processId);
-	test(err==KErrNone);
-
-	/*
-	 * RMDebug_StepTest_Branch
-	 */
-	test.Next(_L("TestStep - Branch\n"));
-
-	startAddress = (TUint32)(&RMDebug_StepTest_Branch);
-
-	endAddress = (TUint32)(&RMDebug_StepTest_Branch_1);
-
-	err = aThreadSpecific
-		? HelpTestStep(iThreadID,startAddress,endAddress,EArmMode,1)
-		: HelpTestStep(iThreadID,startAddress,endAddress,EArmMode,1, EFalse, processId);
-	test(err==KErrNone);
-
-	/*
-	 * RMDebug_StepTest_Branch_And_Link
-	 */
-	test.Next(_L("TestStep - Branch_And_Link\n"));
-
-	startAddress = (TUint32)(&RMDebug_StepTest_Branch_And_Link_1);
-
-	endAddress = (TUint32)(&RMDebug_StepTest_Branch_And_Link_2);
-
-	err = aThreadSpecific
-		? HelpTestStep(iThreadID,startAddress,endAddress,EArmMode,1)
-		: HelpTestStep(iThreadID,startAddress,endAddress,EArmMode,1, EFalse, processId);
-	test(err==KErrNone);
-
-	/*
-	 * RMDebug_StepTest_MOV_PC
-	 */
-	test.Next(_L("TestStep - MOV PC,X\n"));
-
-	startAddress = (TUint32)(&RMDebug_StepTest_MOV_PC_1);
-
-	endAddress = (TUint32)(&RMDebug_StepTest_MOV_PC_2);
-
-	err = aThreadSpecific
-		? HelpTestStep(iThreadID,startAddress,endAddress,EArmMode,1)
-		: HelpTestStep(iThreadID,startAddress,endAddress,EArmMode,1, EFalse, processId);
-	test(err==KErrNone);
-
-	/*
-	 * RMDebug_StepTest_LDR_PC
-	 */
-	test.Next(_L("TestStep - LDR PC\n"));
-
-	startAddress = (TUint32)(&RMDebug_StepTest_LDR_PC);
-
-	endAddress = (TUint32)(&RMDebug_StepTest_LDR_PC_1);
-
-	err = aThreadSpecific
-		? HelpTestStep(iThreadID,startAddress,endAddress,EArmMode,1)
-		: HelpTestStep(iThreadID,startAddress,endAddress,EArmMode,1, EFalse, processId);
-	test(err==KErrNone);
-
-// thumb and interworking tests are not supported on armv4
-#ifdef __MARM_ARMV5__
-
-	/*
-	 * RMDebug_StepTest_Thumb_Non_PC_Modifying
-	 */
-	test.Next(_L("TestStep - Thumb Non PC-Modifying\n"));
-
-	startAddress = (TUint32)(&RMDebug_StepTest_Thumb_Non_PC_Modifying_1);
-
-	endAddress = (TUint32)(&RMDebug_StepTest_Thumb_Non_PC_Modifying_2);
-
-	err = aThreadSpecific
-		? HelpTestStep(iThreadID,startAddress,endAddress,EThumbMode,1)
-		: HelpTestStep(iThreadID,startAddress,endAddress,EThumbMode,1, EFalse, processId);
-	test(err==KErrNone);
-
-	/*
-	 * RMDebug_StepTest_Thumb_Branch
-	 */
-	test.Next(_L("TestStep - Thumb Branch\n"));
-
-	startAddress = (TUint32)(&RMDebug_StepTest_Thumb_Branch_1);
-
-	endAddress = (TUint32)(&RMDebug_StepTest_Thumb_Branch_2);
-
-	err = aThreadSpecific
-		? HelpTestStep(iThreadID,startAddress,endAddress,EThumbMode,1)
-		: HelpTestStep(iThreadID,startAddress,endAddress,EThumbMode,1, EFalse, processId);
-	test(err==KErrNone);
-
-	/*
-	 * RMDebug_StepTest_Thumb_Branch_And_Link
-	 */
-	test.Next(_L("TestStep - Thumb Branch_And_Link\n"));
-
-	startAddress = (TUint32)(&RMDebug_StepTest_Thumb_Branch_And_Link_2);
-
-	endAddress = (TUint32)(&RMDebug_StepTest_Thumb_Branch_And_Link_3);
-
-	TInt muid=0;
-    test(HAL::Get(HAL::EMachineUid, muid)==KErrNone);
-
-	// check if running on ARMv7 core
-	if(muid==HAL::EMachineUid_OmapH6 || muid==HAL::EMachineUid_OmapZoom || muid==HAL::EMachineUid_EmuBoard)
-        {
-        // Note: ARMv7 treats BL instructions as single 32-bit instructions
-        err = aThreadSpecific
-		? HelpTestStep(iThreadID,startAddress,endAddress,EThumbMode,1)
-		: HelpTestStep(iThreadID,startAddress,endAddress,EThumbMode,1, EFalse, processId);
-        }
-    else
-	    {
-        // Note: Due to the fact that the stepper treats BL instructions
-		// as two instructions (as the hardware does), then we must step
-		// the first half instruction first)
-
-		err = aThreadSpecific
-		? HelpTestStep(iThreadID,startAddress,startAddress+2,EThumbMode,1)
-		: HelpTestStep(iThreadID,startAddress,startAddress+2,EThumbMode,1, EFalse, processId);
-		test(err==KErrNone);
-
-	// Now we actually do the BL
-	err = aThreadSpecific
-		? HelpTestStep(iThreadID,startAddress+2,endAddress,EThumbMode,1)
-		: HelpTestStep(iThreadID,startAddress+2,endAddress,EThumbMode,1, EFalse, processId);
-        }
-	test(err==KErrNone);
-
-	/*
-	 * RMDebug_StepTest_Thumb_Back_Branch_And_Link
-	 */
-	test.Next(_L("TestStep - Thumb Back_Branch_And_Link\n"));
-
-	startAddress = (TUint32)(&RMDebug_StepTest_Thumb_Back_Branch_And_Link_2);
-
-	endAddress = (TUint32)(&RMDebug_StepTest_Thumb_Back_Branch_And_Link_3);
-
-	// check if running on ARMv7 core
-	if(muid==HAL::EMachineUid_OmapH6 || muid==HAL::EMachineUid_OmapZoom || muid==HAL::EMachineUid_EmuBoard)
-		{
-		// Note: ARMv7 treats BL instructions as single 32-bit instructions
-		err = aThreadSpecific
-			? HelpTestStep(iThreadID,startAddress,endAddress,EThumbMode,1)
-			: HelpTestStep(iThreadID,startAddress,endAddress,EThumbMode,1, EFalse, processId);
-		}
-	else
-		{
-		// Note: Due to the fact that the stepper treats BL instructions
-		// as two instructions (as the hardware does), then we must step
-		// the first half instruction first)
-
-		err = aThreadSpecific
-	   		? HelpTestStep(iThreadID,startAddress,startAddress+2,EThumbMode,1)
-			: HelpTestStep(iThreadID,startAddress,startAddress+2,EThumbMode,1, EFalse, processId);
-		test(err==KErrNone);
-
-	   	// Now we actually do the BL
-		err = aThreadSpecific
-   			? HelpTestStep(iThreadID,startAddress+2,endAddress,EThumbMode,1)
-			: HelpTestStep(iThreadID,startAddress+2,endAddress,EThumbMode,1, EFalse, processId);
-		}
-	test(err==KErrNone);
-
-	/*
-	 * RMDebug_StepTest_Thumb_AddPC
-	 */
-	test.Next(_L("TestStep - Thumb ADD PC, PC, R0\n"));
-
-	startAddress = (TUint32)(&RMDebug_StepTest_Thumb_AddPC_2);
-
-	endAddress = (TUint32)(&RMDebug_StepTest_Thumb_AddPC_3);
-
-	err = aThreadSpecific
-		? HelpTestStep(iThreadID,startAddress,endAddress,EThumbMode,1)
-		: HelpTestStep(iThreadID,startAddress,endAddress,EThumbMode,1, EFalse, processId);
-	test(err==KErrNone);
-
-	/*
-	 * RMDebug_StepTest_Interwork ARM to Thumb
-	 */
-	test.Next(_L("TestStep - Interworking ARM to Thumb - BLX \n"));
-
-	startAddress = (TUint32)(&RMDebug_StepTest_Interwork_1);
-
-	endAddress = (TUint32)(&RMDebug_StepTest_Interwork_2);
-
-	err = aThreadSpecific // nb initial breakpoint in ARM code
-		? HelpTestStep(iThreadID,startAddress,endAddress,EArmMode,1)
-		: HelpTestStep(iThreadID,startAddress,endAddress,EArmMode,1, EFalse, processId);
-
-	test(err==KErrNone);
-
-	/*
-	 * RMDebug_StepTest_Interwork Thumb to ARM
-	 */
-	test.Next(_L("TestStep - Interworking Thumb to ARM - BLX\n"));
-
-	startAddress = (TUint32)(&RMDebug_StepTest_Interwork_2);
-
-	endAddress = (TUint32)(&RMDebug_StepTest_Interwork_3);
-
-	// check if running on ARMv7 core
-	if(muid==HAL::EMachineUid_OmapH6 || muid==HAL::EMachineUid_OmapZoom || muid==HAL::EMachineUid_EmuBoard)
-        {
-        // ARMv7 treats BLX instructions as single 32-bit instructions
-        err = aThreadSpecific
-		? HelpTestStep(iThreadID,startAddress,endAddress,EThumbMode,1)
-		: HelpTestStep(iThreadID,startAddress,endAddress,EThumbMode,1, EFalse, processId);
-        }
-    else
-        {
-    	// Stepper treats this as a two-stage instruction (just like the hardware)
-	err = aThreadSpecific
-		? HelpTestStep(iThreadID,startAddress,startAddress+2,EThumbMode,1)
-		: HelpTestStep(iThreadID,startAddress,startAddress+2,EThumbMode,1, EFalse, processId);
-	test(err == KErrNone);
-
-	err = aThreadSpecific
-		? HelpTestStep(iThreadID,startAddress+2,endAddress,EThumbMode,1)
-		: HelpTestStep(iThreadID,startAddress+2,endAddress,EThumbMode,1, EFalse, processId);
-        }
-	test(err == KErrNone);
-
-#endif // __MARM_ARMV5__
-
-	/*
-	 * Test multiple-step of ARM code
-	 */
-	test.Next(_L("TestStep - ARM Multiple instruction step\n"));
-
-	startAddress = (TUint32)(&RMDebug_StepTest_ARM_Step_Multiple);
-
-	endAddress = (TUint32)(&RMDebug_StepTest_ARM_Step_Multiple_1);
-
-	err = aThreadSpecific
-		? HelpTestStep(iThreadID,startAddress,endAddress,EArmMode,5)
-		: HelpTestStep(iThreadID,startAddress,endAddress,EArmMode,5, EFalse, processId);
-	test(err == KErrNone);
-	// stepping performance
-	test.Next(_L("TestStep - Steps per second\n"));
-
-	// run until we reach RMDebug_StepTest_Count_1
-	TBreakId stepBreakId;
-	startAddress = (TUint32)(&RMDebug_StepTest_Count_1);
-	endAddress = (TUint32)(&RMDebug_StepTest_Count_2);
-
-	err = aThreadSpecific
-		? HelpTestStepSetBreak(stepBreakId,iThreadID,startAddress,EArmMode)
-		: HelpTestStepSetBreak(stepBreakId,iThreadID,startAddress,EArmMode,EFalse,processId);
-	test (err == KErrNone);
-
-	// wait until we hit the breakpoint
-	TEventInfo info;
-	err = HelpTestStepWaitForBreak(iFileName,info);
-	test (err == KErrNone);
-
-	// Now clear the breakpoint
-	err = iServSession.ClearBreak(stepBreakId);
-	test(err == KErrNone);
-
-	if(aThreadSpecific)
-		{
-		// now step the code
-		TInt stepsPerSecond = 0;
-
-		TUint32 stopTickCount = User::NTickCount() + HelpTicksPerSecond();
-
-		while (User::NTickCount() < stopTickCount)
-			{
-			err = iServSession.Step(iThreadID,1);
-			test (err == KErrNone);
-
-			// we need to wait now until the step completes before asking for the next step
-				{
-				TEventInfo info;
-				static TRequestStatus status;
-
-				TPtr8 infoPtr((TUint8*)&info,0,sizeof(TEventInfo));
-
-				iServSession.GetEvent(iFileName,status,infoPtr);
-
-				// Wait for notification of the breakpoint hit event
-				User::WaitForRequest(status);
-				test(status==KErrNone);
-				}
-
-			// Update the count of steps
-			stepsPerSecond += 1;
-
-			// Gone wrong if we do too many
-			test(stepsPerSecond < 10000);
-			}
-
-		iStepsPerSecond = stepsPerSecond;
-		test(iStepsPerSecond != 0);
-		}
-
-	// finally resume the thread
-	err = iServSession.ResumeThread(iThreadID);
-	test (err == KErrNone);
-
-	err = iServSession.SetEventAction(iFileName,EEventsBreakPoint, EActionIgnore);
-	test (err == KErrNone);
-
-	if(!aThreadSpecific)
-		{
-		err = iServSession.SetEventAction(iFileName, EEventsProcessBreakPoint, EActionIgnore);
-		test (err == KErrNone);
-		}
-
-	test(KErrNone == iServSession.DetachExecutable(iFileName));
-	}
-
-//----------------------------------------------------------------------------------------------
-//! @SYMTestCaseID      KBase-T-RMDEBUG2-0443
-//! @SYMTestType
-//! @SYMPREQ            PREQ1426
-//! @SYMTestCaseDesc    Tests registration and occurrence of target thread event (in this case panic)
-//! @SYMTestActions     Registers for a panic in the target thread, causes it, and catches the panic notification.
-//!
-//! @SYMTestExpectedResults KErrNone.
-//! @SYMTestPriority        High
-//! @SYMTestStatus          Implemented
-//----------------------------------------------------------------------------------------------
-
-void CRunModeAgent::TestEvents()
-	{
-	TInt err = KErrNone;
-
-	test.Next(_L("TestEvents\n"));
-
-	TInt panicReason = 12345;
-
-	test.Printf(_L("Thread t_rmdebug.exe::DebugThread should panic with reason %d.\n"), panicReason);
-
-	//attach non-passively
-	test(KErrNone == iServSession.AttachExecutable(iFileName, EFalse));
-
-	RThread threadToPanic;
-	test(KErrNone == StartDebugThread(threadToPanic, _L("EventsThread")));
-	TThreadId threadToPanicId = threadToPanic.Id();
-	TEventInfo info;
-
-	// Set things up to wait for a thread kill event
-	err = iServSession.SetEventAction(iFileName, EEventsKillThread, EActionContinue);
-	test(err==KErrNone);
-
-	// Wait for an event to occur in this process - nothing should have happened yet.
-	static TRequestStatus status;
-
-	TPtr8 infoPtr((TUint8*)&info,0,sizeof(TEventInfo));
-
-	iServSession.GetEvent(iFileName,status,infoPtr);
-
-	// Test Request cancellation
-	err = iServSession.CancelGetEvent(iFileName);
-	test (err==KErrNone);
-
-	// Again wait for an event to occur in our process - we will provoke the
-	// thread kill event by panic'ing the test thread.
-	iServSession.GetEvent(iFileName,status,infoPtr);
-
-	// Panic the debug thread to cause a thread kill event
-	threadToPanic.Panic(_L("t_rmdebug panic thread test"), panicReason);
-
-	// Wait for notification of the Thread Kill event
-	User::WaitForRequest(status);
-	test(status==KErrNone);
-
-	// Check we are really recieving information about the panic
-	test(info.iProcessIdValid);
-	test(info.iThreadIdValid);
-	test(info.iProcessId==RProcess().Id());
-	test(info.iThreadId==threadToPanicId);
-	test(info.iEventType==EEventsKillThread);
-	test(info.iThreadKillInfo.iExitType==EExitPanic);
-
-	// Ignore other panic events
-	err = iServSession.SetEventAction(iFileName, EEventsKillThread, EActionIgnore);
-	test(err==KErrNone);
-
-	test(KErrNone == iServSession.DetachExecutable(iFileName));
-	}
-
-//----------------------------------------------------------------------------------------------
-//! @SYMTestCaseID      KBase-T-RMDEBUG2-0444
-//! @SYMTestType
-//! @SYMPREQ            PREQ1426
-//! @SYMTestCaseDesc    Tests registration and occurence of target thread events in separate process.
-//! @SYMTestActions     Registers for a hardware exception and kill thread events, and receives them.
-//!
-//! @SYMTestExpectedResults KErrNone.
-//! @SYMTestPriority        High
-//! @SYMTestStatus          Implemented
-//----------------------------------------------------------------------------------------------
-void CRunModeAgent::TestEventsForExternalProcess()
-	{
-	//Dont run the test for an SMP System
-	if (UserSvr::HalFunction(EHalGroupKernel, EKernelHalSmpSupported, 0, 0) == KErrNone)
-		return;
-
-	test.Next(_L("TestEventsForExternalProcess\n"));
-
-	for(TInt main=0; main<3; main++)
-		{
-		for(TInt extra=0; extra<3; extra++)
-			{
-			TestEventsWithExtraThreads((TKernelEventAction)main, (TKernelEventAction)extra, 0);
-			TestEventsWithExtraThreads((TKernelEventAction)main, (TKernelEventAction)extra, 2);
-			}
-		}
-	}
-
-void CRunModeAgent::TestEventsWithExtraThreads(TKernelEventAction aActionMain, TKernelEventAction aActionExtra, TUint32 aExtraThreads)
-	{
-	const TInt KNumberOfTypes = 8;
-	struct TEventStruct
-		{
-		public:
-		TDebugFunctionType iDebugFunctionType;
-		TEventType iEventType;
-		};
-
-	TEventStruct type[KNumberOfTypes] =
-		{
-			{EStackOverflowFunction, EEventsHwExc},
-			{EUserPanicFunction, EEventsKillThread},
-			{EPrefetchAbortFunction, EEventsHwExc},
-			{EDataAbortFunction, EEventsHwExc},
-			{EUndefInstructionFunction, EEventsHwExc},
-			{EDataReadErrorFunction, EEventsHwExc},
-			{EDataWriteErrorFunction, EEventsHwExc},
-			{EUserExceptionFunction, EEventsSwExc},
-		};
-
-	for(TInt j=0; j<KNumberOfTypes; j++)
-		{
-		//RDebug::Printf("**** type: %d, main action: %d, extra action: %d, extraThreads: %d", j, (TUint32)aActionMain, (TUint32)aActionExtra, aExtraThreads);
-
-		// do this check as it seems to hard to do these cases with the current set up
-		if(EEventsKillThread == type[j].iEventType)
-			{
-			if(EActionSuspend != aActionMain)
-				{
-				if(aActionMain != aActionExtra)
-					{
-					return;
-					}
-				}
-			}
-		// attach to KRMDebugTestApplication
-		test(KErrNone == iServSession.AttachExecutable(KRMDebugTestApplication, EFalse));
-
-		// Set things up to wait for the expected exception in KRMDebugTestApplication
-		test(KErrNone == iServSession.SetEventAction(KRMDebugTestApplication, type[j].iEventType, aActionMain));
-
-		if(EActionSuspend != aActionMain)
-			{
-			test(KErrNone == iServSession.SetEventAction(KRMDebugTestApplication, EEventsKillThread, aActionExtra));
-			}
-
-		// declare a TRequestStatus object for asynchronous calls
-		TRequestStatus status;
-
-		TEventInfo info;
-		TPtr8 infoBuffer = TPtr8((TUint8*)&info,0,sizeof(TEventInfo));
-		if(EActionIgnore != aActionMain)
-			{
-			iServSession.GetEvent(KRMDebugTestApplication(), status, infoBuffer);
-			}
-
-		// launch the target process to trigger the expected exception
-		RProcess targetProcess;
-		test(KErrNone == LaunchProcess(targetProcess, KRMDebugTestApplication(), type[j].iDebugFunctionType, 0, aExtraThreads));
-		TProcessId processId(targetProcess.Id());
-		targetProcess.Close();
-
-		if(EActionIgnore != aActionMain)
-			{
-			// wait for notification of the exception
-			User::WaitForRequest(status);
-			test(KErrNone == status.Int());
-
-			// check that this is the event we were expecting
-			test(info.iProcessIdValid);
-			test(info.iThreadIdValid);
-			test(info.iProcessId==processId);
-			test(info.iEventType==type[j].iEventType);
-			}
-
-		if(EActionSuspend == aActionMain)
-			{
-			// read the thread list, partly to check the call works, and partly to check the thread still exists
-			test(ThreadExistsForProcess(info.iThreadId, info.iProcessId));
-
-			// register to catch all the thread kills which will occur
-			test(KErrNone == iServSession.SetEventAction(KRMDebugTestApplication, EEventsKillThread, aActionExtra));
-			// we specified EActionSuspend earlier so need to call resume on this thread
-			test(KErrNone == iServSession.ResumeThread(info.iThreadId));
-			}
-
-		// find out how many threads there are in the process and catch all the thread kill events,
-		// the number of kill thread events should correspond to the number of extra threads launched,
-		// plus one if the main thread panicked with a Sw/Hw exception
-		if(EActionIgnore != aActionExtra)
-			{
-			TInt dyingThreads = aExtraThreads + ( (type[j].iEventType != EEventsKillThread) ? 1 : 0);
-			for(TInt k=0; k<dyingThreads; k++)
-				{
-				iServSession.GetEvent(KRMDebugTestApplication(), status, infoBuffer);
-				// wait for notification of the kill thread
-				User::WaitForRequest(status);
-				test(KErrNone == status.Int());
-
-				// check that this is the event we were expecting
-				test(info.iProcessIdValid);
-				test(info.iThreadIdValid);
-				test(info.iProcessId==processId);
-				test(info.iEventType==EEventsKillThread);
-				if(EActionSuspend == aActionExtra)
-					{
-					// do some calls to check listings work ok at this stage
-					test(ProcessExists(info.iProcessId));
-					test(ThreadExistsForProcess(info.iThreadId, info.iProcessId));
-					// we specified EActionSuspend earlier so need to call resume on this thread
-					test(KErrNone == iServSession.ResumeThread(info.iThreadId));
-					}
-				}
-			}
-		// reset the thread kill event
-		test(KErrNone == iServSession.SetEventAction(KRMDebugTestApplication(), EEventsKillThread, EActionIgnore));
-
-		// reset events for KRMDebugTestApplication
-		test(KErrNone == iServSession.SetEventAction(KRMDebugTestApplication(), type[j].iEventType, EActionIgnore));
-
-		// finished debugging KRMDebugTestApplication so detach
-		test(KErrNone == iServSession.DetachExecutable(KRMDebugTestApplication()));
-
-		// want to validate that the process has really exited, i.e. we're not accidentally keeping a handle to it...
-		if(ProcessExists(processId))
-			{
-			// wait a little while and try again, just in case the process was still being shut down when we tried the first time
-			User::After(1000000);
-			test(!ProcessExists(processId));
-			}
-		}
-	}
-
-// helper function to check whether a thread with id aThreadId exists in the process with id aProcessId
-TBool CRunModeAgent::ThreadExistsForProcess(const TThreadId aThreadId, const TProcessId aProcessId)
-	{
-	TUint32 size;
-	RBuf8 buffer;
-	test(KErrNone == buffer.Create(1024));
-	TInt err = iServSession.GetList(aProcessId, EThreads, buffer, size);
-	while(KErrTooBig == err)
-		{
-		size*=2;
-		test(size<=16*1024);
-		test(KErrNone == buffer.ReAlloc(size));
-		err = iServSession.GetList(aProcessId, EThreads, buffer, size);
-		}
-	test(KErrNone == err);
-
-	//look through the buffer and check if the target debug thread is there
-	TUint8* ptr = (TUint8*)buffer.Ptr();
-	const TUint8* ptrEnd = ptr + size;
-	while(ptr < ptrEnd)
-		{
-		TThreadListEntry& entry = *(TThreadListEntry*)ptr;
-		if(aThreadId.Id() == entry.iThreadId)
-			{
-			buffer.Close();
-			return ETrue;
-			}
-		ptr += Align4(entry.GetSize());
-		}
-	buffer.Close();
-	return EFalse;
-	}
-
-// helper function to check whether a process with id aProcessId exists
-TBool CRunModeAgent::ProcessExists(const TProcessId aProcessId)
-	{
-	TUint32 size;
-	RBuf8 buffer;
-	test(KErrNone == buffer.Create(1024));
-	TInt err = iServSession.GetList(EProcesses, buffer, size);
-	while(KErrTooBig == err)
-		{
-		size*=2;
-		test(size<=16*1024);
-		test(KErrNone == buffer.ReAlloc(size));
-		err = iServSession.GetList(EProcesses, buffer, size);
-		}
-	test(KErrNone == err);
-
-	//look through the buffer and check if the target debug thread is there
-	TUint8* ptr = (TUint8*)buffer.Ptr();
-	const TUint8* ptrEnd = ptr + size;
-	while(ptr < ptrEnd)
-		{
-		TProcessListEntry& entry = *(TProcessListEntry*)ptr;
-		if(aProcessId.Id() == entry.iProcessId)
-			{
-			buffer.Close();
-			return ETrue;
-			}
-		ptr += Align4(entry.GetSize());
-		}
-	buffer.Close();
-	return EFalse;
-	}
-
-//----------------------------------------------------------------------------------------------
-//! @SYMTestCaseID      KBase-T-RMDEBUG2-0445
-//! @SYMTestType
-//! @SYMPREQ            PREQ1426
-//! @SYMTestCaseDesc    Tests basic debug functions work on demand-paged target threads
-//! @SYMTestActions     Checks it can r/w memory, set breakpoints etc in a demand paged target.
-//!
-//! @SYMTestExpectedResults KErrNone.
-//! @SYMTestPriority        High
-//! @SYMTestStatus          Implemented
-//----------------------------------------------------------------------------------------------
-
-void CRunModeAgent::TestDemandPaging(void)
-	{
-	test.Next(_L("TestDemandPaging\n"));
-
-	test(KErrNone == iServSession.AttachExecutable(iFileName, EFalse));
-	test(KErrNone == iServSession.SuspendThread(iThreadID));
-
-	// get the address of a function in code that will be paged in
-	TUint32 address = (TUint32)(&RMDebugDemandPagingTest);
-	const TUint32 armInstSize = 4;
-
-	// read the memory at &RMDebugDemandPagingTest to check that reading memory in demand paged code works
-	TUint32 demandPagedInst = 0;
-	TPtr8 demandPagedInstBuf((TUint8*)&demandPagedInst, armInstSize);
-	test(KErrNone == iServSession.ReadMemory(iThreadID, address, armInstSize, demandPagedInstBuf, EAccess32, EEndLE8));
-
-	// this is the MOVS instruction that we expect to find in RMDebugDemandPagingTest
-	TUint32 expectedDemandPagedInst = 0xe1b02000;
-
-	// check that the instruction we read is as expected
-	test(demandPagedInst == expectedDemandPagedInst);
-
-	// set event action for break points
-	test(KErrNone == iServSession.SetEventAction(RProcess().FileName(), EEventsBreakPoint, EActionContinue));
-
-	// set an arm breakpoint on RMDebugDemandPagingTest
-	TBreakId armBreakId = 0;
-	test(KErrNone == iServSession.SetBreak(armBreakId, iThreadID, address, EArmMode));
-
-	// Ensure that after setting the breakpoint the memory read returns the correct value
-	TUint32 demandPagedInstWithBreakPoint = 0;
-	TPtr8 spinForeverInstWithBreakPointBuf((TUint8*)&demandPagedInstWithBreakPoint, armInstSize);
-	test(KErrNone == iServSession.ReadMemory(iThreadID, address, armInstSize, spinForeverInstWithBreakPointBuf, EAccess32, EEndLE8));
-	test(demandPagedInst == demandPagedInstWithBreakPoint);
-
-	// switch the target thread to run the demand paging function
-	test(KErrNone == SwitchTestFunction(EDemandPagingFunction));
-
-	// set up event watcher to catch breakpoint being hit in demand paged code
-	TEventInfo info;
-	static TRequestStatus status;
-	TPtr8 infoPtr((TUint8*)&info,sizeof(TEventInfo));
-	iServSession.GetEvent(RProcess().FileName(), status, infoPtr);
-
-	// resume the thread
-	test(KErrNone == iServSession.ResumeThread(iThreadID));
-	// wait for notification of the breakpoint hit event
-	User::WaitForRequest(status);
-	test(status==KErrNone);
-
-	// info should now be filled with the details
-	test(info.iProcessIdValid);
-	test(info.iThreadIdValid);
-	test(info.iEventType == EEventsBreakPoint);
-	test(info.iThreadBreakPointInfo.iRmdArmExcInfo.iR15 == address);
-
-	// remove the break point and resume the thread
-	test(KErrNone == iServSession.ClearBreak(armBreakId));
-
-	// switch the target thread to run the default function
-	test(KErrNone == SwitchTestFunction(EDefaultFunction));
-
-	test(KErrNone == iServSession.ResumeThread(iThreadID));
-	test(KErrNone == iServSession.DetachExecutable(iFileName));
-	}
-
-// Names of some test programs used for testing security
-_LIT(KRMDebugSecurity0FileName,"z:\\sys\\bin\\t_rmdebug_security0.exe"); // Debuggable
-_LIT(KRMDebugSecurity1FileName,"z:\\sys\\bin\\t_rmdebug_security1.exe"); // Not debuggable
-_LIT(KRMDebugSecurity2FileName,"z:\\sys\\bin\\t_rmdebug_security2.exe"); // AllFiles
-_LIT(KRMDebugSecurity3FileName,"z:\\sys\\bin\\t_rmdebug_security3.exe"); // TCB AllFiles
-
-// include the test header file here
-#include "rm_debug_kerneldriver.h"
-
-//----------------------------------------------------------------------------------------------
-//! @SYMTestCaseID      KBase-T-RMDEBUG2-0446
-//! @SYMTestType
-//! @SYMPREQ            PREQ1426
-//! @SYMTestCaseDesc    Tests Debug Device Driver is locked to the SID of the Debug Security Svr.
-//! @SYMTestActions     Loads rm-debug.ldd and tries to open a handle to it. This should fail.
-//!
-//! @SYMTestExpectedResults KErrPermissionDenied.
-//! @SYMTestPriority        High
-//! @SYMTestStatus          Implemented
-//----------------------------------------------------------------------------------------------
-
-void CRunModeAgent::TestDriverSecurity(void)
-	{
-	test.Next(_L("TestDriverSecurity\n"));
-
-	RRM_DebugDriver kernelDriver;
-
-	// Load the debug device driver
-	TInt err = User::LoadLogicalDevice( KDebugDriverFileName );
-	test((KErrNone == err) || (KErrAlreadyExists == err));
-
-	// we were allowed to load the driver, or its already loaded.
-
-	// Try to open a handle to the driver - this should return KErrPermissionDenied as we don't have the DSS SID
-	TRM_DebugDriverInfo driverInfo;
-	driverInfo.iUserLibraryEnd = 0;
-	err = kernelDriver.Open(driverInfo);
-	test((err == KErrInUse) || (err == KErrPermissionDenied));
-
-	}
-
-//----------------------------------------------------------------------------------------------
-//! @SYMTestCaseID      KBase-T-RMDEBUG2-0447
-//! @SYMTestType
-//! @SYMPREQ            PREQ1426
-//! @SYMTestCaseDesc    Tests Debug driver can only be access via the DSS. Also tests DSS cannot
-//!						be subverted. Tests functionality of two representative OEM Debug Tokens.
-//! @SYMTestActions     Tries to open rm_debug.ldd (should fail). Tries to debug various processes
-//!						(only debuggable one should succeed).
-//!
-//! @SYMTestExpectedResults KErrPermissionDenied.
-//! @SYMTestPriority        High
-//! @SYMTestStatus          Implemented
-//----------------------------------------------------------------------------------------------
-
-void CRunModeAgent::TestSecurity(void)
-	{
-	// Things to test
-	//
-	// try to use debug driver directly ( should have the wrong UID/SID value!)
-	test.Next(_L("TestSecurity - Bypass Debug Security Server to Debug Device Driver - DSS running\n"));
-
-	// Things to test
-	//
-	// Load the debug device driver
-	RRM_DebugDriver kernelDriver;
-	TInt err = User::LoadLogicalDevice( KDebugDriverFileName );
-	test((KErrNone == err) || (KErrAlreadyExists == err));
-
-	// we were allowed to load the driver, or its already loaded.
-
-	// Try to open handle a to the driver - this should return KErrPermission/KErrInUse as we don't have the DSS SID
-	// and we expect the DSS to already be using it.
-	TRM_DebugDriverInfo driverInfo;
-	driverInfo.iUserLibraryEnd = 0;
-	err = kernelDriver.Open(driverInfo);
-	test(err == KErrInUse);
-
-	//
-	// Attach to the Debug Security Server (passive)
-	//
-	test.Next(_L("TestSecurity - Attach to the Debug Security Server (passive)\n"));
-
-	_LIT(KSecurityServerProcessName, "z:\\sys\\bin\\rm_debug_svr.exe");
-
-	test(KErrPermissionDenied == iServSession.AttachExecutable(KSecurityServerProcessName, ETrue));
-
-	//
-	// Attach to the Debug Security Server (active)
-	//
-	test.Next(_L("TestSecurity - Attach to the Debug Security Server (active)\n"));
-
-	test(KErrPermissionDenied == iServSession.AttachExecutable(KSecurityServerProcessName, EFalse));
-
-	//
-	// Attach to Process 0
-	//
-	// Target: Debuggable
-	//
-	test.Next(_L("TestSecurity - Attach to test process 0\n"));
-
-	// Agent can debug the target app as it is marked debuggable - ie capabilities are ignored)
-	HelpTestSecurityAttachDetachExecutable(KRMDebugSecurity0FileName,ETrue);
-
-	//
-	// Attach to Process - 1
-	//
-	// Target: Non-debuggable for ordinary debug agent, debuggable for OEM/OEM2 token authorised agent
-	//
-	// Note: This target app has no PlatSec capabilities
-	//
-	// Agent cannot debug the app unless it has an OEM/OEM2 Debug Token
-	test.Next(_L("TestSecurity - Attach to test process 1\n"));
-
-#ifdef SYMBIAN_STANDARDDEBUG
-	HelpTestSecurityAttachDetachExecutable(KRMDebugSecurity1FileName,EFalse);
-#endif
-
-#ifdef SYMBIAN_OEMDEBUG
-	HelpTestSecurityAttachDetachExecutable(KRMDebugSecurity1FileName,ETrue);
-#endif
-
-#ifdef SYMBIAN_OEM2DEBUG
-	HelpTestSecurityAttachDetachExecutable(KRMDebugSecurity1FileName,ETrue);
-#endif
-
-	//
-	// Attach to Process - 2
-	//
-	// Target: Non-debuggable for ordinary debug agent, non-debuggable for OEM2 authorised agent (insufficient caps)
-	//
-	// Note: This target app has AllFiles capability
-	//
-	// Agent cannot debug the app unless it has an OEM Debug Token
-	test.Next(_L("TestSecurity - Attach to test process 2\n"));
-
-#ifdef SYMBIAN_STANDARDDEBUG
-	HelpTestSecurityAttachDetachExecutable(KRMDebugSecurity2FileName,EFalse);
-#endif
-
-#ifdef SYMBIAN_OEMDEBUG
-	HelpTestSecurityAttachDetachExecutable(KRMDebugSecurity2FileName,ETrue);
-#endif
-
-#ifdef SYMBIAN_OEM2DEBUG
-	HelpTestSecurityAttachDetachExecutable(KRMDebugSecurity2FileName,EFalse);
-#endif
-
-	//
-	// Attach to Process - 3
-	//
-	// Target: Non-debuggable for ordinary debug agent, non-debuggable for OEM authorised agent (insufficient caps)
-	//
-	// Note: This target app has AllFiles and TCB and NetworkControl capabilities
-	//
-	test.Next(_L("TestSecurity - Attach to test process 3\n"));
-
-	HelpTestSecurityAttachDetachExecutable(KRMDebugSecurity3FileName,EFalse);
-
-	}
-
-//----------------------------------------------------------------------------------------------
-//! @SYMTestCaseID      KBase-T-RMDEBUG2-0543
-//! @SYMTestType
-//! @SYMPREQ            PREQ1426
-//! @SYMTestCaseDesc    Validates that a dll can be built which #include's the rm_debug_api.h header, i.e. rm_debug_api.h contains no static data.
-//! @SYMTestActions     Calls a dummy function in t_rmdebug_dll.dll which implies the dll has been built correctly.
-//!
-//! @SYMTestExpectedResults KErrNone.
-//! @SYMTestPriority        High
-//! @SYMTestStatus          Implemented
-//----------------------------------------------------------------------------------------------
-void CRunModeAgent::TestDllUsage(void)
-	{
-	test.Next(_L("TestDllUsage\n"));
-	test(KUidDebugSecurityServer == GetDSSUid());
-	}
-
-//----------------------------------------------------------------------------------------------
-//! @SYMTestCaseID      KBase-T-RMDEBUG2-0812
-//! @SYMTestType
-//! @SYMPREQ            PREQ1700
-//! @SYMTestCaseDesc    Writes a known data to the crash flash and validates the data written
-//!						using the read operation and finally erase the data. In the absence
-//!						of an OEM debug token, access to the crash partition should not be allowed
-//! @SYMTestActions     Invoke the flash write method in DSS and call the read method in DSS
-//!						to validate the data is written correctly and then erase the written area
-//!
-//! @SYMTestExpectedResults KErrNone.
-//! @SYMTestPriority        High
-//! @SYMTestStatus          Implemented
-//----------------------------------------------------------------------------------------------
-void CRunModeAgent::TestCrashFlash(void)
-	{
-#if  defined (SYMBIAN_STANDARDDEBUG)  || defined (SYMBIAN_OEM2DEBUG)
-
-	test.Next(_L("@SYMTestCaseID:DT-debug-securityserver-006 Testing We cannot Erase the Crash Flash with insufficient privileges"));
-
-	TUint32 size = 0;
-	TInt err = iServSession.EraseCrashLog(0, 1);
-	test(KErrPermissionDenied == err);
-
-	test.Next(_L("@SYMTestCaseID:DT-debug-securityserver-005 Testing We can't Write to the Crash Flash with insufficient privileges"));
-
-	err = iServSession.WriteCrashConfig(0, KCrashDummyData, size);
-	test(KErrPermissionDenied == err);
-	test(size == 0);
-
-	test.Next(_L("@SYMTestCaseID:DT-debug-securityserver-008 Testing We can't Read from the Crash Flash with insufficient privileges"));
-
-	TUint32 readSize = 0x10;
-	RBuf8 buf;
-	buf.CleanupClosePushL();
-	err = buf.Create(readSize);
-
-	test(err == KErrNone);
-
-	err = iServSession.ReadCrashLog(0, buf, readSize);
-	test(KErrPermissionDenied == err);
-
-	test.Next(_L("@SYMTestCaseID:DT-debug-securityserver-004 Testing Writing To an invalid location"));
-
-	TUint32 writeSize = 0;
-	err = iServSession.WriteCrashConfig(0xFFFFFFFF, KCrashDummyData, writeSize);
-
-	test(err == KErrPermissionDenied);
-
-	test.Next(_L("@SYMTestCaseID:DT-debug-securityserver-003 Testing Reading from an invalid location"));
-
-	buf.FillZ();
-	err = iServSession.ReadCrashLog(0, buf, writeSize);
-
-	test(err == KErrPermissionDenied);
-
-	CleanupStack::PopAndDestroy(&buf);
-
-#endif
-
-#ifdef SYMBIAN_OEMDEBUG
-
-	TInt err = KErrNone;
-
-	test.Next(_L("@SYMTestCaseID:DT-debug-securityserver-007 Testing We can Erase the Crash Flash with sufficient privileges"));
-
-	err = iServSession.EraseCrashLog(0, 1);
-
- 	//For platforms without a flash partition we get KErrNotFound - this is still a pass
- 	if(KErrNotFound == err)
- 		{
- 		test.Printf(_L("Platform has no flash partition - continue"));
- 		return;
- 		}
-
-	test(KErrNone == err);
-
-	//Read back the start of the block to make sure its 0xFFFFFFFF
-	const TUint numBytesToCheck = 0x80;  //We dont know the block size
-	TBuf8<numBytesToCheck> eraseCheck;
-	eraseCheck.SetLength(numBytesToCheck);
-
-	err = iServSession.ReadCrashLog(0, eraseCheck, numBytesToCheck);
-	test(err == KErrNone);
-
-	TBool dataIsOk = ETrue;
-	for(TUint cnt = 0; cnt < numBytesToCheck; cnt++)
-		{
-		if(eraseCheck[cnt] != 0xFF)
-			{
-			dataIsOk = EFalse;
-			}
-		}
-
-	test(dataIsOk);
-
-	test.Next(_L("@SYMTestCaseID:DT-debug-securityserver-002 Testing We can Write to the Crash Flash with sufficient privileges"));
-
-	TUint32 writeSize = 0;
-	err = iServSession.WriteCrashConfig(0, KCrashDummyData, writeSize);
-
-	test(writeSize == KCrashDummyData().Length());
-
-	test.Next(_L("@SYMTestCaseID:DT-debug-securityserver-001 Testing We can Read from the Crash Flash with sufficient privileges"));
-
-	RBuf8 buf;
-	buf.CleanupClosePushL();
-	err = buf.Create(writeSize);
-
-	test(err == KErrNone);
-
-	buf.FillZ();
-
-	err = iServSession.ReadCrashLog(0, buf, writeSize);
-
-	test(0 == buf.Compare(KCrashDummyData));
-
-	test.Next(_L("@SYMTestCaseID:DT-debug-securityserver-004 Testing Writing To an invalid location"));
-
-	writeSize = 0;
-	err = iServSession.WriteCrashConfig(0xFFFFFFFF, KCrashDummyData, writeSize);
-
-	test(err == KErrArgument);
-
-	test.Next(_L("@SYMTestCaseID:DT-debug-securityserver-003 Testing Reading from an invalid location"));
-
-	buf.FillZ();
-	err = iServSession.ReadCrashLog(0xFFFFFFFF, buf, writeSize);
-
-	test(err == KErrArgument);
-
-	CleanupStack::PopAndDestroy(&buf);
-
-#endif
-	}
-//----------------------------------------------------------------------------------------------
-//! @SYMTestCaseID      KBase-T-RMDEBUG2-0735
-//! @SYMTestType
-//! @SYMPREQ            PREQ1426
-//! @SYMTestCaseDesc    Tests the Kill Process functionality. Only can kill a debuggable process.
-//! @SYMTestActions     Launches a debuggable and non-debuggable process and tries to kill both.
-//!
-//! @SYMTestExpectedResults KErrNone.
-//! @SYMTestPriority        High
-//! @SYMTestStatus          Implemented
-//----------------------------------------------------------------------------------------------
-void CRunModeAgent::TestKillProcess(void)
-	{
-	test.Next(_L("TestKillProcess\n"));
-
-	// Kill a debuggable process
-
-	// check that killing a process is supported
-	TTag tag = GetTag(ETagHeaderIdKillObjects, EFunctionalityKillProcess);
-	test(tag.iValue);
-	// check that killing a thread is not supported
-	tag = GetTag(ETagHeaderIdKillObjects, EFunctionalityKillThread);
-	test(!tag.iValue);
-
-	// attach first!
-	TInt err = iServSession.AttachExecutable(KRMDebugTestApplication, EFalse /* Active */);
-	test(err == KErrNone);
-
-	// first launch a debuggable process
-	RProcess process;
-	err = LaunchProcess(process, KRMDebugTestApplication(),ESpinForever, 0, 0);
-	test (err == KErrNone);
-
-	// try to find the process in the list
-_LIT(KRMDebugAppName, "t_rmdebug_app");
-
-	TBool found = ProcessExists(KRMDebugAppName);
-	test (found);
-
-	// program now running, so try to kill it
-	err = iServSession.KillProcess(process.Id(), 0 /* kill reason */);
-	test(err == KErrNone);
-
-	process.Close();
-
-	User::After(2000000);	// should die within two seconds.
-
-	// can we still find it? Should be gone
-	found = ProcessExists(KRMDebugAppName);
-	test (!found);
-
-	// release the program again.
-	err = iServSession.DetachExecutable(KRMDebugTestApplication);
-	test(err == KErrNone);
-
-	// Try to kill a non-debuggable process and fail.
-
-	// first launch a non-debuggable process
-	RProcess process2;
-	err = LaunchProcess(process2, KRMDebugSecurity1FileName(),ESpinForever, 0, 0);
-	test (err == KErrNone);
-
-	// try to find the process in the list
-_LIT(KRMDebugAppName2, "t_rmdebug_security1");
-
-	TBool found2 = ProcessExists(KRMDebugAppName2);
-	test (found2);
-
-	// program now running, so try to kill it
-	err = iServSession.KillProcess(process2.Id(), 0 /* kill reason */);
-	test(err == KErrPermissionDenied);
-
-	process2.Close();
-
-	User::After(2000000);	// should die within two seconds if it is going to die.
-
-	// can we still find it? Should be still around!
-	found2 = ProcessExists(KRMDebugAppName2);
-	test (found2);
-
-	}
-
-//----------------------------------------------------------------------------------------------
-//! @SYMTestCaseID      KBase-T-RMDEBUG2-1388
-//! @SYMTestType
-//! @SYMPREQ            PREQ1426
-//! @SYMTestCaseDesc    Tests the correct operation of the AddProcess and Remove Process
-//! @SYMTestActions     1. Registers for AddProcess and Remove Process events
-//!                     2. Starts a test process z:\sys\bin\t_rmdebug_security0.exe
-//!                     3. Wait for the AddProcess event to be reported
-//!                     4. Kill the newly started test process
-//!                     5. Wait for the RemoveProcess event to be reported
-//!                     6. Tell the DSS it is no longer interested in AddProcess and RemoveProcess events
-//!
-//! @SYMTestExpectedResults KErrNone.
-//! @SYMTestPriority        High
-//! @SYMTestStatus          Implemented
-//----------------------------------------------------------------------------------------------
-
-void CRunModeAgent::TestAddRemoveProcessEvents()
-	{
-	test.Next(_L("TestAddRemoveProcessEvents\n"));
-
-	// attach to a process (e.g. one of the simple security test programs)
-	// launch the security program
-	// wait for the add event
-	// continue the program.
-	// wait for the remove event
-	// detach process
-
-	test(KErrNone == iServSession.AttachExecutable(KRMDebugSecurity0FileName, EFalse));
-
-	test(KErrNone == iServSession.SetEventAction(KRMDebugSecurity0FileName,EEventsAddProcess, EActionContinue));
-
-	test(KErrNone == iServSession.SetEventAction(KRMDebugSecurity0FileName,EEventsRemoveProcess, EActionContinue));
-
-	// Creator thread ID of the current thread (to be creator of test application)
-	TInt creatorThreadId = RThread().Id();
-
-	RProcess process;
-	TInt err = process.Create(KRMDebugSecurity0FileName, KNullDesC, EOwnerProcess);
-	test (err == KErrNone);
-
-	// Rendezvous with process
-	TRequestStatus status;
-	process.Rendezvous(status);
-
-	// Start the test program
-	process.Resume();
-	User::WaitForRequest(status);
-	test(status==KErrNone);
-
-	// Wait for the addprocess event
-	TEventInfo info;
-	TPtr8 infoPtr((TUint8*)&info,0,sizeof(TEventInfo));
-
-	iServSession.GetEvent(KRMDebugSecurity0FileName,status,infoPtr);
-
-	// Wait for notification of the addprocess hit event
-	User::WaitForRequest(status);
-	test(status==KErrNone);
-
-	// Check this was the right kind of event
-	test(info.iEventType == EEventsAddProcess);
-
-	const TInt uid3offset = 2;
-
-	// Get UID3 for current process
-	TUint32 Uid3 = process.Type()[uid3offset].iUid;
-
-	// Check correct UID3 is returned from the driver
-    test(info.iAddProcessInfo.iUid3 == Uid3);
-
-    // Check correct creator ID for test application is returned from the driver
-    test(info.iAddProcessInfo.iCreatorThreadId == creatorThreadId);
-
-	// Kill the process, as we don't need it anymore
-	process.Kill(KErrNone);
-
-	// Wait for the remove process event
-	iServSession.GetEvent(KRMDebugSecurity0FileName,status,infoPtr);
-
-	// Wait for notification of the remove process hit event
-	User::WaitForRequest(status);
-	test(status==KErrNone);
-
-	// Check this was the right kind of event
-	test(info.iEventType == EEventsRemoveProcess);
-
-	test(KErrNone == iServSession.SetEventAction(KRMDebugSecurity0FileName,EEventsRemoveProcess, EActionIgnore));
-
-	test(KErrNone == iServSession.SetEventAction(KRMDebugSecurity0FileName,EEventsAddProcess, EActionIgnore));
-
-	test(KErrNone == iServSession.DetachExecutable(KRMDebugSecurity0FileName));
-
-	}
-
-//----------------------------------------------------------------------------------------------
-//! @SYMTestCaseID      KBase-T-RMDEBUG2-0736
-//! @SYMTestType
-//! @SYMPREQ            PREQ1426
-//! @SYMTestCaseDesc    Checks that process break points can be set, and that they can co-exist alongside thread breakpoints
-//! @SYMTestActions     Checks that process break points can be set, and that they can co-exist alongside thread breakpoints
-//!
-//! @SYMTestExpectedResults KErrNone.
-//! @SYMTestPriority        High
-//! @SYMTestStatus          Implemented
-//----------------------------------------------------------------------------------------------
-void CRunModeAgent::TestProcessBreakPoints(void)
-	{
-	test.Next(_L("TestProcessBreakPoints\n"));
-
-	// check that process breakpoints are supported
-	TTag tag = GetTag(ETagHeaderIdBreakpoints, EBreakpointProcess);
-	test(tag.iValue);
-
-	test(KErrNone == iServSession.AttachExecutable(iFileName, EFalse));
-	test(KErrNone == iServSession.SuspendThread(iThreadID));
-
-	// Try to set the breakpoint
-	TBreakId breakId;
-	TUint32 address = (TUint32)(&RMDebug_BranchTst1);
-	RProcess process;
-	TProcessId processId = process.Id();
-	process.Close();
-
-	test(KErrNone == iServSession.SetProcessBreak(breakId, processId, address, EArmMode));
-	test(KErrAlreadyExists == iServSession.SetBreak(breakId, iThreadID, address, EArmMode));
-	test(KErrAlreadyExists == iServSession.SetBreak(breakId, iThreadID, address, EThumbMode));
-	test(KErrAlreadyExists == iServSession.SetProcessBreak(breakId, processId, address, EArmMode));
-	test(KErrAlreadyExists == iServSession.SetProcessBreak(breakId, processId, address, EThumbMode));
-	test(KErrNone == iServSession.ClearBreak(breakId));
-
-	test(KErrNone == iServSession.SetBreak(breakId, iThreadID, address, EArmMode));
-	test(KErrAlreadyExists == iServSession.SetProcessBreak(breakId, processId, address, EArmMode));
-	test(KErrAlreadyExists == iServSession.SetProcessBreak(breakId, processId, address, EThumbMode));
-	test(KErrNone == iServSession.ClearBreak(breakId));
-
-	test(KErrNone == iServSession.ResumeThread(iThreadID));
-
-	test(KErrNone == iServSession.DetachExecutable(iFileName));
-	}
-
-//----------------------------------------------------------------------------------------------
-//! @SYMTestCaseID      KBase-T-RMDEBUG2-1309
-//! @SYMTestType
-//! @SYMPREQ            PREQ1426
-//! @SYMTestCaseDesc    Checks that in the case of multiple low priority events (user traces in this case) we can still receive higher
-//!				priority events should the buffer reach a critical level
-//! @SYMTestActions     Run to first breakpoint in our test code. Then multiple trace events are issued. We should still be able to hit
-//!				the second breakpoint
-//!
-//! @SYMTestExpectedResults KErrNone.
-//! @SYMTestPriority        High
-//! @SYMTestStatus          Implemented
-//----------------------------------------------------------------------------------------------
-
-void CRunModeAgent::TestMultipleTraceEvents(void)
-	{
-	//Dont run the test for an SMP System
-	if (UserSvr::HalFunction(EHalGroupKernel, EKernelHalSmpSupported, 0, 0) == KErrNone)
-		return;
-
-	test.Next(_L("TestMultipleTraceEvents\n"));
-
-	//attach to target debug process
-	test(KErrNone == iServSession.AttachExecutable(iFileName, EFalse));
-
-	//and suspend the thread
-	test(KErrNone == iServSession.SuspendThread(iThreadID));
-
-	//register interest in BP's & trace events and trace ignored events
-	test(KErrNone == iServSession.SetEventAction(iFileName,EEventsBreakPoint, EActionSuspend));
-	test(KErrNone == iServSession.SetEventAction(iFileName,EEventsUserTrace, EActionContinue));
-	test(KErrNone == iServSession.SetEventAction(iFileName,EEventsUserTracesLost, EActionContinue));
-
-	// Try to set the breakpoints
-	TBreakId armBreakId;
-	TBreakId armBreakId2;
-	TUint32 address = (TUint32)(&RMDebug_BranchTst1);
-	TUint32 address2 = (TUint32)(&RMDebug_StepTest_Non_PC_Modifying);
-
-	test(KErrNone == iServSession.SetBreak(armBreakId,iThreadID,address,EArmMode));
-	test(KErrNone == iServSession.SetBreak(armBreakId2,iThreadID,address2,EArmMode));
-
-	//set the target thread to execute the trace test function
-	test(KErrNone == SwitchTestFunction(EMultipleTraceCalls));
-
-	// Continue the thread
-	test(KErrNone == iServSession.ResumeThread(iThreadID));
-
-	// wait for the breakpoint to be hit
-	TEventInfo info;
-	static TRequestStatus status;
-
-	TPtr8 infoPtr((TUint8*)&info,0,sizeof(TEventInfo));
-	iServSession.GetEvent(iFileName,status,infoPtr);
-
-	// Wait for notification of the 1st breakpoint hit event
-	User::WaitForRequest(status);
-	test(status==KErrNone);
-
-	// info should now be filled with the details
-	test(info.iEventType == EEventsBreakPoint);
-	test(info.iThreadBreakPointInfo.iRmdArmExcInfo.iR15 == address);
-	test(info.iProcessIdValid);
-	test(info.iThreadIdValid);
-
-	// Continue the thread
-	test(KErrNone == iServSession.ResumeThread(iThreadID));
-
-	//Now we try to hit the second breakpoint. This will occur after a number of trace calls. If we hit this breakpoint it
-	//means many trace calls are not preventing us hitting breakpoints.
-	iServSession.GetEvent(iFileName,status,infoPtr);
-
-	// Wait for notification of the 2nd breakpoint hit event
-	User::WaitForRequest(status);
-	test(status==KErrNone);
-
-	TBool receivedTracesLost = EFalse;
-
-	while(info.iEventType == EEventsUserTrace || info.iEventType == EEventsUserTracesLost)
-		{
-		//ensure we get told traces are being thrown away - we generate enough to flood the buffer
-		if(info.iEventType == EEventsUserTracesLost)
-			{
-			receivedTracesLost = ETrue;
-			}
-
-		iServSession.GetEvent(iFileName,status,infoPtr);
-
-		// Wait for notification of the 2nd breakpoint hit event
-		User::WaitForRequest(status);
-		test(status==KErrNone);
-		}
-
-	//make sure we got told traces were lost
-	test(receivedTracesLost != EFalse);
-
-	// info should now be filled with the details of our breakpoint.
-	test(info.iEventType == EEventsBreakPoint);
-	test(info.iThreadBreakPointInfo.iRmdArmExcInfo.iR15 == address2);
-	test(info.iProcessIdValid);
-	test(info.iThreadIdValid);
-
-	//dont care for breakpoints or trace events no more
-	test(KErrNone == iServSession.SetEventAction(iFileName,EEventsBreakPoint, EActionIgnore));
-	test(KErrNone == iServSession.SetEventAction(iFileName,EEventsUserTrace, EActionIgnore));
-	test(KErrNone == iServSession.SetEventAction(iFileName,EEventsUserTracesLost, EActionIgnore));
-
-	//clear the breaks we set
-	test(KErrNone == iServSession.ClearBreak(armBreakId));
-	test(KErrNone == iServSession.ClearBreak(armBreakId2));
-
-	// Continue the thread
-	test(KErrNone == iServSession.ResumeThread(iThreadID));
-
-	//attach to target debug process
-	test(KErrNone == iServSession.DetachExecutable(iFileName));
-
-	}
-
-//----------------------------------------------------------------------------------------------
-//! @SYMTestCaseID KBase-T-RMDEBUG2-2441
-//! @SYMTestType
-//! @SYMPREQ PREQ1426
-//! @SYMTestCaseDesc Test clearing of a process breakpoint once the process has been killed.
-//! @SYMTestActions Creates a new process then tries to set a process breakpoint and then kills the process which should clear the previously set breakpoint. Then repeat the step once again.
-//! @SYMTestExpectedResults KErrNone
-//! @SYMTestPriority High
-//! @SYMTestStatus Implemented
-//----------------------------------------------------------------------------------------------
-
-void CRunModeAgent::TestProcessKillBreakpoint(void)
-	{
-	//Dont run the test for an SMP System
-	if (UserSvr::HalFunction(EHalGroupKernel, EKernelHalSmpSupported, 0, 0) == KErrNone)
-		return;
-
-	test.Next(_L("TestProcessKillBreakpoint\n"));
-	//SID retrieved, used in Define/Attach of the property
-	iMySid.iUid = RProcess().SecureId();
-
-	static _LIT_SECURITY_POLICY_PASS(KAllowAllPolicy);
-
-	//define a property to pass on the address from the other process we would try to debug
-	test ( KErrNone == RProperty::Define(iMySid, EMyPropertyInteger, RProperty::EInt, KAllowAllPolicy, KAllowAllPolicy));
-	    //define a global semaphore to synchronise with debuggable process publishing the property
-	test ( KErrNone == iAddressGlobSem.CreateGlobal(_L("RMDebugGlobSem"), 0) );
-
-	DoTestProcessKillBreakpoint();
-	// called once again
-	// to check if we can set the breakpoint once again after the process gets killed
-	DoTestProcessKillBreakpoint();
-
-	//delete the property
-	test ( KErrNone == RProperty::Delete(iMySid, EMyPropertyInteger));
-	//close the semaphore
-	iAddressGlobSem.Close();
-	}
-
-void CRunModeAgent::DoTestProcessKillBreakpoint()
-	{
-	test.Printf(_L("\nDoTestProcessKillBreakpoint\n"));
-
-	TInt err = KErrNone;
-
-	// check that killing a process is supported
-	TTag tag = GetTag(ETagHeaderIdKillObjects, EFunctionalityKillProcess);
-	test(tag.iValue);
-	// check that killing a thread is not supported
-	tag = GetTag(ETagHeaderIdKillObjects, EFunctionalityKillThread);
-	test(!tag.iValue);
-
-	// attach first!
-	test ( KErrNone == iServSession.AttachExecutable(KRMDebugTestApplication, EFalse/*  Active */));
-
-	// first launch a debuggable process
-	RProcess processDebug;
-	test ( KErrNone == LaunchProcess(processDebug, KRMDebugTestApplication(),ESpinForeverWithBreakPoint, 0, 0));
-
-	// try to find the process in the list
-	_LIT(KRMDebugAppName, "t_rmdebug_app");
-	TBool found = ProcessExists(KRMDebugAppName);
-	test (found);
-
-	//search for the main thread created
-   _LIT(KThreadWildCard, "t_rmdebug_app*");
-	TProcessId processDebugId = processDebug.Id();
-	TThreadId threadDebugId;
-
-   	TFindThread find(KThreadWildCard);
-	TFullName name;
-	found = EFalse;
-	while(find.Next(name)==KErrNone && !found)
-		{
-		RThread thread;
-		err = thread.Open(find);
-       	if (err == KErrNone)
-			{
-			RProcess process;
-			thread.Process(process);
-			if (((TUint32)process.Id() == processDebugId))
-				{
-				TFullName fullname = thread.FullName();
-				test.Printf(_L("Match Found Name %lS Process ID%ld Thread Id %ld"), &fullname, process.Id().Id(), thread.Id().Id());
-				found = ETrue;
-				threadDebugId = thread.Id();
-				}
-			process.Close();
-			}
-			thread.Close();
-   		}
-
-	test (found); //check if we actually found the thread we want to debug
-
-	//get the value(property) for the breakpoint address for the process to debug
-	TInt address;
-	RProperty integerProperty;
-	test ( KErrNone == integerProperty.Attach(iMySid, EMyPropertyInteger, EOwnerThread));
-
-	//waiting on semaphore to be sure that the property is set
-	iAddressGlobSem.Wait();
-
-	test ( KErrNone == integerProperty.Get(address));
-	integerProperty.Close();
-
-	test.Printf(_L("Address retrieved to set breakpoint 0x%8x"), address);
-
-	//suspend the thread before we set a breakpoint
-	test ( KErrNone == iServSession.SuspendThread(threadDebugId));
-
-	//set a process breakpoint
-	TBreakId breakId;
-	test(KErrNone == iServSession.SetProcessBreak(breakId, processDebugId, address, EArmMode));
-
-	test(KErrNone ==iServSession.SetEventAction(KRMDebugTestApplication,EEventsProcessBreakPoint, EActionContinue));
-
-	//resume the thread now
-	test(KErrNone == iServSession.ResumeThread(threadDebugId));
-
-	// wait for the breakpoint to be hit
-	static TRequestStatus status;
-	TEventInfo info;
-	TPtr8 infoPtr((TUint8*)&info,0,sizeof(TEventInfo));
-	iServSession.GetEvent(KRMDebugTestApplication,status,infoPtr);
-	// Wait for notification of the breakpoint hit event
-	User::WaitForRequest(status);
-	test(status==KErrNone);
-
-	// info should now be filled with the details
-	test(info.iEventType ==  EEventsProcessBreakPoint);
-	test(info.iThreadBreakPointInfo.iRmdArmExcInfo.iR15 == address);
-	test(info.iProcessIdValid);
-	test(info.iThreadIdValid);
-
-	// Not interested in breakpoint events any more
-	test(KErrNone == iServSession.SetEventAction(KRMDebugTestApplication, EEventsProcessBreakPoint, EActionIgnore));
-
-	// program now running, so try to kill it which should clear all the breakpoints
-	test(KErrNone == iServSession.KillProcess(processDebugId, 0  /* kill reason */ ));
-
-	processDebug.Close();
-	User::After(2000000);	// should die within two seconds.
-
-	// can we still find it? Should be gone
-	found = ProcessExists(KRMDebugAppName);
-	test (!found);
-
-	// release the program again
-	test(KErrNone == iServSession.DetachExecutable(KRMDebugTestApplication));
-
-	}
-
-void CRunModeAgent::HelpTestSecurityAttachDetachExecutable(const TDesC& aProcessName, TBool aExpectSuccess)
-	{
-	RProcess process;
-	TInt err = process.Create(aProcessName, KNullDesC, EOwnerProcess);
-	test (err == KErrNone);
-
-	// rendezvous with process
-	TRequestStatus status;
-	process.Rendezvous(status);
-
-	// start the test program
-	process.Resume();
-	User::WaitForRequest(status);
-	test(status==KErrNone);
-
-	// attach to the program (passively)
-	err = iServSession.AttachExecutable(aProcessName, EFalse);
-
-	// Do we expect to successfully attach
-	if (aExpectSuccess)
-	{
-		// Yes
-		test(KErrNone == err);
-
-		// Now detach again
-		test(KErrNone == iServSession.DetachExecutable(aProcessName));
-	}
-	else
-	{
-		// No
-		test(KErrPermissionDenied == err);
-
-		// Just to be sure, try active attachment
-		test(KErrPermissionDenied == iServSession.AttachExecutable(aProcessName, ETrue));
-	}
-
-	// Kill the process, as we don't need it anymore
-	process.Kill(KErrNone);
-	}
-
-void CRunModeAgent::ReportPerformance(void)
-//
-// Reports performance metrics from all the tests
-//
-	{
-	test.Printf(_L("\nPerformance\n"));
-	test.Printf(_L("========================\n"));
-
-	// Memory
-	test.Printf(_L("Memory read: %d KBytes/sec\n"),iMemoryReadKbytesPerSecond);
-	test.Printf(_L("Memory write: %d KBytes/sec\n"),iMemoryWriteKbytesPerSecond);
-
-	// Registers
-	// to do
-
-	// events
-	// to do
-
-	// Breakpoints
-	test.Printf(_L("Breakpoint set/clear: %d/sec\n"),iBreakpointsPerSecond);
-	test.Printf(_L("Maximum number of breakpoints: %d\n"),iMaxBreakpoints);
-
-	// Stepping
-	test.Printf(_L("Stepping speed: %d/sec\n"),iStepsPerSecond);
-
-	// Runtime
-	TInt ticks = HelpGetTestTicks();
-	test (ticks != 0);
-
-	TInt nkTicksPerSecond = HelpTicksPerSecond();
-	test (nkTicksPerSecond != 0);
-
-	test.Printf(_L("Total test runtime: %d seconds\n"),ticks/nkTicksPerSecond);
-
-	// Final sizes of executables/rom/ram etc
-	// to do
-
-	test.Printf(_L("\n"));
-	}
-
-/**
- * Helper code for the stepping tests. Sets a breakpoint in a running thread.
- * It suspends the thread, sets the breakpoint, and resumes the thread.
- *
- * @param aBreakId - Reference to a TBreakId which will be set when the breakpoint is set
- * @param aThreadId - The thread id for which we should set the breakpoint.
- * @param aBreakAddress - The address to set the breakpoint
- * @param aMode - The architecture of the breakpoint to be set (ARM/Thumb/Thumb2EE)
- * @return KErrNone if successful. One of the other system wide error codes otherwise.
- */
-TInt CRunModeAgent::HelpTestStepSetBreak(TBreakId& aBreakId, TThreadId aThreadId, const TUint32 aBreakAddress, TArchitectureMode aMode, TBool aThreadSpecific, TProcessId aProcessId)
-	{
-	TInt err = KErrNone;
-
-	// Suspend the thread
-	err = iServSession.SuspendThread(aThreadId);
-	if (err != KErrNone)
-		{
-		test.Printf(_L("HelpTestStepSetBreak - Failed to suspend thread\n"));
-		return err;
-		}
-
-	// Set the breakpoint
-	err = aThreadSpecific
-		? iServSession.SetBreak(aBreakId,aThreadId,aBreakAddress,aMode)
-		: iServSession.SetProcessBreak(aBreakId, aProcessId, aBreakAddress, aMode);
-	if (err != KErrNone)
-		{
-		test.Printf(_L("HelpTestStepSetBreak - Failed to set breakpoint\n"));
-		return err;
-		}
-
-	// Continue the thread
-	err = iServSession.ResumeThread(aThreadId);
-	if (err != KErrNone)
-		{
-		test.Printf(_L("HelpTestStepSetBreak - Failed to resume thread\n"));
-		return err;
-		}
-
-	return KErrNone;
-	}
-
-/**
- * Helper code for the stepping tests. Clears a breakpoint in a running thread.
- * It suspends the thread, clears the breakpoint, and resumes the thread.
- *
- * @param aBreakId - Reference to a TBreakId which will be set when the breakpoint is set
- * @return KErrNone if successful. One of the other system wide error codes otherwise.
- */
-TInt CRunModeAgent::HelpTestStepClearBreak(TBreakId aBreakId, const TThreadId aThreadId, TBool aThreadSpecific)
-	{
-	TInt err = KErrNone;
-
-	// Find out what thread id we need to suspend
-	TThreadId threadId;
-	TProcessId processId;
-	TUint32 address;
-	TArchitectureMode mode;
-
-	err = aThreadSpecific
-		? iServSession.BreakInfo(aBreakId, threadId, address, mode)
-		: iServSession.ProcessBreakInfo(aBreakId, processId, address, mode);
-	if (err != KErrNone )
-		{
-		test.Printf(_L("HelpTestStepClearBreak - failed to obtain information for breakpoint\n"));
-		return err;
-		}
-	if(aThreadSpecific && aThreadId != threadId)
-		{
-		test.Printf(_L("HelpTestStepClearBreak - mismatched thread Ids\n"));
-		return KErrGeneral;
-		}
-
-	// Suspend the thread
-	err = iServSession.SuspendThread(aThreadId);
-	if (!(err == KErrNone || err == KErrAlreadyExists))
-		{
-		test.Printf(_L("HelpTestStepClearBreak - failed to suspend thread\n"));
-		return err;
-		}
-
-	// Clear the breakpoint
-	err = iServSession.ClearBreak(aBreakId);
-	if (err != KErrNone)
-		{
-		test.Printf(_L("HelpTestStepClearBreak - failed to clear breakpoint\n"));
-		return err;
-		}
-
-	// Continue the thread
-	err = iServSession.ResumeThread(aThreadId);
-	if (!(err == KErrNone || err == KErrNotFound))
-		{
-		test.Printf(_L("HelpTestStepClearBreak - failed to resume thread\n"));
-		return err;
-		}
-
-	return KErrNone;
-	}
-
-/**
- * Helper code for the stepping tests. Waits for a previously set breakpoint to be hit.
- *
- * @param aProcessName - The name of the process in which the breakpoint is set. E.g. z:\sys\bin\app.exe
- * @param aEventInfo - The event information block which is filled in when the breakpoint is hit.
- * @return KErrNone if successful. One of the other system wide error codes otherwise.
- */
-TInt CRunModeAgent::HelpTestStepWaitForBreak(const TDesC& aProcessName, TEventInfo& aEventInfo)
-	{
-	static TRequestStatus status;
-
-	TPtr8 infoPtr((TUint8*)&aEventInfo,0,sizeof(TEventInfo));
-
-	iServSession.GetEvent(aProcessName,status,infoPtr);
-
-	// Wait for notification of the breakpoint hit event
-	User::WaitForRequest(status);
-	if (status == KErrNone)
-		{
-		return KErrNone;
-		}
-	else
-		{
-		return KErrGeneral;
-		}
-	}
-
-/**
- * Helper code for the stepping tests. Reads the current target PC for a given thread.
- *
- * @param aThreadId - Thread id for which to read the current target PC.
- * @param aPc - Reference to a TUint32 which will be set to the current target PC.
- * @return KErrNone if successful. One of the other system wide error codes otherwise.
- */
-TInt CRunModeAgent::HelpTestStepReadPC(TThreadId aThreadId, TUint32& aPC)
-	{
-	TInt err = KErrNone;
-
-	//create buffer containing PC register ID
-	RBuf8 pcId;
-	err = pcId.Create(sizeof(TRegisterInfo));
-	if (err != KErrNone)
-		{
-		return err;
-		}
-
-	TRegisterInfo reg1 = (TRegisterInfo)0x00000f00;
-	pcId.Append(reinterpret_cast<const TUint8*>(&reg1), sizeof(TRegisterInfo));
-
-	//create buffer containing desired PC value
-	TPtr8 pcValue((TUint8*)&aPC,4,4);
-
-	//create buffer for PC flag value
-	RBuf8 pcFlag;
-	err = pcFlag.Create(sizeof(TUint8));
-
-	//read the new PC value
-	err = iServSession.ReadRegisters(aThreadId, pcId, pcValue, pcFlag);
-	if (err != KErrNone)
-		{
-		//delete temporary buffers
-		pcId.Close();
-		pcFlag.Close();
-		return err;
-		}
-
-	//get the flag and check the PC value was read ok
-	TRegisterFlag flag = ENotSupported;
-	err = GetFlag(pcFlag, 0, flag);
-	if (err != KErrNone)
-		{
-		//delete temporary buffers
-		pcId.Close();
-		pcFlag.Close();
-		return err;
-		}
-
-	if (flag == EValid)
-		{
-		//delete temporary buffers
-		pcId.Close();
-		pcFlag.Close();
-		return KErrNone;
-		}
-	else
-		{
-		//delete temporary buffers
-		pcId.Close();
-		pcFlag.Close();
-		return err;
-		}
-	}
-
-/**
- * Helper code for the stepping tests. Single steps a given thread from aStartAddress to aEndAddress. Note
- * that it reaches aStartAddress by setting a breakpoint at that address and waiting until it is hit.
- *
- * @param aThreadId - Thread id for which to read the current target PC.
- * @param aStartAddress - The target address at which stepping will start.
- * @param aEndAddress - The target address at which stepping will end.
- * @param aMode - The architecture of the breakpoint which must be set at the start address (ARM/Thumb/Thumb2EE).
- * @return KErrNone if successful. One of the other system wide error codes otherwise.
- */
-TInt CRunModeAgent::HelpTestStep(TThreadId aThreadId, TUint32 aStartAddress, TUint32 aEndAddress, TArchitectureMode aMode, TUint aNumSteps, TBool aThreadSpecific, TProcessId aProcessId)
-	{
-	TInt err = KErrNone;
-
-	// Ensure that the supplied addresses are word/half-word aligned as appropriate.
-	if (aMode == EArmMode)
-		{
-		// ARM breakpoints must be word-aligned (2 lsb must be zero)
-		aStartAddress &= 0xFFFFFFFC;
-		aEndAddress &= 0xFFFFFFFC;
-		}
-	else if (aMode == EThumbMode)
-		{
-		// Thumb breakpoints must be half-word aligned (lsb must be zero)
-		aStartAddress &= 0xFFFFFFFE;
-		aEndAddress	 &= 0xFFFFFFFE;
-		}
-	else if (aMode == EThumb2EEMode)
-	{
-		// Thumb2EE breakpoints are not currently supported
-		return KErrNotSupported;
-	}
-
-	// Set breakpoint at the start address
-	TBreakId tempBreakId;
-	TEventInfo info;
-
-	err = HelpTestStepSetBreak(tempBreakId,aThreadId,aStartAddress,aMode,aThreadSpecific,aProcessId);
-	if (err != KErrNone)
-		{
-		test.Printf(_L("HelpTestStep - Failed to set breakpoint at aStartAddress 0x%08x\n"),aStartAddress);
-		return err;
-		}
-
-	// wait for the breakpoint to be hit
-	err = HelpTestStepWaitForBreak(iFileName,info);
-	if (err != KErrNone)
-		{
-		test.Printf(_L("HelpTestStep - Failed to hit the breakpoint at aStartAddress 0x%08x\n"),aStartAddress);
-		return err;
-		}
-
-	// Check the PC == aStartAddress
-	TUint32 pc = 0;
-	err = HelpTestStepReadPC(aThreadId,pc);
-	if (err != KErrNone)
-		{
-		test.Printf(_L("HelpTestStep - Failed to read the PC after hitting breakpoint at aStartAddress 0x%08x\n"),aStartAddress);
-		return err;
-		}
-
-	if (pc != aStartAddress)
-		{
-		test.Printf(_L("HelpTestStep - Incorrect PC value after hitting breakpoint (expected 0x%08x actual 0x%08x)\n"),aStartAddress,pc);
-		return KErrGeneral;
-		}
-
-	err = iServSession.Step(aThreadId,aNumSteps);
-	if (err != KErrNone)
-		{
-		test.Printf(_L("HelpTestStep - Failed to do step from 0x%08x to 0x%08x\n"),aStartAddress,aEndAddress,aNumSteps);
-		return err;
-		}
-
-	// only one 'completed step' event in the buffer.
-	err = HelpTestStepWaitForBreak(iFileName,info);
-	if (err != KErrNone)
-		{
-		test.Printf(_L("HelpTestStep - Could not read breakpoint event info after stepping"));
-		return err;
-		}
-	// end
-
-	// Check PC == aEndAddress
-	err = HelpTestStepReadPC(aThreadId,pc);
-	if (err != KErrNone)
-		{
-		test.Printf(_L("HelpTestStep - failed read the PC after stepping\n"));
-		return err;
-		}
-	if (pc != aEndAddress)
-		{
-		test.Printf(_L("HelpTestStep - Incorrect PC value after stepping (expected 0x%08x actual 0x%08x)\n"),aEndAddress,pc);
-		return KErrGeneral;
-		}
-
-	// Clear the breakpoint
-	err = HelpTestStepClearBreak(tempBreakId, aThreadId, aThreadSpecific);
-	if (err != KErrNone)
-		{
-		test.Printf(_L("HelpTestStep - failed to clear temporary breakpoint\n"));
-		return err;
-		}
-
-	return KErrNone;
-	}
-
-/**
- * Helper code for the stepping tests. Returns the number of nanokernel ticks in one second.
- *
- * @return Number of nanokernel ticks. 0 if unsuccesful.
- */
-TInt CRunModeAgent::HelpTicksPerSecond(void)
-	{
-	TInt nanokernel_tick_period;
-	HAL::Get(HAL::ENanoTickPeriod, nanokernel_tick_period);
-
-	ASSERT(nanokernel_tick_period != 0);
-
-	static const TInt KOneMillion = 1000000;
-
-	return KOneMillion/nanokernel_tick_period;
-	}
-
-/**
-  Given aTestNumber runs the appropriate test inside heap markers
-
-  @param aTestNumber test to run, corresponds to an entry in iTestArray
-
-  @panic Panic if aTestNumber is not in valid range
-  */
-void CRunModeAgent::RunTest(TInt aTestNumber)
-	{
-	if( (aTestNumber<0) || (aTestNumber>=KMaxTests) )
-		{
-		User::Panic(_L("Test number out of range"), aTestNumber);
-		}
-	__UHEAP_MARK;
-	(this->*(iTestArray[aTestNumber].iFunctionPtr))();
-	__UHEAP_MARKEND;
-	}
-
-void CRunModeAgent::PrintVersion()
-	{
-	test.Printf(_L("\nt_rmdebug2.exe\nVersion: %S\n"), &(testVersion.Name()));
-	test.Printf(_L("Press any key...\n"));
-	test.Getch();
-	}
-
-void CRunModeAgent::PrintUsage()
-	{
-	test.Printf(_L("Invoke with arguments:\n"));
-	test.Printf(_L("-r: run specified tests in reverse order\n"));
-	test.Printf(_L("-h: display usage information\n"));
-	test.Printf(_L("-v: display version\n"));
-	test.Printf(_L("<number>: test number to run, can specify more than one from the following list:\n"));
-	test.Printf(_L("Press any key for list...\n"));
-	test.Getch();
-	// if there are too many of these they won't fit on the screen! Stick another Getch() in if there get too many
-	for(TInt i=0; i<KMaxTests; i++)
-		{
-		test.Printf(_L("%2d: %S\n"), i, &(iTestArray[i].iFunctionName));
-		}
-	test.Printf(_L("Press any key...\n"));
-	test.Getch();
-	}
-
-/**
-  Parse the command line, see CRunModeAgent::PrintUsage for syntax
-  */
-void CRunModeAgent::ParseCommandLineL(TUint32& aMode, RArray<TInt>& aTests)
-	{
-	// get the length of the command line arguments
-	TInt argc = User::CommandLineLength();
-
-	// allocate a buffer for the command line arguments and extract the data to it
-	HBufC* commandLine = HBufC::NewLC(argc);
-	TPtr commandLineBuffer = commandLine->Des();
-	User::CommandLine(commandLineBuffer);
-
-	// reset mode
-	aMode = (TTestMode)0;
-
-	// create a lexer and read through the command line
-	TLex lex(*commandLine);
-	while (!lex.Eos())
-		{
-		// expecting the first character to be a '-'
-		if (lex.Get() == '-')
-			{
-			TChar arg = lex.Get();
-			switch (arg)
-				{
-				case 'v':
-					//print out the help
-					aMode |= EModeVersion;
-					break;
-				case 'h':
-					//print out the help
-					aMode |= EModeHelp;
-					break;
-				case 'r':
-					//store the fact that we want to run in reverse
-					aMode |= EModeReverse;
-					break;
-				default:
-					// unknown argument so leave
-					User::Leave(KErrArgument);
-				}
-			}
-		else
-			{
-			lex.UnGet();
-			TInt testNumber;
-			User::LeaveIfError(lex.Val(testNumber));
-			if( (testNumber<0) || (testNumber>=KMaxTests) )
-				{
-				User::Leave(KErrArgument);
-				}
-			aTests.AppendL(testNumber);
-			}
-		lex.SkipSpace();
-		}
-	// if no tests specified then run them all
-	if(aTests.Count() == 0)
-		{
-		aMode |= EModeAll;
-		}
-
-	// do clean up
-	CleanupStack::PopAndDestroy(commandLine);
-	}
-
-void CRunModeAgent::ClientAppL()
-//
-// Performs each test in turn
-//
-	{
-	test.Start(_L("ClientAppL"));
-
-	RArray<TInt> testsToRun;
-	TUint32 testMode = 0;
-	ParseCommandLineL(testMode, testsToRun);
-
-	//if help or version mode specified then just print out the relevant stuff and quit
-	if((testMode & EModeHelp) || (testMode & EModeVersion))
-		{
-		if(testMode & EModeHelp)
-			{
-			PrintUsage();
-			}
-		if(testMode & EModeVersion)
-			{
-			PrintVersion();
-			}
-		test.End();
-		return;
-		}
-
-	if(testMode & EModeAll)
-		{
-		for(TInt i=0; i<KMaxTests; i++)
-			{
-			testsToRun.AppendL(i);
-			}
-		}
-
-	// if EModeReverse specified then reverse the array elements
-	TInt numberOfTests = testsToRun.Count();
-	if(testMode & EModeReverse)
-		{
-		for(TInt i=0; i<(numberOfTests>>1); i++)
-			{
-			TInt temp = testsToRun[i];
-			testsToRun[i] = testsToRun[numberOfTests - (i+1)];
-			testsToRun[numberOfTests - (i+1)] = temp;
-			}
-		}
-
-	__UHEAP_MARK;
-	SetupAndAttachToDSS();
-	__UHEAP_MARKEND;
-
-	HelpStartTestTimer();
-	for(TInt i=0; i<numberOfTests; i++)
-		{
-		RunTest(testsToRun[i]);
-		}
-	testsToRun.Close();
-
-	HelpStopTestTimer();
-
-	ReportPerformance();
-
-	test.End();
-	}
-
-/**
-  Fill the test array with pointers to each test.
-  */
-void CRunModeAgent::FillArray()
-	{
-	iTestArray[0].iFunctionPtr = &CRunModeAgent::TestDriverSecurity;
-	iTestArray[0].iFunctionName = _L("TestDriverSecurity");
-	iTestArray[1].iFunctionPtr = &CRunModeAgent::TestDllUsage;
-	iTestArray[1].iFunctionName = _L("TestDllUsage");
-	iTestArray[2].iFunctionPtr = &CRunModeAgent::TestSecurity;
-	iTestArray[2].iFunctionName = _L("TestSecurity");
-	iTestArray[3].iFunctionPtr = &CRunModeAgent::TestAttachExecutable;
-	iTestArray[3].iFunctionName = _L("TestAttachExecutable");
-	iTestArray[4].iFunctionPtr = &CRunModeAgent::TestGetExecutablesList;
-	iTestArray[4].iFunctionName = _L("TestGetExecutablesList");
-	iTestArray[5].iFunctionPtr = &CRunModeAgent::TestGetProcessList;
-	iTestArray[5].iFunctionName = _L("TestGetProcessList");
-	iTestArray[6].iFunctionPtr = &CRunModeAgent::TestGetXipLibrariesList;
-	iTestArray[6].iFunctionName = _L("TestGetXipLibrariesList");
-	iTestArray[7].iFunctionPtr = &CRunModeAgent::TestGetThreadList;
-	iTestArray[7].iFunctionName = _L("TestGetThreadList");
-	iTestArray[8].iFunctionPtr = &CRunModeAgent::TestGetCodeSegsList;
-	iTestArray[8].iFunctionName = _L("TestGetCodeSegsList");
-	iTestArray[9].iFunctionPtr = &CRunModeAgent::TestGetListInvalidData;
-	iTestArray[9].iFunctionName = _L("TestGetListInvalidData");
-	iTestArray[10].iFunctionPtr = &CRunModeAgent::TestMemoryAccess;
-	iTestArray[10].iFunctionName = _L("TestMemoryAccess");
-	iTestArray[11].iFunctionPtr = &CRunModeAgent::TestDebugFunctionality;
-	iTestArray[11].iFunctionName = _L("TestDebugFunctionality");
-	iTestArray[12].iFunctionPtr = &CRunModeAgent::TestSuspendResume;
-	iTestArray[12].iFunctionName = _L("TestSuspendResume");
-	iTestArray[13].iFunctionPtr = &CRunModeAgent::TestBreakPoints;
-	iTestArray[13].iFunctionName = _L("TestBreakPoints");
-	iTestArray[14].iFunctionPtr = &CRunModeAgent::TestModifyBreak;
-	iTestArray[14].iFunctionName = _L("TestModifyBreak");
-	iTestArray[15].iFunctionPtr = &CRunModeAgent::TestBreakInfo;
-	iTestArray[15].iFunctionName = _L("TestBreakInfo");
-	iTestArray[16].iFunctionPtr = &CRunModeAgent::TestRunToBreak;
-	iTestArray[16].iFunctionName = _L("TestRunToBreak");
-	iTestArray[17].iFunctionPtr = &CRunModeAgent::TestRegisterAccess;
-	iTestArray[17].iFunctionName = _L("TestRegisterAccess");
-	iTestArray[18].iFunctionPtr = &CRunModeAgent::TestStep;
-	iTestArray[18].iFunctionName = _L("TestStep");
-	iTestArray[19].iFunctionPtr = &CRunModeAgent::TestDemandPaging;
-	iTestArray[19].iFunctionName = _L("TestDemandPaging");
-	iTestArray[20].iFunctionPtr = &CRunModeAgent::TestEventsForExternalProcess;
-	iTestArray[20].iFunctionName = _L("TestEventsForExternalProcess");
-	iTestArray[21].iFunctionPtr = &CRunModeAgent::TestEvents;
-	iTestArray[21].iFunctionName = _L("TestEvents");
-	iTestArray[22].iFunctionPtr = &CRunModeAgent::TestKillProcess;
-	iTestArray[22].iFunctionName = _L("TestKillProcess");
-	iTestArray[23].iFunctionPtr = &CRunModeAgent::TestProcessBreakPoints;
-	iTestArray[23].iFunctionName = _L("TestProcessBreakPoints");
-	iTestArray[24].iFunctionPtr = &CRunModeAgent::TestMultipleTraceEvents;
-	iTestArray[24].iFunctionName = _L("TestMultipleTraceEvents");
-	iTestArray[25].iFunctionPtr = &CRunModeAgent::TestAddRemoveProcessEvents;
-	iTestArray[25].iFunctionName = _L("TestAddRemoveProcessEvents");
-	iTestArray[26].iFunctionPtr = &CRunModeAgent::TestCrashFlash;
-	iTestArray[26].iFunctionName = _L("TestCrashFlash");
-	iTestArray[27].iFunctionPtr = &CRunModeAgent::TestProcessKillBreakpoint;
-	iTestArray[27].iFunctionName = _L("TestProcessKillBreakpoint");
-	};
-
-GLDEF_C TInt E32Main()
-//
-// Entry point for run mode debug driver test
-//
-	{
-   TInt ret = KErrNone;
-
-	// client
-	CTrapCleanup* trap = CTrapCleanup::New();
-	if (!trap)
-		return KErrNoMemory;
-   	test.Title();
-   RunModeAgent = CRunModeAgent::NewL();
-   if (RunModeAgent != NULL)
-       {
-        __UHEAP_MARK;
-	    TRAP(ret,RunModeAgent->ClientAppL());
-	    __UHEAP_MARKEND;
-
-	    delete RunModeAgent;
-       }
-
-	delete trap;
-
-	return ret;
-	}
-
-/**
-Helper function to get the aOffset'th value from aFlags
-
-@param aFlags descriptor containing TRegisterFlag type flags
-@param aOffset index of flag value to extract from aFlags
-@param aFlagValue the flag value if function returned successfully
-
-@return KErrNone if value was read successfully, KErrTooBig if aOffset is
-        greater than aFlags.Length()
-*/
-TInt CRunModeAgent::GetFlag(const TDes8& aFlags, const TUint aOffset, TRegisterFlag &aFlagValue) const
-	{
-	//get pointer to data
-	const TUint8 *ptr = aFlags.Ptr();
-
-	//check aOffset is valid
-	TUint length = aFlags.Length();
-	if(aOffset >= length)
-		return KErrTooBig;
-
-	//get flag value
-	aFlagValue = (TRegisterFlag)ptr[aOffset];
-	return KErrNone;
-	}
-
-/**
-  Helper function to set the value of FunctionChooser in the target debug thread.
-
-  @param aTestFunction TTestFunction enum to set FunctionChooser to
-
-  @return KErrNone if the value was set correctly, or one of the other system wide error codes
-  */
-TInt CRunModeAgent::SwitchTestFunction(TTestFunction aTestFunction)
-	{
-	//suspend the target thread
-	TInt suspendError = iServSession.SuspendThread(iThreadID);
-	if(! ( (suspendError == KErrNone) || (suspendError == KErrAlreadyExists) ) )
-		{
-		//the thread is not suspended so exit
-		return suspendError;
-		}
-
-	//get the address of FunctionChooser
-	TUint32 functionChooserAddress = (TUint32)&FunctionChooser;
-	//put the new value for FunctionChooser into a descriptor
-	TPtr8 functionBuf((TUint8*)&aTestFunction, sizeof(TTestFunction), sizeof(TTestFunction));
-	//write the new value into the target thread
-	TInt writeError = iServSession.WriteMemory(iThreadID, functionChooserAddress, sizeof(TTestFunction), functionBuf, EAccess32, EEndLE8);
-
-	if(KErrNone == suspendError)
-		{
-		//if this function suspended the target thread then we need to resume it
-		TInt resumeError = iServSession.ResumeThread(iThreadID);
-		if(KErrNone != resumeError)
-			{
-			//resuming failed so return the error
-			return resumeError;
-			}
-		}
-
-	//suspending and resuming was successful so return the error code from the WriteMemory call
-	return writeError;
-	}
-
-/**
-  Launch a separate process to debug.
-
-  @param aProcess the RProcess object to use to create the process
-  @param aFileName file name of the executable to create the process from
-  @param aFunctionType function that the target process should call on execution
-  @param aDelay delay before the new process should call the function represented by aFunctionType
-  @param aExtraThreads number of extra threads to create in the child process
-
-  @return KErrNone on success, or one of the other system wide error codes
-  */
-TInt CRunModeAgent::LaunchProcess(RProcess& aProcess, const TDesC& aFileName, TDebugFunctionType aFunctionType, TUint32 aDelay, TUint32 aExtraThreads)
-	{
-	// at the moment we support two arguments, this number might have to be increased to support arguments
-	const TUint KMaxCommandLineLength = 32;
-
-	// create a command line buffer
-	RBuf commandLine;
-	commandLine.Create(KMaxCommandLineLength);
-
-	// append the command line arguments to the buffer
-	_LIT(KFArg, "-f");
-	commandLine.Append(KFArg());
-	commandLine.AppendNum(aFunctionType);
-
-	_LIT(KSpace, " ");
-	commandLine.Append(KSpace());
-
-	_LIT(KDArg, "-d");
-	commandLine.Append(KDArg());
-	commandLine.AppendNum(aDelay);
-
-	commandLine.Append(KSpace());
-
-	_LIT(KEArg, "-e");
-	commandLine.Append(KEArg());
-	commandLine.AppendNum(aExtraThreads);
-
-	// create the new process, matching on file name only, not specifying uid values
-	TInt err = aProcess.Create(aFileName, commandLine);	// owned by the process
-
-	// check that there was no error raised
-	if(err != KErrNone)
-		{
-		commandLine.Close();
-		return err;
-		}
-
-	TRequestStatus status = KRequestPending;
-	aProcess.Rendezvous(status);
-
-	commandLine.Close();	// after target thread starts
-
-	if(KRequestPending != status.Int())
-		{
-		// startup failed so kill the process
-		aProcess.Kill(KErrNone);
-		return status.Int();
-		}
-	else
-		{
-		// start up succeeded so resume the process
-		aProcess.Resume();
-		User::WaitForRequest(status);
-		if(KErrNone != status.Int())
-			{
-			aProcess.Kill(KErrNone);
-			}
-		return status.Int();
-		}
-	}
-
-/**
-  Helper function to read a tag header from a debug functionality block
-
-  @param aDebugFunctionalityBlock block to read header from
-  @param aTagHdrId header type to find
-
-  @return pointer to the header, or NULL if not available
-  */
-TTagHeader* CRunModeAgent::GetTagHdr(const TDesC8& aDebugFunctionalityBlock, const TTagHeaderId aTagHdrId) const
-	{
-	TUint8* ptr = (TUint8*) aDebugFunctionalityBlock.Ptr();
-	TUint8* blockEnd = ptr + aDebugFunctionalityBlock.Size();
-
-	while(ptr < blockEnd)
-		{
-		TTagHeader* header = (TTagHeader*)ptr;
-		if(header->iTagHdrId == aTagHdrId)
-			{
-			return header;
-			}
-		ptr += sizeof(TTagHeader) + (header->iNumTags * sizeof(TTag));
-		}
-	return NULL;
-	}
-
-/**
-  Helper function to read a tag from a debug functionality block
-
-  @param aTagHdr pointer to a tag header in a debug functionality block
-  @param aElement element to return from the header's data
-
-  @return pointer to the tag, or NULL if not available
-  */
-TTag* CRunModeAgent::GetTag(const TTagHeader* aTagHdr, const TInt aElement) const
-	{
-	TUint8* ptr = (TUint8*)aTagHdr + sizeof(TTagHeader);
-	TUint8* blockEnd = ptr + (aTagHdr->iNumTags * sizeof(TTag));
-
-	while(ptr < blockEnd)
-		{
-		TTag* tag = (TTag*)ptr;
-		if(tag->iTagId == aElement)
-			{
-			return tag;
-			}
-		ptr += sizeof(TTag);
-		}
-	return NULL;
-	}
-
-TTag CRunModeAgent::GetTag(const TTagHeaderId aTagHdrId, const TInt aElement)
-	{
-	TUint32 bufsize = 0;	// Safe default size
-
-	// Get functionality block size
-	test(KErrNone == iServSession.GetDebugFunctionalityBufSize(&bufsize));
-
-	// Ensure we have a finite buffer size
-	test(bufsize!=0);
-
-	// Allocate space for the functionality data
-	HBufC8* dftext = HBufC8::NewLC(bufsize);
-
-	// create an empty TPtr8 refering to dftext
-	TPtr8 dftextPtr(dftext->Des());
-
-	// Get the functionality block
-	test(KErrNone == iServSession.GetDebugFunctionality(dftextPtr));
-
-	// read a value from the data to check it has come through as expected
-	TTagHeader* header = GetTagHdr(dftext->Des(), aTagHdrId);
-	test(header != NULL);
-	TTag* tag = GetTag(header, aElement);
-	test(tag != NULL);
-
-	TTag tagToReturn = *tag;
-
-	// Remove our temporary buffer
-	CleanupStack::PopAndDestroy(dftext);
-
-	return tagToReturn;
-	}
-
-/**
-  Helper function which returns a Boolean indicating with a process with the
-  specified name is currently running.
-
-  @param aProcessName - Name of the process to find
-  @return ETrue if found, EFalse otherwise
-  */
-TBool CRunModeAgent::ProcessExists(const TDesC& aProcessName)
-	{
-	TInt    err=KErrNone;
-	TBool	found = FALSE;
-
-_LIT(KWildCard,"*");
-
-	TFindProcess find(KWildCard);
-	TFullName name;
-	while(find.Next(name)==KErrNone)
-		{
-		RProcess process;
-		err = process.Open(find);
-		if (err == KErrNone)
-			{
-			if (name.Find(aProcessName) != KErrNotFound)
-				{
-					found = TRUE;
-				}
-			process.Close();
-			}
-	   }
-
-	return found;
-	}
--- a/kerneltest/e32test/rm_debug/t_rmdebug2.h	Tue Feb 02 01:24:03 2010 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,189 +0,0 @@
-// Copyright (c) 2006-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:
-// Definitions for the run mode debug tests
-// 
-//
-
-/**
- @file
- @internalTechnology
- @released
-*/
-
-#ifndef RMDEBUG_H
-#define RMDEBUG_H
-
-#include "t_rmdebug_app.h"
-#include "r_user_low_memory_security_svr_session.h"
-#include "r_kernel_low_memory_security_svr_session.h"
-
-
-class CRunModeAgent;
-
-// Create a pointer to function type
-typedef void (CRunModeAgent::*testFunction)();
-
-class TFunctionData
-	{
-public:
-	testFunction iFunctionPtr;
-	TBuf<40> iFunctionName;
-	};
-
-//number of test functions that we have
-const TInt KMaxTests = 28;
-
-//
-// class CRunModeAgent
-//
-// The basic run mode agent.
-//
-class CRunModeAgent : public CBase
-	{
-public:
-	static CRunModeAgent* NewL();
-	~CRunModeAgent();
-	void ClientAppL();
-
-private:
-	CRunModeAgent();
-	void ConstructL();
-	void SetupAndAttachToDSS();
-
-	TInt TestStartup();
-	TInt TestShutdown();
-
-	void TestGetExecutablesList();
-	void TestGetProcessList();
-	void TestGetThreadList();
-	void TestGetCodeSegsList();
-	void TestGetXipLibrariesList();
-	void TestGetListInvalidData();
-
-	void DoTestGetThreadList(const TBool aShouldPass, const Debug::TListScope aListScope, const TUint64 aTargetId=0);
-	void DoTestGetCodeSegsList(const TBool aShouldPass, const Debug::TListScope aListScope, const TUint64 aTargetId=0);
-
-	void DoGetList(const Debug::TListId aListId, const Debug::TListScope aListScope, RBuf8& aBuffer, TUint32& aSize, const TUint64 aTargetId=0);
-
-	void TestMemoryAccess();
-	void TestSuspendResume();
-	void TestBreakPoints();
-	void TestConsecutiveBreakPoints();
-	void TestModifyBreak();
-	void DoTestModifyBreak(TBool aThreadSpecific);
-	void TestBreakInfo();
-	void DoTestBreakInfo(TBool aThreadSpecific);
-	void TestRunToBreak();
-	void DoTestRunToBreak(TBool aThreadSpecific);
-	void TestRegisterAccess();
-	void TestAttachExecutable();
-	void TestDebugFunctionality();
-	void TestStep();
-	void DoTestStep(TBool aThreadSpecific);
-	void TestDriverSecurity();
-	void TestSecurity();
-	void TestEvents();
-	void TestEventsForExternalProcess();
-	void TestDemandPaging();
-	void TestTraceSecurity();
-	void TestDllUsage();
-	void TestKillProcess();
-	void TestProcessBreakPoints();
-	void TestMultipleTraceEvents();
-	void TestAddRemoveProcessEvents();
-	void TestProcessKillBreakpoint();
-	void DoTestProcessKillBreakpoint();
-
-	//crash flash test functions
-	void TestCrashFlash();
-		
-	TInt GetFlag(const TDes8 &aFlags, const TUint aOffset, Debug::TRegisterFlag &aFlagValue) const;
-
-	void ReportPerformance(void);
-
-	// helper functions
-	void HelpTestSecurityAttachDetachExecutable(const TDesC& aProcessName, TBool aExpectSuccess);
-
-	TInt HelpTestStepSetBreak(Debug::TBreakId& aBreakId, TThreadId aThreadId, const TUint32 aBreakAddress, Debug::TArchitectureMode aMode, TBool aThreadSpecific=ETrue, TProcessId aProcessId=0);
-	TInt HelpTestStepClearBreak(const Debug::TBreakId aBreakId, const TThreadId aThreadId, TBool aThreadSpecific);
-	TInt HelpTestStepWaitForBreak(const TDesC& aProcessName, Debug::TEventInfo& aEventInfo);
-	TInt HelpTestStepReadPC(TThreadId aThreadId, TUint32& aPC);
-	TInt HelpTestStep(TThreadId aThreadId, TUint32 aStartAddress, TUint32 aEndAddress, Debug::TArchitectureMode aMode, TUint aNumSteps, TBool aThreadSpecific=ETrue, TProcessId=0);
-
-	TInt HelpTicksPerSecond(void);
-
-	// helper functions
-	void HelpStartTestTimer(void) { iStartTick = User::NTickCount(); iStopTick = 0; };
-	void HelpStopTestTimer(void) { iStopTick = User::NTickCount(); };
-	TInt HelpGetTestTicks(void) { return (iStopTick - iStartTick); };
-	TInt SwitchTestFunction(TTestFunction aTestFunction);
-	TInt LaunchProcess(RProcess& aProcess, const TDesC& aFileName, TDebugFunctionType aFunctionType, TUint32 aDelay=0, TUint32 aExtraThreads=0);
-	Debug::TTagHeader* GetTagHdr(const TDesC8& aDebugFunctionalityBlock, const Debug::TTagHeaderId aTagHdrId) const;
-	Debug::TTag* GetTag(const Debug::TTagHeader* aTagHdr, const TInt aElement) const;
-	Debug::TTag GetTag(const Debug::TTagHeaderId aTagHdrId, const TInt aElement);
-	TBool ProcessExists(const TProcessId aProcessId);
-	TBool ThreadExistsForProcess(const TThreadId aThreadId, const TProcessId aProcessId);
-	TBool ListingSupported(const Debug::TListId aListId, const Debug::TListScope aListScope);
-	void TestEventsWithExtraThreads(Debug::TKernelEventAction aActionMain, Debug::TKernelEventAction aActionExtra, TUint32 aExtraThreads);
-	void FillArray();
-	void PrintUsage();
-	void PrintVersion();
-
-	enum TTestMode 
-		{
-		//run all the tests
-		EModeAll = 1<<0,
-		//run the specified tests in reverse order
-		EModeReverse = 1<<1,
-		//print out help
-		EModeHelp = 1<<2,
-		//print out help
-		EModeVersion = 1<<3
-		};
-
-	void RunTest(TInt aTestNumber);
-	void ParseCommandLineL(TUint32& aMode, RArray<TInt>& aTests);
-
-	TBool ProcessExists(const TDesC& aProcessName);
-
-private:
-
-	TFunctionData iTestArray[KMaxTests];
-#if defined(KERNEL_OOM_TESTING)
-	RKernelLowMemorySecuritySvrSession iServSession;
-#elif defined (USER_OOM_TESTING)
-	RUserLowMemorySecuritySvrSession iServSession;
-#else
-	Debug::RSecuritySvrSession iServSession;
-#endif
-	RThread	iDebugThread;
-	RProcess iDSSProcess;
-	RSemaphore iAddressGlobSem;
-	TThreadId iThreadID;
-	TFileName iFileName;
-	TUid iMySid;
-
-	// Performance data
-	TInt iMemoryReadKbytesPerSecond;	
-	TInt iMemoryWriteKbytesPerSecond;	
-	TInt iBreakpointsPerSecond;
-	TInt iMaxBreakpoints;
-	TInt iStepsPerSecond;
-
-	// Timing information
-	TInt iStartTick;
-	TInt iStopTick;
-	};
-
-#endif // RMDEBUG_H
--- a/kerneltest/e32test/rm_debug/t_rmdebug2_oemtoken.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,32 +0,0 @@
-// Copyright (c) 2007-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:
-//
-
-/**
- @file
- @internalTechnology
- @released
-*/
-
-#include <e32base.h>
-#include <e32base_private.h>
-
-GLDEF_C TInt E32Main()
-	{
-	// No need to do anything, the only requirement is that
-	// this executable can be loaded and runs to completion
-	return 0;
-	}
-
-// End of file - t_rmdebug2_oemtoken.cpp
--- a/kerneltest/e32test/rm_debug/t_rmdebug_app.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,328 +0,0 @@
-// Copyright (c) 2007-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:
-//
-
-#include <e32base.h>
-#include <e32base_private.h>
-#include <e32cmn.h>
-#include <e32cmn_private.h>
-#include <e32debug.h>
-#include <e32property.h> 
-#include "t_rmdebug_app.h"
-
-IMPORT_C extern void RMDebug_BranchTst2();
-
-LOCAL_C void ParseCommandLineL(TInt32& aFunctionType, TUint& aDelay, TUint& aExtraThreads)
-	{
-	// get the length of the command line arguments
-	TInt argc = User::CommandLineLength();
-
-	// allocate a buffer for the command line arguments and extract the data to it
-	HBufC* commandLine = HBufC::NewLC(argc);
-	TPtr commandLineBuffer = commandLine->Des();
-	User::CommandLine(commandLineBuffer);
-
-	// create a lexer and read through the command line
-	TLex lex(*commandLine);
-	while (!lex.Eos())
-		{
-		// expecting the first character to be a '-'
-		if (lex.Get() == '-')
-			{
-			TChar arg = lex.Get();
-			switch (arg)
-				{
-				case 'f':
-					// the digits following '-f' give the function type
-					User::LeaveIfError(lex.Val(aFunctionType));
-					break;
-				case 'd':
-					// the digits following '-d' give the delay
-					User::LeaveIfError(lex.Val(aDelay));
-					break;
-				case 'e':
-					// the digits following '-e' give the number of extra threads to launch
-					User::LeaveIfError(lex.Val(aExtraThreads));
-					break;
-				default:
-					// unknown argument so leave
-					User::Leave(KErrArgument);
-				}
-			lex.SkipSpace();
-			}
-		else
-			{
-			// unknown argument so leave
-			User::Leave(KErrArgument);
-			}
-		}
-
-	// do clean up
-	CleanupStack::PopAndDestroy(commandLine);
-	}
-
-typedef void (*TPfun)();
-
-// test function to call corresponding to EPrefetchAbortFunction
-void PrefetchAbort()
-	{
-	TPfun f = NULL;
-	f();
-	}
-
-// test function to call corresponding to EUserPanicFunction
-void UserPanic()
-	{
-	User::Panic(KUserPanic, KUserPanicCode);
-	}
-
-// calls self repeatedly until stack is used up. Slightly convoluted to prevent UREL optimising this out...
-TUint32 StackOverFlowFunction(TUint32 aInt=0)
-	{
-	TUint32 unusedArray[150];
-	for(TInt i=0; i<150; i++)
-		{
-		unusedArray[i] = StackOverFlowFunction(i);
-		}
-	return unusedArray[0];
-	}
-
-void DataAbort()
-	{
-	TInt* r = (TInt*) 0x1000;
-	*r = 0x42;              
-	}
-
-void UndefInstruction()
-	{
-	TUint32 undef = 0xE6000010;
-	TPfun f = (TPfun) &undef;
-	f();
-	}
-
-TInt DataRead()
-	{
-	TInt* r = (TInt*) 0x1000;
-	TInt rr = (TInt)*r;
-	//include the following line to ensure that rr doesn't get optimised out
-	RDebug::Printf("Shouldn't see this being printed out: %d", rr);
-
-	// Stop compilation warning. Should not get here anyway.
-	rr++;
-	return rr;
-	}
-
-void DataWrite()
-	{
-	TInt* r = (TInt*) 0x1000;
-	*r = 0x42;                
-	}
-
-void UserException()
-	{
-	User::RaiseException(EExcGeneral);
-	}
-
-void SpinForeverWithBreakPoint()
-	{
-
-    // finding the process t_rmdebug2/t_rmdebug2_oem/t_rmdebug2_oem2
-    // we find the process.SID to attach to the property
-	_LIT(KThreadWildCard, "t_rmdebug2*");
-
-	TInt err = KErrNone;
-	TUid propertySid = KNullUid;
-	TFindThread find(KThreadWildCard);
-	TFullName name;
-	TBool found = EFalse;
-	while(find.Next(name)==KErrNone && !found)
-		{
-		RThread thread;
-		err = thread.Open(find);
-		if (err == KErrNone)
-			{
-			RProcess process;
-			thread.Process(process);
-			TFullName fullname = thread.FullName();
-		    //RDebug::Printf("SID Search Match Found Name %lS Process ID%ld Thread Id %ld", &fullname, process.Id().Id(), thread.Id().Id());
-			found = ETrue;
-			//SID saved so that the property can be attached to
-			propertySid = process.SecureId();
-			process.Close();
-			}
-		thread.Close();
-	}
-
-    //attach to the property to publish the address of the RMDebug_BranchTst2 with the correct SID value
-	RProperty integerProperty;
-	err = integerProperty.Attach(propertySid, EMyPropertyInteger, EOwnerThread);
-	if(KErrNone != err)
-		RDebug::Printf("Error Attach to the property %d", err);
-
-	TInt address = (TInt)&RMDebug_BranchTst2;
-	
-	// publish the address where the breakpoint would be set
-	err = integerProperty.Set(address);
-	if(KErrNone != err)
-		RDebug::Printf("Error Set of the property %d", err);
-	integerProperty.Close();
-	
-	//open semaphore to signal the fact we have reached the point where we have to set the property
-	RSemaphore globsem;
-	globsem.OpenGlobal(_L("RMDebugGlobSem"));
-	globsem.Signal();
-	globsem.Close();
-
-	RProcess thisProcess;
-	TFileName thisProcessName = thisProcess.FileName();
-	RDebug::Printf("App Process Name %lS process id %ld thread id %ld", &thisProcessName, thisProcess.Id().Id(), RThread().Id().Id());
-
-	TInt i=0;
-	RThread::Rendezvous(KErrNone);
-	while(i<0xffffffff)
-		{
-		RMDebug_BranchTst2();
-		User::After(10000);
-		}
-	}
-void SpinForever()
-	{
-	TInt i=0;
-	RThread::Rendezvous(KErrNone);
-	while(i<0xffffffff)
-		{
-		User::After(10000);
-		}
-	}
-
-void LaunchThreads(TUint aNumber)
-	{
-	_LIT(KDebugThreadName, "DebugThread");
-	const TUint KDebugThreadDefaultHeapSize=0x10000;
-	for(TInt i=0; i<aNumber; i++)
-		{
-		RThread thread;
-		RBuf threadName;
-		threadName.Create(KDebugThreadName().Length()+10); // the 10 is for appending i to the end of the name
-		threadName.Append(KDebugThreadName());
-		threadName.AppendNum(i);
-		TInt err = thread.Create(threadName, (TThreadFunction)SpinForever, KDefaultStackSize, KDebugThreadDefaultHeapSize, KDebugThreadDefaultHeapSize, NULL);
-		if(err != KErrNone)
-			{
-			RDebug::Printf("Couldn't create thread %d", err);
-			threadName.Close();
-			thread.Close();
-			break;
-			}
-		thread.SetPriority(EPriorityNormal);
-		TRequestStatus status;
-		thread.Rendezvous(status);
-		thread.Resume();
-		User::WaitForRequest(status);
-		thread.Close();
-		threadName.Close();
-		}
-	}
-
-void WaitFiveSecondsThenExit(void)
-	{
-	// wait for 5 seconds
-	User::After(5000000);
-	}
-
-// call the function corresponding to aFunctionType
-LOCAL_C void CallFunction(TDebugFunctionType aFunctionType, TUint aDelay, TUint aExtraThreads)
-	{
-	// pause for aDelay microseconds
-	User::After(aDelay);
-
-	// launch the extra threads
-	LaunchThreads(aExtraThreads);
-
-	// call appropriate function
-	switch( aFunctionType )
-		{
-		case EPrefetchAbortFunction:
-			PrefetchAbort();
-			break;
-		case EUserPanicFunction:
-			UserPanic();
-			break;
-		case EStackOverflowFunction:
-			StackOverFlowFunction();
-			break;
-		case EDataAbortFunction:
-			DataAbort();
-			break;
-		case EUndefInstructionFunction:
-			UndefInstruction();
-			break;
-		case EDataReadErrorFunction:
-			DataRead();
-			break;
-		case EDataWriteErrorFunction:
-			DataWrite();
-			break;
-		case EUserExceptionFunction:
-			UserException();
-			break;
-		case EWaitFiveSecondsThenExit:
-			WaitFiveSecondsThenExit();
-			break;
-		case ESpinForever:
-			SpinForever();
-			break;
-		case ESpinForeverWithBreakPoint:
-			SpinForeverWithBreakPoint();
-			break;
-		case EDefaultDebugFunction:
-		default:
-			break;
-		}
-	}
-
-void PrintHelp()
-	{
-	RDebug::Printf("Invoke with arguments:\n");
-	RDebug::Printf("\t-d<delay>\n\t: delay in microseconds before calling target function\n");
-	RDebug::Printf("\t-f<function-number>\n\t: enumerator from TDebugFunctionType representing function to call\n");
-	RDebug::Printf("\t-e<number>\n\t: number of extra threads to launch, these threads run endlessly\n");
-	}
-
-TInt E32Main()
-	{
-	// setup heap checking and clean up trap
-	__UHEAP_MARK;
-	CTrapCleanup* cleanup=CTrapCleanup::New();
-	RThread().SetPriority(EPriorityNormal);
-	RProcess::Rendezvous(KErrNone);
-
-	// read arguments from command line
-	TUint delay = 0;
-	TInt32 functionTypeAsTInt32 = (TInt32)EDefaultDebugFunction;
-	TUint extraThreads = 0;
-	TRAPD(err, ParseCommandLineL(functionTypeAsTInt32, delay, extraThreads));
-
-	if(KErrNone == err)
-		{
-		// if the command line arguments were successfully read then call the appropriate function
-		CallFunction((TDebugFunctionType)functionTypeAsTInt32, delay, extraThreads);
-		}
-
-	// perform clean up and return any error which was recorded
-	delete cleanup;
-	__UHEAP_MARKEND;
-	return err;
-	}
-
--- a/kerneltest/e32test/rm_debug/t_rmdebug_app.h	Tue Feb 02 01:24:03 2010 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,44 +0,0 @@
-// Copyright (c) 2007-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:
-//
-
-#ifndef T_RMDEBUG_APP_H
-#define T_RMDEBUG_APP_H
-
-_LIT(KRMDebugTestApplication, "z:\\sys\\bin\\t_rmdebug_app.exe");
-_LIT(KUserPanic, "UserPanic");
-const TInt KUserPanicCode = 0x1234ABCD;
-
-enum TMyPropertyKeys {EMyPropertyInteger};
-
-
-// enumeration of functions to call in test debug application
-enum TDebugFunctionType
-	{
-	EDefaultDebugFunction,
-	EPrefetchAbortFunction,
-	EUserPanicFunction,
-	EStackOverflowFunction,
-	EDataAbortFunction,
-	EUndefInstructionFunction,
-	EDataReadErrorFunction,
-	EDataWriteErrorFunction,
-	EUserExceptionFunction,
-	EWaitFiveSecondsThenExit,
-	ESpinForever,
-	ESpinForeverWithBreakPoint
-	};
-
-#endif //T_RMDEBUG_APP_H
-
--- a/kerneltest/e32test/rm_debug/t_rmdebug_dll.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,25 +0,0 @@
-// Copyright (c) 2007-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:
-//
-
-#include <e32std.h>
-#include <e32std_private.h>
-#include <rm_debug_api.h>
-#include "t_rmdebug_dll.h"
-
-EXPORT_C TUid GetDSSUid()
-	{
-	return Debug::KUidDebugSecurityServer;
-	}
-
--- a/kerneltest/e32test/rm_debug/t_rmdebug_dll.h	Tue Feb 02 01:24:03 2010 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,23 +0,0 @@
-// Copyright (c) 2007-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:
-//
-
-#include <e32std.h>
-
-/**
-  This is a simple function that uses an element from rm_debug_api.h.
-  If the e32tests can be built and run then this is 'proof' that the
-  rm_debug_api.h header file can be #include'd into a dll
-  */
-IMPORT_C TUid GetDSSUid();
--- a/kerneltest/e32test/rm_debug/t_rmdebug_security.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,100 +0,0 @@
-// Copyright (c) 2006-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 application to be debugged by t_rmdebug.exe when testing
-// security restrictions. This application is built with various
-// capabilities by the t_rmdebug_securityX.mmp files. This allows
-// the t_rmdebug2 program to ensure that security restrictions are
-// properly enforced by the DSS/DDD subsystem.
-// 
-//
-
-#include <e32base.h>
-#include <e32base_private.h>
-#include <e32cons.h>
-#include <e32test.h>
-#include <e32ldr.h>
-#include <e32cmn.h>
-#include <e32cmn_private.h>
-#include "t_rmdebug_security.h"
-
-CRunModeApp* CRunModeApp::NewL()
-//
-// CRunModeApp::NewL
-//
-	{
-	CRunModeApp* self = new(ELeave) CRunModeApp();
-
-  	self->ConstructL();
-   
-	return self;
-	}
-
-CRunModeApp::CRunModeApp()
-//
-// CRunModeApp constructor
-//
-	{
-	}
-
-CRunModeApp::~CRunModeApp()
-//
-// CRunModeApp destructor
-//
-	{
-	}
-
-void CRunModeApp::ConstructL()
-//
-// CRunModeApp::ConstructL
-//
-	{
-	}
-
-void CRunModeApp::TestWaitDebug()
-//
-// CRunModeApp::TestWaitDebug
-//
-	{
-	RProcess::Rendezvous(KErrNone);
-
-	// Wait a 3secs then quit (long enough to test, but not hang around forever)
-	User::After(3000000);
-	}
-
-GLDEF_C TInt E32Main()
-//
-// Entry point for run mode debug app test program
-//
-	{
-   TInt ret = KErrNone;
-   
-	// client
-	CTrapCleanup* trap = CTrapCleanup::New();
-	if (!trap)
-		return KErrNoMemory;
-
-   CRunModeApp* myApp = CRunModeApp::NewL();
-   if (myApp != NULL)
-       {
-        __UHEAP_MARK;
-	    TRAP(ret,myApp->TestWaitDebug());
-	    __UHEAP_MARKEND;
-
-	    delete myApp;
-       }
-       
-	delete trap;
-
-	return ret;
-	}
--- a/kerneltest/e32test/rm_debug/t_rmdebug_security.h	Tue Feb 02 01:24:03 2010 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,44 +0,0 @@
-// Copyright (c) 2006-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 application to be debugged by t_rmdebug2.exe when testing
-// security restrictions. This application is built with various
-// capabilities by the t_rmdebug_securityX.mmp files. This allows
-// the t_rmdebug2 program to ensure that security restrictions are
-// properly enforced by the DSS/DDD subsystem.
-// 
-//
-
-/**
- @file
- @internalTechnology
- @released
-*/
-
-#ifndef T_RMDEBUG_SECURITY_H
-#define T_RMDEBUG_SECURITY_H
-
-class CRunModeApp : public CBase
-{
-public:
-	static CRunModeApp* NewL();
-	~CRunModeApp();
-
-	void TestWaitDebug();
-
-private:
-	CRunModeApp();
-	void ConstructL();
-};
-
-#endif // T_RMDEBUG_SECURITY_H
--- a/kerneltest/e32test/rm_debug/t_trkdummyapp.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,532 +0,0 @@
-// Copyright (c) 2008-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:
-// Ensure that old insecure Trk debug agent cannot be installed
-// as it should be blocked from SWInstall'ing by a trkdummyapp.exe contained within
-// the base OS with the same SID as the insecure Trk.
-// 
-//
-
-#include <e32base.h>
-#include <e32base_private.h>
-#include <e32cons.h>
-#include <e32test.h>
-#include <e32ldr.h>
-#include <e32cmn.h>
-#include <e32cmn_private.h>
-#include <f32dbg.h>
-#include <f32file.h>
-#include "t_trkdummyapp.h"
-
-LOCAL_D RTest test(_L("T_TRKDUMMYAPP"));
-
-CTrkDummyAppTest::CTrkDummyAppTest()
-//
-// CTrkDummyAppTest constructor
-//
-	{
-	// nothing to do
-	}
-
-CTrkDummyAppTest* CTrkDummyAppTest::NewL()
-//
-// CRunModeAgent::NewL
-//
-	{
-	CTrkDummyAppTest* self = new(ELeave) CTrkDummyAppTest();
-
-  	self->ConstructL();
-
-	return self;
-	}
-
-CTrkDummyAppTest::~CTrkDummyAppTest()
-//
-// CTrkDummyAppTest destructor
-//
-	{
-	// Nothing to do
-	}
-
-void CTrkDummyAppTest::ConstructL()
-//
-// CTrkDummyAppTest::ConstructL
-//
-	{
-	// nothing to do here
-	}
-
-
-CTrkDummyAppTest *TrkDummyTest;
-
-//----------------------------------------------------------------------------------------------
-//! @SYMTestCaseID      KBase-T-TRKDUMMYAPP-0792
-//! @SYMTestType        
-//! @SYMPREQ            PREQ1426
-//! @SYMTestCaseDesc    Tests that a known insecure debug agent trkapp.sis cannot be installed
-//!                     by ensuring the existence of a Symbian OS common app called trkdummyapp.exe
-//!                     already exists with the same Secure ID as the insecure app.
-//! @SYMTestActions     
-//!    
-//!     1.              Calls RProcess.Create() on z:\sys\bin\trkdummyapp.exe. Fail if unsuccessful.
-//!     
-//!     2.              Obtain the Secure ID of the process derived from z:\sys\bin\trkdummyapp.exe.
-//!
-//!     3.              Close the process derived from z:\sys\bin\trkdummyapp.exe.
-//!
-//! @SYMTestExpectedResults 
-//!
-//!     1.              Fails if unable to create a process from z:\sys\bin\trkdummyapp.exe.
-//!
-//!     2.              The Secure ID of trkdummyapp.exe has the Secure ID 0x101F7159. Fail otherwise.
-//! 
-//! @SYMTestPriority        High
-//! @SYMTestStatus          Implemented
-//----------------------------------------------------------------------------------------------
-
-// Names of some test programs used for testing security
-_LIT(KRMDebugSecurityTrkDummyApp,"z:\\sys\\bin\\trkdummyapp.exe");
-
-void CTrkDummyAppTest::TestSecurityCheckPreventInsecureTrkDebugAgent(void)
-	{
-
-	test.Next(_L("TestSecurityCheckPreventInsecureTrkDebugAgent, SID 0x101F7159\n"));
-
-	RProcess process;
-	TInt err = process.Create(KRMDebugSecurityTrkDummyApp, KNullDesC, EOwnerProcess);
-	test (err == KErrNone);
-
-	// rendezvous with process
-	TRequestStatus status;
-	process.Rendezvous(status);
-
-	// obtain the secure ID for the process
-	TSecurityInfo secInfo(process);
-
-	static const TSecureId KTrkDummyAppSID = 0x101F7159;
-
-	test(secInfo.iSecureId.iId == KTrkDummyAppSID);
-
-	// Kill the process, as we don't need it anymore
-	process.Kill(KErrNone);
-
-	process.Close();
-	}
-
-//----------------------------------------------------------------------------------------------
-//! @SYMTestCaseID      KBase-T-TRKDUMMYAPP-0793
-//! @SYMTestType        
-//! @SYMPREQ            PREQ1426
-//! @SYMTestCaseDesc    Tests that a known insecure debug agent trkapp.sis cannot be installed
-//!                     by ensuring the existence of a Symbian OS common app called trkdummyapp.exe
-//!                     already exists with the same Secure ID as the insecure app.
-//! @SYMTestActions     
-//!    
-//!     1.              Calls RProcess.Create() on z:\sys\bin\trkdummyapp2.exe. Fail if unsuccessful.
-//!     
-//!     2.              Obtain the Secure ID of the process derived from z:\sys\bin\trkdummyapp2.exe.
-//!
-//!     3.              Close the process derived from z:\sys\bin\trkdummyapp2.exe.
-//!
-//! @SYMTestExpectedResults 
-//!
-//!     1.              Fails if unable to create a process from z:\sys\bin\trkdummyapp2.exe.
-//!
-//!     2.              The Secure ID of trkdummyapp.exe has the Secure ID 0x2000a7dd. Fail otherwise.
-//! 
-//! @SYMTestPriority        High
-//! @SYMTestStatus          Implemented
-//----------------------------------------------------------------------------------------------
-
-// Names of some test programs used for testing security
-_LIT(KRMDebugSecurityTrkDummyApp2,"z:\\sys\\bin\\trkdummyapp2.exe");
-
-void CTrkDummyAppTest::TestSecurityCheckPreventInsecureTrkDebugAgent2(void)
-	{
-
-	test.Next(_L("TestSecurityCheckPreventInsecureTrkDebugAgent2, SID 0x2000a7dd\n"));
-
-	RProcess process;
-	TInt err = process.Create(KRMDebugSecurityTrkDummyApp2, KNullDesC, EOwnerProcess);
-	test (err == KErrNone);
-
-	// rendezvous with process
-	TRequestStatus status;
-	process.Rendezvous(status);
-
-	// obtain the secure ID for the process
-	TSecurityInfo secInfo(process);
-
-	static const TSecureId KTrkDummyAppSID2 = 0x2000a7dd;
-
-	test(secInfo.iSecureId.iId == KTrkDummyAppSID2);
-
-	// Kill the process, as we don't need it anymore
-	process.Kill(KErrNone);
-
-	process.Close();
-	}
-
-//----------------------------------------------------------------------------------------------
-//! @SYMTestCaseID      KBase-T-TRKDUMMYAPP-2396
-//! @SYMTestType        
-//! @SYMPREQ            PREQ1426
-//! @SYMTestCaseDesc    Tests that a known insecure debug agent trkapp.sis cannot be installed
-//!                     by ensuring the existence of a Symbian OS common app called trkdummyapp200159D8.exe
-//!                     already exists with the same Secure ID as the insecure app.
-//! @SYMTestActions     
-//!    
-//!     1.              Calls RProcess.Create() on z:\sys\bin\trkdummyapp200159D8.exe. Fail if unsuccessful.
-//!     
-//!     2.              Obtain the Secure ID of the process derived from z:\sys\bin\trkdummyapp200159D8.exe.
-//!
-//!     3.              Close the process derived from z:\sys\bin\trkdummyapp200159D8.exe.
-//!
-//! @SYMTestExpectedResults 
-//!
-//!     1.              Fails if unable to create a process from z:\sys\bin\trkdummyapp200159D8.exe.
-//!
-//!     2.              The Secure ID of trkdummyapp200159D8.exe has the Secure ID 0x200159D8. Fail otherwise.
-//! 
-//! @SYMTestPriority        High
-//! @SYMTestStatus          Implemented
-//----------------------------------------------------------------------------------------------
-
-// Names of some test programs used for testing security
-_LIT(KRMDebugSecurityTrkDummyApp200159D8,"z:\\sys\\bin\\trkdummyapp200159D8.exe");
-
-void CTrkDummyAppTest::TestSecurityCheckPreventInsecureTrkDebugAgent200159D8(void)
-	{
-	test.Next(_L("TestSecurityCheckPreventInsecureTrkDebugAgent, SID 0x200159D8\n"));
-
-	RProcess process;
-	TInt err = process.Create(KRMDebugSecurityTrkDummyApp200159D8, KNullDesC, EOwnerProcess);
-	test (err == KErrNone);
-
-	// rendezvous with process
-	TRequestStatus status;
-	process.Rendezvous(status);
-
-	// obtain the secure ID for the process
-	TSecurityInfo secInfo(process);
-
-	static const TSecureId KTrkDummyAppSID2 = 0x200159D8;
-
-	test(secInfo.iSecureId.iId == KTrkDummyAppSID2);
-
-	// Kill the process, as we don't need it anymore
-	process.Kill(KErrNone);
-
-	process.Close();
-	}
-
-//----------------------------------------------------------------------------------------------
-//! @SYMTestCaseID      KBase-T-TRKDUMMYAPP-2397
-//! @SYMTestType        
-//! @SYMPREQ            PREQ1426
-//! @SYMTestCaseDesc    Tests that a known insecure debug agent trkapp.sis cannot be installed
-//!                     by ensuring the existence of a Symbian OS common app called trkdummyapp200170BC.exe
-//!                     already exists with the same Secure ID as the insecure app.
-//! @SYMTestActions     
-//!    
-//!     1.              Calls RProcess.Create() on z:\sys\bin\trkdummyapp200170BC.exe. Fail if unsuccessful.
-//!     
-//!     2.              Obtain the Secure ID of the process derived from z:\sys\bin\trkdummyapp200170BC.exe.
-//!
-//!     3.              Close the process derived from z:\sys\bin\trkdummyapp200170BC.exe.
-//!
-//! @SYMTestExpectedResults 
-//!
-//!     1.              Fails if unable to create a process from z:\sys\bin\trkdummyapp200170BC.exe.
-//!
-//!     2.              The Secure ID of trkdummyapp.exe has the Secure ID 0x200170BC. Fail otherwise.
-//! 
-//! @SYMTestPriority        High
-//! @SYMTestStatus          Implemented
-//----------------------------------------------------------------------------------------------
-
-// Names of some test programs used for testing security
-_LIT(KRMDebugSecurityTrkDummyApp200170BC,"z:\\sys\\bin\\trkdummyapp200170BC.exe");
-
-void CTrkDummyAppTest::TestSecurityCheckPreventInsecureTrkDebugAgent200170BC(void)
-	{
-
-	test.Next(_L("TestSecurityCheckPreventInsecureTrkDebugAgent, SID 0x200170BC\n"));
-
-	RProcess process;
-	TInt err = process.Create(KRMDebugSecurityTrkDummyApp200170BC, KNullDesC, EOwnerProcess);
-	test (err == KErrNone);
-
-	// rendezvous with process
-	TRequestStatus status;
-	process.Rendezvous(status);
-
-	// obtain the secure ID for the process
-	TSecurityInfo secInfo(process);
-
-	static const TSecureId KTrkDummyAppSID2 = 0x200170BC;
-
-	test(secInfo.iSecureId.iId == KTrkDummyAppSID2);
-
-	// Kill the process, as we don't need it anymore
-	process.Kill(KErrNone);
-
-	process.Close();
-	}
-
-void CTrkDummyAppTest::ClientAppL()
-//
-// Performs each test in turn
-//
-	{
-	test.Start(_L("ClientAppL"));
-
-	TestSecurityCheckPreventInsecureTrkDebugAgent();
-
-	TestSecurityCheckPreventInsecureTrkDebugAgent2();
-
-	TestSecurityCheckPreventInsecureTrkDebugAgent200159D8();
-
-	TestSecurityCheckPreventInsecureTrkDebugAgent200170BC();
-
-	test.End();
-	}
-
-
-
-GLDEF_C TInt E32Main()
-//
-// Entry point for run mode debug driver test
-//
-	{
-   TInt ret = KErrNone;
-
-	// client
-	CTrapCleanup* trap = CTrapCleanup::New();
-	if (!trap)
-		return KErrNoMemory;
-
-   	test.Title();
-   TrkDummyTest = CTrkDummyAppTest::NewL();
-   if (TrkDummyTest != NULL)
-       {
-        __UHEAP_MARK;
-	    TRAP(ret,TrkDummyTest->ClientAppL());
-	    __UHEAP_MARKEND;
-
-	    delete TrkDummyTest;
-       }
-       
-	delete trap;
-
-	return ret;
-	}
-
-// End of file - t_trkdummyapp.cpp
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
--- a/kerneltest/e32test/rm_debug/t_trkdummyapp.h	Tue Feb 02 01:24:03 2010 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,59 +0,0 @@
-// Copyright (c) 2008-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:
-// Ensure that old insecure Trk debug agent cannot be installed
-// as it should be blocked from SWInstall'ing by a trkdummyapp.exe contained within
-// the base OS with the same SID as the insecure Trk.
-// 
-//
-
-/**
-@file
-@internalTechnology
-@released
-*/
-
-#ifndef T_TRKDUMMYAPP_H
-#define T_TRKDUMMYAPP_H
-
-class CTrkDummyAppTest;
-
-//
-// class CTrkDummyAppTest
-//
-// Basic test of the existence of the TrkDummyApp.
-//
-class CTrkDummyAppTest : public CBase
-	{
-public:
-	static CTrkDummyAppTest* NewL();
-	~CTrkDummyAppTest();
-	void ClientAppL();
-
-	void TestSecurityCheckPreventInsecureTrkDebugAgent(void);
-
-	void TestSecurityCheckPreventInsecureTrkDebugAgent2(void);
-
-	void TestSecurityCheckPreventInsecureTrkDebugAgent200159D8(void);
-
-	void TestSecurityCheckPreventInsecureTrkDebugAgent200170BC(void);
-
-private:
-	CTrkDummyAppTest();
-	void ConstructL();
-
-	void TestTrkDummyAppExists();
-
-	};
-
-#endif // T_TRKDUMMYAPP_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/rm_debug/trk_blocking/t_trkdummyapp.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,532 @@
+// Copyright (c) 2008-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:
+// Ensure that old insecure Trk debug agent cannot be installed
+// as it should be blocked from SWInstall'ing by a trkdummyapp.exe contained within
+// the base OS with the same SID as the insecure Trk.
+// 
+//
+
+#include <e32base.h>
+#include <e32base_private.h>
+#include <e32cons.h>
+#include <e32test.h>
+#include <e32ldr.h>
+#include <e32cmn.h>
+#include <e32cmn_private.h>
+#include <f32dbg.h>
+#include <f32file.h>
+#include "t_trkdummyapp.h"
+
+LOCAL_D RTest test(_L("T_TRKDUMMYAPP"));
+
+CTrkDummyAppTest::CTrkDummyAppTest()
+//
+// CTrkDummyAppTest constructor
+//
+	{
+	// nothing to do
+	}
+
+CTrkDummyAppTest* CTrkDummyAppTest::NewL()
+//
+// CRunModeAgent::NewL
+//
+	{
+	CTrkDummyAppTest* self = new(ELeave) CTrkDummyAppTest();
+
+  	self->ConstructL();
+
+	return self;
+	}
+
+CTrkDummyAppTest::~CTrkDummyAppTest()
+//
+// CTrkDummyAppTest destructor
+//
+	{
+	// Nothing to do
+	}
+
+void CTrkDummyAppTest::ConstructL()
+//
+// CTrkDummyAppTest::ConstructL
+//
+	{
+	// nothing to do here
+	}
+
+
+CTrkDummyAppTest *TrkDummyTest;
+
+//----------------------------------------------------------------------------------------------
+//! @SYMTestCaseID      KBase-T-TRKDUMMYAPP-0792
+//! @SYMTestType        
+//! @SYMPREQ            PREQ1426
+//! @SYMTestCaseDesc    Tests that a known insecure debug agent trkapp.sis cannot be installed
+//!                     by ensuring the existence of a Symbian OS common app called trkdummyapp.exe
+//!                     already exists with the same Secure ID as the insecure app.
+//! @SYMTestActions     
+//!    
+//!     1.              Calls RProcess.Create() on z:\sys\bin\trkdummyapp.exe. Fail if unsuccessful.
+//!     
+//!     2.              Obtain the Secure ID of the process derived from z:\sys\bin\trkdummyapp.exe.
+//!
+//!     3.              Close the process derived from z:\sys\bin\trkdummyapp.exe.
+//!
+//! @SYMTestExpectedResults 
+//!
+//!     1.              Fails if unable to create a process from z:\sys\bin\trkdummyapp.exe.
+//!
+//!     2.              The Secure ID of trkdummyapp.exe has the Secure ID 0x101F7159. Fail otherwise.
+//! 
+//! @SYMTestPriority        High
+//! @SYMTestStatus          Implemented
+//----------------------------------------------------------------------------------------------
+
+// Names of some test programs used for testing security
+_LIT(KRMDebugSecurityTrkDummyApp,"z:\\sys\\bin\\trkdummyapp.exe");
+
+void CTrkDummyAppTest::TestSecurityCheckPreventInsecureTrkDebugAgent(void)
+	{
+
+	test.Next(_L("TestSecurityCheckPreventInsecureTrkDebugAgent, SID 0x101F7159\n"));
+
+	RProcess process;
+	TInt err = process.Create(KRMDebugSecurityTrkDummyApp, KNullDesC, EOwnerProcess);
+	test (err == KErrNone);
+
+	// rendezvous with process
+	TRequestStatus status;
+	process.Rendezvous(status);
+
+	// obtain the secure ID for the process
+	TSecurityInfo secInfo(process);
+
+	static const TSecureId KTrkDummyAppSID = 0x101F7159;
+
+	test(secInfo.iSecureId.iId == KTrkDummyAppSID);
+
+	// Kill the process, as we don't need it anymore
+	process.Kill(KErrNone);
+
+	process.Close();
+	}
+
+//----------------------------------------------------------------------------------------------
+//! @SYMTestCaseID      KBase-T-TRKDUMMYAPP-0793
+//! @SYMTestType        
+//! @SYMPREQ            PREQ1426
+//! @SYMTestCaseDesc    Tests that a known insecure debug agent trkapp.sis cannot be installed
+//!                     by ensuring the existence of a Symbian OS common app called trkdummyapp.exe
+//!                     already exists with the same Secure ID as the insecure app.
+//! @SYMTestActions     
+//!    
+//!     1.              Calls RProcess.Create() on z:\sys\bin\trkdummyapp2.exe. Fail if unsuccessful.
+//!     
+//!     2.              Obtain the Secure ID of the process derived from z:\sys\bin\trkdummyapp2.exe.
+//!
+//!     3.              Close the process derived from z:\sys\bin\trkdummyapp2.exe.
+//!
+//! @SYMTestExpectedResults 
+//!
+//!     1.              Fails if unable to create a process from z:\sys\bin\trkdummyapp2.exe.
+//!
+//!     2.              The Secure ID of trkdummyapp.exe has the Secure ID 0x2000a7dd. Fail otherwise.
+//! 
+//! @SYMTestPriority        High
+//! @SYMTestStatus          Implemented
+//----------------------------------------------------------------------------------------------
+
+// Names of some test programs used for testing security
+_LIT(KRMDebugSecurityTrkDummyApp2,"z:\\sys\\bin\\trkdummyapp2.exe");
+
+void CTrkDummyAppTest::TestSecurityCheckPreventInsecureTrkDebugAgent2(void)
+	{
+
+	test.Next(_L("TestSecurityCheckPreventInsecureTrkDebugAgent2, SID 0x2000a7dd\n"));
+
+	RProcess process;
+	TInt err = process.Create(KRMDebugSecurityTrkDummyApp2, KNullDesC, EOwnerProcess);
+	test (err == KErrNone);
+
+	// rendezvous with process
+	TRequestStatus status;
+	process.Rendezvous(status);
+
+	// obtain the secure ID for the process
+	TSecurityInfo secInfo(process);
+
+	static const TSecureId KTrkDummyAppSID2 = 0x2000a7dd;
+
+	test(secInfo.iSecureId.iId == KTrkDummyAppSID2);
+
+	// Kill the process, as we don't need it anymore
+	process.Kill(KErrNone);
+
+	process.Close();
+	}
+
+//----------------------------------------------------------------------------------------------
+//! @SYMTestCaseID      KBase-T-TRKDUMMYAPP-2396
+//! @SYMTestType        
+//! @SYMPREQ            PREQ1426
+//! @SYMTestCaseDesc    Tests that a known insecure debug agent trkapp.sis cannot be installed
+//!                     by ensuring the existence of a Symbian OS common app called trkdummyapp200159D8.exe
+//!                     already exists with the same Secure ID as the insecure app.
+//! @SYMTestActions     
+//!    
+//!     1.              Calls RProcess.Create() on z:\sys\bin\trkdummyapp200159D8.exe. Fail if unsuccessful.
+//!     
+//!     2.              Obtain the Secure ID of the process derived from z:\sys\bin\trkdummyapp200159D8.exe.
+//!
+//!     3.              Close the process derived from z:\sys\bin\trkdummyapp200159D8.exe.
+//!
+//! @SYMTestExpectedResults 
+//!
+//!     1.              Fails if unable to create a process from z:\sys\bin\trkdummyapp200159D8.exe.
+//!
+//!     2.              The Secure ID of trkdummyapp200159D8.exe has the Secure ID 0x200159D8. Fail otherwise.
+//! 
+//! @SYMTestPriority        High
+//! @SYMTestStatus          Implemented
+//----------------------------------------------------------------------------------------------
+
+// Names of some test programs used for testing security
+_LIT(KRMDebugSecurityTrkDummyApp200159D8,"z:\\sys\\bin\\trkdummyapp200159D8.exe");
+
+void CTrkDummyAppTest::TestSecurityCheckPreventInsecureTrkDebugAgent200159D8(void)
+	{
+	test.Next(_L("TestSecurityCheckPreventInsecureTrkDebugAgent, SID 0x200159D8\n"));
+
+	RProcess process;
+	TInt err = process.Create(KRMDebugSecurityTrkDummyApp200159D8, KNullDesC, EOwnerProcess);
+	test (err == KErrNone);
+
+	// rendezvous with process
+	TRequestStatus status;
+	process.Rendezvous(status);
+
+	// obtain the secure ID for the process
+	TSecurityInfo secInfo(process);
+
+	static const TSecureId KTrkDummyAppSID2 = 0x200159D8;
+
+	test(secInfo.iSecureId.iId == KTrkDummyAppSID2);
+
+	// Kill the process, as we don't need it anymore
+	process.Kill(KErrNone);
+
+	process.Close();
+	}
+
+//----------------------------------------------------------------------------------------------
+//! @SYMTestCaseID      KBase-T-TRKDUMMYAPP-2397
+//! @SYMTestType        
+//! @SYMPREQ            PREQ1426
+//! @SYMTestCaseDesc    Tests that a known insecure debug agent trkapp.sis cannot be installed
+//!                     by ensuring the existence of a Symbian OS common app called trkdummyapp200170BC.exe
+//!                     already exists with the same Secure ID as the insecure app.
+//! @SYMTestActions     
+//!    
+//!     1.              Calls RProcess.Create() on z:\sys\bin\trkdummyapp200170BC.exe. Fail if unsuccessful.
+//!     
+//!     2.              Obtain the Secure ID of the process derived from z:\sys\bin\trkdummyapp200170BC.exe.
+//!
+//!     3.              Close the process derived from z:\sys\bin\trkdummyapp200170BC.exe.
+//!
+//! @SYMTestExpectedResults 
+//!
+//!     1.              Fails if unable to create a process from z:\sys\bin\trkdummyapp200170BC.exe.
+//!
+//!     2.              The Secure ID of trkdummyapp.exe has the Secure ID 0x200170BC. Fail otherwise.
+//! 
+//! @SYMTestPriority        High
+//! @SYMTestStatus          Implemented
+//----------------------------------------------------------------------------------------------
+
+// Names of some test programs used for testing security
+_LIT(KRMDebugSecurityTrkDummyApp200170BC,"z:\\sys\\bin\\trkdummyapp200170BC.exe");
+
+void CTrkDummyAppTest::TestSecurityCheckPreventInsecureTrkDebugAgent200170BC(void)
+	{
+
+	test.Next(_L("TestSecurityCheckPreventInsecureTrkDebugAgent, SID 0x200170BC\n"));
+
+	RProcess process;
+	TInt err = process.Create(KRMDebugSecurityTrkDummyApp200170BC, KNullDesC, EOwnerProcess);
+	test (err == KErrNone);
+
+	// rendezvous with process
+	TRequestStatus status;
+	process.Rendezvous(status);
+
+	// obtain the secure ID for the process
+	TSecurityInfo secInfo(process);
+
+	static const TSecureId KTrkDummyAppSID2 = 0x200170BC;
+
+	test(secInfo.iSecureId.iId == KTrkDummyAppSID2);
+
+	// Kill the process, as we don't need it anymore
+	process.Kill(KErrNone);
+
+	process.Close();
+	}
+
+void CTrkDummyAppTest::ClientAppL()
+//
+// Performs each test in turn
+//
+	{
+	test.Start(_L("ClientAppL"));
+
+	TestSecurityCheckPreventInsecureTrkDebugAgent();
+
+	TestSecurityCheckPreventInsecureTrkDebugAgent2();
+
+	TestSecurityCheckPreventInsecureTrkDebugAgent200159D8();
+
+	TestSecurityCheckPreventInsecureTrkDebugAgent200170BC();
+
+	test.End();
+	}
+
+
+
+GLDEF_C TInt E32Main()
+//
+// Entry point for run mode debug driver test
+//
+	{
+   TInt ret = KErrNone;
+
+	// client
+	CTrapCleanup* trap = CTrapCleanup::New();
+	if (!trap)
+		return KErrNoMemory;
+
+   	test.Title();
+   TrkDummyTest = CTrkDummyAppTest::NewL();
+   if (TrkDummyTest != NULL)
+       {
+        __UHEAP_MARK;
+	    TRAP(ret,TrkDummyTest->ClientAppL());
+	    __UHEAP_MARKEND;
+
+	    delete TrkDummyTest;
+       }
+       
+	delete trap;
+
+	return ret;
+	}
+
+// End of file - t_trkdummyapp.cpp
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/rm_debug/trk_blocking/t_trkdummyapp.h	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,59 @@
+// Copyright (c) 2008-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:
+// Ensure that old insecure Trk debug agent cannot be installed
+// as it should be blocked from SWInstall'ing by a trkdummyapp.exe contained within
+// the base OS with the same SID as the insecure Trk.
+// 
+//
+
+/**
+@file
+@internalTechnology
+@released
+*/
+
+#ifndef T_TRKDUMMYAPP_H
+#define T_TRKDUMMYAPP_H
+
+class CTrkDummyAppTest;
+
+//
+// class CTrkDummyAppTest
+//
+// Basic test of the existence of the TrkDummyApp.
+//
+class CTrkDummyAppTest : public CBase
+	{
+public:
+	static CTrkDummyAppTest* NewL();
+	~CTrkDummyAppTest();
+	void ClientAppL();
+
+	void TestSecurityCheckPreventInsecureTrkDebugAgent(void);
+
+	void TestSecurityCheckPreventInsecureTrkDebugAgent2(void);
+
+	void TestSecurityCheckPreventInsecureTrkDebugAgent200159D8(void);
+
+	void TestSecurityCheckPreventInsecureTrkDebugAgent200170BC(void);
+
+private:
+	CTrkDummyAppTest();
+	void ConstructL();
+
+	void TestTrkDummyAppExists();
+
+	};
+
+#endif // T_TRKDUMMYAPP_H
--- a/kerneltest/e32test/system/d_dobject.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kerneltest/e32test/system/d_dobject.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -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/system/d_mstim.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kerneltest/e32test/system/d_mstim.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -91,7 +91,7 @@
 #endif
 #ifdef __NE1_TB__
 inline TCounter TIMER()
-	{ return NETimer::Timer(2).iTimerCount; }
+	{ return NETimer::Timer(5).iTimerCount; }
 #endif
 #if defined(__EPOC32__) && defined(__CPU_X86)
 TCounter TIMER();
@@ -188,8 +188,8 @@
 	return aTicks*500;					// 2kHz tick
 #endif
 #if defined(__NE1_TB__)
-	NETimer& T2 = NETimer::Timer(2);
-	TUint prescale = __e32_find_ms1_32(T2.iPrescaler & 0x3f);
+	NETimer& T5 = NETimer::Timer(5);
+	TUint prescale = __e32_find_ms1_32(T5.iPrescaler & 0x3f);
 	TInt f = 66666667 >> prescale;
 	TInt64 x = I64LIT(1000000);
 	x *= TInt64(aTicks);
@@ -264,7 +264,24 @@
 	TRvEmuBoard::EnableTimer(KHwCounterTimer1, TRvEmuBoard::EEnable);
 #endif
 #if defined(__NE1_TB__)
-	// nothing to do since variant has already set up timer
+    // set up timer 5
+    NETimer& T5 = NETimer::Timer(5);
+
+	T5.iTimerCtrl = 0;						// stop and reset timer 5
+	T5.iGTICtrl = 0;						// disable timer 5 capture modes
+	__e32_io_completion_barrier();
+	T5.iPrescaler = KNETimerPrescaleBy32;	// Timer 5 prescaled by 32 (=2.0833MHz)
+	__e32_io_completion_barrier();
+	T5.iGTInterruptEnable = 0;
+	__e32_io_completion_barrier();
+	T5.iGTInterrupt = KNETimerGTIInt_All;
+	__e32_io_completion_barrier();
+	T5.iTimerCtrl = KNETimerCtrl_CE;		// deassert reset for timer 5, count still stopped
+	__e32_io_completion_barrier();
+	T5.iTimerReset = 0xffffffffu;			// timer 5 wraps after 2^32 counts
+	__e32_io_completion_barrier();
+	T5.iTimerCtrl = KNETimerCtrl_CE | KNETimerCtrl_CAE;	// start timer 5
+	__e32_io_completion_barrier();		
 #endif
 #if defined(__EPOC32__) && defined(__CPU_X86)
 	// Set up timer channel 2 as free running counter at 14318180/12 Hz
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/timestamp/d_timestamp.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,463 @@
+/*
+* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "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: 
+*
+*/
+
+
+#include <kern_priv.h>
+#include <kernel.h>
+#include "d_timestamp.h"
+#include "d_timestamp_dev.h"
+
+// time stamp test defaults
+static const TInt KTimerDurationS = 5;  // time interval for NTimer
+static const TInt KNErrPercent = 1;  // percent error acceptable
+static const TInt KIterations = 5;  // required number of valid runs (with LPM entry) 
+static const TInt KRetries = 4;  // retries are reset on every succesful run
+
+//
+// DTimestampTestFactory
+//
+
+/**
+   Standard export function for LDDs. This creates a DLogicalDevice derived object,
+   in this case, our DTimestampTestFactory
+*/
+DECLARE_STANDARD_LDD()
+	{
+	return new DTimestampTestFactory;
+	}
+
+/**
+   Constructor
+*/
+DTimestampTestFactory::DTimestampTestFactory()
+	{
+	// Set version number for this device
+	iVersion=RTimestampTest::VersionRequired();
+    // Indicate that we work with a PDD
+	iParseMask=KDeviceAllowPhysicalDevice;
+    }
+
+/**
+   Second stage constructor for DTimestampTestFactory.
+   This must at least set a name for the driver object.
+
+   @return KErrNone if successful, otherwise one of the other system wide error codes.
+*/
+TInt DTimestampTestFactory::Install()
+	{
+	return SetName(&RTimestampTest::Name());
+	}
+
+/**
+   Destructor
+*/
+DTimestampTestFactory::~DTimestampTestFactory()
+	{
+    
+    }
+
+/**
+   Return the drivers capabilities.
+   Called in the response to an RDevice::GetCaps() request.
+
+   @param aDes User-side descriptor to write capabilities information into
+*/
+void DTimestampTestFactory::GetCaps(TDes8& aDes) const
+	{
+	// Create a capabilities object
+	RTimestampTest::TCaps caps;
+	caps.iVersion = iVersion;
+	// Write it back to user memory
+	Kern::InfoCopy(aDes,(TUint8*)&caps,sizeof(caps));
+	}
+
+
+/**
+   Called by the kernel's device driver framework to create a Logical Channel.
+   This is called in the context of the user thread (client) which requested the creation of a Logical Channel
+   (E.g. through a call to RBusLogicalChannel::DoCreate)
+   The thread is in a critical section.
+
+   @param aChannel Set to point to the created Logical Channel
+
+   @return KErrNone if successful, otherwise one of the other system wide error codes.
+*/
+TInt DTimestampTestFactory::Create(DLogicalChannelBase*& aChannel)
+	{
+	aChannel=new DTimestampTestChannel;
+	if(!aChannel)
+        {
+		return KErrNoMemory;
+        }
+    
+	return KErrNone;
+	}
+
+
+//
+// Logical Channel
+//
+
+/**
+   Constructor
+*/
+DTimestampTestChannel::DTimestampTestChannel()
+    :iTimer(timerExpire,this),iDfc(dfcFn,this,7),iStarted(EFalse)
+	{
+	// Get pointer to client threads DThread object
+	iClient=&Kern::CurrentThread();
+	// Open a reference on client thread so it's control block can't dissapear until
+	// this driver has finished with it.
+	// Note, this call to Open can't fail since its the thread we are currently running in
+	iClient->Open();
+	}
+
+/**
+   Second stage constructor called by the kernel's device driver framework.
+   This is called in the context of the user thread (client) which requested the creation of a Logical Channel
+   (E.g. through a call to RBusLogicalChannel::DoCreate)
+   The thread is in a critical section.
+
+   @param aUnit The unit argument supplied by the client to RBusLogicalChannel::DoCreate
+   @param aInfo The info argument supplied by the client to RBusLogicalChannel::DoCreate
+   @param aVer The version argument supplied by the client to RBusLogicalChannel::DoCreate
+
+   @return KErrNone if successful, otherwise one of the other system wide error codes.
+*/
+TInt DTimestampTestChannel::DoCreate(TInt /*aUnit*/, const TDesC8* /*aInfo*/, const TVersion& aVer)
+	{
+	// Check version
+	if (!Kern::QueryVersionSupported(RTimestampTest::VersionRequired(),aVer))
+		return KErrNotSupported;
+
+	// Setup LDD for receiving client messages
+    TInt r = Kern::CreateClientRequest(iStartRequest);
+    if (r != KErrNone) return r;
+    r = Kern::CreateClientDataRequest(iWaitOnTimerRequest);
+    if (r != KErrNone) return r;
+    r = Kern::DynamicDfcQCreate(iQue,Kern::DfcQue0()->iThread->iPriority,RTimestampTest::Name());
+    if (KErrNone!=r) return r;
+    iDfc.SetDfcQ(iQue);
+    SetDfcQ(iQue);
+    iMsgQ.Receive();
+    // Done
+	return KErrNone;
+	}
+
+
+/**
+   Destructor
+*/
+DTimestampTestChannel::~DTimestampTestChannel()
+	{
+	// Cancel all processing that we may be doing
+	DoCancel(TUint(RTimestampTest::EAllRequests));
+    Kern::DestroyClientRequest(iWaitOnTimerRequest);
+    Kern::DestroyClientRequest(iStartRequest);
+    iQue->Destroy();
+	// Close our reference on the client thread
+	Kern::SafeClose((DObject*&)iClient,NULL);
+	}
+
+/**
+   Called when a user thread requests a handle to this channel.
+*/
+TInt DTimestampTestChannel::RequestUserHandle(DThread* aThread, TOwnerType aType)
+	{
+	// Make sure that only our client can get a handle
+	if (aType!=EOwnerThread || aThread!=iClient)
+		return KErrAccessDenied;
+	return KErrNone;
+	}
+
+/**
+   override SendMsg method to allow pinning data in the context of the client thread
+*/
+TInt DTimestampTestChannel::SendMsg(TMessageBase* aMsg)
+	{
+	TThreadMessage& m=*(TThreadMessage*)aMsg;
+    TInt id = m.iValue;
+
+	// we only support one client
+	if (id != (TInt)ECloseMsg && m.Client() != iClient)
+		return KErrAccessDenied;
+	
+	TInt r = KErrNone;
+	if (id != (TInt)ECloseMsg && id != KMaxTInt)
+		{
+		if (id<0)
+			{
+			TRequestStatus* pS=(TRequestStatus*)m.Ptr0();
+			r = SendRequest(aMsg);
+			if (r != KErrNone)
+				Kern::RequestComplete(pS,r);
+			}
+		else
+			r = SendControl(aMsg);
+		}
+	else
+		r = DLogicalChannel::SendMsg(aMsg);
+	
+	return r;
+	}
+
+/**
+   Process a message for this logical channel.
+   This function is called in the context of a DFC thread.
+
+   @param aMessage The message to process.
+   The iValue member of this distinguishes the message type:
+   iValue==ECloseMsg, channel close message
+   iValue==KMaxTInt, a 'DoCancel' message
+   iValue>=0, a 'DoControl' message with function number equal to iValue
+   iValue<0, a 'DoRequest' message with function number equal to ~iValue
+*/
+void DTimestampTestChannel::HandleMsg(TMessageBase* aMsg)
+	{
+	TThreadMessage& m=*(TThreadMessage*)aMsg;
+
+	// Get message type
+	TInt id=m.iValue;
+
+	// Decode the message type and dispatch it to the relevent handler function...
+
+	if (id==(TInt)ECloseMsg)
+		{
+		// Channel Close
+        DoCancel(TUint(RTimestampTest::EAllRequests));
+        iMsgQ.CompleteAll(KErrServerTerminated);
+		m.Complete(KErrNone, EFalse);
+		return;
+		}
+
+	if (id==KMaxTInt)
+		{
+		// DoCancel
+		DoCancel(m.Int0());
+		m.Complete(KErrNone,ETrue);
+		return;
+		}
+
+	if (id<0)
+		{
+		// DoRequest
+		TRequestStatus* pS=(TRequestStatus*)m.Ptr0();
+		DoRequest(~id,pS,m.Ptr1(),m.Ptr2());
+		m.Complete(KErrNone,ETrue);
+		}
+	else
+		{
+		// DoControl
+		TInt r=DoControl(id,m.Ptr0(),m.Ptr1());
+		m.Complete(r,ETrue);
+		}
+	}
+
+/**
+   Preprocess synchronous 'control' requests
+*/
+TInt DTimestampTestChannel::SendControl(TMessageBase* aMsg)
+	{
+	TThreadMessage& m=*(TThreadMessage*)aMsg;
+    TInt id=m.iValue;
+
+	switch (id)
+		{
+        
+    case RTimestampTest::EConfig:
+        {
+        STimestampTestConfig info;
+#ifdef __SMP__
+        info.iFreq = NKern::TimestampFrequency();
+#else
+        info.iFreq = NKern::FastCounterFrequency();
+#endif
+        info.iIterations = KIterations;
+        info.iRetries = KRetries;
+        info.iTimerDurationS = KTimerDurationS;
+        info.iErrorPercent = KNErrPercent;
+        // Allow PDD to override defaults
+        Pdd().TestConfig(info);
+        kumemput(m.Ptr0(),&info,sizeof(STimestampTestConfig));
+        return KErrNone;
+		}
+    
+        }
+    
+
+	TInt r = DLogicalChannel::SendMsg(aMsg);
+	if (r != KErrNone)
+		return r;
+
+// 	switch (id)
+// 		{
+// 		}
+
+	return r;
+	}
+
+/**
+   Process synchronous 'control' requests
+*/
+TInt DTimestampTestChannel::DoControl(TInt aFunction, TAny* a1, TAny* a2)
+	{
+	(void)a2;   
+	(void)a1;   
+	(void) aFunction;
+
+	// TInt r = KErrNone;
+	// switch (aFunction)
+	// 	{
+    // default:
+    //     r = KErrNotSupported;
+	// 	}
+
+	return KErrNotSupported;
+	}
+
+
+/**
+   Preprocess asynchronous requests.
+*/
+TInt DTimestampTestChannel::SendRequest(TMessageBase* aMsg)
+    {
+	TThreadMessage& m=*(TThreadMessage*)aMsg;
+    TInt function = ~m.iValue;
+    TRequestStatus* pS=(TRequestStatus*)m.Ptr0();
+		
+	TInt r = KErrNotSupported;
+
+	switch (function)
+		{
+		case RTimestampTest::EStart:
+            if (!iStarted) 
+                {
+                r = iStartRequest->SetStatus(pS);
+                }
+            else 
+                {
+                r = KErrInUse;
+                }
+            break;
+            
+		case RTimestampTest::EWaitOnTimer:
+            if (iStarted)
+                {
+                iWaitOnTimerRequest->SetDestPtr(m.Ptr1());
+                r = iWaitOnTimerRequest->SetStatus(pS);
+                }
+            else
+                {
+                r = KErrNotReady;
+                }
+            
+            break;
+        default:
+            r = KErrNotSupported;
+		}
+
+	if (r == KErrNone)
+		r = DLogicalChannel::SendMsg(aMsg);
+	return r;
+    }
+
+
+/**
+   Process asynchronous requests.
+*/
+void DTimestampTestChannel::DoRequest(TInt aReqNo, TRequestStatus* aStatus, TAny* a1, TAny* a2)
+	{
+	(void)a2;   
+	(void)a1;   
+    (void)aStatus;
+    
+	TInt r = KErrNone;
+
+	switch(aReqNo)
+		{
+    case RTimestampTest::EStart:
+        iNTicks = (TInt) a1;
+        r = iTimer.OneShot(0);
+        if (KErrNone!=r) Kern::QueueRequestComplete(iClient,iStartRequest,r);
+        break;
+    case RTimestampTest::EWaitOnTimer:
+        Pdd().StartLPMEntryCheck();   // PDD will start checking if we have entered LPM
+        r = iTimer.Again(iNTicks);
+        if (KErrNone!=r) Kern::QueueRequestComplete(iClient,iWaitOnTimerRequest,r);
+        break;
+		}
+    
+	}
+
+
+
+/**
+   Process cancelling of asynchronous requests.
+*/
+void DTimestampTestChannel::DoCancel(TUint aMask)
+	{
+    (void)aMask;
+    iTimer.Cancel(); // no real guarantees on SMP systems
+    iDfc.Cancel();
+	}
+
+
+/**
+ * process timer expiry
+*/
+void DTimestampTestChannel::DoTimerExpire()
+	{
+#ifdef __SMP__
+    TUint64 ts = NKern::Timestamp();
+#else
+    TUint64 ts = NKern::FastCounter();
+#endif
+    iTimestampDelta = ts-iLastTimestamp;
+    iLastTimestamp = ts;
+    iDfc.Add();
+	}
+
+void DTimestampTestChannel::timerExpire(TAny* aParam)
+    {
+    DTimestampTestChannel* pD = (DTimestampTestChannel*) aParam;
+    pD->DoTimerExpire();
+    }
+
+
+
+void DTimestampTestChannel::DoDfcFn()
+	{
+    if (!iStarted)
+        {
+        iStarted = ETrue;
+        Kern::QueueRequestComplete(iClient,iStartRequest,KErrNone);
+        }
+    else
+        {
+        iWaitOnTimerRequest->Data().iDelta = iTimestampDelta;
+        // PDD will return ETrue here if we have entered LPM
+        iWaitOnTimerRequest->Data().iLPMEntered = Pdd().EndLPMEntryCheck(); 
+        Kern::QueueRequestComplete(iClient,iWaitOnTimerRequest,KErrNone);
+        }
+	}
+
+void DTimestampTestChannel::dfcFn(TAny* aParam)
+    {
+    DTimestampTestChannel* pD = (DTimestampTestChannel*) aParam;
+    pD->DoDfcFn();
+    }
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/timestamp/d_timestamp.h	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,181 @@
+/*
+* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "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: 
+*
+*/
+
+
+
+#ifndef __TIMESTAMPTEST_H__
+#define __TIMESTAMPTEST_H__
+
+#include <e32cmn.h>
+#include <e32ver.h>
+#ifndef __KERNEL_MODE__
+#include <e32std.h>
+#endif
+
+/*
+ *  Update by driver when a every time NTimer expires
+ */
+
+struct STimestampResult
+    {
+    TUint64 iDelta;   // difference in timestamp value between this and the last run
+    TBool   iLPMEntered; // true if low power modes wich restored timestamp was entered
+                         // since last NTimer expiry
+    };
+
+/*
+ *  Hold time stamp information, for now just freq
+ */
+
+struct STimestampTestConfig
+    {
+    TUint32 iFreq;  
+    TUint  iIterations;
+    TUint  iRetries;
+    TUint  iTimerDurationS;
+    TUint  iErrorPercent;
+    };
+
+    
+/**
+User interface for 'TimestampTest'
+*/
+class RTimestampTest : public RBusLogicalChannel
+	{
+public:
+	/**
+	Structure for holding driver capabilities information
+	(Just a version number in this example.)
+	*/
+	class TCaps
+		{
+	public:
+		TVersion iVersion;
+		};
+    static TVersion VersionRequired();
+    static const TDesC& Name();
+    
+public:
+	TInt Open();
+	void Start(TRequestStatus& aStatus, TInt aNTicks);
+    void WaitOnTimer(TRequestStatus& aStatus, STimestampResult& aResult);
+	TInt Config(STimestampTestConfig& aConfig);
+private:
+	/**
+	Enumeration of Control messages.
+	*/
+	enum TControl
+		{
+        EConfig
+		};
+
+	/**
+	Enumeration of Request messages.
+	*/
+	enum TRequest
+		{
+        EStart,
+        EWaitOnTimer,
+        EAllRequests=-1        
+		};
+
+	// Kernel side LDD channel is a friend
+	friend class DTimestampTestChannel;
+	};
+
+/**
+  The driver's name
+
+  @return The name of the driver
+
+  @internalComponent
+*/
+inline const TDesC& RTimestampTest::Name()
+	{
+	_LIT(KTimestampTestName,"TIMESTAMPTEST");
+	return KTimestampTestName;
+	}
+
+/**
+  The driver's version
+
+  @return The version number of the driver
+
+  @internalComponent
+*/
+inline TVersion RTimestampTest::VersionRequired()
+	{
+	const TInt KMajorVersionNumber=1;
+	const TInt KMinorVersionNumber=0;
+	const TInt KBuildVersionNumber=KE32BuildVersionNumber;
+	return TVersion(KMajorVersionNumber,KMinorVersionNumber,KBuildVersionNumber);
+	}
+
+/*
+  NOTE: The following methods would normally be exported from a seperate client DLL
+  but are included inline in this header file for convenience.
+*/
+
+#ifndef __KERNEL_MODE__
+
+/**
+  Open a logical channel to the driver
+  @return One of the system wide error codes.
+*/
+TInt RTimestampTest::Open()
+	{
+	return DoCreate(Name(),VersionRequired(),KNullUnit,NULL,NULL,EOwnerThread);
+	}
+
+
+/**
+  Start measuring timestamp intervals in the timer
+  @param aStatus request status for aync request
+  @param aNTicks number of ticks used with the NTimer in the driver
+*/
+void RTimestampTest::Start(TRequestStatus& aStatus, TInt aNTicks)
+	{
+	DoRequest(EStart,aStatus,(TAny*) aNTicks);
+	}
+
+
+/**
+  Wait for next timer expiry of aNTicks used in Start function
+  @param aStatus request status for aync request
+  @param aStatus request status for aync request
+  
+*/
+void RTimestampTest::WaitOnTimer(TRequestStatus& aStatus, STimestampResult& aResult)
+	{
+	DoRequest(EWaitOnTimer,aStatus,(TAny*) &aResult);
+	}
+
+
+/**
+  Open a logical channel to the driver
+  @return One of the system wide error codes.
+*/
+TInt RTimestampTest::Config(STimestampTestConfig& aConfig)
+	{
+	return DoControl(EConfig,(TAny*) &aConfig);
+	}
+
+
+#endif  // !__KERNEL_MODE__
+
+#endif
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/timestamp/d_timestamp_dev.h	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,117 @@
+/*
+* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "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: 
+*
+*/
+
+
+#ifndef __D_TIMERSTAMP_DEV_H__
+#define __D_TIMERSTAMP_DEV_H__
+
+/**
+  Logical Device (factory class) for 'TimestampTest'
+*/
+class DTimestampTestFactory : public DLogicalDevice
+	{
+public:
+	DTimestampTestFactory();
+	~DTimestampTestFactory();
+	//	Inherited from DLogicalDevice
+	virtual TInt Install();
+	virtual void GetCaps(TDes8& aDes) const;
+	virtual TInt Create(DLogicalChannelBase*& aChannel);
+	};
+
+class DTimestampTestPddChannel;
+
+/**
+  Logical Channel class for 'TimestampTest'
+*/
+class DTimestampTestChannel : public DLogicalChannel
+	{
+public:
+	DTimestampTestChannel();
+	virtual ~DTimestampTestChannel();
+	//	Inherited from DObject
+	virtual TInt RequestUserHandle(DThread* aThread, TOwnerType aType);
+	// Inherited from DLogicalChannelBase
+	virtual TInt DoCreate(TInt aUnit, const TDesC8* anInfo, const TVersion& aVer);
+	virtual void HandleMsg(TMessageBase* aMsg);
+    // intercept messages on client thread
+    virtual TInt SendMsg(TMessageBase* aMsg);
+private:
+	// Panic reasons
+	enum TPanic
+		{
+		ERequestAlreadyPending = 1
+		};
+	// Implementation for the differnt kinds of messages sent through RBusLogicalChannel
+	TInt DoControl(TInt aFunction, TAny* a1, TAny* a2);
+	void DoRequest(TInt aReqNo, TRequestStatus* aStatus, TAny* a1, TAny* a2);
+    TInt SendRequest(TMessageBase* aMsg);
+    TInt SendControl(TMessageBase* aMsg);
+	void DoCancel(TUint aMask);
+    void DoTimerExpire();
+    void DoDfcFn();
+    // Accessor for the PDD
+	inline DTimestampTestPddChannel& Pdd();
+protected:
+    
+    
+private:
+    static void timerExpire(TAny* aParam);
+    static void dfcFn(TAny* aParam);
+    DThread* iClient;
+    TDynamicDfcQue* iQue;
+    TClientDataRequest<STimestampResult> *iWaitOnTimerRequest;
+    TClientRequest *iStartRequest;
+    TInt iNTicks;
+    NTimer iTimer;
+    TDfc iDfc;
+    TUint64 iLastTimestamp;
+    TUint64 iTimestampDelta;
+    TBool iStarted;
+	};
+
+
+inline DTimestampTestPddChannel& DTimestampTestChannel::Pdd()
+	{ return *((DTimestampTestPddChannel*)iPdd); }
+
+/*
+ * DTimestampTestPddChannel
+ * Interface Pdd
+ */
+
+
+class DTimestampTestPddChannel : public DBase
+    {
+public:
+    /*
+     * reset any variables requried to check entry into a low power mode
+     * between time of call and time at which iTimer will next expire
+     */
+    virtual void StartLPMEntryCheck() = 0;
+    /*
+     * @return ETrue if a low power modes was entered
+     */
+    virtual TBool EndLPMEntryCheck() = 0;
+    /*
+     * Provide test parameters
+     */
+    virtual void TestConfig(STimestampTestConfig& aInfo) = 0;
+    };
+
+
+
+#endif //__D_TIMERSTAMP_DEV_H__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/timestamp/t_timestamp.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -0,0 +1,205 @@
+// Copyright (c) 2010 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 test checks the accuracy if NKern::Timestamp (in SMP systems) or
+// NKern::Fastcounter (in unicore), when low power modes are being selected
+// during idle.
+// Platforms requiring this test need to provide a d_timestamp.pdd which
+// implements the functions required to test the accurary. If no pdd is 
+// supplied the test is skipped and claims to succeed.
+// Overview:
+
+//-------------------------------------------------------------------------------------------
+//! @SYMTestCaseID				KBASE-t_timestamp-2706
+//! @SYMTestCaseDesc			verifying that NKern::Timestamp/FastCounter works correctly 
+//!                             accross low power modes
+//! @SYMPREQ					417-52765
+//! @SYMTestPriority			High
+//! @SYMTestActions				
+//! 1. This test harness first gets information about NKern::Timestamp or
+//!     NKern::FastCounter in particular its frequency. It also obtains
+//!     the following constants: Number of timer to run the test, number
+//!     of retries before giving up if no low power modes are detected,
+//!     and acceptable error percent. Length in nanokernel ticks of each cycle
+//! 2. Then it measures the timestamp before and after a time interval 
+//!    controlled by NTimerIntervalInS (constant is in seconds)
+//!    2.1 If in period of KTimerInterval a low power mode was entered and 
+//!        the timer underlying NKern::Timestamp had to be restated then before
+//!        and after time is stored. The cycle is considered successful.
+//! 3. If KNMaxentries occur with no successful entries the test fails
+//! 4. If any valid entry has an interval as measured with NKern::Timestamp that
+//!    is outside KNErrPercent of the same interval as measured with nanokernel 
+//!    ticks then the test fails
+//! 5. If KNValidRuns valid cycles have an acceptable error the test succeeds
+//! 
+//! @SYMTestExpectedResults 
+//!     test passed
+//-------------------------------------------------------------------------------------------
+
+#include <e32std.h>
+#include <e32base.h>
+#include <e32debug.h>
+#define __E32TEST_EXTENSION__
+#include <e32test.h>
+#include <hal.h>
+#include <u32hal.h>
+#include <e32svr.h>
+#include "d_timestamp.h"
+
+_LIT(KTimestampTestLddFileName,"D_TIMESTAMP.LDD");
+_LIT(KTimestampTestPddFileName,"D_TIMESTAMP.PDD");
+
+RTest test(_L("T_TIMESTAMP"));
+
+LOCAL_C void UnloadDrivers()
+	{
+    test.Printf(_L("Unloading LDD\n"));
+
+	TInt r=User::FreeLogicalDevice(RTimestampTest::Name());
+    test_KErrNone(r);
+    
+	TName pddName(RTimestampTest::Name());
+	_LIT(KPddWildcardExtension,".*");
+	pddName.Append(KPddWildcardExtension);
+	TFindPhysicalDevice findPD(pddName);
+	TFullName findResult;
+	r=findPD.Next(findResult);
+	while (r==KErrNone)
+		{
+        test.Printf(_L("Unloading PDD: %S\n"),&findResult);
+		r=User::FreePhysicalDevice(findResult);
+        test_KErrNone(r);
+		findPD.Find(pddName); // Reset the find handle now that we have deleted something from the container.
+		r=findPD.Next(findResult);
+		} 
+	}
+
+
+GLDEF_C TInt E32Main()
+    {
+
+    TBool dontFail = (User::CommandLineLength()!=0);
+    
+    test.Title();
+
+    test.Start(_L("Timestamp accuracy test"));
+    
+
+    TInt r;
+    TRequestStatus st;
+    
+    r = User::LoadPhysicalDevice(KTimestampTestPddFileName);
+    if (KErrNotFound == r)
+        {
+        test.Printf(_L("No timestamp pdd, test skipped\n"));
+        test.End(); // skip test if this platform does not supply a PDD
+        return 0;
+        }
+    
+
+	r=User::LoadLogicalDevice(KTimestampTestLddFileName);
+	test(r==KErrNone || r==KErrAlreadyExists);
+    
+    RTimestampTest ldd;
+    r = ldd.Open();
+    test_KErrNone(r);
+    
+    test.Next(_L("Get timestamp frequency"));
+    STimestampTestConfig info;
+    r = ldd.Config(info);
+    test_KErrNone(r);
+    
+
+    TUint retries = 0;
+    TUint validruns = 0;
+    
+    test.Next(_L("Get nanotick frequency"));
+	TInt tickPeriod = 0;
+	r = HAL::Get(HAL::ENanoTickPeriod, tickPeriod);
+    test_KErrNone(r);
+    test.Printf(_L(" tick period in uS== %d\n"), tickPeriod);
+
+    TInt ticks = info.iTimerDurationS*1000000/tickPeriod;
+    TUint64 expected = info.iTimerDurationS*info.iFreq;
+    TUint64 acceptError = info.iErrorPercent*expected/100;
+    
+    test.Printf(_L("running at %dHz for %d interations, each lasting %d seconds and with %d retries\n"),
+                info.iFreq,
+                info.iIterations,
+                info.iTimerDurationS,
+                info.iRetries
+        );
+    
+    test.Printf(_L("expecting %lu with up to %lu error\n"),expected,acceptError);
+
+    test.Next(_L("test timer interval"));
+    STimestampResult result;
+    STimestampResult* validResults = new STimestampResult[info.iIterations];
+    memset(&validResults[0],0,sizeof(validResults));
+    ldd.Start(st,ticks);
+    User::WaitForRequest(st);
+    test_KErrNone(st.Int());
+    
+    FOREVER
+        {
+        ldd.WaitOnTimer(st,result);
+        User::WaitForRequest(st);
+        test_KErrNone(st.Int());
+        TUint64 error = (result.iDelta>expected) ? result.iDelta-expected : expected - result.iDelta;
+
+        if (error < acceptError)
+            {
+            test.Printf(_L("Got %lu expected %lu, LPM Entered:%d, error %lu is OK \n"),
+                        result.iDelta,expected,result.iLPMEntered,error);
+            }
+        else 
+            {
+            test.Printf(_L("Got %lu expected %lu, LPM Entered:%d, error %lu is BAD\n"),
+                        result.iDelta,expected,result.iLPMEntered,error);
+            if (!dontFail) 
+                {
+                delete [] validResults;
+                ldd.Close();
+                UnloadDrivers();
+                test(error < acceptError);
+                }
+            }
+
+        if (result.iLPMEntered)
+            {
+            retries = 0;
+            validResults[validruns] = result;
+            if (++validruns==info.iIterations) break;
+            }
+        else
+            {
+            retries++;
+            if (retries==info.iRetries) 
+                {
+                test.Printf(_L("several retries with no power mode entry ... aborting ...\n"));
+                ldd.Close();
+                delete [] validResults;
+                UnloadDrivers();
+                test_Compare(retries,<,info.iRetries);
+                }
+            
+            }
+        }
+
+    delete [] validResults;
+    ldd.Close();
+    UnloadDrivers();
+    test.End();
+	return(0);
+    }
--- a/kerneltest/e32test/usb/t_usb_device/include/activecontrol.h	Tue Feb 02 01:24:03 2010 +0200
+++ b/kerneltest/e32test/usb/t_usb_device/include/activecontrol.h	Fri Apr 16 16:24:37 2010 +0300
@@ -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	Tue Feb 02 01:24:03 2010 +0200
+++ b/kerneltest/e32test/usb/t_usb_device/src/activecontrol.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -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	Tue Feb 02 01:24:03 2010 +0200
+++ b/kerneltest/e32test/usb/t_usb_device/src/activedevicestatenotifier.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -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/usb/t_usb_win/scripts/massstorage/bmwritelargefile.pl	Tue Feb 02 01:24:03 2010 +0200
+++ b/kerneltest/e32test/usb/t_usb_win/scripts/massstorage/bmwritelargefile.pl	Fri Apr 16 16:24:37 2010 +0300
@@ -2,7 +2,7 @@
 # Copyright (c) 2006-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"
+# under the terms of "Eclipse Public License v1.0"
 # which accompanies this distribution, and is available
 # at the URL "http://www.eclipse.org/legal/epl-v10.html".
 #
--- a/kerneltest/e32test/usb/t_usb_win/scripts/massstorage/bmwritemanyfiles.pl	Tue Feb 02 01:24:03 2010 +0200
+++ b/kerneltest/e32test/usb/t_usb_win/scripts/massstorage/bmwritemanyfiles.pl	Fri Apr 16 16:24:37 2010 +0300
@@ -2,7 +2,7 @@
 # Copyright (c) 2006-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"
+# under the terms of "Eclipse Public License v1.0"
 # which accompanies this distribution, and is available
 # at the URL "http://www.eclipse.org/legal/epl-v10.html".
 #
--- a/kerneltest/e32test/usb/t_usb_win/scripts/massstorage/createfilesanddirs.pl	Tue Feb 02 01:24:03 2010 +0200
+++ b/kerneltest/e32test/usb/t_usb_win/scripts/massstorage/createfilesanddirs.pl	Fri Apr 16 16:24:37 2010 +0300
@@ -2,7 +2,7 @@
 # Copyright (c) 2004-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"
+# under the terms of "Eclipse Public License v1.0"
 # which accompanies this distribution, and is available
 # at the URL "http://www.eclipse.org/legal/epl-v10.html".
 #
--- a/kerneltest/e32test/usb/t_usb_win/scripts/massstorage/createlargefile.pl	Tue Feb 02 01:24:03 2010 +0200
+++ b/kerneltest/e32test/usb/t_usb_win/scripts/massstorage/createlargefile.pl	Fri Apr 16 16:24:37 2010 +0300
@@ -2,7 +2,7 @@
 # Copyright (c) 2004-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"
+# under the terms of "Eclipse Public License v1.0"
 # which accompanies this distribution, and is available
 # at the URL "http://www.eclipse.org/legal/epl-v10.html".
 #
--- a/kerneltest/e32test/usbho/t_usbdi/inc/PBASE-T_USBDI-1231.h	Tue Feb 02 01:24:03 2010 +0200
+++ b/kerneltest/e32test/usbho/t_usbdi/inc/PBASE-T_USBDI-1231.h	Fri Apr 16 16:24:37 2010 +0300
@@ -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	Tue Feb 02 01:24:03 2010 +0200
+++ b/kerneltest/e32test/usbho/t_usbdi/src/PBASE-T_USBDI-1231.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -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/base_e32utils.mrp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kerneltest/e32utils/group/base_e32utils.mrp	Fri Apr 16 16:24:37 2010 +0300
@@ -1,3 +1,18 @@
+#
+# 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 "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: 
+#
 # component name "E32 Utilities"
 
 component	base_e32utils
--- a/kerneltest/e32utils/group/bld.inf	Tue Feb 02 01:24:03 2010 +0200
+++ b/kerneltest/e32utils/group/bld.inf	Fri Apr 16 16:24:37 2010 +0300
@@ -53,6 +53,9 @@
 btrace_host
 #endif
 
+//Nist statistical test suite for Secure RNG in kernel
+nistsecurerng
+
 PRJ_MMPFILES
 
 #if defined(TOOLS2)
@@ -99,7 +102,6 @@
 
 #ifndef SMP
 ../d_exc/d_exc
-../sdpartition/sdpartition
 #endif
 
 ../d_exc/minkda
@@ -115,3 +117,4 @@
 
 #endif //	!TOOLS
 
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32utils/group/nistsecurerng.mmp	Fri Apr 16 16:24:37 2010 +0300
@@ -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/e32utils/trace/btrace_analyse.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kerneltest/e32utils/trace/btrace_analyse.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -433,6 +433,7 @@
 		CASE_CAT_NAME(EProfiling);
 		CASE_CAT_NAME(ESymbianKernelSync);
 		CASE_CAT_NAME(EFlexibleMemModel);
+		CASE_CAT_NAME(EHSched);
 		CASE_CAT_NAME(ETest1);
 		CASE_CAT_NAME(ETest2);
 		default:
@@ -629,6 +630,12 @@
 			}
 		break;
 
+	case BTrace::EHSched:
+		switch((BTrace::THSched)aSubCategory)
+			{
+		CASE_CAT_NAME(ELbDone);
+			}
+		break;
 		}
 	return UnknownNames[aSubCategory];
 	}
@@ -1390,7 +1397,7 @@
 		{
 	case BTrace::ENanoThreadCreate:
 		CHECK_TRACE_DATA_WORDS(1);
-		thread = Thread::FindOrCreate(aTrace,0);
+		Thread::FindOrCreate(aTrace,0);
 		break;
 
 	case BTrace::ENanoThreadDestroy:
@@ -1430,7 +1437,7 @@
 		CHECK_TRACE_DATA_WORDS(2);
 		if(aTrace.iData[0])
 			{
-			thread = Thread::FindOrCreate(aTrace,0);
+			Thread::FindOrCreate(aTrace,0);
 			process = Process::Find(aTrace.iData[1]);
 			if(!process || (process->iNameLength && !process->IsName(aTrace.iData+2,aTrace.iDataSize-2*4)))
 				{
@@ -1450,13 +1457,13 @@
 	case BTrace::EThreadId:
 		CHECK_TRACE_DATA_WORDS(2);
 		thread = Thread::FindOrCreate(aTrace,0);
-		process = Process::FindOrCreate(aTrace,1);
+		Process::FindOrCreate(aTrace,1);
 		thread->iId = aTrace.iData[2];
 		break;
 
 	case BTrace::EProcessCreate:
 		CHECK_TRACE_DATA_WORDS(1);
-		process = Process::FindOrCreate(aTrace,0);
+		Process::FindOrCreate(aTrace,0);
 		break;
 
 	case BTrace::EProcessDestroy:
@@ -1887,7 +1894,7 @@
 
 	case BTrace::ECodeSegMapped:
 		CHECK_TRACE_DATA_WORDS(2);
-		codeseg = CodeSeg::FindOrCreate(aTrace,0);
+		CodeSeg::FindOrCreate(aTrace,0);
 		Process::FindOrCreate(aTrace,1);
 		break;
 
@@ -2535,6 +2542,22 @@
 	printf("\n");
 	}
 
+
+void PreProcessHSched(TraceRecord& aTrace)
+	{
+	switch((BTrace::THSched)aTrace.iSubCategory)
+		{
+		case BTrace::ELbDone:
+			{
+			CHECK_TRACE_DATA_WORDS(2);
+			Thread::Find(aTrace, 0);
+			break;
+			}
+		}
+	}
+
+
+
 //
 // Trace processing
 //
@@ -2724,6 +2747,8 @@
 		PreProcessProfiling(aTrace); break;
 	case BTrace::ESymbianKernelSync:
 		PreProcessSymbianKernelSync(aTrace); break;
+	case BTrace::EHSched:
+		PreProcessHSched(aTrace); break;
 	default:
 		break;
 		}
--- a/kerneltest/f32test/demandpaging/t_wdpstress.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kerneltest/f32test/demandpaging/t_wdpstress.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -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	Tue Feb 02 01:24:03 2010 +0200
+++ b/kerneltest/f32test/fileshare/handshare.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -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	Tue Feb 02 01:24:03 2010 +0200
+++ b/kerneltest/f32test/filesystem/automounter/t_automounter.mmp	Fri Apr 16 16:24:37 2010 +0300
@@ -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/filesystem/fat/b_fat32.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kerneltest/f32test/filesystem/fat/b_fat32.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -63,15 +63,16 @@
 
 const TInt KMaxFatEntries  = 2048;
 const TInt KMaxFatSize     = KMaxFatEntries * 4;
-const TInt KDirAttrReadOnly  = 0x01;
-const TInt KDirAttrHidden    = 0x02;
-const TInt KDirAttrSystem    = 0x04;
-const TInt KDirAttrVolumeId  = 0x08;
-const TInt KDirAttrDirectory = 0x10;
-const TInt KDirAttrArchive   = 0x20;
-const TInt KDirAttrLongName  = KDirAttrReadOnly | KDirAttrHidden | KDirAttrSystem | KDirAttrVolumeId;
-const TInt KDirAttrLongMask  = KDirAttrLongName | KDirAttrDirectory | KDirAttrArchive;
-const TInt KDirLastLongEntry = 0x40;
+
+const TUint KDirAttrReadOnly  = 0x01;
+const TUint KDirAttrHidden    = 0x02;
+const TUint KDirAttrSystem    = 0x04;
+const TUint KDirAttrVolumeId  = 0x08;
+const TUint KDirAttrDirectory = 0x10;
+const TUint KDirAttrArchive   = 0x20;
+const TUint KDirAttrLongName  = KDirAttrReadOnly | KDirAttrHidden | KDirAttrSystem | KDirAttrVolumeId;
+const TUint KDirAttrLongMask  = KDirAttrLongName | KDirAttrDirectory | KDirAttrArchive;
+const TUint KDirLastLongEntry = 0x40;
 
 void CreateFatEntry(const TDesC& aDir, TBool aVFatEntry, TDes *apFileName=NULL);
 
@@ -1495,7 +1496,7 @@
     }
 
 
-static  void TestMakeDir(const TDesC& aName,TInt aNewClust,TInt aParentClust)
+static  void TestMakeDir(const TDesC& aName, TUint aNewClust, TUint aParentClust)
 //
 // Test make dir
 //
@@ -1526,7 +1527,7 @@
     pE++;
     if (pE->Name()[0]!='.' || pE->Name()[1]!='.')
         Error(_L("Second entry is not '..'"),KErrNone);
-    if (pE->StartCluster() != ((aParentClust==gRootCluster)?0:aParentClust))
+    if (pE->StartCluster() != ((aParentClust==(TUint)gRootCluster)?0:aParentClust))
         Error(_L("Start cluster of .. is not parent directory"),KErrNone);
     }
 
--- a/kerneltest/f32test/filesystem/fat/t_compat32.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kerneltest/f32test/filesystem/fat/t_compat32.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -156,7 +156,7 @@
 // Replace a 8.3 filename with upper and lower case letters which is, actually out of FAT specs.
 // I.e. VFAT entries are valid, but DOS entry has a lower case symbol, which is wrong.
 //
-LOCAL_C void Test1(TNameCase aCase)
+static void Test1(TNameCase aCase)
 	{
 	test.Next(_L("Replace a file with a wrong DOS entry"));
 	QuickFormat();
@@ -190,7 +190,7 @@
 // Renaming a 8.3 filename with upper and lower case letters which is, actually out of FAT specs.
 // I.e. VFAT entries are valid, but DOS entry has a lower case symbol, which is wrong.
 //
-LOCAL_C void Test2(TNameCase aCase)
+static void Test2(TNameCase aCase)
 	{
 	test.Next(_L("Rename a file with a wrong DOS entry"));
 	QuickFormat();
@@ -520,11 +520,89 @@
 
 }
 
+//---------------------------------------------
+/**
+    Test that the created VFAT entryset corresponds to what Windows creates in the 
+    same situation
+*/
+void TestVFatEntryInterop()
+{
+    test.Next(_L("Testind VFAT entries interoperability\n"));
+    QuickFormat();
 
-GLDEF_C void CallTestsL()
-//
-// Call tests that may leave
-//
+    TInt nRes;
+    _LIT(KFName, "\\longfilename12345678");
+    
+    //-- 1. create a file with long FN that isn't multiple of 13 (max unicode characters in VFAT entry)
+    const TUint KFileSize = 24;
+    nRes = CreateEmptyFile(TheFs, KFName, KFileSize);
+    test(nRes == KErrNone);
+
+    //-- 2. verify that the dir. entries are the same what Windows creates.
+	nRes = TheDisk.Open(TheFs,CurrentDrive());
+	test(nRes == KErrNone);
+
+    //-- read 1st dir. entry from the root dir and check it.
+    //-- this is the rest of the LFN 
+    TInt64 posEntry = gBootSector.RootDirStartSector() << KDefaultSectorLog2; //-- dir entry1 position
+
+    TFatDirEntry fatEntry;
+	TPtr8 ptrEntry((TUint8*)&fatEntry, KSizeOfFatDirEntry);
+
+    nRes = TheDisk.Read(posEntry, ptrEntry);
+    test(nRes == KErrNone);
+
+    //-- the expected entry #1 contents (what Windows places there). 
+    const TUint8 KEntry1[KSizeOfFatDirEntry] = {0x42, 0x32, 0x00, 0x33, 0x00, 0x34, 0x00, 0x35, 0x00, 0x36, 0x00, 0x0F, 0x00, 0xF7, 0x37, 0x00,
+                                                0x38, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF };
+
+    nRes = Mem::Compare(fatEntry.iData, KSizeOfFatDirEntry, KEntry1, KSizeOfFatDirEntry);
+    test(nRes == KErrNone);
+
+    //-- read 2nd dir. entry from the root dir and check it.
+    //-- this is the beginning of the LFN 
+
+    posEntry += KSizeOfFatDirEntry;
+    nRes = TheDisk.Read(posEntry, ptrEntry);
+    test(nRes == KErrNone);
+
+    //-- the expected entry #2 contents (what Windows places there). 
+    const TUint8 KEntry2[KSizeOfFatDirEntry] = { 0x01, 0x6C, 0x00, 0x6F, 0x00, 0x6E, 0x00, 0x67, 0x00, 0x66, 0x00, 0x0F, 0x00, 0xF7, 0x69, 0x00,
+                                                 0x6C, 0x00, 0x65, 0x00, 0x6E, 0x00, 0x61, 0x00, 0x6D, 0x00, 0x00, 0x00, 0x65, 0x00, 0x31, 0x00 };
+
+    nRes = Mem::Compare(fatEntry.iData, KSizeOfFatDirEntry, KEntry2, KSizeOfFatDirEntry);
+    test(nRes == KErrNone);
+
+    //-- read the last, 3rd entry from the root dir and check it.
+    //-- this is the DOS entry
+
+    posEntry += KSizeOfFatDirEntry;
+    nRes = TheDisk.Read(posEntry, ptrEntry);
+    test(nRes == KErrNone);
+
+    //-- first 13 bytes of DOS entry SFN, attributes and DIR_NTRes field
+    const TUint8 KEntry3[13] = {'L','O','N','G','F','I','~','1',' ',' ',' ', 0x20, 0x00 };
+    nRes = Mem::Compare(fatEntry.iData, 13, KEntry3, 13);
+    test(nRes == KErrNone);
+
+    //-- skip file time stamps, they are not consistent
+
+    //-- test file size and start cluster of the file
+    test(fatEntry.StartCluster() != gBootSector.RootClusterNum() && fatEntry.StartCluster() != 0);
+    test(fatEntry.Size() == KFileSize);
+
+    //-- goto the next entry, this must be the end of directory
+    posEntry += KSizeOfFatDirEntry;
+    nRes = TheDisk.Read(posEntry, ptrEntry);
+    test(nRes == KErrNone);
+    test(fatEntry.IsEndOfDirectory());
+
+    TheDisk.Close();
+
+}
+
+
+void CallTestsL()
 	{
 
 	TInt drvNum;
@@ -546,6 +624,8 @@
 
 	GetBootInfo();
 
+    TestVFatEntryInterop();
+
 	Test1(EUpper); // Test directory entries with 8.3 uppercase (no VFAT entries expected)
 	Test1(ELower); // Test directory entries with 8.3 lowercase (   VFAT entries expected)
 	Test1(EMixed); // Test directory entries with 8.3 mixed     (   VFAT entries expected)
@@ -559,7 +639,6 @@
 	TestPDEF116912();
 
     TestReplaceByShortName();
-
 	}
 
 
--- a/kerneltest/f32test/filesystem/fat/t_scn32dr1.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kerneltest/f32test/filesystem/fat/t_scn32dr1.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -597,7 +597,7 @@
             RDebug::Print(_L("%5d: ------------- end of directory"), aNum);
         return EFalse;
         }
-    else if ((d->Attributes() & KDirAttrLongMask) == KDirAttrLongName)
+    else if (((TInt)d->Attributes() & KDirAttrLongMask) == KDirAttrLongName)
         {
         TBuf16<15> name;
         ExtractNameString(name, aEntry);
@@ -795,7 +795,7 @@
     TheRawDisk.Close();
     RDebug::Print(_L("Cluster %d @ 0x%08X:"), aCluster, ClusterToByte(aCluster));
     TFatDirEntry* d = (TFatDirEntry*)ptr.Ptr() + aEntry;
-    while ((d->Attributes() & KDirAttrLongMask) == KDirAttrLongName && aEntry < gEntriesPerCluster)
+    while (((TInt)d->Attributes() & KDirAttrLongMask) == KDirAttrLongName && aEntry < gEntriesPerCluster)
         {
         if (d->IsErased() || d->IsEndOfDirectory())
             break;
@@ -807,7 +807,7 @@
         start = -1;
     else if (d->IsEndOfDirectory())
         start = -1;
-    else if ((d->Attributes() & KDirAttrLongMask) == KDirAttrLongName)
+    else if (((TInt)d->Attributes() & KDirAttrLongMask) == KDirAttrLongName)
         start = -1;
     else if (!IsValidDirEntry(d))
         start = -1;
--- a/kerneltest/f32test/filesystem/fat/t_tscan32.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kerneltest/f32test/filesystem/fat/t_tscan32.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -563,7 +563,7 @@
 		}
 	else if (d->IsEndOfDirectory())
 		return EFalse;
-	else if ((d->Attributes() & KDirAttrLongMask) == KDirAttrLongName)
+	else if (((TInt)d->Attributes() & KDirAttrLongMask) == KDirAttrLongName)
 		{
 		TBuf16<15> name;
 		ExtractNameString(name, aEntry);
--- a/kerneltest/f32test/fileutils/inc/fat_utils.h	Tue Feb 02 01:24:03 2010 +0200
+++ b/kerneltest/f32test/fileutils/inc/fat_utils.h	Fri Apr 16 16:24:37 2010 +0300
@@ -77,22 +77,22 @@
 
 
 //-----------------------------------------------------------------------------
-const TInt KFatFirstSearchCluser    =2;     ///< FAT usable clusters start from 2; FAT[0] and FAT[1] are reserved
+const TUint KFatFirstSearchCluser   =2;     ///< FAT usable clusters start from 2; FAT[0] and FAT[1] are reserved
 const TInt KFatDirNameSize			=11;    ///< Dos directory/File name length
-const TInt KFatDirReserved1Size		=8;     ///< Size of reserved area one in a directory enrty
+const TUint KFatDirReserved1Size	=8;     ///< Size of reserved area one in a directory enrty
 const TInt KVolumeLabelSize			=11;    ///< Volume lable size
 const TInt KFileSysTypeSize			=8;     ///< File system type parameter size
 const TInt KVendorIdSize			=8;     ///< Vendor ID parameter size
-const TInt KVFatEntryAttribute		=0x0F;  ///< VFat entry attribute setting
-const TInt KBootSectorSignature		=0xAA55;///< File system Boot sector signiture
+const TUint KVFatEntryAttribute		=0x0F;  ///< VFat entry attribute setting
+const TUint KBootSectorSignature	=0xAA55;///< File system Boot sector signiture
 const TUint8 KDotEntryByte			=0x2e;  ///< Dot value for self and parent pointer directory entries
 const TUint8 KBlankSpace			=0x20;  ///< Blank space in a directory entry
-const TInt KSizeOfFatDirEntry		=32;    ///< Size in bytes of a Fat directry entry 
-const TInt KSizeOfFatDirEntryLog2	=5;     ///< Log2 of size in bytes of a Fat directry entry 
-const TInt KFat16VolumeLabelPos 	=43;    ///< Position of volume lable in BPB for Fat12/16
-const TInt KFat32VolumeLabelPos		=71;    ///< Position of volume lable in BPB for Fat32
-const TInt KReservedIdOldEntry		=1;	    ///< used for TFatDirEntry::SetReserved2(..)
-const TInt KReservedIdNewEntry		=0;
+const TUint  KSizeOfFatDirEntry		=32;    ///< Size in bytes of a Fat directry entry 
+const TUint  KSizeOfFatDirEntryLog2	=5;     ///< Log2 of size in bytes of a Fat directry entry 
+const TUint  KFat16VolumeLabelPos 	=43;    ///< Position of volume lable in BPB for Fat12/16
+const TUint  KFat32VolumeLabelPos	=71;    ///< Position of volume lable in BPB for Fat32
+const TUint  KReservedIdOldEntry	=1;	    ///< used for TFatDirEntry::SetReserved2(..)
+const TUint  KReservedIdNewEntry	=0;
 const TInt KSizeOfFatBootSector     =90;    ///< Size in bytes of Boot sector parameter block (BPB) 
 
 const TUint32 KBootSectorNum        =0;     ///< Main Boot Sector number (always 0)
@@ -325,9 +325,9 @@
     void InitZ();
 
     const TPtrC8 Name() const;
-    TInt Attributes() const;
+    TUint Attributes() const;
     TTime Time() const;
-    TInt StartCluster() const;
+    TUint32 StartCluster() const;
     TUint32 Size() const;
     TBool IsErased() const;
     TBool IsCurrentDirectory() const;
@@ -335,10 +335,10 @@
     TBool IsEndOfDirectory() const;
     TBool IsGarbage() const;
     void SetName(const TDesC8& aDes);
-    void SetAttributes(TInt anAtt);
+    void SetAttributes(TUint anAtt);
     void SetTime(TTime aTime);
     void SetCreateTime(TTime aTime);
-    void SetStartCluster(TInt aStartCluster);
+    void SetStartCluster(TUint32 aStartCluster);
     void SetSize(TUint32 aFilesize);
     void SetErased();
     void SetCurrentDirectory();
--- a/kerneltest/f32test/fileutils/src/fat_utils.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kerneltest/f32test/fileutils/src/fat_utils.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -1149,7 +1149,7 @@
 	{return TPtrC8((TUint8*)&(pDir->iName),KFatDirNameSize);}
 
 /** @return The attributes for the Directory entry */
-TInt TFatDirEntry::Attributes() const
+TUint TFatDirEntry::Attributes() const
 	{return pDir->iAttributes;}
 
 /** @return Time of file creation */
@@ -1157,7 +1157,7 @@
 	{return DosTimeToTTime(pDir->iTime,pDir->iDate);}
 
 /** @return The Start cluster for the file or directory for this entry  */
-TInt TFatDirEntry::StartCluster() const		
+TUint32 TFatDirEntry::StartCluster() const		
 	{
     const TUint16 KStClustMaskHi = 0x0FFF;	
     return ((pDir->iStartClusterHi&KStClustMaskHi)<<16) | pDir->iStartClusterLo;
@@ -1198,7 +1198,7 @@
 Set the file or directory attributes for this entry 
 @param anAtts The file or directory attributes
 */
-void TFatDirEntry::SetAttributes(TInt anAtts)
+void TFatDirEntry::SetAttributes(TUint anAtts)
 	{
 	ASSERT(!(anAtts&~KMaxTUint8));
 	pDir->iAttributes=(TUint8)anAtts;
@@ -1224,7 +1224,7 @@
 Set the start cluster number of the file or directory refered to by the entry
 @param aStartCluster The start cluster number
 */
-void TFatDirEntry::SetStartCluster(TInt aStartCluster)
+void TFatDirEntry::SetStartCluster(TUint32 aStartCluster)
 	{
 	const TUint32 KHalfWordMask	= 0x0000FFFF;
     pDir->iStartClusterLo=(TUint16)(aStartCluster & KHalfWordMask);
--- a/kerneltest/f32test/group/b_gen.mmp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kerneltest/f32test/group/b_gen.mmp	Fri Apr 16 16:24:37 2010 +0300
@@ -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/group/base_f32test.mrp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kerneltest/f32test/group/base_f32test.mrp	Fri Apr 16 16:24:37 2010 +0300
@@ -1,3 +1,18 @@
+#
+# 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 "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: 
+#
 # component name "File Server Tests"
 
 component	base_f32test
--- a/kerneltest/f32test/loader/base_loader.mrp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kerneltest/f32test/loader/base_loader.mrp	Fri Apr 16 16:24:37 2010 +0300
@@ -1,1 +1,16 @@
+#
+# 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 "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: 
+#
 # dummy MRP so that the tools put the build output directory in a place consistant with other components
--- a/kerneltest/f32test/locl/localeutils/elocl32_japan/src/t_tlocl32_lat1.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kerneltest/f32test/locl/localeutils/elocl32_japan/src/t_tlocl32_lat1.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -2,7 +2,7 @@
 * Copyright (c) 1995-1999 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"
+* under the terms of "Eclipse Public License v1.0"
 * which accompanies this distribution, and is available
 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
 *
--- a/kerneltest/f32test/server/b_gen.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kerneltest/f32test/server/b_gen.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -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).
@@ -34,70 +32,42 @@
 #define MINIMUM_DATE (315532800L)
 #define DateTests   10
 
-// 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];
-
-
-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;
+TBuf<0x100> gNameBuf;
+TBuf<0x100> gNameOut;
+RFile gFile;
+RFile gFileErr;
+RFile gFile2;
+RDir gDir;
+RFormat gFormat;
+TFileName fBuf;
+TInt gDriveNum = -1;
 
 
-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;
-//LOCAL_D TInt NoFileSystemErr=KErrNotReady;
-//LOCAL_D TInt NotSupportedErr=KErrNotSupported;
-LOCAL_D 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;
-//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;
-
-LOCAL_C TInt P_FUPDATE=EFileWrite;
+static TBuf8<0x4000> gDataBuf;
+static TEntry gFileEntry;
+static TVolumeInfo volInfo;
+static TFileName pathBuf;
 
 
-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 +93,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 +118,7 @@
 	}
 
 
-LOCAL_C void testDir(const TDesC& aDirName)
+static void testDir(const TDesC& aDirName)
 //
 // Create a directory
 //
@@ -173,7 +143,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 +163,7 @@
     }
 */
 
-LOCAL_C void testDeviceInfo(const TDesC& aDeviceName,TInt anErr)
+static void testDeviceInfo(const TDesC& aDeviceName,TInt anErr)
 //
 // Test p_dinfo.
 //
@@ -218,7 +188,7 @@
 		}
     }
 
-LOCAL_C void testFileInfo(const TDesC& aFileName,TInt anErr)
+static void testFileInfo(const TDesC& aFileName,TInt anErr)
 //
 // Test entry info
 //
@@ -232,14 +202,14 @@
 		{
 		if (aFileName.Length()>=2 && aFileName[0]=='Z' && aFileName[1]==':')
 			{
-			if ((gFileEntry.iAtt&(P_FAREAD|P_FAEXEC|P_FASTREAM)) != (TUint32)(P_FAREAD|P_FAEXEC|P_FASTREAM) && gFileEntry.iAtt!=KEntryAttDir)
+			if ((gFileEntry.iAtt&(KEntryAttReadOnly|EFileStream)) != (TUint32)(KEntryAttReadOnly|EFileStream) && gFileEntry.iAtt!=KEntryAttDir)
 				Error(_L("Info status check Z:\\"),0);
 			}
 		else
 			{
 			if (gFileEntry.iAtt&KEntryAttDir)
 				return; // Found directory entry
-			if (gFileEntry.iAtt!=(TUint32)(P_FASTREAM|P_FAMOD))
+			if (gFileEntry.iAtt!=(TUint32)(EFileStream|KEntryAttArchive))
 				Error(_L("Info status check"),0);
 			if (gFileEntry.iSize!=0L)
 				Error(_L("Info size check"),0);
@@ -247,7 +217,7 @@
 		}
 	}
 
-LOCAL_C void testRenameFromRoot(const TDesC& aRName,const TDesC& aDName)
+static void testRenameFromRoot(const TDesC& aRName,const TDesC& aDName)
 //
 //
 //
@@ -259,11 +229,11 @@
 	if ((c=gFile.Open(TheFs,aDName,EFileStream))!=KErrNone)
 		Error(_L("Open 92"),c);
 	gFile.Close();
-	if ((c=TheFs.Delete(aRName))!=NotExistsErr)
+	if ((c=TheFs.Delete(aRName))!=KErrNotFound)
 		Error(_L("Delete 92"),c);
 	}
 
-LOCAL_C void testRenameToRoot(const TDesC& pName,const TDesC& rName)
+static void testRenameToRoot(const TDesC& pName,const TDesC& rName)
 //
 //
 //
@@ -278,11 +248,11 @@
 	if ((c=gFile.Open(TheFs,rName,EFileStream))!=KErrNone)
 		Error(_L("Open 91"),c);
 	gFile.Close();
-	if ((c=TheFs.Delete(pName))!=NotExistsErr)
+	if ((c=TheFs.Delete(pName))!=KErrNotFound)
 		Error(_L("Delete 91"),c);
 	}
 
-LOCAL_C void verifyTestPat1()
+static void verifyTestPat1()
 //
 //
 //
@@ -320,7 +290,7 @@
 	test(err == KErrNone);
 	}
 	
-LOCAL_C void testRename()
+static void testRename()
 //
 // Test TheFs.Rename function.
 //
@@ -332,7 +302,7 @@
 	test.Printf(_L("Test TheFs.Rename\n"));
 
 	test.Printf(_L("Test rename into root\n"));
-	if ((c=gFile.Replace(TheFs,_L("\\TESTPAT1.DAT"),EFileStream|P_FUPDATE))!=KErrNone)
+	if ((c=gFile.Replace(TheFs,_L("\\TESTPAT1.DAT"),EFileStream|EFileWrite))!=KErrNone)
 		Error(_L("Create testpat1"),c);
 	gDataBuf.Fill('X',512);
 	if ((c=gFile.Write(gDataBuf,512))!=KErrNone)
@@ -369,28 +339,28 @@
 		Error(_L("Delete 80"),c);
 
 	test.Printf(_L("Test rename with wild cards\n"));
-	if ((c=TheFs.Rename(_L("*.*"),_L("FRED")))!=NameErr)
+	if ((c=TheFs.Rename(_L("*.*"),_L("FRED")))!=KErrBadName)
 		Error(_L("Rename 100"),c);
-	if ((c=TheFs.Rename(_L("?"),_L("FRED")))!=NameErr)
+	if ((c=TheFs.Rename(_L("?"),_L("FRED")))!=KErrBadName)
 		Error(_L("Rename 101"),c);
-	if ((c=TheFs.Rename(_L(""),_L("FRED")))!=KErrBadName) // NameErr)
+	if ((c=TheFs.Rename(_L(""),_L("FRED")))!=KErrBadName) // KErrBadName)
 		Error(_L("Rename 101.11"),c);
-	if ((c=TheFs.Rename(_L("."),_L("FRED")))!=NameErr)
+	if ((c=TheFs.Rename(_L("."),_L("FRED")))!=KErrBadName)
 		Error(_L("Rename 101.12"),c);
-	if ((c=TheFs.Rename(_L("NOEXIST"),_L("*")))!=NameErr)
+	if ((c=TheFs.Rename(_L("NOEXIST"),_L("*")))!=KErrBadName)
 		Error(_L("Rename 101.1"),c);
 	if ((c=gFile.Create(TheFs,_L("FILE1"),EFileStream))!=KErrNone)
 		Error(_L("Create 101.2"),c);
 	gFile.Close();
-	if ((c=TheFs.Rename(_L("FILE1"),_L("AAA?")))!=NameErr)
+	if ((c=TheFs.Rename(_L("FILE1"),_L("AAA?")))!=KErrBadName)
 		Error(_L("Rename 101.3"),c);
-	if ((c=TheFs.Rename(_L("FILE1"),_L("")))!=KErrBadName) // NameErr)
+	if ((c=TheFs.Rename(_L("FILE1"),_L("")))!=KErrBadName) // KErrBadName)
 		Error(_L("Rename 101.41"),c);
-	if ((c=TheFs.Rename(_L(""),_L("")))!=KErrBadName) // NameErr)
+	if ((c=TheFs.Rename(_L(""),_L("")))!=KErrBadName) // KErrBadName)
 		Error(_L("Rename 101.42"),c);
 	if ((c=TheFs.Delete(_L("FILE1")))!=KErrNone)
 		Error(_L("Delete 101.5"),c);
-	if ((c=TheFs.Rename(_L("\\"),_L("FRED")))!=NameErr)
+	if ((c=TheFs.Rename(_L("\\"),_L("FRED")))!=KErrBadName)
 		Error(_L("Rename 101.6"),c);
 
 	test.Printf(_L("Test rename of directories\n"));
@@ -400,7 +370,7 @@
 		Error(_L("Rename 103.1"),c);
 	if ((c=TheFs.Rename(_L("\\A2345678.123"),_L("\\DIR2")))!=KErrNone)
 		Error(_L("Rename 103.2"),c);
-	if ((c=TheFs.Rename(_L("\\DIR2"),_L("\\A234567.1234")))!=KErrNone) // ****** NameErr) Long filenames are supported
+	if ((c=TheFs.Rename(_L("\\DIR2"),_L("\\A234567.1234")))!=KErrNone) // ****** KErrBadName) Long filenames are supported
 		Error(_L("Rename 103.3"),c);
 	if ((c=TheFs.Rename(_L("\\A234567.1234"),_L("\\DIR2")))!=KErrNone)
 		Error(_L("Rename 103.3"),c);
@@ -410,18 +380,18 @@
 	test.Printf(_L("Test rename of open files\n"));
 	if ((c=gFile.Create(TheFs,_L("\\DIR1\\FILE1"),EFileStreamText))!=KErrNone)
 		Error(_L("Create 105"),c);
-	if ((c=TheFs.Rename(_L("\\DIR1\\FILE1"),_L("\\DIR1\\FILE1")))!=LockedErr)
+	if ((c=TheFs.Rename(_L("\\DIR1\\FILE1"),_L("\\DIR1\\FILE1")))!=KErrInUse)
 		Error(_L("Rename 106"),c);
-	if ((c=TheFs.Rename(_L("\\DIR1\\FILE1"),_L("\\DIR2\\FILE1")))!=LockedErr)
+	if ((c=TheFs.Rename(_L("\\DIR1\\FILE1"),_L("\\DIR2\\FILE1")))!=KErrInUse)
 		Error(_L("Rename 106.1"),c);
-	if ((c=gFile2.Open(TheFs,_L("\\DIR2\\FILE1"),EFileStream))!=NotExistsErr)
+	if ((c=gFile2.Open(TheFs,_L("\\DIR2\\FILE1"),EFileStream))!=KErrNotFound)
 		Error(_L("Create 105"),c);
 	gFile.Close();
 
 	test.Printf(_L("Test rename to same name\n"));
-	if ((c=TheFs.Rename(_L("\\DIR1\\FILE1"),_L("\\DIR1\\FILE1")))!=KErrNone) // !=ExistsErr)
+	if ((c=TheFs.Rename(_L("\\DIR1\\FILE1"),_L("\\DIR1\\FILE1")))!=KErrNone) // !=KErrAlreadyExists)
 		Error(_L("Rename 105.1"),c);
-	if ((c=TheFs.Rename(_L("\\DIR1"),_L("\\DIR1")))!=KErrNone) // !=ExistsErr)
+	if ((c=TheFs.Rename(_L("\\DIR1"),_L("\\DIR1")))!=KErrNone) // !=KErrAlreadyExists)
 		Error(_L("Rename 105.2"),c);
 
 	test.Printf(_L("Test rename of read-only files\n"));     // IS ALLOWED //
@@ -430,15 +400,15 @@
 	if ((c=TheFs.Entry(_L("\\DIR1\\FILE1"),gFileEntry))!=KErrNone)
 		Error(_L("File info 106.1"),c);
 	test.Printf(_L("STATUS=%04x\n"),gFileEntry.iAtt);
-	if (gFileEntry.iAtt!=(TUint32)(P_FAREAD|P_FASTREAM|P_FAMOD))
+	if (gFileEntry.iAtt!=(TUint32)(KEntryAttReadOnly|EFileStream|KEntryAttArchive))
 		Error(_L("Status check 106.2"),0);
 	if ((c=TheFs.Entry(_L("\\DIR1"),gFileEntry))!=KErrNone)
 		Error(_L("File info 106.3"),c);
 	test.Printf(_L("STATUS=%04x\n"),gFileEntry.iAtt);
-	if (gFileEntry.iAtt!=(TUint32)(P_FASTREAM|P_FADIR))
+	if (gFileEntry.iAtt!=(TUint32)(EFileStream|KEntryAttDir))
 		Error(_L("Status check 106.4"),0);
 
-	if ((c=TheFs.Rename(_L("\\DIR1\\FILE1"),_L("\\DIR1\\FILE1")))!=KErrNone) // !=ExistsErr)
+	if ((c=TheFs.Rename(_L("\\DIR1\\FILE1"),_L("\\DIR1\\FILE1")))!=KErrNone) // !=KErrAlreadyExists)
 		Error(_L("Rename 107"),c);
 	if ((c=TheFs.Rename(_L("\\DIR1\\FILE1"),_L("\\DIR1\\FILE2")))!=KErrNone)
 		Error(_L("Rename 108"),c);
@@ -460,9 +430,9 @@
 	gFile.Close();
 
 	test.Printf(_L("Test rename of directories across directories\n"));
-	if ((c=TheFs.Rename(_L("\\DIR1"),_L("\\DIR2\\DIR1")))!=KErrNone) // ******** AccessErr)
+	if ((c=TheFs.Rename(_L("\\DIR1"),_L("\\DIR2\\DIR1")))!=KErrNone) // ******** KErrAccessDenied)
 		Error(_L("Rename 114"),c);
-	if ((c=TheFs.Rename(_L("\\DIR1"),_L("\\")))!=NameErr)
+	if ((c=TheFs.Rename(_L("\\DIR1"),_L("\\")))!=KErrBadName)
 		Error(_L("Rename 114.1"),c);
 
 	if ((c=TheFs.Delete(_L("\\DIR2\\FILE1")))!=KErrNone)
@@ -475,7 +445,7 @@
 	TestINC103141();  // PDEF104017
 	}    
 
-LOCAL_C void testDelete()
+static void testDelete()
 //
 // Test RFs::Delete function.
 //
@@ -488,11 +458,11 @@
 		Error(_L("Make dir 500"),c);
 	if ((c=gFile.Create(TheFs,_L("\\TESTDIR\\NAME.EXT"),EFileStream))!=KErrNone)
 		Error(_L("Create"),c);
-	if ((c=TheFs.Delete(_L("\\TESTDIR\\")))!=KErrBadName) // ******* AccessErr)
+	if ((c=TheFs.Delete(_L("\\TESTDIR\\")))!=KErrBadName) // ******* KErrAccessDenied)
 		Error(_L("Delete 501"),c);
 
 	test.Printf(_L("Test delete open file\n"));
-	if ((c=TheFs.Delete(_L("\\TESTDIR\\NAME.EXT")))!=LockedErr)
+	if ((c=TheFs.Delete(_L("\\TESTDIR\\NAME.EXT")))!=KErrInUse)
 		Error(_L("Delete 502"),c);
 	gFile.Close();
 	if ((c=TheFs.Delete(_L("\\TESTDIR\\NAME.EXT")))!=KErrNone)
@@ -501,7 +471,7 @@
 		Error(_L("Delete 504"),c);
 	}
 
-LOCAL_C void testUnique(TUint fileFormat)
+static void testUnique(TUint fileFormat)
 //
 // Test RFile::Temp
 //
@@ -525,7 +495,7 @@
 		Error(_L("Delete"),c);
 	}
 
-LOCAL_C void testFileName(const TDesC& aFileName,TInt res)
+static void testFileName(const TDesC& aFileName,TInt res)
 //
 //
 //
@@ -556,8 +526,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 +534,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 +573,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)
 //
 //
 //
@@ -633,7 +601,7 @@
             if ((c=gDir.Open(TheFs,buf,KEntryAttMaskSupported))!=KErrNone)
                 Error2(_L("Directory open 1"),c, line);
             gDataBuf[0]=0;
-            if ((c=gDir.Read(gFileEntry))!=EofErr)
+            if ((c=gDir.Read(gFileEntry))!=KErrEof)
             	{
                 test.Printf(_L("buf=\"%S\"\n"),&gFileEntry.iName);
                 Error2(_L("Directory read"),c, line);
@@ -663,8 +631,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 +642,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 +681,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;
@@ -743,15 +725,15 @@
 	testDir(_L("Z:\\*.*"));
 
 	test.Printf(_L("Test names containing '\\'\n"));
-	if ((c=gFile.Create(TheFs,_L("Q\\ZZZ"),EFileWrite))!=NameErr)
+	if ((c=gFile.Create(TheFs,_L("Q\\ZZZ"),EFileWrite))!=KErrBadName)
 		Error(_L("Create 1"),c);
 
 	test.Printf(_L("Test create in non-exist directory\n"));
-	if ((c=gFile.Create(TheFs,_L("\\Q1DDX\\ZZZ"),EFileWrite))!=DirErr)
+	if ((c=gFile.Create(TheFs,_L("\\Q1DDX\\ZZZ"),EFileWrite))!=KErrPathNotFound)
 		Error(_L("Create 2"),c);
 
 	test.Printf(_L("Test filenames starting with '.'\n"));
-	if ((c=gFile.Create(TheFs,_L("\\.ZZZ"),EFileWrite))!=KErrNone) // ****** NameErr)
+	if ((c=gFile.Create(TheFs,_L("\\.ZZZ"),EFileWrite))!=KErrNone) // ****** KErrBadName)
 		Error(_L("Create 3"),c);
 	gFile.Close();
 	if ((c=TheFs.Delete(_L("\\.ZZZ")))!=KErrNone)
@@ -819,18 +801,18 @@
 	testDelete();
 	testRename();
 	test.Printf(_L("Test get file info\n"));
-//	testFileInfo(_L("*.*"),NameErr); ********** Allowed (?)
-	testFileInfo(_L(""),KErrNone); // NameErr);
-	testFileInfo(_L("\\"),NameErr);
-	testFileInfo(_L("."),NameErr);
-	testFileInfo(_L(".."),NameErr);
-	testFileInfo(_L("a.1234"),KErrNotFound); // ********* NameErr);
-	testFileInfo(_L("a23456789"),KErrNotFound); // ********* NameErr);
-	testFileInfo(_L(".a"),KErrNotFound); // ********** NameErr);
-	testFileInfo(_L("?"),NameErr);
-	testFileInfo(_L("NOEXIST"),NotExistsErr);
-	testFileInfo(_L("\\NODIR\\NAME"),DirErr);
-	testFileInfo(_L("L:\\NAME"),DeviceErr);
+//	testFileInfo(_L("*.*"),KErrBadName); ********** Allowed (?)
+	testFileInfo(_L(""),KErrNone); // KErrBadName);
+	testFileInfo(_L("\\"),KErrBadName);
+	testFileInfo(_L("."),KErrBadName);
+	testFileInfo(_L(".."),KErrBadName);
+	testFileInfo(_L("a.1234"),KErrNotFound); // ********* KErrBadName);
+	testFileInfo(_L("a23456789"),KErrNotFound); // ********* KErrBadName);
+	testFileInfo(_L(".a"),KErrNotFound); // ********** KErrBadName);
+	testFileInfo(_L("?"),KErrBadName);
+	testFileInfo(_L("NOEXIST"),KErrNotFound);
+	testFileInfo(_L("\\NODIR\\NAME"),KErrPathNotFound);
+	testFileInfo(_L("L:\\NAME"),KErrNotReady);
 	gNameBuf.SetLength(0);
 	if ((c=gFile.Temp(TheFs,gNameBuf,gNameOut,EFileStream))!=KErrNone)
 		Error(_L("Open 1.1"),c);
@@ -842,7 +824,7 @@
 
 	test.Printf(_L("Test get device info\n"));
 	testDeviceInfo(_L(""),FALSE);           // NULL is current device //
-	testDeviceInfo(_L("L:"),DeviceErr);
+	testDeviceInfo(_L("L:"),KErrNotReady);
 	testDeviceInfo(_L("Z:"),FALSE);
 	testDeviceInfo(fBuf,FALSE);
 	
@@ -865,88 +847,88 @@
 //	testNodeInfo(_L("...::"),0,E_GEN_FSYS);
 
 //	testFileInfo(_L("Z:SYS$WSRV.IMG"),FALSE);
-//	testFileInfo(_L("Z:\\SYS$WSRV.IMG"),NameErr);    // \ not allowed  - no path //
+//	testFileInfo(_L("Z:\\SYS$WSRV.IMG"),KErrBadName);    // \ not allowed  - no path //
 //	testFileInfo(_L("Z:*"),FALSE);               // Z: allows *'s ! //
-//	testFileInfo(_L("Z:SYS$WSRV."),NotExistsErr);
+//	testFileInfo(_L("Z:SYS$WSRV."),KErrNotFound);
 //	testFileInfo(_L("XXX::"),NoFileSystemErr);
 	if(PlatSec::ConfigSetting(PlatSec::EPlatSecEnforceSysBin))
 		testFileInfo(_L("Z:\\Sys\\Bin\\ESHELL.EXE"),FALSE);    // we now have paths //
 	else
 		testFileInfo(_L("Z:\\System\\Bin\\ESHELL.EXE"),FALSE);    // we now have paths //
 //	testFileInfo(_L("Z:*"),KErrPathNotFound); // session path gets inserted ,FALSE);
-//	testFileInfo(_L("Z:SYS$WSRV."),NotExistsErr);
+//	testFileInfo(_L("Z:SYS$WSRV."),KErrNotFound);
 //	testFileInfo(_L("H:"),KErrBadName); // ************** NoFileSystemErr);
 
 	test.Printf(_L("Test weird filenames\n"));
 // Test SPACES // 
 
-	testFileName(_L("A B"),KErrNone); // ******* NameErr);
-	testFileName(_L(" AB"),KErrNone); // ******* NameErr);
-	testFileName(_L(" AB      "),KErrNone); // ******* NameErr);
+	testFileName(_L("A B"),KErrNone); // ******* KErrBadName);
+	testFileName(_L(" AB"),KErrNone); // ******* KErrBadName);
+	testFileName(_L(" AB      "),KErrNone); // ******* KErrBadName);
 	testFileName(_L("    AB"),KErrNone);
 	testFileName(_L(" AB  . cdef"),KErrNone);
 	testFileName(_L(" AB  .  cdef  "),KErrNone);
-	testFileName(_L("A2345678 "),KErrNone); // ******* NameErr);
-	testFileName(_L("A2345678.XY "),KErrNone); // ******* NameErr);
-	testFileName(_L("A2345678.XYZ "),KErrNone); // ******* NameErr);
-	testFileName(_L("A2345678 XYZ"),KErrNone); // ******* NameErr);
-	testFileName(_L(" "),NameErr);
-	testFileName(_L("\\A B\\NAME"),KErrPathNotFound); // ******* NameErr);
-	testFileName(_L("\\ \\NAME"),NameErr);
-	testFileName(_L("\\asdf\\qer\\   \\asdf\\NAME"),NameErr);
-	testFileName(_L("     "),NameErr);
-	testFileName(_L("C:\\asdf\\     "),NameErr);
+	testFileName(_L("A2345678 "),KErrNone); // ******* KErrBadName);
+	testFileName(_L("A2345678.XY "),KErrNone); // ******* KErrBadName);
+	testFileName(_L("A2345678.XYZ "),KErrNone); // ******* KErrBadName);
+	testFileName(_L("A2345678 XYZ"),KErrNone); // ******* KErrBadName);
+	testFileName(_L(" "),KErrBadName);
+	testFileName(_L("\\A B\\NAME"),KErrPathNotFound); // ******* KErrBadName);
+	testFileName(_L("\\ \\NAME"),KErrBadName);
+	testFileName(_L("\\asdf\\qer\\   \\asdf\\NAME"),KErrBadName);
+	testFileName(_L("     "),KErrBadName);
+	testFileName(_L("C:\\asdf\\     "),KErrBadName);
 // Test short names //
-	testFileName(_L(""),NameErr);
-	testFileName(_L("\\"),NameErr);
+	testFileName(_L(""),KErrBadName);
+	testFileName(_L("\\"),KErrBadName);
 	testFileName(_L("1"),FALSE);
-	testFileName(_L(".1"),KErrNone); // ******* NameErr);
-	testFileName(_L(".1"),KErrNone); // ******* NameErr);
-	testFileName(_L("\\.1"),KErrNone); // ******* NameErr);
+	testFileName(_L(".1"),KErrNone); // ******* KErrBadName);
+	testFileName(_L(".1"),KErrNone); // ******* KErrBadName);
+	testFileName(_L("\\.1"),KErrNone); // ******* KErrBadName);
 	testFileName(_L("1.1"),FALSE);
 // Test long names //
 	testFileName(_L("12345678.123"),FALSE);
-	testFileName(_L("123456789.123"),KErrNone); // ******* NameErr);
-	testFileName(_L("12345678.1234"),KErrNone); // ******* NameErr);
-	testFileName(_L("1.1234"),KErrNone); // ******* NameErr);
-	testFileName(_L("123456789"),KErrNone); // ******* NameErr);
+	testFileName(_L("123456789.123"),KErrNone); // ******* KErrBadName);
+	testFileName(_L("12345678.1234"),KErrNone); // ******* KErrBadName);
+	testFileName(_L("1.1234"),KErrNone); // ******* KErrBadName);
+	testFileName(_L("123456789"),KErrNone); // ******* KErrBadName);
 	gDataBuf.SetLength(256);
 	gDataBuf.Fill('A',255);
-	testFileName(gDataBuf,NameErr);
+	testFileName(gDataBuf,KErrBadName);
 	gDataBuf.SetLength(257);
 	gDataBuf.Fill('B',256);
-	testFileName(gDataBuf,NameErr);
+	testFileName(gDataBuf,KErrBadName);
 	gDataBuf.SetLength(258);
 	gDataBuf.Fill('C',257);
-	testFileName(gDataBuf,NameErr);
+	testFileName(gDataBuf,KErrBadName);
 	gDataBuf.SetLength(4096);
 	gDataBuf.Fill('D',4095);
-	testFileName(gDataBuf,NameErr);
+	testFileName(gDataBuf,KErrBadName);
 // Test DOTS //
 	testFileName(_L("A.X"),FALSE);
-	testFileName(_L("A..X"),KErrNone); // ******* NameErr);
-	testFileName(_L("A.........X"),KErrNone); // ******* NameErr);
+	testFileName(_L("A..X"),KErrNone); // ******* KErrBadName);
+	testFileName(_L("A.........X"),KErrNone); // ******* KErrBadName);
 	testFileName(_L("A."),FALSE);
-	testFileName(_L(".X"),KErrNone); // ******* NameErr);
-	testFileName(_L("."),NameErr);
-	testFileName(_L(".."),NameErr);
-//	testFileName(_L("..."),KErrNone); // NameErr); // !!! ********* NT error KErrAccessDenied (?)
-	testFileName(_L("\\a.x\\NAME"),DirErr); // DirErr == KErrPathNotFound
-	testFileName(_L("\\a..x\\NAME"),DirErr); // ******** NameErr);
-	testFileName(_L("\\.\\NAME"),NameErr);
-	testFileName(_L("\\..\\NAME"),NameErr);
-//	testFileName(_L("\\...\\NAME"),KErrPathNotFound); // ******** NameErr); // !! NT treats ... as .. ??
+	testFileName(_L(".X"),KErrNone); // ******* KErrBadName);
+	testFileName(_L("."),KErrBadName);
+	testFileName(_L(".."),KErrBadName);
+//	testFileName(_L("..."),KErrNone); // KErrBadName); // !!! ********* NT error KErrAccessDenied (?)
+	testFileName(_L("\\a.x\\NAME"),KErrPathNotFound); // KErrPathNotFound == KErrPathNotFound
+	testFileName(_L("\\a..x\\NAME"),KErrPathNotFound); // ******** KErrBadName);
+	testFileName(_L("\\.\\NAME"),KErrBadName);
+	testFileName(_L("\\..\\NAME"),KErrBadName);
+//	testFileName(_L("\\...\\NAME"),KErrPathNotFound); // ******** KErrBadName); // !! NT treats ... as .. ??
 // Test WILD CARDS //
-	testFileName(_L("*.*"),NameErr);
-	testFileName(_L("*"),NameErr);
-	testFileName(_L("\\*"),NameErr);
-	testFileName(_L("?"),NameErr);
-	testFileName(_L("\\?"),NameErr);
-	testFileName(_L("\\A?B\\NAME"),NameErr);
-	testFileName(_L("\\A*B\\NAME"),NameErr);
-	testFileName(_L("\\*\\NAME"),NameErr);
-	testFileName(_L("\\********.***\\NAME"),NameErr);
-	testFileName(_L("A?X"),NameErr);
+	testFileName(_L("*.*"),KErrBadName);
+	testFileName(_L("*"),KErrBadName);
+	testFileName(_L("\\*"),KErrBadName);
+	testFileName(_L("?"),KErrBadName);
+	testFileName(_L("\\?"),KErrBadName);
+	testFileName(_L("\\A?B\\NAME"),KErrBadName);
+	testFileName(_L("\\A*B\\NAME"),KErrBadName);
+	testFileName(_L("\\*\\NAME"),KErrBadName);
+	testFileName(_L("\\********.***\\NAME"),KErrBadName);
+	testFileName(_L("A?X"),KErrBadName);
 
 	test.Printf(_L("Test set volume name\n"));
 // New behaviour: SetVolumeName accepts any string < 12 chars
@@ -1011,64 +993,64 @@
 
 // Test path 
 	testMakeDir(_L("\\A2345678.A23\\NAME"),FALSE);
-	testMakeDir(_L("\\A23456789.A23\\NAME"),KErrNone); // ******** NameErr);
-	testMakeDir(_L("\\A2345678.A234\\NAME"),KErrNone); // ******** NameErr);
-	testMakeDir(_L("\\A.1234\\NAME"),KErrNone); // ********* NameErr);
+	testMakeDir(_L("\\A23456789.A23\\NAME"),KErrNone); // ******** KErrBadName);
+	testMakeDir(_L("\\A2345678.A234\\NAME"),KErrNone); // ******** KErrBadName);
+	testMakeDir(_L("\\A.1234\\NAME"),KErrNone); // ********* KErrBadName);
 	testMakeDir(_L("\\A2345678\\NAME"),FALSE);
-	testMakeDir(_L("\\A23456789\\NAME"),KErrNone); // ******** NameErr);
+	testMakeDir(_L("\\A23456789\\NAME"),KErrNone); // ******** KErrBadName);
 	testMakeDir(_L("\\A.X\\NAME"),FALSE);
-	testMakeDir(_L("\\A..X\\NAME"),KErrNone); // ******** NameErr);
-	testMakeDir(_L("\\A.\\NAME"),NameErr);
-	testMakeDir(_L("\\.X\\NAME"),KErrNone); // ******** NameErr);
-	testMakeDir(_L("\\.\\NAME"),NameErr);
-	testMakeDir(_L("\\..\\NAME"),NameErr);
-	testMakeDir(_L("\\\\NAME"),NameErr);
-	testMakeDir(_L("\\\\"),NameErr);
-	testMakeDir(_L("\\A\\A2\\A23\\a2345678\\a2345678.\\a2345678.1\\a2345678.123"),NameErr);
-	testMakeDir(_L("\\A\\A2\\A23\\a2345678\\a2345678.\\a2345678.1\\a2345678..123"),NameErr); // ******* NameErr);
-	testMakeDir(_L("\\A\\A2\\A23\\a2345678\\a2345678.\\a2345678.1\\a2345678.1234"),NameErr); // ******* NameErr);
+	testMakeDir(_L("\\A..X\\NAME"),KErrNone); // ******** KErrBadName);
+	testMakeDir(_L("\\A.\\NAME"),KErrBadName);
+	testMakeDir(_L("\\.X\\NAME"),KErrNone); // ******** KErrBadName);
+	testMakeDir(_L("\\.\\NAME"),KErrBadName);
+	testMakeDir(_L("\\..\\NAME"),KErrBadName);
+	testMakeDir(_L("\\\\NAME"),KErrBadName);
+	testMakeDir(_L("\\\\"),KErrBadName);
+	testMakeDir(_L("\\A\\A2\\A23\\a2345678\\a2345678.\\a2345678.1\\a2345678.123"),KErrBadName);
+	testMakeDir(_L("\\A\\A2\\A23\\a2345678\\a2345678.\\a2345678.1\\a2345678..123"),KErrBadName); // ******* KErrBadName);
+	testMakeDir(_L("\\A\\A2\\A23\\a2345678\\a2345678.\\a2345678.1\\a2345678.1234"),KErrBadName); // ******* KErrBadName);
 	gDataBuf.SetLength(256);
 	gDataBuf.Fill('V',255);
-	testMakeDir(gDataBuf,NameErr);
+	testMakeDir(gDataBuf,KErrBadName);
 	gDataBuf.SetLength(257);
 	gDataBuf.Fill('W',256);
-	testMakeDir(gDataBuf,NameErr);
+	testMakeDir(gDataBuf,KErrBadName);
 	gDataBuf.SetLength(258);
 	gDataBuf.Fill('X',257);
-	testMakeDir(gDataBuf,NameErr);
+	testMakeDir(gDataBuf,KErrBadName);
 	gDataBuf.SetLength(259);
 	gDataBuf.Fill('Y',258);
-	testMakeDir(gDataBuf,NameErr);
+	testMakeDir(gDataBuf,KErrBadName);
 	gDataBuf.SetLength(4096);
 	gDataBuf.Fill('Z',4095);
-	testMakeDir(gDataBuf,NameErr);
+	testMakeDir(gDataBuf,KErrBadName);
 
 // Test names 
-	testMakeDir(_L("A..X"),KErrAlreadyExists); // ******* NameErr);
+	testMakeDir(_L("A..X"),KErrAlreadyExists); // ******* KErrBadName);
 	testMakeDir(_L("\\A\\"),FALSE);
 	testMakeDir(_L("\\12345678.123\\"),FALSE);
-	testMakeDir(_L("\\.\\"),NameErr);
-	testMakeDir(_L("\\..\\"),NameErr);
+	testMakeDir(_L("\\.\\"),KErrBadName);
+	testMakeDir(_L("\\..\\"),KErrBadName);
 	testMakeDir(_L("\\X\\"),FALSE);
-	testMakeDir(_L("\\12345678.1234\\"),KErrNone); // ******* NameErr);
-	testMakeDir(_L("\\123456789\\"),KErrNone); // ******** NameErr);
+	testMakeDir(_L("\\12345678.1234\\"),KErrNone); // ******* KErrBadName);
+	testMakeDir(_L("\\123456789\\"),KErrNone); // ******** KErrBadName);
 // Test max levels
 	testMakeDir(_L("\\A\\B\\C\\D\\E\\F\\G\\H\\I\\J\\K\\L\\M\\N\\O\\P\\Q\\R\\S\\T\\U\\V\\W\\X\\Y\\Z"),FALSE);
 	testMakeDir(_L("\\00000000.000\\11111111.111\\22222222.222\\33333333.333\\45678901.3"),FALSE);
 	testMakeDir(_L("\\00000000.000\\11111111.111\\22222222.222\\33333333.333\\45678901.34"),FALSE);
 	testMakeDir(_L("\\00000000.000\\11111111.111\\22222222.222\\33333333.333\\45678901.345"),FALSE);
 	testMakeDir(_L("\\00000000.000\\11111111.111\\22222222.222\\33333333.333\\45678901.3\\xxxxxxxx.xxx"),FALSE);
-	testMakeDir(_L("\\00000000.000\\11111111.111\\22222222.222\\33333333.333\\45678901.34\\xxxxxxxx.xxx"),KErrNone); // ******* NameErr);
-	testMakeDir(_L("\\00000000.000\\11111111.111\\22222222.222\\33333333.333\\45678901.345\\xxxxxxxx.xxx"),KErrNone); // ******* NameErr);
+	testMakeDir(_L("\\00000000.000\\11111111.111\\22222222.222\\33333333.333\\45678901.34\\xxxxxxxx.xxx"),KErrNone); // ******* KErrBadName);
+	testMakeDir(_L("\\00000000.000\\11111111.111\\22222222.222\\33333333.333\\45678901.345\\xxxxxxxx.xxx"),KErrNone); // ******* KErrBadName);
 	testMakeDir(_L("\\2\\4\\6\\8\\0\\2\\4\\6\\8\\0\\2\\4\\6\\8\\0\\2\\4\\6\\8\\0\\2\\4\\6\\8\\0\\2\\4\\6\\8\\0\\23"),FALSE);
 	testMakeDir(_L("\\2\\4\\6\\8\\0\\2\\4\\6\\8\\0\\2\\4\\6\\8\\0\\2\\4\\6\\8\\0\\2\\4\\6\\8\\0\\2\\4\\6\\8\\0\\23456789.123"),FALSE);
 	testMakeDir(_L("\\2\\4\\6\\8\\0\\2\\4\\6\\8\\0\\2\\4\\6\\8\\0\\2\\4\\6\\8\\0\\2\\4\\6\\8\\0\\2\\4\\6\\8\\0\\23\\5"),FALSE);
 	testMakeDir(_L("\\2\\4\\6\\8\\0\\2\\4\\6\\8\\0\\2\\4\\6\\8\\0\\2\\4\\6\\8\\0\\2\\4\\6\\8\\0\\2\\4\\6\\8\\0\\23\\56789012.456"),FALSE);
-	testMakeDir(_L("\\2\\4\\6\\8\\0\\2\\4\\6\\8\\0\\2\\4\\6\\8\\0\\2\\4\\6\\8\\0\\2\\4\\6\\8\\0\\2\\4\\6\\8\\0\\234\\6"),KErrNone); // ******** NameErr);
-	testMakeDir(_L("Z:\\ROMDIR\\"),KErrAccessDenied); // *********** NotSupportedErr);
+	testMakeDir(_L("\\2\\4\\6\\8\\0\\2\\4\\6\\8\\0\\2\\4\\6\\8\\0\\2\\4\\6\\8\\0\\2\\4\\6\\8\\0\\2\\4\\6\\8\\0\\234\\6"),KErrNone); // ******** KErrBadName);
+	testMakeDir(_L("Z:\\ROMDIR\\"),KErrAccessDenied); //
 	test.Printf(_L("Test setEof to same length\n"));
 	gNameBuf.SetLength(0);
-	if ((c=gFile.Temp(TheFs,gNameBuf,gNameOut,EFileStream|P_FUPDATE))!=KErrNone)
+	if ((c=gFile.Temp(TheFs,gNameBuf,gNameOut,EFileStream|EFileWrite))!=KErrNone)
 		Error(_L("Open 50"),c);
 	gFile.Close();
 	testSetEof(gNameOut,0L,FALSE);  // should be no change //
@@ -1092,29 +1074,29 @@
 	test.Printf(_L("Test read of zero bytes\n"));
 	gNameBuf.SetLength(0);
 
-	if ((c=gFile.Temp(TheFs,gNameBuf,gNameOut,EFileStream|P_FUPDATE))!=KErrNone)
+	if ((c=gFile.Temp(TheFs,gNameBuf,gNameOut,EFileStream|EFileWrite))!=KErrNone)
 		Error(_L("Open 60"),c);
-	if ((c=gFile.Read(gDataBuf,0))!=KErrNone) // ******** EofErr)
+	if ((c=gFile.Read(gDataBuf,0))!=KErrNone) // ******** KErrEof)
 		Error(_L("Read 61"),c);
-	if ((c=gFile.Read(gDataBuf,0))!=KErrNone) // ******** EofErr)
+	if ((c=gFile.Read(gDataBuf,0))!=KErrNone) // ******** KErrEof)
 		Error(_L("Read 62"),c);
 	if ((c=gFile.Write(gDataBuf,0))!=KErrNone)
 		Error(_L("Write 63"),c);
-	if ((c=gFile.Read(gDataBuf,0))!=KErrNone) // ******** EofErr)
+	if ((c=gFile.Read(gDataBuf,0))!=KErrNone) // ******** KErrEof)
 		Error(_L("Read 64"),c);
 	gFile.Close();
-	if ((c=gFile.Open(TheFs,gNameOut,EFileStream|P_FUPDATE|P_FRANDOM))!=KErrNone)
+	if ((c=gFile.Open(TheFs,gNameOut,EFileStream|EFileWrite))!=KErrNone)
 		Error(_L("Open 70"),c);
-	if ((c=gFile.Read(gDataBuf,0))!=KErrNone) // ******** EofErr)
+	if ((c=gFile.Read(gDataBuf,0))!=KErrNone) // ******** KErrEof)
 		Error(_L("Read 71"),c);
 	gDataBuf.SetLength(1);
 	gDataBuf[0]=0xf0;
 	if ((c=gFile.Write(gDataBuf,1))!=KErrNone)
 		Error(_L("Write 72"),c);
-	if ((c=gFile.Read(gDataBuf,0))!=KErrNone) // ********* EofErr)
+	if ((c=gFile.Read(gDataBuf,0))!=KErrNone) // ********* KErrEof)
 		Error(_L("Read 73"),c);
 	pos=0L;
-	if ((c=gFile.Seek((TSeek)P_FABS,pos))!=KErrNone)
+	if ((c=gFile.Seek((TSeek)ESeekStart,pos))!=KErrNone)
 		Error(_L("Seek 74"),c);
 	gDataBuf.SetLength(1);
 	gDataBuf[0]=0x83;
@@ -1129,9 +1111,9 @@
 		Error(_L("Read 77"),c);
 	if (gDataBuf[0]!=0xf0)
 		Error(_L("buffer 1 check"),0);
-	if ((c=gFile.Read(gDataBuf,0))!=KErrNone) // ******** EofErr)
+	if ((c=gFile.Read(gDataBuf,0))!=KErrNone) // ******** KErrEof)
 		Error(_L("Read 78"),c);
-	if ((c=gFile.Read(gDataBuf,16384))!=KErrNone) // ******* EofErr)
+	if ((c=gFile.Read(gDataBuf,16384))!=KErrNone) // ******* KErrEof)
 		Error(_L("Read 79"),c);
 	gFile.Close();
 	if ((c=TheFs.Delete(gNameOut))!=KErrNone)
@@ -1139,7 +1121,7 @@
 
     test.Printf(_L("Test write of zero bytes\n"));
     gNameBuf.SetLength(0);
-    if ((c=gFile.Temp(TheFs,gNameBuf,gNameOut,EFileStream|P_FUPDATE))!=KErrNone)
+    if ((c=gFile.Temp(TheFs,gNameBuf,gNameOut,EFileStream|EFileWrite))!=KErrNone)
         Error(_L("Open 50"),c);
     gFile.Close();
 //	********** Error(_L("Close"),c); close has no return value
@@ -1159,45 +1141,45 @@
 
 	test.Printf(_L("Test ReadOnly files\n"));
 	gNameBuf.SetLength(0);
-	if ((c=gFile.Create(TheFs,_L("TEST1.TMP"),EFileStream|P_FUPDATE))!=KErrNone)
+	if ((c=gFile.Create(TheFs,_L("TEST1.TMP"),EFileStream|EFileWrite))!=KErrNone)
 		Error(_L("Create 40"),c);
 	gFile.Close();
-	if ((c=gFile.Temp(TheFs,gNameBuf,gNameOut,EFileStream|P_FUPDATE))!=KErrNone)
+	if ((c=gFile.Temp(TheFs,gNameBuf,gNameOut,EFileStream|EFileWrite))!=KErrNone)
 		Error(_L("Open 40"),c);
 	mask=0;
 	attrib=KEntryAttReadOnly;                       // Remove writable //
-	if ((c=TheFs.SetAtt(gNameOut,attrib,mask))!=LockedErr)
+	if ((c=TheFs.SetAtt(gNameOut,attrib,mask))!=KErrInUse)
 		Error(_L("TheFs.SetAtt not locked"),c);
 	gFile.Close();
 	if ((c=TheFs.SetAtt(gNameOut,attrib,mask))!=KErrNone)
 		Error(_L("Att 41"),c);
-	if ((c=gFile.Open(TheFs,gNameOut,EFileStream|P_FUPDATE))!=AccessErr)
+	if ((c=gFile.Open(TheFs,gNameOut,EFileStream|EFileWrite))!=KErrAccessDenied)
 		Error(_L("Open 41"),c);
 	if ((c=gFile.Open(TheFs,gNameOut,EFileStream))!=KErrNone)
 		Error(_L("Open 42"),c);
-	if ((c=gFileErr.Open(TheFs,gNameOut,EFileStream))!=LockedErr)
+	if ((c=gFileErr.Open(TheFs,gNameOut,EFileStream))!=KErrInUse)
 		Error(_L("Open 43"),c);
-	if ((c=TheFs.Rename(_L("TEST1.TMP"),gNameOut))!=ExistsErr)
+	if ((c=TheFs.Rename(_L("TEST1.TMP"),gNameOut))!=KErrAlreadyExists)
 		Error(_L("Rename 43.1"),c);
-	if ((c=gFileErr.Create(TheFs,gNameOut,EFileStream))!=ExistsErr) // LockedErr)
+	if ((c=gFileErr.Create(TheFs,gNameOut,EFileStream))!=KErrAlreadyExists) // KErrInUse)
 		Error(_L("Open 44"),c);
-	if ((c=gFileErr.Replace(TheFs,gNameOut,EFileStream))!=LockedErr)
+	if ((c=gFileErr.Replace(TheFs,gNameOut,EFileStream))!=KErrInUse)
 		Error(_L("Open 45"),c);
 	gFile.Close();
-	if ((c=gFile.Create(TheFs,gNameOut,EFileStream))!=ExistsErr)
+	if ((c=gFile.Create(TheFs,gNameOut,EFileStream))!=KErrAlreadyExists)
 		Error(_L("Create 46"),c);
-	if ((c=gFile.Replace(TheFs,gNameOut,EFileStream))!=AccessErr)
+	if ((c=gFile.Replace(TheFs,gNameOut,EFileStream))!=KErrAccessDenied)
 		Error(_L("Replace 47"),c);
 	if ((c=gFile.Create(TheFs,_L("FILE1.TMP"),EFileStream))!=KErrNone)
 		Error(_L("Create 48"),c);
-	if ((c=TheFs.Rename(_L("FILE1.TMP"),_L("FILE2.TMP")))!=LockedErr)
+	if ((c=TheFs.Rename(_L("FILE1.TMP"),_L("FILE2.TMP")))!=KErrInUse)
 		Error(_L("Rename 49"),c);
 	gFile.Close();
 	if ((c=TheFs.Rename(_L("FILE1.TMP"),_L("FILE2.TMP")))!=KErrNone)
 		Error(_L("Rename 50"),c);
-	if ((c=TheFs.Rename(_L("FILE2.TMP"),gNameOut))!=ExistsErr)
+	if ((c=TheFs.Rename(_L("FILE2.TMP"),gNameOut))!=KErrAlreadyExists)
 		Error(_L("Rename 51"),c);
-	if ((c=TheFs.Delete(gNameOut))!=AccessErr)
+	if ((c=TheFs.Delete(gNameOut))!=KErrAccessDenied)
 		Error(_L("Delete"),c);
 	mask=KEntryAttReadOnly;
 	attrib=0;
@@ -1217,13 +1199,13 @@
 	if ((c=gFile.Open(TheFs,_L("B_GEN.001"),EFileStream))!=KErrNone)
 		Error(_L("Open 30"),c);
 	pos=1L;
-	if ((c=gFile.SetSize(pos))!=ReadOnlyErr)
+	if ((c=gFile.SetSize(pos))!=KErrAccessDenied)
 		Error(_L("Set EOF 30"),c);
 	if ((c=TheFs.Entry(_L("B_GEN.001"),gFileEntry))!=KErrNone)
 		Error(_L("File info 30"),c);
 	if (gFileEntry.iSize!=0L)
 		Error(_L("Size check 30"),0);
-	if ((c=gFile.Write(gDataBuf,1))!=ReadOnlyErr)
+	if ((c=gFile.Write(gDataBuf,1))!=KErrAccessDenied)
 		Error(_L("Write 30"),c);
 	if ((c=TheFs.Entry(_L("B_GEN.001"),gFileEntry))!=KErrNone)
 		Error(_L("File info 31"),c);
@@ -1240,28 +1222,55 @@
 
 	test.Printf(_L("Test dir entries are written out\n"));
 	gNameBuf.SetLength(0);
-	if ((c=gFile.Temp(TheFs,gNameBuf,gNameOut,EFileStream|P_FRANDOM))!=KErrNone)
+	
+    if ((c=gFile.Temp(TheFs,gNameBuf,gNameOut,EFileStream))!=KErrNone)
 		Error(_L("Open 20"),c); 
+	
 	if ((c=TheFs.Entry(gNameOut,gFileEntry))!=KErrNone)
 		Error(_L("File info 0"),c);
-	if ((gFileEntry.iAtt & P_FAMOD)==0)
+	
+    if ((gFileEntry.iAtt & KEntryAttArchive)==0)
 		Error(_L("Status 20"),0);
+	
 	test.Printf(_L("Size=%u\n"),gFileEntry.iSize);
+	
 	if (gFileEntry.iSize!=0L)
 		Error(_L("Size check 0"),0);
+	
 	saveTime=gFileEntry.iModified;
 	test.Printf(_L("Wait 3 seconds...\n"));
 	User::After(3000000L);
 	gDataBuf.SetLength(1);
+	
 	if ((c=gFile.Write(gDataBuf,1))!=KErrNone)
 		Error(_L("Write 1"),c);
+	
+         /* === pay attention to the code below if the "not updating file timestamp on Flush" mode is enabled (at least on FAT)
+         //-- the timestamp in the "real" entry on the media (RFs::Entry()) and what we get by RFile::Modified()
+         //-- can differ even after flushing file. The timestamp will be updated only on _closing_ the file.
+         //-- This behaviour can be an optimisation to reduce number of media writes due to updating file timestamps.
+         gFile.Close();
+         nRes = gFile.Open(TheFs, gNameOut, EFileWrite);
+         test(nRes == KErrNone);
+         //-- restore the expected position in the file
+         TInt pos1 = 0;
+         nRes = gFile.Seek(ESeekEnd, pos1);
+         test(nRes == KErrNone);
+         //------------------------------------ 
+         */
+
+
 	if ((c=TheFs.Entry(gNameOut,gFileEntry))!=KErrNone)
 		Error(_L("File info 1"),c);
+	
 	test.Printf(_L("Size=%u\n"),gFileEntry.iSize);
 	if (gFileEntry.iSize!=1L)
 		Error(_L("Size check 1"),0);
+	
 	if (gFileEntry.iModified==saveTime)
 		Error(_L("Time update"),0);
+
+
 	gDataBuf.SetLength(16384);
 	if ((c=gFile.Write(gDataBuf,16384))!=KErrNone)
 		Error(_L("Write 2"),c);
@@ -1271,7 +1280,7 @@
 	if (gFileEntry.iSize!=16385L)
 		Error(_L("Size check 2"),0);
 	pos=0L;
-	if ((c=gFile.Seek((TSeek)P_FABS,pos))!=KErrNone)
+	if ((c=gFile.Seek((TSeek)ESeekStart,pos))!=KErrNone)
 		Error(_L("Seek 0"),c);
 	if ((c=gFile.Write(gDataBuf,1))!=KErrNone)
 		Error(_L("Write 3"),c);
@@ -1281,7 +1290,7 @@
 	if (gFileEntry.iSize!=16385L)
 		Error(_L("Size check 3"),0);
 	pos=0L;
-	if ((c=gFile.Seek((TSeek)P_FABS,pos))!=KErrNone)
+	if ((c=gFile.Seek((TSeek)ESeekStart,pos))!=KErrNone)
 		Error(_L("Seek 1"),c);
 	if ((c=gFile.Write(gDataBuf,16384))!=KErrNone)
 		Error(_L("Write 4"),c);
@@ -1323,46 +1332,46 @@
 		Error(_L("File info 8"),c);
 	if (gFileEntry.iSize!=0L)
 		Error(_L("Size check 7"),0);
-	mask=P_FAMOD;
+	mask=KEntryAttArchive;
 	attrib=0;
 	if ((c=TheFs.SetAtt(gNameOut,attrib,mask))!=KErrNone)
 		Error(_L("Att 20"),c);
 
 //
-	if ((c=gFile.Open(TheFs,gNameOut,EFileStream|P_FUPDATE|P_FRANDOM))!=KErrNone)
+	if ((c=gFile.Open(TheFs,gNameOut,EFileStream|EFileWrite))!=KErrNone)
 		Error(_L("Open 21"),c);
 	if ((c=TheFs.Entry(gNameOut,gFileEntry))!=KErrNone)
 		Error(_L("File info 9"),c);
-	if (gFileEntry.iAtt & P_FAMOD)
+	if (gFileEntry.iAtt & KEntryAttArchive)
 		Error(_L("Status 21"),0);
 	if ((c=gFile.Write(gDataBuf,0))!=KErrNone)
 		Error(_L("Write 21"),c);
 	if ((c=TheFs.Entry(gNameOut,gFileEntry))!=KErrNone)
 		Error(_L("File info 9"),c);
-	if ((gFileEntry.iAtt & P_FAMOD))       // write 0 should not modify //
+	if ((gFileEntry.iAtt & KEntryAttArchive))       // write 0 should not modify //
 		Error(_L("Status 22"),0);
 	gFile.Close();
-	mask=P_FAMOD;
+	mask=KEntryAttArchive;
 	attrib=0;
 	if ((c=TheFs.SetAtt(gNameOut,attrib,mask))!=KErrNone)
 		Error(_L("Att 20"),c);
-	if ((c=gFile.Open(TheFs,gNameOut,EFileStream|P_FUPDATE|P_FRANDOM))!=KErrNone)
+	if ((c=gFile.Open(TheFs,gNameOut,EFileStream|EFileWrite))!=KErrNone)
 		Error(_L("Open 22"),c);
 	if ((c=TheFs.Entry(gNameOut,gFileEntry))!=KErrNone)
 		Error(_L("File info 9"),c);
-	if (gFileEntry.iAtt & P_FAMOD)
+	if (gFileEntry.iAtt & KEntryAttArchive)
 		Error(_L("Status 23"),0);
 	pos=0L;
 	if ((c=gFile.SetSize(pos))!=KErrNone)        // no change //
 		Error(_L("Set EOF 21"),c);
 	if ((c=TheFs.Entry(gNameOut,gFileEntry))!=KErrNone)
 		Error(_L("File info 9"),c);
-	if ((gFileEntry.iAtt & P_FAMOD))
+	if ((gFileEntry.iAtt & KEntryAttArchive))
 		Error(_L("Status 24"),0);
 	gFile.Close();
 	if ((c=TheFs.Entry(gNameOut,gFileEntry))!=KErrNone)
 		Error(_L("File info 0"),c);
-	if ((c=gFile.Open(TheFs,gNameOut,EFileStream|P_FUPDATE|P_FRANDOM))!=KErrNone)
+	if ((c=gFile.Open(TheFs,gNameOut,EFileStream|EFileWrite))!=KErrNone)
 		Error(_L("Open 23"),c);
 	saveTime=gFileEntry.iModified;
 	test.Printf(_L("Wait 3 seconds...\n"));
@@ -1376,7 +1385,7 @@
 		Error(_L("File info 61"),c);
 	if (gFileEntry.iModified!=saveTime)
 		Error(_L("Close new time"),0);
-	if ((c=gFile.Open(TheFs,gNameOut,EFileStream|P_FUPDATE|P_FRANDOM))!=KErrNone)
+	if ((c=gFile.Open(TheFs,gNameOut,EFileStream|EFileWrite))!=KErrNone)
 		Error(_L("Open 24"),c);
 	if ((c=gFile.Write(gDataBuf,1))!=KErrNone)
 		Error(_L("Write 60"),c);
@@ -1405,7 +1414,7 @@
 	if ((c=gFile.Open(TheFs,gNameOut,EFileStream))!=KErrNone)
 		Error(_L("Open 10"),c); // Temp file is created as writable. 
 	TTime fileTime(0);
-	if ((c=gFile.SetModified(fileTime))!=AccessErr) // LockedErr)
+	if ((c=gFile.SetModified(fileTime))!=KErrAccessDenied) // KErrInUse)
 		Error(_L("Set file date 10"),c);
 	gFile.Close();
 
@@ -1441,48 +1450,26 @@
 	gNameOut.SetLength(0);
 	if ((c=gFile.Temp(TheFs,gNameBuf,gNameOut,EFileStream))!=KErrNone)
 		Error(_L("Open 1"),c);
-	if ((c=gFormat.Open(TheFs,fBuf,EFullFormat,count))!=LockedErr)
+	if ((c=gFormat.Open(TheFs,fBuf,EFullFormat,count))!=KErrInUse)
 		Error(_L("Format lock check 1"),c);
-	if ((c=gFormat.Open(TheFs,fBuf,EQuickFormat,count))!=LockedErr)
+	if ((c=gFormat.Open(TheFs,fBuf,EQuickFormat,count))!=KErrInUse)
 		Error(_L("Format lock check 2"),c);
 	gFile.Close();
 
 	if ((c=gFormat.Open(TheFs,fBuf,EFullFormat,count))!=KErrNone)
 		{
-		if (c==LockedErr || c==AccessErr)
+		if (c==KErrInUse || c==KErrAccessDenied)
 			{
 			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	Tue Feb 02 01:24:03 2010 +0200
+++ b/kerneltest/f32test/server/t_falsespace.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -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_fman.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kerneltest/f32test/server/t_fman.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -13,6 +13,8 @@
 // Description:
 //
 
+#define __E32TEST_EXTENSION__
+
 #include <f32file.h>
 #include <e32test.h>
 #include <hal.h>
@@ -57,8 +59,8 @@
 		TFileName fileName=iFileMan->CurrentEntry().iName;
 		if (gAsynch==EFalse)
 			test.Printf(_L("CurrentEntry is %S\n"),&fileName);
-		test(lastError==KErrAlreadyExists);
-		test(fileName.MatchF(_L("PIPE1.PLP"))!=KErrNotFound || fileName.MatchF(_L("FOUR"))!=KErrNotFound || fileName.MatchF(_L("File*.TXT"))!=KErrNotFound  || fileName.MatchF(_L("ah"))!=KErrNotFound || fileName.MatchF(_L("a"))!=KErrNotFound);
+		test_Equal(KErrAlreadyExists, lastError);
+		test_Value(KErrNotFound, fileName.MatchF(_L("PIPE1.PLP"))!=KErrNotFound || fileName.MatchF(_L("FOUR"))!=KErrNotFound || fileName.MatchF(_L("File*.TXT"))!=KErrNotFound  || fileName.MatchF(_L("ah"))!=KErrNotFound || fileName.MatchF(_L("a"))!=KErrNotFound);
 		}
 	return(MFileManObserver::EContinue);
 	}
@@ -78,7 +80,7 @@
 //
 	{
 	User::WaitForRequest(gStat);
-	test(gStat==aResult);
+	test_Value(aResult, gStat==aResult);
 	}
 
 LOCAL_C void TestResult(TInt aReturnVal, TInt aExpectedAsynchReturnStatus=KErrNone, TInt aExpectedSynchReturn=KErrNone)
@@ -87,10 +89,12 @@
 //
 	{
 	if (!gAsynch)
-		test(aReturnVal==aExpectedAsynchReturnStatus);
+		{
+		test_Equal(aExpectedAsynchReturnStatus, aReturnVal);
+		}
 	else
 		{
-		test(aReturnVal==aExpectedSynchReturn);
+		test_Equal(aExpectedSynchReturn, aReturnVal);
 		WaitForResult(aExpectedAsynchReturnStatus);
 		}
 	}
@@ -102,7 +106,7 @@
 	{
 	gFileMan->Attribs(aDirName, 0, KEntryAttReadOnly, 0, CFileMan::ERecurse);
 	TInt r=gFileMan->RmDir(aDirName);
-	test(r==KErrNone || r==KErrNotFound || r==KErrPathNotFound);
+	test_Value(r, r==KErrNone || r==KErrNotFound || r==KErrPathNotFound);
 	}
 
 LOCAL_C void Compare(const TDesC& aDir1,const TDesC& aDir2)
@@ -174,25 +178,25 @@
 		*aDestOtherDrive = gSessionPath[0] == 'C' ? _L("Y:\\F32-TST\\TFMAN\\dest\\") : _L("C:\\F32-TST\\TFMAN\\dest\\");
 #endif
 		err = TheFs.MkDirAll(*aDestOtherDrive);
-		test(err == KErrNone || err == KErrAlreadyExists);
+		test_Value(err, err == KErrNone || err == KErrAlreadyExists);
 		}
 
 	err = TheFs.MkDirAll(sourceName);
-	test(err == KErrNone || err == KErrAlreadyExists);
+	test_Value(err, err == KErrNone || err == KErrAlreadyExists);
 
 	err = TheFs.MkDirAll(sourceCompare);
-	test(err == KErrNone || err == KErrAlreadyExists);
+	test_Value(err, err == KErrNone || err == KErrAlreadyExists);
 
 	err = TheFs.MkDirAll(destSameDrive);
-	test(err == KErrNone || err == KErrAlreadyExists);
+	test_Value(err, err == KErrNone || err == KErrAlreadyExists);
 
 	if(aCreateFiles)
 		{
 		err = TheFs.MkDirAll(sourceNameSubDir);
-		test(err == KErrNone || err == KErrAlreadyExists);
+		test_Value(err, err == KErrNone || err == KErrAlreadyExists);
 
 		err = TheFs.MkDirAll(sourceCompareSubDir);
-		test(err == KErrNone || err == KErrAlreadyExists);
+		test_Value(err, err == KErrNone || err == KErrAlreadyExists);
 		
 		for(TInt i=0; i<5; i++)
 			{
@@ -204,7 +208,7 @@
 
 			RFile file;
 			err = file.Create(TheFs,name,EFileRead|EFileWrite);
-			test(err == KErrNone || err == KErrAlreadyExists);
+			test_Value(err, err == KErrNone || err == KErrAlreadyExists);
 			file.Close();
 
 			// ...and another to compare against
@@ -214,7 +218,7 @@
 			name.Append(_L(".TXT"));
 
 			err = file.Create(TheFs,name,EFileRead|EFileWrite);
-			test(err == KErrNone || err == KErrAlreadyExists);
+			test_Value(err, err == KErrNone || err == KErrAlreadyExists);
 			file.Close();
 			}
 		}
@@ -233,7 +237,7 @@
 		buf.Insert(0, _L("\\"));
 		buf.Append(_L("\\file"));
 		err = TheFs.Delete(buf);
-		test(err == KErrNone);
+		test_KErrNone(err);
   		ret = ETrue;
 		}
 	RmDir(_L("\\longname1\\"));
@@ -276,7 +280,7 @@
 		MakeFile(_L("\\TEST\\LONG\\NAME\\ABCDE\\FILEFILE01FILEFILE02FILEFILE03FILEFILE04"));
 		TFileName name1(KLongName1);
 		r=gFileMan->Rename(_L("\\TEST\\LONG"),name1,CFileMan::EOverWrite);
-		test(r==KErrNone);
+		test_KErrNone(r);
 	//	Two long directory names - makes paths invalid
 		MakeDir(_L("\\TEST\\LONG\\NAME\\FGHIJ"));
 		MakeDir(_L("\\TEST\\LONG\\NAME\\FGHIJ\\DIRECTORY1DIRECTORY2DIRECTORY3DIRECTORY4\\"));
@@ -285,14 +289,14 @@
 		
 		// Testing invalid long file name (i.e. >256) 
 		r=gFileMan->Rename(_L("\\TEST\\LONG"),KInvalidLongName,CFileMan::EOverWrite);
-		test(r==KErrBadName);
+		test_Equal(KErrBadName, r);
 		
 		// Testing invalid long path (i.e. >256)
 		r=gFileMan->Rename(_L("\\TEST\\LONG"),KInvalidLongPath,CFileMan::EOverWrite);
-		test(r==KErrBadName);
+		test_Equal(KErrBadName, r);
 
 		r=gFileMan->Rename(_L("\\TEST\\LONG"),_L("\\TEST\\asdffdsa01asdffdsa02asdffdsa03asdffdsa04asdffdsa05asdffdsa06asdffdsa07asdffdsa08asdffdsa09asdffdsa10asdffdsa11asdffdsa12asdffdsa13asdffdsa14asdffdsa15asdffdsa16asdffdsa17asdffdsa18asdffdsa19asdffdsa20as\\fdsa21asdffds"),CFileMan::EOverWrite);
-		test(r==KErrNone);
+		test_KErrNone(r);
 		}
 
 	//testing invalid source path at the beginning:
@@ -337,10 +341,10 @@
 			TFileName name1(KLongName1);
 			name1+=_L("\\NAME\\ABCDE\\*.*");
 			r=gFileMan->Delete(name1);	
-			test(r==KErrNone);
+			test_KErrNone(r);
 
 			r=gFileMan->Delete(_L("\\TEST\\asdffdsa01asdffdsa02asdffdsa03asdffdsa04asdffdsa05asdffdsa06asdffdsa07asdffdsa08asdffdsa09asdffdsa10asdffdsa11asdffdsa12asdffdsa13asdffdsa14asdffdsa15asdffdsa16asdffdsa17asdffdsa18asdffdsa19asdffdsa20as\\fdsa21asdffds\\NAME\\FGHIJ\\*.*"));	
-			test(r==KErrNone);
+			test_KErrNone(r);
 			}
 		}
 	else
@@ -353,11 +357,11 @@
 			name1+=_L("\\NAME\\ABCDE\\*.*");
 			r=gFileMan->Delete(name1,0,gStat);	
 			WaitForSuccess();
-			test(r==KErrNone);
+			test_KErrNone(r);
 		
 			r=gFileMan->Delete(_L("\\TEST\\asdffdsa01asdffdsa02asdffdsa03asdffdsa04asdffdsa05asdffdsa06asdffdsa07asdffdsa08asdffdsa09asdffdsa10asdffdsa11asdffdsa12asdffdsa13asdffdsa14asdffdsa15asdffdsa16asdffdsa17asdffdsa18asdffdsa19asdffdsa20as\\fdsa21asdffds\\NAME\\FGHIJ\\*.*"),0,gStat);	
 			WaitForSuccess();
-			test(r==KErrNone);
+			test_KErrNone(r);
 			}
 		}
 
@@ -372,7 +376,7 @@
 	if (testingInvalidPathLengths)
 		{
 		r=gFileMan->RmDir(_L("\\TEST\\"));
-		test(r==KErrNone);
+		test_KErrNone(r);
 		}
 
 	/**
@@ -383,25 +387,25 @@
 	*/ 
 	TInt theDrive; 
 	r=TheFs.CharToDrive(gDriveToTest,theDrive);
-	test(r==KErrNone);
+	test_KErrNone(r);
     TFSName f;
 	r = TheFs.FileSystemName(f, theDrive);
-	test(r == KErrNone || r == KErrNotFound);
+	test_Value(r, r == KErrNone || r == KErrNotFound);
     if (f.FindF(_L("Fat")) == 0 )
     	{
 		test.Next(_L("Test wild card matching in short file names"));
     	MakeFile(_L("abcdefghi.txt"));
     	TInt err = gFileMan->Delete(_L("ABCDEF~*"));
-    	test(err == KErrNone);
+    	test_KErrNone(err);
     	MakeFile(_L("abcdefghi.txt"));
     	err = gFileMan->Delete(_L("ABCDEF~*.TXT"));
-    	test(err == KErrNone);
+    	test_KErrNone(err);
     	MakeFile(_L("abcdefghi.txt"));
     	err = gFileMan->Delete(_L("ABCDEF~*.?XT"));
-    	test(err == KErrNone);
+    	test_KErrNone(err);
     	MakeFile(_L("abcdefghi.txt"));
     	err = gFileMan->Delete(_L("ABCDEF~1.*"));
-    	test(err == KErrNone);
+    	test_KErrNone(err);
     	}
 	}
 
@@ -441,7 +445,7 @@
 		MakeFile(_L("\\START\\LONG\\DINOSAUR01DINOSAUR02DINOSAUR03DINOSAUR04.txt"));
 		MakeFile(_L("\\START\\LONG\\FILEFILE01FILEFILE02FILEFILE03FILEFILE04.txt"));
 		r=gFileMan->Rename(_L("\\START\\LONG"),_L("\\START\\asdffdsa01asdffdsa02asdffdsa03asdffdsa04asdffdsa05asdffdsa06asdffdsa07asdffdsa08asdffdsa09asdffdsa10asdffdsa11asdffdsa12asdffdsa13asdffdsa14asdffdsa15asdffdsa16asdffdsa17asdffdsa18asdffdsa19asdffdsa20asdffdsa21asdffdsa22asdff"),CFileMan::EOverWrite);
-		test(r==KErrNone);
+		test_KErrNone(r);
 		MakeDir(_L("\\START\\ASDFFDSA\\"));
 		}
 
@@ -533,35 +537,35 @@
 	if (!gAsynch)
 		{
 		r=gFileMan->Copy(_L("\\F32-TST\\TFMAN\\DELDIR\\*.TXT"),_L("\\F32-TST\\TFMAN\\COPYDIR\\"));
-		test(r==KErrNone);
+		test_KErrNone(r);
 		if (testingInvalidPathLengths)
 			{
 			test.Next(_L("Test invalid length paths"));
 			r=gFileMan->Copy(_L("\\START\\asdffdsa01asdffdsa02asdffdsa03asdffdsa04asdffdsa05asdffdsa06asdffdsa07asdffdsa08asdffdsa09asdffdsa10asdffdsa11asdffdsa12asdffdsa13asdffdsa14asdffdsa15asdffdsa16asdffdsa17asdffdsa18asdffdsa19asdffdsa20asdffdsa21asdffdsa22asdff\\*.*"),_L("\\FINISH\\"));
-			test(r==KErrNone);
+			test_KErrNone(r);
 			r=gFileMan->RmDir(_L("\\START\\"));
-			test(r==KErrNone);
+			test_KErrNone(r);
 			r=gFileMan->RmDir(_L("\\FINISH\\"));
-			test(r==KErrNone);
+			test_KErrNone(r);
 			}
 		}
 	else
 		{
 		r=gFileMan->Copy(_L("\\F32-TST\\TFMAN\\DELDIR\\*.TXT"),_L("\\F32-TST\\TFMAN\\COPYDIR\\"),0,gStat);
 		WaitForSuccess();
-		test(r==KErrNone);
+		test_KErrNone(r);
 		if (testingInvalidPathLengths)
 			{
 			test.Next(_L("Test invalid length paths (Asynch)"));
 			r=gFileMan->Copy(_L("\\START\\asdffdsa01asdffdsa02asdffdsa03asdffdsa04asdffdsa05asdffdsa06asdffdsa07asdffdsa08asdffdsa09asdffdsa10asdffdsa11asdffdsa12asdffdsa13asdffdsa14asdffdsa15asdffdsa16asdffdsa17asdffdsa18asdffdsa19asdffdsa20asdffdsa21asdffdsa22asdff\\*.*"),_L("\\FINISH\\"),0,gStat);
 			WaitForSuccess();
-			test(r==KErrNone);
+			test_KErrNone(r);
 			r=gFileMan->RmDir(_L("\\START\\"),gStat);
 			WaitForSuccess();
-			test(r==KErrNone);
+			test_KErrNone(r);
 			r=gFileMan->RmDir(_L("\\FINISH\\"),gStat);
 			WaitForSuccess();
-			test(r==KErrNone);
+			test_KErrNone(r);
 			}
 		}
 	
@@ -593,23 +597,27 @@
 
 	TEntry entry;
 	r=TheFs.Entry(_L("\\F32-TST\\TFMAN\\COPYDIR\\T_FSRV.CPP"),entry);
-	test(r==KErrNone);
+	test_KErrNone(r);
 	test(entry.iName.MatchF(_L("T_FSRV.CPP"))!=KErrNotFound);
 #if defined (__WINS__)
-	test(entry.iAtt==KEntryAttArchive);
+	test_Equal(KEntryAttArchive, entry.iAtt);
 #else
 	if (!IsTestingLFFS())
-		test(entry.iAtt==KEntryAttReadOnly);
+		{
+	    test_Equal(KEntryAttReadOnly, entry.iAtt);
+		}
 	else
+		{
 		test(entry.iAtt&KEntryAttReadOnly); // ???
+		}
 #endif
 	r=TheFs.SetAtt(_L("\\F32-TST\\TFMAN\\COPYDIR\\T_FSRV.CPP"),0,KEntryAttReadOnly);
-	test(r==KErrNone);
+	test_KErrNone(r);
 
 	r=gFileMan->Delete(_L("\\F32-TST\\TFMAN\\AFTER\\RUMBA?.TXT"));
-	test(r==KErrNone);
+	test_KErrNone(r);
 	r=gFileMan->Delete(_L("\\F32-TST\\TFMAN\\DELDIR\\RUMBA?.TXT"));
-	test(r==KErrNone);
+	test_KErrNone(r);
 	}
 
 LOCAL_C void TestDEF121663_Setup(TFileName& aSrcPath)
@@ -1017,7 +1025,7 @@
 		MakeFile(_L("\\START\\LONG\\DINOSAUR01DINOSAUR02DINOSAUR03DINOSAUR04.txt"));
 		MakeFile(_L("\\START\\LONG\\FILEFILE01FILEFILE02FILEFILE03FILEFILE04.txt"));
 		r=gFileMan->Rename(_L("\\START\\LONG"),_L("\\START\\asdffdsa01asdffdsa02asdffdsa03asdffdsa04asdffdsa05asdffdsa06asdffdsa07asdffdsa08asdffdsa09asdffdsa10asdffdsa11asdffdsa12asdffdsa13asdffdsa14asdffdsa15asdffdsa16asdffdsa17asdffdsa18asdffdsa19asdffdsa20asdffdsa21asdffdsa22asdff"),CFileMan::EOverWrite);
-		test(r==KErrNone);
+		test_KErrNone(r);
 
 		//	Two long directory names - makes paths invalid
 		MakeDir(_L("\\TEST\\LONG\\NAME\\FGHIJ"));
@@ -1025,7 +1033,7 @@
 		MakeFile(_L("\\TEST\\LONG\\NAME\\FGHIJ\\ELEPHANT01ELEPHANT02ELEPHANT03ELEPHANT04"));
 		MakeFile(_L("\\TEST\\LONG\\NAME\\FGHIJ\\FILEFILE01FILEFILE02FILEFILE03FILEFILE04"));
 		r=gFileMan->Rename(_L("\\TEST\\LONG"),_L("\\TEST\\asdffdsa01asdffdsa02asdffdsa03asdffdsa04asdffdsa05asdffdsa06asdffdsa07asdffdsa08asdffdsa09asdffdsa10asdffdsa11asdffdsa12asdffdsa13asdffdsa14asdffdsa15asdffdsa16asdffdsa17asdffdsa18asdffdsa19asdffdsa20as\\fdsa21asdffds"),CFileMan::EOverWrite);
-		test(r==KErrNone);
+		test_KErrNone(r);
 	
 		MakeDir(_L("\\START\\ASDFFDSA\\"));
 		}
@@ -1106,30 +1114,30 @@
 	if ((!gAsynch)&&(testingInvalidPathLengths))
 		{
 		r=gFileMan->Move(_L("\\START\\asdffdsa01asdffdsa02asdffdsa03asdffdsa04asdffdsa05asdffdsa06asdffdsa07asdffdsa08asdffdsa09asdffdsa10asdffdsa11asdffdsa12asdffdsa13asdffdsa14asdffdsa15asdffdsa16asdffdsa17asdffdsa18asdffdsa19asdffdsa20asdffdsa21asdffdsa22asdff\\*.*"),_L("\\FINISH\\"));
-		test(r==KErrNone);
+		test_KErrNone(r);
 		
 		r=gFileMan->Move(_L("\\TEST\\asdffdsa01asdffdsa02asdffdsa03asdffdsa04asdffdsa05asdffdsa06asdffdsa07asdffdsa08asdffdsa09asdffdsa10asdffdsa11asdffdsa12asdffdsa13asdffdsa14asdffdsa15asdffdsa16asdffdsa17asdffdsa18asdffdsa19asdffdsa20as\\fdsa21asdffds\\*.*"),_L("\\FINISH\\"), CFileMan::EOverWrite | CFileMan::ERecurse);
-		test(r==KErrNone);
+		test_KErrNone(r);
 
 		r=gFileMan->RmDir(_L("\\START\\"));
-		test(r==KErrNone);
+		test_KErrNone(r);
 		r=gFileMan->RmDir(_L("\\FINISH\\"));
-		test(r==KErrNone);
+		test_KErrNone(r);
 		}
 	if ((gAsynch)&&(testingInvalidPathLengths))
 		{
 		r=gFileMan->Move(_L("\\START\\asdffdsa01asdffdsa02asdffdsa03asdffdsa04asdffdsa05asdffdsa06asdffdsa07asdffdsa08asdffdsa09asdffdsa10asdffdsa11asdffdsa12asdffdsa13asdffdsa14asdffdsa15asdffdsa16asdffdsa17asdffdsa18asdffdsa19asdffdsa20asdffdsa21asdffdsa22asdff\\*.*"),_L("\\FINISH\\"),CFileMan::EOverWrite,gStat);
 		User::WaitForRequest(gStat);
-		test(r==KErrNone);
+		test_KErrNone(r);
 		r=gFileMan->Move(_L("\\TEST\\asdffdsa01asdffdsa02asdffdsa03asdffdsa04asdffdsa05asdffdsa06asdffdsa07asdffdsa08asdffdsa09asdffdsa10asdffdsa11asdffdsa12asdffdsa13asdffdsa14asdffdsa15asdffdsa16asdffdsa17asdffdsa18asdffdsa19asdffdsa20as\\fdsa21asdffds\\*.*"),_L("\\FINISH\\"), CFileMan::EOverWrite | CFileMan::ERecurse,gStat);
 		User::WaitForRequest(gStat);
-		test(r==KErrNone);
+		test_KErrNone(r);
 		r=gFileMan->RmDir(_L("\\START\\"),gStat);
 		WaitForSuccess();
-		test(r==KErrNone);
+		test_KErrNone(r);
 		r=gFileMan->RmDir(_L("\\FINISH\\"),gStat);
 		WaitForSuccess();
-		test(r==KErrNone);
+		test_KErrNone(r);
 		}
 
 	if (!gAsynch)
@@ -1157,7 +1165,7 @@
 		r=gFileMan->Move(_L("\\F32-TST\\TFMAN\\DELDIR\\FILE1.TXT"),_L("\\F32-TST\\TFMAN\\MoveDIR\\FILE1.TXT"),0,gStat);
 	TestResult(r,KErrAlreadyExists);
 	r=TheFs.Delete(_L("\\F32-TST\\TFMAN\\DELDIR\\FILE1.TXT"));
-	test(r==KErrNone);
+	test_KErrNone(r);
 
 	test.Next(_L("Check files have been moved"));
 	RmDir(_L("\\F32-TST\\TFMAN\\AFTER\\*"));
@@ -1176,7 +1184,7 @@
 	if (testingInvalidPathLengths)
 		{
 		r=gFileMan->RmDir(_L("\\TEST\\"));
-		test(r==KErrNone);
+		test_KErrNone(r);
 		}
 	
 	TestDEF121663(); // Test moving directory to its subdirectory
@@ -1207,9 +1215,9 @@
 	CFileMan* fman=CFileMan::NewL(TheFs);
 	TRequestStatus stat1;
 	TInt r=fman->Delete(_L("\\F32-TST\\TFMAN\\FMAN1\\*.*"),0,stat1);
-	test(r==KErrNone);
+	test_KErrNone(r);
 	r=gFileMan->Rename(_L("\\F32-TST\\TFMAN\\FMAN2\\*.TXT"),_L("\\F32-TST\\TFMAN\\FMAN2\\*.EXT"),0,gStat);
-	test(r==KErrNone);
+	test_KErrNone(r);
 	FOREVER
 		{
 		if (stat1!=KRequestPending && gStat!=KRequestPending)
@@ -1243,11 +1251,11 @@
 	MakeFile(_L("\\DEF092084\\FILE1.TXT"));
 	
 	TInt r = gFileMan->Rename(_L("\\DEF092084\\*.TXT"),_L("\\DEF092084\\*.DDB"), CFileMan::EOverWrite);
-	test(r==KErrNone); 
+	test_KErrNone(r); 
 	CheckFileExists(_L("\\DEF092084\\FILE1.DDB"), KErrNone);
 	
 	r = gFileMan->Rename(_L("\\DEF092084\\?*.DD?"),_L("\\DEF092084\\?*.TXT"), CFileMan::EOverWrite);
-	test(r==KErrNone); 
+	test_KErrNone(r); 
 	CheckFileExists(_L("\\DEF092084\\FILE1.TXT"), KErrNone);
 	
 	RmDir(_L("\\DEF092084\\"));  
@@ -1316,44 +1324,44 @@
 	test.Printf(_L("1: Create Test File\n"));
 	RFile testFile;
 	r = testFile.Create(TheFs, KTestFile, EFileRead | EFileWrite);
-	test(r == KErrNone);
+	test_KErrNone(r);
 
 	test.Printf(_L("2: Populate testFile1 Data\n"));
 	r = testFile.Write(_L8("ABCDEFGHIJKLMNOPQRSTUVWXYZ"));
-	test(r == KErrNone);
+	test_KErrNone(r);
 
 	test.Printf(_L("3: Get Initial Attributes\n"));
 	TUint atts = 0;
 	r = testFile.Att(atts);
-	test(r == KErrNone);
+	test_KErrNone(r);
 	test.Printf(_L("   Attributes: %08x"), atts);
 
 	test.Printf(_L("4: Set KEntryAttHidden Attribute\n"));
 	r = testFile.SetAtt(KEntryAttHidden, 0);
-	test(r == KErrNone);
+	test_KErrNone(r);
 
 	test.Printf(_L("5: Verify KEntryAttHidden Attribute is set for testFile1\n"));
 	r = testFile.Att(atts);
-	test(r == KErrNone);
+	test_KErrNone(r);
 	test(atts & KEntryAttHidden);
 
 	test.Printf(_L("6: Read Data from beginning of file testFile1\n"));
 	TBuf8<4> data;
 	r = testFile.Read(0, data);
-	test(r == KErrNone);
+	test_KErrNone(r);
 
 	test.Printf(_L("7: Close all the testFiles\n"));
 	testFile.Close();
 	
 	test.Printf(_L("8: Verify KEntryAttHidden is present\n"));
 	r = TheFs.Att(KTestFile, atts);
-	test(r == KErrNone);
+	test_KErrNone(r);
 	test.Printf(_L("  Finally, attributes are : %08x\n"), atts);
 	test(atts & KEntryAttHidden);
 	
 	test.Printf(_L("9: Delete Test File\n"));
 	r = TheFs.Delete(KTestFile);
-	test(r == KErrNone || r == KErrNotFound);
+	test_Value(r, r == KErrNone || r == KErrNotFound);
 	}
 	
 LOCAL_C void TestDEF113299()
@@ -1413,7 +1421,7 @@
 		MakeFile(_L("\\LONGNAME\\DINOSAUR01DINOSAUR02DINOSAUR03DINOSAUR04.txt"));
 		MakeFile(_L("\\LONGNAME\\FILEFILE01FILEFILE02FILEFILE03FILEFILE04.bin"));
 		r=gFileMan->Rename(_L("\\LONGNAME"),_L("\\asdffdsa01asdffdsa02asdffdsa03asdffdsa04asdffdsa05asdffdsa06asdffdsa07asdffdsa08asdffdsa09asdffdsa10asdffdsa11asdffdsa12asdffdsa13asdffdsa14asdffdsa15asdffdsa16asdffdsa17asdffdsa18asdffdsa19asdffdsa20asdffdsa21asdffdsa22asdff"),CFileMan::EOverWrite);
-		test(r==KErrNone);
+		test_KErrNone(r);
 
 	//	Two long directory names - makes paths invalid
 		MakeDir(_L("\\TEST\\LONG\\NAME\\FGHIJ"));
@@ -1421,7 +1429,7 @@
 		MakeFile(_L("\\TEST\\LONG\\NAME\\FGHIJ\\ELEPHANT01ELEPHANT02ELEPHANT03ELEPHANT.txt"));
 		MakeFile(_L("\\TEST\\LONG\\NAME\\FGHIJ\\FILEFILE01FILEFILE02FILEFILE03FILEFILE.txt"));
 		r=gFileMan->Rename(_L("\\TEST\\LONG"),_L("\\TEST\\asdffdsa01asdffdsa02asdffdsa03asdffdsa04asdffdsa05asdffdsa06asdffdsa07asdffdsa08asdffdsa09asdffdsa10asdffdsa11asdffdsa12asdffdsa13asdffdsa14asdffdsa15asdffdsa16asdffdsa17asdffdsa18asdffdsa19asdffdsa20as\\fdsa21asdffds"),CFileMan::EOverWrite);
-		test(r==KErrNone);
+		test_KErrNone(r);
 		}
 
 	//testing invalid source path at the beginning:
@@ -1494,28 +1502,28 @@
 	if (!gAsynch)
 		{
 		r=gFileMan->Rename(_L("\\F32-TST\\TFMAN\\RENAME\\SRC\\*.TXT"),_L("\\F32-TST\\TFMAN\\RENAME\\DEST\\*.DDB"),CFileMan::EOverWrite);
-		test(r==KErrNone);
+		test_KErrNone(r);
 		if (testingInvalidPathLengths)
 			{
 			r=gFileMan->Rename(_L("\\asdffdsa01asdffdsa02asdffdsa03asdffdsa04asdffdsa05asdffdsa06asdffdsa07asdffdsa08asdffdsa09asdffdsa10asdffdsa11asdffdsa12asdffdsa13asdffdsa14asdffdsa15asdffdsa16asdffdsa17asdffdsa18asdffdsa19asdffdsa20asdffdsa21asdffdsa22asdff\\elephant01elephant02elephant03elephant04.txt"),_L("\\asdffdsa01asdffdsa02asdffdsa03asdffdsa04asdffdsa05asdffdsa06asdffdsa07asdffdsa08asdffdsa09asdffdsa10asdffdsa11asdffdsa12asdffdsa13asdffdsa14asdffdsa15asdffdsa16asdffdsa17asdffdsa18asdffdsa19asdffdsa20asdffdsa21asdffdsa22asdff\\elephant01elephant02elephant03elephant04.bin"));
-			test(r==KErrBadName);
+			test_Equal(KErrBadName, r);
 			r=gFileMan->Rename(_L("\\asdffdsa01asdffdsa02asdffdsa03asdffdsa04asdffdsa05asdffdsa06asdffdsa07asdffdsa08asdffdsa09asdffdsa10asdffdsa11asdffdsa12asdffdsa13asdffdsa14asdffdsa15asdffdsa16asdffdsa17asdffdsa18asdffdsa19asdffdsa20asdffdsa21asdffdsa22asdff"),_L("\\Shortened"),CFileMan::EOverWrite);
-			test(r==KErrNone);
+			test_KErrNone(r);
 			r=gFileMan->Rename(_L("\\Shortened\\*.txt"),_L("\\Shortened\\*.cat"));
-			test(r==KErrNone);
+			test_KErrNone(r);
 			r=gFileMan->RmDir(_L("\\Shortened\\"));
-			test(r==KErrNone);
+			test_KErrNone(r);
 
 			r=gFileMan->Rename(_L("\\TEST\\asdffdsa01asdffdsa02asdffdsa03asdffdsa04asdffdsa05asdffdsa06asdffdsa07asdffdsa08asdffdsa09asdffdsa10asdffdsa11asdffdsa12asdffdsa13asdffdsa14asdffdsa15asdffdsa16asdffdsa17asdffdsa18asdffdsa19asdffdsa20as\\fdsa21asdffds"),_L("\\TEST\\asdffdsa01asdffdsa02asdffdsa03asdffdsa04asdffdsa05asdffdsa06asdffdsa07asdffdsa08asdffdsa09asdffdsa10asdffdsa11asdffdsa12asdffdsa13asdffdsa14asdffdsa15asdffdsa16asdffdsa17asdffdsa18asdffdsa19asdffdsa20as\\NotSoShortened"),CFileMan::EOverWrite);
-			test(r==KErrNone);
+			test_KErrNone(r);
 			r=gFileMan->Rename(_L("\\TEST"),_L("\\OXO!"));
-			test(r==KErrNone);
+			test_KErrNone(r);
 			r=gFileMan->Rename(_L("\\OXO!\\asdffdsa01asdffdsa02asdffdsa03asdffdsa04asdffdsa05asdffdsa06asdffdsa07asdffdsa08asdffdsa09asdffdsa10asdffdsa11asdffdsa12asdffdsa13asdffdsa14asdffdsa15asdffdsa16asdffdsa17asdffdsa18asdffdsa19asdffdsa20as"),_L("\\OXO!\\Shorter"));
-			test(r==KErrNone);
+			test_KErrNone(r);
 			r=gFileMan->Rename(_L("\\OXO!\\Shorter\\NotSoShortened\\NAME\\FGHIJ\\*.txt"),_L("\\TEST\\Shorter\\NotSoShortened\\NAME\\FGHIJ\\*.cat"));
-			test(r==KErrNone);
+			test_KErrNone(r);
 			r=gFileMan->RmDir(_L("\\OXO!\\"));
-			test(r==KErrNone);
+			test_KErrNone(r);
 
 			}
 		}
@@ -1526,7 +1534,7 @@
 		if (testingInvalidPathLengths)
 			{
 			r=gFileMan->Rename(_L("\\asdffdsa01asdffdsa02asdffdsa03asdffdsa04asdffdsa05asdffdsa06asdffdsa07asdffdsa08asdffdsa09asdffdsa10asdffdsa11asdffdsa12asdffdsa13asdffdsa14asdffdsa15asdffdsa16asdffdsa17asdffdsa18asdffdsa19asdffdsa20asdffdsa21asdffdsa22asdff\\elephant01elephant02elephant03elephant04.txt"),_L("\\asdffdsa01asdffdsa02asdffdsa03asdffdsa04asdffdsa05asdffdsa06asdffdsa07asdffdsa08asdffdsa09asdffdsa10asdffdsa11asdffdsa12asdffdsa13asdffdsa14asdffdsa15asdffdsa16asdffdsa17asdffdsa18asdffdsa19asdffdsa20asdffdsa21asdffdsa22asdff\\elephant01elephant02elephant03elephant04.bin"));
-			test(r==KErrBadName);
+			test_Equal(KErrBadName, r);
 			r=gFileMan->Rename(_L("\\asdffdsa01asdffdsa02asdffdsa03asdffdsa04asdffdsa05asdffdsa06asdffdsa07asdffdsa08asdffdsa09asdffdsa10asdffdsa11asdffdsa12asdffdsa13asdffdsa14asdffdsa15asdffdsa16asdffdsa17asdffdsa18asdffdsa19asdffdsa20asdffdsa21asdffdsa22asdff"),_L("\\Shortened"),CFileMan::EOverWrite,gStat);
 			WaitForSuccess();
 			r=gFileMan->Rename(_L("\\Shortened\\*.txt"),_L("\\Shortened\\*.bin"),0,gStat);
@@ -1536,20 +1544,20 @@
 
 			r=gFileMan->Rename(_L("\\TEST\\asdffdsa01asdffdsa02asdffdsa03asdffdsa04asdffdsa05asdffdsa06asdffdsa07asdffdsa08asdffdsa09asdffdsa10asdffdsa11asdffdsa12asdffdsa13asdffdsa14asdffdsa15asdffdsa16asdffdsa17asdffdsa18asdffdsa19asdffdsa20as\\fdsa21asdffds"),_L("\\TEST\\asdffdsa01asdffdsa02asdffdsa03asdffdsa04asdffdsa05asdffdsa06asdffdsa07asdffdsa08asdffdsa09asdffdsa10asdffdsa11asdffdsa12asdffdsa13asdffdsa14asdffdsa15asdffdsa16asdffdsa17asdffdsa18asdffdsa19asdffdsa20as\\NotSoShortened"),CFileMan::EOverWrite,gStat);
 			WaitForSuccess();
-			test(r==KErrNone);
+			test_KErrNone(r);
 			r=gFileMan->Rename(_L("\\TEST"),_L("\\OXO!"),CFileMan::EOverWrite,gStat);
 			WaitForSuccess();
-			test(r==KErrNone);
+			test_KErrNone(r);
 			r=gFileMan->Rename(_L("\\OXO!\\asdffdsa01asdffdsa02asdffdsa03asdffdsa04asdffdsa05asdffdsa06asdffdsa07asdffdsa08asdffdsa09asdffdsa10asdffdsa11asdffdsa12asdffdsa13asdffdsa14asdffdsa15asdffdsa16asdffdsa17asdffdsa18asdffdsa19asdffdsa20as"),_L("\\OXO!\\Shorter"),CFileMan::EOverWrite,gStat);
 			WaitForSuccess();
-			test(r==KErrNone);
+			test_KErrNone(r);
 			r=gFileMan->Rename(_L("\\OXO!\\Shorter\\NotSoShortened\\NAME\\FGHIJ\\*.txt"),_L("\\TEST\\Shorter\\NotSoShortened\\NAME\\FGHIJ\\*.cat"),CFileMan::EOverWrite,gStat);
 			WaitForSuccess();
-			test(r==KErrNone);
+			test_KErrNone(r);
 			r=gFileMan->RmDir(_L("\\OXO!\\"));
-			test(r==KErrNone);
+			test_KErrNone(r);
 			r=gFileMan->RmDir(_L("\\TEST\\"));
-			test(r==KErrNone);
+			test_KErrNone(r);
 			}
 		}
 	RmDir(_L("\\F32-TST\\TFMAN\\after\\"));
@@ -1598,28 +1606,28 @@
 	// For this, default should be session path
 	TFileName sessionPath;
 	TInt err=TheFs.SessionPath(sessionPath);
-	test(err==KErrNone);
+	test_KErrNone(err);
 
 	SetupDirectories(ETrue, NULL);
 	err=TheFs.SetSessionPath(_L("\\F32-TST\\TFMAN\\dest\\"));
-	test(err == KErrNone);
+	test_KErrNone(err);
 
 	err = gFileMan->Rename(_L("\\F32-TST\\TFMAN\\source"), _L(""));
-	test(err == KErrNone);
+	test_KErrNone(err);
 	Compare(_L("\\F32-TST\\TFMAN\\compare\\*"), _L("\\F32-TST\\TFMAN\\dest\\source\\*"));
 
 	RmDir(_L("\\F32-TST\\TFMAN\\dest\\"));
 	RmDir(_L("\\F32-TST\\TFMAN\\source\\"));
 	SetupDirectories(ETrue, NULL);
 	err=TheFs.SetSessionPath(_L("\\F32-TST\\TFMAN\\source\\"));
-	test(err == KErrNone);
+	test_KErrNone(err);
 
 	err = gFileMan->Rename(_L(""), _L("\\F32-TST\\TFMAN\\dest\\"));
-	test(err == KErrNone);
+	test_KErrNone(err);
 	Compare(_L("\\F32-TST\\TFMAN\\compare\\*"), _L("\\F32-TST\\TFMAN\\dest\\*"));
 		
 	err=TheFs.SetSessionPath(sessionPath);
-	test(err==KErrNone);
+	test_KErrNone(err);
 	
 	TestINC109754(); // Test empty source directory should exist after contents being renamed
 	TestDEF092084(); // Test wildcards are replaced with letters from the matched file
@@ -1641,12 +1649,12 @@
 	if (!gAsynch)
 		{
 		TInt r=gFileMan->Attribs(_L("\\F32-TST\\TFMAN\\ATTRIBS\\AT*.AT"),setMask,clearMask,TTime(0));
-		test(r==KErrNone);
+		test_KErrNone(r);
 		}
 	else
 		{
 		TInt r=gFileMan->Attribs(_L("\\F32-TST\\TFMAN\\ATTRIBS\\AT*.AT"),setMask,clearMask,TTime(0),0,gStat);
-		test(r==KErrNone);
+		test_KErrNone(r);
 		WaitForSuccess();
 		}
 	
@@ -1655,13 +1663,13 @@
 	CDir* entryList;
 	scan->NextL(entryList);
 	TInt count=entryList->Count();
-	test(count==2);
+	test_Equal(2, count);
 	TEntry entry=(*entryList)[0];
 	test(entry.iName.MatchF(_L("attrib1.AT"))!=KErrNotFound);
-	test(entry.iAtt==KEntryAttReadOnly);
+	test_Equal(KEntryAttReadOnly, entry.iAtt);
 	entry=(*entryList)[1];
 	test(entry.iName.MatchF(_L("attrib2.AT"))!=KErrNotFound);
-	test(entry.iAtt==KEntryAttReadOnly);
+	test_Equal(KEntryAttReadOnly, entry.iAtt);
 	delete entryList;
 
 	TDateTime dateTime(1990,ENovember,20,9,5,0,0);
@@ -1670,22 +1678,22 @@
 	if (!gAsynch)
 		{
 		TInt r=gFileMan->Attribs(_L("\\F32-TST\\TFMAN\\ATTRIBS\\AT*.AT"),0,legalAttMask,time);
-		test(r==KErrNone);
+		test_KErrNone(r);
 		}
 	else
 		{
 		TInt r=gFileMan->Attribs(_L("\\F32-TST\\TFMAN\\ATTRIBS\\AT*.AT"),0,legalAttMask,time,0,gStat);
-		test(r==KErrNone);
+		test_KErrNone(r);
 		WaitForSuccess();
 		}
 	
 	scan->SetScanDataL(_L("\\F32-TST\\TFMAN\\ATTRIBS\\*"),KEntryAttMaskSupported,ESortByName);
 	scan->NextL(entryList);
 	count=entryList->Count();
-	test(count==2);
+	test_Equal(2, count);
 	entry=(*entryList)[0];
 	test(entry.iName.MatchF(_L("attrib1.AT"))!=KErrNotFound);
-	test(entry.iAtt==0);
+	test_Equal(0, entry.iAtt);
 	TDateTime dt=(entry.iModified).DateTime();
 	test(dt.Year()==dateTime.Year());
 	test(dt.Month()==dateTime.Month());
@@ -1696,7 +1704,7 @@
 	test(entry.iModified==time);
 	entry=(*entryList)[1];
 	test(entry.iName.MatchF(_L("attrib2.AT"))!=KErrNotFound);
-	test(entry.iAtt==0);
+	test_Equal(0, entry.iAtt);
 	test(entry.iModified==time);
 	delete entryList;
 	delete scan;
@@ -1727,10 +1735,10 @@
 	if(oldname.Length() >= KMaxFileName-5) // if not, it means that we won't be calling ShrinkNames !!
 		{
 		TInt r = gFileMan->Rename(_L("\\12345678\\Book\\12345678"),_L("\\INC091841\\Book\\012-235-abcd"),0);
-		test(r==KErrNone);  
+		test_KErrNone(r);  
 		CDir* dir;
 		r = TheFs.GetDir(_L("\\INC091841\\Book\\012-235-abcd\\"), KEntryAttNormal, ESortNone, dir);
-		test(r==KErrNone);   
+		test_KErrNone(r);   
 		r = KErrNotFound;
 		TInt dirlen = sizeof("\\INC091841\\Book\\012-235-abcd\\");
 		for(TInt i=0; r==KErrNotFound && i<dir->Count(); i++)
@@ -1741,9 +1749,9 @@
 				}
 			}
 		delete dir;
-		test(r==KErrNone);  
+		test_KErrNone(r);  
 		r = gFileMan->RmDir(_L("\\INC091841\\"));
-		test(r==KErrNone);  
+		test_KErrNone(r);  
 		}
 	RmDir(_L("\\12345678\\"));
 	}
@@ -1774,7 +1782,7 @@
 		MakeFile(_L("\\LONGNAMETEST\\ELEPHANT01ELEPHANT02ELEPHANT03ELEPHANT04"));
 		MakeFile(_L("\\LONGNAMETEST\\FILEFILE01FILEFILE02FILEFILE03FILEFILE04"));
 		r=gFileMan->Rename(_L("\\LONGNAMETEST"),_L("\\asdffdsa01asdffdsa02asdffdsa03asdffdsa04asdffdsa05asdffdsa06asdffdsa07asdffdsa08asdffdsa09asdffdsa10asdffdsa11asdffdsa12asdffdsa13asdffdsa14asdffdsa15asdffdsa16asdffdsa17asdffdsa18asdffdsa19asdffdsa20asdffdsa21asdffdsa22asdff"),CFileMan::EOverWrite);
-		test(r==KErrNone);
+		test_KErrNone(r);
 		}
 
 	//testing invalid source path at the beginning:
@@ -1813,72 +1821,72 @@
 	if (!gAsynch)
 		{
 		r=gFileMan->RmDir(_L("\\F32-TST\\TFMAN\\RMDIR\\*.AT"));
-		test(r==KErrNone);
+		test_KErrNone(r);
 			if (testingInvalidPathLengths)
 			{
 			r=gFileMan->RmDir(_L("\\asdffdsa01asdffdsa02asdffdsa03asdffdsa04asdffdsa05asdffdsa06asdffdsa07asdffdsa08asdffdsa09asdffdsa10asdffdsa11asdffdsa12asdffdsa13asdffdsa14asdffdsa15asdffdsa16asdffdsa17asdffdsa18asdffdsa19asdffdsa20asdffdsa21asdffdsa22asdff\\"));
-			test(r==KErrNone);
+			test_KErrNone(r);
 			}
 		}
 	else
 		{
 		r=gFileMan->RmDir(_L("\\F32-TST\\TFMAN\\RMDIR\\*.AT"),gStat);
-		test(r==KErrNone);
+		test_KErrNone(r);
 		WaitForSuccess();
 		if (testingInvalidPathLengths)
 			{
 			r=gFileMan->RmDir(_L("\\asdffdsa01asdffdsa02asdffdsa03asdffdsa04asdffdsa05asdffdsa06asdffdsa07asdffdsa08asdffdsa09asdffdsa10asdffdsa11asdffdsa12asdffdsa13asdffdsa14asdffdsa15asdffdsa16asdffdsa17asdffdsa18asdffdsa19asdffdsa20asdffdsa21asdffdsa22asdff\\"),gStat);
-			test(r==KErrNone);
+			test_KErrNone(r);
 			WaitForSuccess();
 			}
 		}
 
 	TEntry entry;
 	r=TheFs.Entry(_L("\\F32-TST\\TFMAN\\RMDIR"),entry);
-	test(r==KErrNotFound);
+	test_Equal(KErrNotFound, r);
 
 	MakeDir(_L("\\F32-TST\\TFMAN\\READONLY\\"));
 	r=TheFs.SetAtt(_L("\\F32-TST\\TFMAN\\READONLY\\"),KEntryAttReadOnly,0);
-	test(r==KErrNone);
+	test_KErrNone(r);
 
 	if (!gAsynch)
 		{
 		r=gFileMan->RmDir(_L("\\F32-TST\\TFMAN\\READONLY\\"));
-		test(r==KErrAccessDenied);
+		test_Equal(KErrAccessDenied, r);
 		}
 	else
 		{
 		r=gFileMan->RmDir(_L("\\F32-TST\\TFMAN\\READONLY\\"),gStat);
-		test(r==KErrNone);
+		test_KErrNone(r);
 		WaitForResult(KErrAccessDenied);
 		}
 
 	r=TheFs.SetAtt(_L("\\F32-TST\\TFMAN\\READONLY\\"),0,KEntryAttReadOnly);
-	test(r==KErrNone);
+	test_KErrNone(r);
 
 	r=gFileMan->RmDir(_L("\\F32-TST\\TFMAN\\READONLY\\"));
-	test(r==KErrNone);
+	test_KErrNone(r);
 	
 	// Test behaviour for omitted parameters
 	// For this, default should be session path
 	TFileName sessionPath;
 	r=TheFs.SessionPath(sessionPath);
-	test(r==KErrNone);
+	test_KErrNone(r);
 
 	SetupDirectories(ETrue, NULL);
 	r=TheFs.SetSessionPath(_L("\\F32-TST\\TFMAN\\source\\"));
 
 	// Default removal of session path
 	r=gFileMan->RmDir(_L(""));
-	test(r==KErrNone);
+	test_KErrNone(r);
 
 	r=TheFs.SetSessionPath(sessionPath);
 	
 	r = gFileMan->Rename(_L("\\F32-TST\\TFMAN\\source\\subdir"), _L("\\F32-TST\\TFMAN\\source\\tofail"), CFileMan::ERecurse);
-	test(r == KErrPathNotFound);
+	test_Equal(KErrPathNotFound, r);
 	
 	r = gFileMan->RmDir(_L("\\F32-TST\\TFMAN\\"));
-	test(r==KErrNone);
+	test_KErrNone(r);
 	MakeDir(_L("\\F32-TST\\TFMAN\\"));
 	
 	if(testingInvalidPathLengths)
@@ -1905,28 +1913,28 @@
 
 	RFile file;
 	r = file.Open(TheFs,_L("\\F32-TST\\TFMAN\\OPENFILE\\FILE.TXT"), EFileRead | EFileShareExclusive);
-	test(r==KErrNone);
+	test_KErrNone(r);
 
 	if (!gAsynch)
 		{
 		r=gFileMan->RmDir(_L("\\F32-TST\\TFMAN\\OPENFILE\\"));
-		test(r==KErrInUse);
+		test_Equal(KErrInUse, r);
 		
 		file.Close();
 		
 		r=gFileMan->RmDir(_L("\\F32-TST\\TFMAN\\OPENFILE\\"));
-		test(r==KErrNone);
+		test_KErrNone(r);
 		}
 	else
 		{
 		r=gFileMan->RmDir(_L("\\F32-TST\\TFMAN\\OPENFILE\\"), gStat);
-		test(r==KErrNone);
+		test_KErrNone(r);
 		WaitForResult(KErrInUse);
 
 		file.Close();
 
 		r=gFileMan->RmDir(_L("\\F32-TST\\TFMAN\\OPENFILE\\"), gStat);
-		test(r==KErrNone);
+		test_KErrNone(r);
 		WaitForResult(KErrNone);
 		}
 
@@ -1976,7 +1984,7 @@
 	// For this, default should be session path
 	TFileName sessionPath;
 	r=TheFs.SessionPath(sessionPath);
-	test(r==KErrNone);
+	test_KErrNone(r);
 
 	RmDir(_L("\\F32-TST\\TFMAN\\COPYDIR\\"));
 	MakeDir(_L("\\F32-TST\\TFMAN\\COPYDIR\\"));
@@ -2005,7 +2013,7 @@
 	RmDir(_L("\\F32-TST\\TFMAN\\COPYDIR\\"));
 	RmDir(_L("\\F32-TST\\TFMAN\\DELDIR\\"));
 	r=TheFs.SetSessionPath(sessionPath);
-	test(r==KErrNone);
+	test_KErrNone(r);
 	}
 	
 LOCAL_C void TestRecursiveAttribs()
@@ -2021,12 +2029,12 @@
 	if (!gAsynch)
 		{
 		TInt r=gFileMan->Attribs(_L("\\F32-TST\\TFMAN\\RECATTRIBS\\"),KEntryAttReadOnly,0,TTime(0),CFileMan::ERecurse);
-		test(r==KErrNone);
+		test_KErrNone(r);
 		}
 	else
 		{
 		TInt r=gFileMan->Attribs(_L("\\F32-TST\\TFMAN\\RECATTRIBS\\"),KEntryAttReadOnly,0,TTime(0),CFileMan::ERecurse,gStat);
-		test(r==KErrNone);
+		test_KErrNone(r);
 		WaitForSuccess();
 		}
 
@@ -2035,32 +2043,44 @@
 	scan->SetScanDataL(_L("\\F32-TST\\TFMAN\\RECATTRIBS\\*"),KEntryAttMaskSupported,ESortByName);
 	scan->NextL(entryList);
 	TInt count=entryList->Count();
-	test(count==3);
+	test_Equal(3, count);
 	TEntry entry=(*entryList)[0];
 	test(entry.iName.MatchF(_L("ATTRIB1.AT"))!=KErrNotFound);
 	if (!IsTestingLFFS())
-		test(entry.iAtt==(KEntryAttReadOnly|KEntryAttArchive));
+		{
+		test_Equal((KEntryAttReadOnly|KEntryAttArchive), entry.iAtt);
+		}
 	else
+		{
 		test(entry.iAtt&KEntryAttReadOnly); // ???
+		}
 	entry=(*entryList)[1];
 	test(entry.iName.MatchF(_L("ATTRIB2.AT"))!=KErrNotFound);
 	if (!IsTestingLFFS())
-		test(entry.iAtt==(KEntryAttReadOnly|KEntryAttArchive));
+		{
+		test_Equal((KEntryAttReadOnly|KEntryAttArchive), entry.iAtt);
+		}
 	else
+		{
 		test(entry.iAtt&KEntryAttReadOnly); // ???
+		}
 	entry=(*entryList)[2];
 	test(entry.iName.MatchF(_L("SUBDIR"))!=KErrNotFound);
 	delete entryList;
 
 	scan->NextL(entryList);
 	count=entryList->Count();
-	test(count==1);
+	test_Equal(1, count);
 	entry=(*entryList)[0];
 	test(entry.iName.MatchF(_L("ATFILE.TXT"))!=KErrNotFound);
 	if (!IsTestingLFFS())
-		test(entry.iAtt==(KEntryAttReadOnly|KEntryAttArchive));
+		{
+		test_Equal((KEntryAttReadOnly|KEntryAttArchive), entry.iAtt);
+		}
 	else
+		{
 		test(entry.iAtt&KEntryAttReadOnly); // ???
+		}
 	delete entryList;
 
 	scan->NextL(entryList);
@@ -2069,35 +2089,35 @@
 	if (!gAsynch)
 		{
 		TInt r=gFileMan->Attribs(_L("\\F32-TST\\TFMAN\\RECATTRIBS\\"),0,KEntryAttReadOnly|KEntryAttArchive,TTime(0),CFileMan::ERecurse);
-		test(r==KErrNone);
+		test_KErrNone(r);
 		}
 	else
 		{
 		TInt r=gFileMan->Attribs(_L("\\F32-TST\\TFMAN\\RECATTRIBS\\"),0,KEntryAttReadOnly|KEntryAttArchive,TTime(0),CFileMan::ERecurse,gStat);
-		test(r==KErrNone);
+		test_KErrNone(r);
 		WaitForSuccess();
 		}
 
 	scan->SetScanDataL(_L("\\F32-TST\\TFMAN\\RECATTRIBS\\*"),KEntryAttMaskSupported,ESortByName);
 	scan->NextL(entryList);
 	count=entryList->Count();
-	test(count==3);
+	test_Equal(3, count);
 	entry=(*entryList)[0];
 	test(entry.iName.MatchF(_L("ATTRIB1.AT"))!=KErrNotFound);
-	test(entry.iAtt==KEntryAttNormal);
+	test_Equal(KEntryAttNormal, entry.iAtt);
 	entry=(*entryList)[1];
 	test(entry.iName.MatchF(_L("ATTRIB2.AT"))!=KErrNotFound);
-	test(entry.iAtt==KEntryAttNormal);
+	test_Equal(KEntryAttNormal, entry.iAtt);
 	entry=(*entryList)[2];
 	test(entry.iName.MatchF(_L("SUBDIR"))!=KErrNotFound);
 	delete entryList;
 
 	scan->NextL(entryList);
 	count=entryList->Count();
-	test(count==1);
+	test_Equal(1, count);
 	entry=(*entryList)[0];
 	test(entry.iName.MatchF(_L("ATFILE.TXT"))!=KErrNotFound);
-	test(entry.iAtt==KEntryAttNormal);
+	test_Equal(KEntryAttNormal, entry.iAtt);
 	delete entryList;
 
 	scan->NextL(entryList);
@@ -2119,12 +2139,12 @@
 	if (!gAsynch)
 		{
 		TInt r=gFileMan->Delete(_L("\\F32-TST\\TFMAN\\RECDELETE\\*.PLP"),CFileMan::ERecurse);
-		test(r==KErrNone);
+		test_KErrNone(r);
 		}
 	else
 		{
 		TInt r=gFileMan->Delete(_L("\\F32-TST\\TFMAN\\RECDELETE\\*.PLP"),CFileMan::ERecurse,gStat);
-		test(r==KErrNone);
+		test_KErrNone(r);
 		WaitForSuccess();
 		}
 
@@ -2230,7 +2250,7 @@
 		err = gFileMan->Move(_L("\\F32-TST\\TFMAN\\INC108401\\src"), _L("\\F32-TST\\TFMAN\\INC108401\\dest\\"), 0, gStat);
 	test.Next(_L("Test INC108401 : SAME DRIVE with 0"));
 	TestResult(err);
-	// test(err==KErrNone);
+	// test_KErrNone(err);
 	RmDir(_L("\\F32-TST\\TFMAN\\INC108401\\"));
 	
 	// case for gFileMan->Move(_L("\\F32-TST\\TFMAN\\INC108401\\src"), _L("\\F32-TST\\TFMAN\\INC108401\\dest\\"), CFileMan::EOverWrite);
@@ -2247,7 +2267,7 @@
 		err = gFileMan->Move(_L("\\F32-TST\\TFMAN\\INC108401\\src"), _L("\\F32-TST\\TFMAN\\INC108401\\dest\\"), CFileMan::EOverWrite, gStat);
 	test.Next(_L("Test INC108401 : SAME DRIVE with CFileMan::EOverWrite"));
 	TestResult(err);
-	// test(err==KErrNone);
+	// test_KErrNone(err);
 	RmDir(_L("\\F32-TST\\TFMAN\\INC108401\\"));
 	
 	// case for gFileMan->Move(_L("\\F32-TST\\TFMAN\\INC108401\\src"), _L("\\F32-TST\\TFMAN\\INC108401\\dest\\"), CFileMan::EOverWrite|CFileMan::ERecurse);
@@ -2268,7 +2288,7 @@
 		err = gFileMan->Move(_L("\\F32-TST\\TFMAN\\INC108401\\src"), _L("\\F32-TST\\TFMAN\\INC108401\\dest\\"), CFileMan::ERecurse|CFileMan::EOverWrite, gStat);
 	test.Next(_L("Test INC108401 : SAME DRIVES with CFileMan::ERecurse|CFileMan::EOverWrite"));
 	TestResult(err);
-	// test(err==KErrNone);
+	// test_KErrNone(err);
 	RmDir(_L("\\F32-TST\\TFMAN\\INC108401\\"));
 	
 	// cleanup for the current drive
@@ -2295,13 +2315,13 @@
 	MakeFile(_L("\\INC089638\\source\\subdir2\\file5"));
 	MakeFile(_L("\\INC089638\\source\\subdir2\\file6"));
 	MakeDir(_L("\\INC089638\\dest\\"));
-	test(TheFs.SetAtt(_L("\\INC089638\\source\\subdir1"), KEntryAttHidden, 0) == KErrNone);
-	test(TheFs.SetAtt(_L("\\INC089638\\source\\subdir2"), KEntryAttReadOnly, 0) == KErrNone);
+	test_KErrNone(TheFs.SetAtt(_L("\\INC089638\\source\\subdir1"), KEntryAttHidden, 0));
+	test_KErrNone(TheFs.SetAtt(_L("\\INC089638\\source\\subdir2"), KEntryAttReadOnly, 0));
 	
 	TInt r = gFileMan->Move(_L("\\INC089638\\source\\"), _L("\\INC089638\\dest\\"), CFileMan::ERecurse);
-	test(r==KErrNone);
+	test_KErrNone(r);
 	r = TheFs.RmDir(_L("\\INC089638\\source\\"));
-	test(r==KErrNone);
+	test_KErrNone(r);
 	
 	RmDir(_L("\\INC089638\\"));
   }
@@ -2325,7 +2345,7 @@
 		err = gFileMan->Move(KSourceDir, dest, CFileMan::ERecurse|CFileMan::EOverWrite);
 	else
 		err = gFileMan->Move(KSourceDir, dest, CFileMan::ERecurse|CFileMan::EOverWrite, gStat);
-	test(err==KErrInUse); // Recursive move prohibited
+	test_Equal(KErrInUse, err); // Recursive move prohibited
 	if (gAsynch)
 		WaitForResult(KErrInUse);
 	CheckFileContents(KFile1, _L8("qwerty"));
@@ -2386,43 +2406,43 @@
 
 	TEntry entry;
 	r = gFileMan->Move(src, KDest, 0); // ahsx\ah
-	test(r == KErrNone);
+	test_KErrNone(r);
 	r = TheFs.Entry(src, entry);
-	test(r == KErrNotFound);
+	test_Equal(KErrNotFound, r);
 
 	src.SetLength(src.Length()-1); // ahsx\a
 	r = gFileMan->Move(src, KDest, 0);
-	test(r == KErrNone);
+	test_KErrNone(r);
 	r = TheFs.Entry(src, entry);
-	test(r == KErrNotFound);
+	test_Equal(KErrNotFound, r);
 	
 	src.SetLength(src.Length()-3); // ahs
 	r = gFileMan->Move(src, KDest, 0);
-	test(r == KErrNone);
+	test_KErrNone(r);
 	r = TheFs.Entry(src, entry);
-	test(r == KErrNotFound);
+	test_Equal(KErrNotFound, r);
 	
 	src.SetLength(src.Length()-1); // ah
 	r = gFileMan->Move(src, KDest, 0);
-	test(r == KErrAlreadyExists);
+	test_Equal(KErrAlreadyExists, r);
 	r = TheFs.Entry(src, entry);
-	test(r == KErrNone);
+	test_KErrNone(r);
 
 	r = gFileMan->Move(src, KDest, CFileMan::EOverWrite); // ah
-	test(r == KErrNone);
+	test_KErrNone(r);
 	r = TheFs.Entry(src, entry);
-	test(r == KErrNotFound);
+	test_Equal(KErrNotFound, r);
 
 	src.SetLength(src.Length()-1); // a
 	r = gFileMan->Move(src, KDest, 0);
-	test(r == KErrAlreadyExists);
+	test_Equal(KErrAlreadyExists, r);
 	r = TheFs.Entry(src, entry);
-	test(r == KErrNone);
+	test_KErrNone(r);
 
 	r = gFileMan->Move(src, KDest, CFileMan::EOverWrite); // a
-	test(r == KErrNone);
+	test_KErrNone(r);
 	r = TheFs.Entry(src, entry);
-	test(r == KErrNotFound);
+	test_Equal(KErrNotFound, r);
 
 	RmDir(source);
 	RmDir(KDest);
@@ -2537,25 +2557,25 @@
 	SetupDirectories(EFalse, NULL);
 
 	err = gFileMan->Move(_L("\\F32-TST\\TFMAN\\source\\"), _L("\\F32-TST\\TFMAN\\dest\\"), CFileMan::ERecurse);
-	test(err == KErrNotFound);	// Expected - directory is empty
+	test_Equal(KErrNotFound, err);	// Expected - directory is empty
 
 	// Test that all directories are still present
 	TEntry entry;
 	err = TheFs.Entry(_L("\\F32-TST\\TFMAN\\source\\"), entry);
-	test(err == KErrNone);
+	test_KErrNone(err);
 	err = TheFs.Entry(_L("\\F32-TST\\TFMAN\\dest\\"), entry);
-	test(err == KErrNone);
+	test_KErrNone(err);
 
 	SetupDirectories(EFalse, NULL);
 
 	err = gFileMan->Move(_L("\\F32-TST\\TFMAN\\source"), _L("\\F32-TST\\TFMAN\\dest\\"), CFileMan::ERecurse);
-	test(err == KErrNone);		// Expected - should move (or rename) directory
+	test_KErrNone(err);		// Expected - should move (or rename) directory
 
 	// Test directory has been moved
 	err = TheFs.Entry(_L("\\F32-TST\\TFMAN\\dest\\source\\"), entry);
-	test(err == KErrNone);
+	test_KErrNone(err);
 	err = TheFs.Entry(_L("\\F32-TST\\TFMAN\\source\\"), entry);
-	test(err == KErrNotFound);
+	test_Equal(KErrNotFound, err);
 
 	RmDir(_L("\\F32-TST\\TFMAN\\dest\\source\\"));
 
@@ -2566,7 +2586,7 @@
 
 	SetupDirectories(ETrue, NULL);
 	err = gFileMan->Move(_L("\\F32-TST\\TFMAN\\source\\"), _L("\\F32-TST\\TFMAN\\dest\\"), CFileMan::ERecurse | CFileMan::EOverWrite);
-	test(err == KErrNone);
+	test_KErrNone(err);
 
 	Compare(_L("\\F32-TST\\TFMAN\\compare\\*"), _L("\\F32-TST\\TFMAN\\dest\\*"));
 
@@ -2587,7 +2607,7 @@
 	RmDir(_L("\\F32-TST\\TFMAN\\dest\\"));
 
 	err = gFileMan->Move(_L("\\F32-TST\\TFMAN\\source\\"), _L("\\F32-TST\\TFMAN\\dest\\"), CFileMan::ERecurse);
-	test(err == KErrNone);
+	test_KErrNone(err);
 
 	Compare(_L("\\F32-TST\\TFMAN\\compare\\*"), _L("\\F32-TST\\TFMAN\\dest\\*"));
 
@@ -2596,7 +2616,7 @@
 	RmDir(_L("\\F32-TST\\TFMAN\\dest\\"));
 
 	err = gFileMan->Move(_L("\\F32-TST\\TFMAN\\source\\"), _L("\\F32-TST\\TFMAN\\dest"), CFileMan::ERecurse);
-	test(err == KErrNone);
+	test_KErrNone(err);
 
 	Compare(_L("\\F32-TST\\TFMAN\\compare\\*"), _L("\\F32-TST\\TFMAN\\dest\\*"));
 
@@ -2605,7 +2625,7 @@
 	RmDir(_L("\\F32-TST\\TFMAN\\dest\\"));
 
 	err = gFileMan->Move(_L("\\F32-TST\\TFMAN\\source"), _L("\\F32-TST\\TFMAN\\dest\\"), CFileMan::ERecurse);
-	test(err == KErrNone);
+	test_KErrNone(err);
 
 	MakeDir(_L("\\F32-TST\\TFMAN\\compare\\subdir\\"));
 	Compare(_L("\\F32-TST\\TFMAN\\compare\\*"), _L("\\F32-TST\\TFMAN\\dest\\source\\*"));
@@ -2616,7 +2636,7 @@
 	RmDir(_L("\\F32-TST\\TFMAN\\dest\\"));
 
 	err = gFileMan->Move(_L("\\F32-TST\\TFMAN\\source\\File1.TXT"), _L("\\F32-TST\\TFMAN\\dest\\"), CFileMan::ERecurse);
-	test(err == KErrNone);
+	test_KErrNone(err);
 
 	CheckFileExists(_L("\\F32-TST\\TFMAN\\source\\File1.TXT"), KErrNotFound, ETrue);
 	CheckFileExists(_L("\\F32-TST\\TFMAN\\dest\\File1.TXT"),   KErrNone,     ETrue);
@@ -2628,28 +2648,28 @@
 	// For this, default should be session path
 	TFileName sessionPath;
 	err=TheFs.SessionPath(sessionPath);
-	test(err==KErrNone);
+	test_KErrNone(err);
 
 	SetupDirectories(ETrue, NULL);
 	err=TheFs.SetSessionPath(_L("\\F32-TST\\TFMAN\\dest\\"));
-	test(err == KErrNone);
+	test_KErrNone(err);
 
 	err = gFileMan->Move(_L("\\F32-TST\\TFMAN\\source"), _L(""), CFileMan::ERecurse);
-	test(err == KErrNone);
+	test_KErrNone(err);
 	Compare(_L("\\F32-TST\\TFMAN\\compare\\*"), _L("\\F32-TST\\TFMAN\\dest\\source\\*"));
 
 	RmDir(_L("\\F32-TST\\TFMAN\\dest\\"));
 	RmDir(_L("\\F32-TST\\TFMAN\\source\\"));
 	SetupDirectories(ETrue, NULL);
 	err=TheFs.SetSessionPath(_L("\\F32-TST\\TFMAN\\source\\"));
-	test(err == KErrNone);
+	test_KErrNone(err);
 
 	err = gFileMan->Move(_L(""), _L("\\F32-TST\\TFMAN\\dest\\"), CFileMan::ERecurse);
-	test(err == KErrNone);
+	test_KErrNone(err);
 	Compare(_L("\\F32-TST\\TFMAN\\compare\\*"), _L("\\F32-TST\\TFMAN\\dest\\*"));
 		
 	err=TheFs.SetSessionPath(sessionPath);
-	test(err==KErrNone);
+	test_KErrNone(err);
 
 	//--------------------------------------------- 
 	//! @SYMTestCaseID			PBASE-T_FMAN-0520
@@ -2813,14 +2833,14 @@
 	SetupDirectories(EFalse, &destOtherDrive);
 
 	err = gFileMan->Move(_L("\\F32-TST\\TFMAN\\source\\"), destOtherDrive, CFileMan::ERecurse);
-	test(err == KErrNotFound);	// Expected - directory is empty
+	test_Equal(KErrNotFound, err);	// Expected - directory is empty
 
 	// Test that all directories are still present
 	TEntry entry;
 	err = TheFs.Entry(_L("\\F32-TST\\TFMAN\\source\\"), entry);
-	test(err == KErrNone);
+	test_KErrNone(err);
 	err = TheFs.Entry(destOtherDrive, entry);
-	test(err == KErrNone);
+	test_KErrNone(err);
 
 	//--------------------------------------------- 
 	//! @SYMTestCaseID			PBASE-T_FMAN-0571
@@ -2863,7 +2883,7 @@
 
 	SetupDirectories(ETrue, &destOtherDrive);
 	err = gFileMan->Move(_L("\\F32-TST\\TFMAN\\source\\"), destOtherDrive, CFileMan::ERecurse | CFileMan::EOverWrite);
-	test(err == KErrNone);
+	test_KErrNone(err);
 
 	destOtherDrive.Append(_L("*"));
 	Compare(_L("\\F32-TST\\TFMAN\\compare\\*"), destOtherDrive);
@@ -2885,7 +2905,7 @@
 	RmDir(destOtherDrive);
 
 	err = gFileMan->Move(_L("\\F32-TST\\TFMAN\\source\\"), destOtherDrive, CFileMan::ERecurse);
-	test(err == KErrNone);
+	test_KErrNone(err);
 
 	Compare(_L("\\F32-TST\\TFMAN\\compare\\*"), destOtherDrive);
 
@@ -2894,7 +2914,7 @@
 	RmDir(destOtherDrive);
 
 	err = gFileMan->Move(_L("\\F32-TST\\TFMAN\\source"), destOtherDrive, CFileMan::ERecurse);
-	test(err == KErrNone);
+	test_KErrNone(err);
 
 	MakeDir(_L("\\F32-TST\\TFMAN\\compare\\subdir\\"));
 	destOtherDrive.Append(_L("source\\"));
@@ -2906,7 +2926,7 @@
 	RmDir(destOtherDrive);
 
 	err = gFileMan->Move(_L("\\F32-TST\\TFMAN\\source\\File1.TXT"), destOtherDrive, CFileMan::ERecurse);
-	test(err == KErrNone);
+	test_KErrNone(err);
 
 	CheckFileExists(_L("\\F32-TST\\TFMAN\\source\\File1.TXT"), KErrNotFound, ETrue);
 	destOtherDrive.Append(_L("File1.TXT"));
@@ -2926,11 +2946,11 @@
 	for(level=0; level < KNumFiles; level++)
 		{
 		err = TheFs.MkDirAll(complexFile[level]);
-		test(err == KErrNone || err == KErrAlreadyExists);
+		test_Value(err, err == KErrNone || err == KErrAlreadyExists);
 
 		RFile file;
 		err = file.Create(TheFs, complexFile[level], EFileRead | EFileWrite);
-		test(err == KErrNone || err == KErrAlreadyExists || err == KErrBadName);
+		test_Value(err, err == KErrNone || err == KErrAlreadyExists || err == KErrBadName);
 		file.Close();
 		}
 
@@ -2942,16 +2962,16 @@
 	//
 
 	err = gFileMan->Move(_L("\\F32-TST\\TFMAN\\complex\\dir1"), _L("\\F32-TST\\TFMAN\\complex\\dir12\\"), CFileMan::ERecurse);
-	test(err == KErrAlreadyExists);
+	test_Equal(KErrAlreadyExists, err);
 
 	for(level=0; level < KNumFilesResult1; level++)
 		{
 		err = TheFs.MkDirAll(complexResult1[level]);
-		test(err == KErrNone || err == KErrAlreadyExists);
+		test_Value(err, err == KErrNone || err == KErrAlreadyExists);
 
 		RFile file;
 		err = file.Create(TheFs, complexResult1[level], EFileRead | EFileWrite);
-		test(err == KErrNone || err == KErrAlreadyExists || err == KErrBadName);
+		test_Value(err, err == KErrNone || err == KErrAlreadyExists || err == KErrBadName);
 		file.Close();
 		}
 
@@ -2961,16 +2981,16 @@
 	// Move directory 'dir1' into 'dir12' *with* overwrite flag set
 	//
 	err = gFileMan->Move(_L("\\F32-TST\\TFMAN\\complex\\dir1"), _L("\\F32-TST\\TFMAN\\complex\\dir12\\"), CFileMan::ERecurse | CFileMan::EOverWrite);
-	test(err == KErrNone);
+	test_KErrNone(err);
 
 	for(level=0; level < KNumFilesResult2; level++)
 		{
 		err = TheFs.MkDirAll(complexResult2[level]);
-		test(err == KErrNone || err == KErrAlreadyExists);
+		test_Value(err, err == KErrNone || err == KErrAlreadyExists);
 
 		RFile file;
 		err = file.Create(TheFs, complexResult2[level], EFileRead | EFileWrite);
-		test(err == KErrNone || err == KErrAlreadyExists || err == KErrBadName);
+		test_Value(err, err == KErrNone || err == KErrAlreadyExists || err == KErrBadName);
 		file.Close();
 		}
 
@@ -3107,7 +3127,7 @@
 	TInt lastError=iFileMan->GetLastError();
 	if (lastError!=KErrNone)
 		{
-		test(lastError==KErrAlreadyExists);
+		test_Equal(KErrAlreadyExists, lastError);
 		if (gAsynch==EFalse)
 			{
 			TFileName fileName=iFileMan->CurrentEntry().iName;
@@ -3139,40 +3159,40 @@
 	if (!gAsynch)
 		{
 		TInt r=gFileMan->Copy(_L("\\F32-TST\\TFMAN\\OVERWRITE\\SRC"),_L("\\F32-TST\\TFMAN\\OVERWRITE\\TRG"),0);
-		test(r==KErrAlreadyExists);
+		test_Equal(KErrAlreadyExists, r);
 		}
 	else
 		{
 		TInt r=gFileMan->Copy(_L("\\F32-TST\\TFMAN\\OVERWRITE\\SRC"),_L("\\F32-TST\\TFMAN\\OVERWRITE\\TRG"),0,gStat);
-		test(r==KErrNone);
+		test_KErrNone(r);
 		WaitForResult(KErrAlreadyExists);
 		}
 
 	RFile f;
 	TInt r=f.Open(TheFs,_L("\\F32-TST\\TFMAN\\OVERWRITE\\TRG\\FILE1.TXT"),EFileRead);
-	test(r==KErrNone);
+	test_KErrNone(r);
 	TBuf8<128> data;
 	r=f.Read(data);
-	test(r==KErrNone);
-	test(data.Length()==0);
+	test_KErrNone(r);
+	test_Equal(0, data.Length());
 	f.Close();
 
 	if (!gAsynch)
 		{
 		TInt r=gFileMan->Copy(_L("\\F32-TST\\TFMAN\\OVERWRITE\\SRC"),_L("\\F32-TST\\TFMAN\\OVERWRITE\\TRG"),CFileMan::EOverWrite);
-		test(r==KErrNone);
+		test_KErrNone(r);
 		}
 	else
 		{
 		TInt r=gFileMan->Copy(_L("\\F32-TST\\TFMAN\\OVERWRITE\\SRC"),_L("\\F32-TST\\TFMAN\\OVERWRITE\\TRG"),CFileMan::EOverWrite,gStat);
-		test(r==KErrNone);
+		test_KErrNone(r);
 		WaitForSuccess();
 		}
 
 	r=f.Open(TheFs,_L("\\F32-TST\\TFMAN\\OVERWRITE\\TRG\\FILE1.TXT"),EFileRead);
-	test(r==KErrNone);
+	test_KErrNone(r);
 	r=f.Read(data);
-	test(r==KErrNone);
+	test_KErrNone(r);
 	test(data==contentsFile1);
 	f.Close();
 
@@ -3183,38 +3203,38 @@
 	if (!gAsynch)
 		{
 	TInt r=gFileMan->Rename(_L("\\F32-TST\\TFMAN\\OVERWRITE\\SRC\\*"),_L("\\F32-TST\\TFMAN\\OVERWRITE\\TRG\\*"),0);
-		test(r==KErrAlreadyExists);
+		test_Equal(KErrAlreadyExists, r);
 		}
 	else
 		{
 		TInt r=gFileMan->Rename(_L("\\F32-TST\\TFMAN\\OVERWRITE\\SRC\\*"),_L("\\F32-TST\\TFMAN\\OVERWRITE\\TRG\\*"),0,gStat);
-		test(r==KErrNone);
+		test_KErrNone(r);
 		WaitForResult(KErrAlreadyExists);
 		}
 
 	r=f.Open(TheFs,_L("\\F32-TST\\TFMAN\\OVERWRITE\\TRG\\FILE2.TXT"),EFileRead);
-	test(r==KErrNone);
+	test_KErrNone(r);
 	r=f.Read(data);
-	test(r==KErrNone);
-	test(data.Length()==0);
+	test_KErrNone(r);
+	test_Equal(0, data.Length());
 	f.Close();
 
 	if (!gAsynch)
 		{
 		TInt r=gFileMan->Rename(_L("\\F32-TST\\TFMAN\\OVERWRITE\\SRC\\*"),_L("\\F32-TST\\TFMAN\\OVERWRITE\\TRG\\*"),CFileMan::EOverWrite);
-		test(r==KErrNone);
+		test_KErrNone(r);
 		}
 	else
 		{
 		TInt r=gFileMan->Rename(_L("\\F32-TST\\TFMAN\\OVERWRITE\\SRC\\*"),_L("\\F32-TST\\TFMAN\\OVERWRITE\\TRG\\*"),CFileMan::EOverWrite,gStat);
-		test(r==KErrNone);
+		test_KErrNone(r);
 		WaitForSuccess();
 		}
 
 	r=f.Open(TheFs,_L("\\F32-TST\\TFMAN\\OVERWRITE\\TRG\\FILE2.TXT"),EFileRead);
-	test(r==KErrNone);
+	test_KErrNone(r);
 	r=f.Read(data);
-	test(r==KErrNone);
+	test_KErrNone(r);
 	test(data==contentsFile2);
 	f.Close();
 	gFileMan->SetObserver(gObserver);
@@ -3230,12 +3250,12 @@
 	if (!gAsynch)
 		{
 		TInt r=gFileMan->Delete(_L("\\F32-TST\\TFMAN\\BADPATH\\*"));
-		test(r==KErrPathNotFound);
+		test_Equal(KErrPathNotFound, r);
 		}
 	else
 		{
 		TInt r=gFileMan->Delete(_L("\\F32-TST\\TFMAN\\BADPATH\\*"),0,gStat);
-		test(r==KErrNone);
+		test_KErrNone(r);
 		WaitForResult(KErrPathNotFound);
 		}
 
@@ -3252,7 +3272,7 @@
 			TBuf<16> bad(KBad);
 			bad[0] = TUint16('A'+drvNum);
 			TInt r=fMan->Delete(bad);
-			test(r==KErrNotReady);
+			test_Equal(KErrNotReady, r);
 			break;
 			}
 		}
@@ -3266,28 +3286,28 @@
 		r=gFileMan->Copy(_L("\\ONE\\TWO\\*"),_L("\\ONE\\TWO\\THREE\\"),CFileMan::ERecurse);
 	else
 		r=gFileMan->Copy(_L("\\ONE\\TWO\\*"),_L("\\ONE\\TWO\\THREE\\"),CFileMan::ERecurse,gStat);
-	test(r==KErrArgument);
+	test_Equal(KErrArgument, r);
 
 	test.Next(_L("Test src name == trg name"));
 	if (!gAsynch)
 		{
 		r=gFileMan->Copy(_L("\\ONE\\TWO\\FOUR"),_L("\\ONE\\TWO\\FOUR")); // default aSwitch=EOverWrite
-		test(r==KErrNone);
+		test_KErrNone(r);
 		r=gFileMan->Copy(_L("\\ONE\\TWO\\FOUR"),_L("\\ONE\\TWO\\FOUR"), 0);
-		test(r==KErrAlreadyExists);
+		test_Equal(KErrAlreadyExists, r);
 		r=gFileMan->Copy(_L("\\ONE\\TWO\\FOUR"),_L("\\ONE\\TWO\\FOUR"),CFileMan::ERecurse);
-		test(r==KErrAlreadyExists);
+		test_Equal(KErrAlreadyExists, r);
 		r=gFileMan->Copy(_L("\\ONE\\TWO\\F*R"),_L("\\ONE\\TWO\\FOUR"),CFileMan::ERecurse);
-		test(r==KErrAlreadyExists);
+		test_Equal(KErrAlreadyExists, r);
 		}
 	else
 		{
 		r=gFileMan->Copy(_L("\\ONE\\TWO\\*.TXT"),_L("\\ONE\\TWO\\*.TXT"),0,gStat);
-		test(r==KErrNone);
+		test_KErrNone(r);
 		WaitForResult(KErrAlreadyExists);
 		r=gFileMan->Copy(_L("\\ONE\\TWO\\FOUR"),_L("\\ONE\\TWO\\F*R"),CFileMan::ERecurse,gStat);
-		test(r==KErrNone);
-		WaitForResult(KErrNone);
+		test_KErrNone(r);
+        WaitForResult(KErrNone);
 		}
 	RmDir(_L("\\ONE\\"));
 
@@ -3295,17 +3315,17 @@
 	if (!gAsynch)
 		{
 		r=gFileMan->Copy(_L("\\ONE\\TWO\\XXXYYY"),_L("\\ONE\\TWO\\asdfsadf"));
-		test(r==KErrPathNotFound);
+		test_Equal(KErrPathNotFound, r);
 		r=gFileMan->Copy(_L("\\ONE\\TWO\\XXXYYY"),_L("\\ONE\\TWO\\asdfsadf"),CFileMan::ERecurse);
-		test(r==KErrPathNotFound);
+		test_Equal(KErrPathNotFound, r);
 		}
 	else
 		{
 		r=gFileMan->Copy(_L("\\ONE\\TWO\\*.TXT"),_L("\\ONE\\TWO\\*.YYY"),0,gStat);
-		test(r==KErrNone);
+		test_KErrNone(r);
 		WaitForResult(KErrPathNotFound);
 		r=gFileMan->Copy(_L("\\ONE\\TWO\\XXXYYY"),_L("\\ONE\\TWO\\asdfsadf"),CFileMan::ERecurse,gStat);
-		test(r==KErrNone);
+		test_KErrNone(r);
 		WaitForResult(KErrPathNotFound);
 		}
 		
@@ -3313,17 +3333,17 @@
 	if (!gAsynch)
 		{
 		r=gFileMan->Copy(_L("\\F32-TST\\TFMAN\\*.LPQ"),_L("\\ONE\\TWO\\*.YYY"));
-		test(r==KErrNotFound);
+		test_Equal(KErrNotFound, r);
 		r=gFileMan->Copy(_L("\\F32-TST\\TFMAN\\XXXYYY"),_L("\\ONE\\TWO\\asdfsadf"),CFileMan::ERecurse);
-		test(r==KErrNotFound);
+		test_Equal(KErrNotFound, r);
 		}
 	else
 		{
 		r=gFileMan->Copy(_L("\\F32-TST\\TFMAN\\XXXYYY"),_L("\\ONE\\TWO\\asdfsadf"),0,gStat);
-		test(r==KErrNone);
+		test_KErrNone(r);
 		WaitForResult(KErrNotFound);
 		r=gFileMan->Copy(_L("\\F32-TST\\TFMAN\\XXXYYY"),_L("\\ONE\\TWO\\asdfsadf"),CFileMan::ERecurse,gStat);
-		test(r==KErrNone);
+		test_KErrNone(r);
 		WaitForResult(KErrNotFound);
 		}
 		
@@ -3335,27 +3355,27 @@
  	if (!gAsynch)
  		{
  		r=gFileMan->Copy(_L("\\EMPTYSRC\\"),_L("\\EMPTYTRG\\"));
- 		test(r==KErrNotFound);
+ 		test_Equal(KErrNotFound, r);
  		r=gFileMan->Copy(_L("\\EMPTYSRC\\"),_L("\\EMPTYTRG\\"), CFileMan::ERecurse);
- 		test(r==KErrNotFound);
+ 		test_Equal(KErrNotFound, r);
  		r=gFileMan->Copy(_L("\\EMPTYSRC"),_L("\\EMPTYTRG\\"));
- 		test(r==KErrNotFound);
+ 		test_Equal(KErrNotFound, r);
  		r=gFileMan->Copy(_L("\\EMPTYSRC"),_L("\\EMPTYTRG\\"), CFileMan::ERecurse);
- 		test(r==KErrNotFound);
+ 		test_Equal(KErrNotFound, r);
  		}
  	else
  		{
  		r=gFileMan->Copy(_L("\\EMPTYSRC\\"),_L("\\EMPTYTRG\\"), 0, gStat);
- 		test(r==KErrNone);
+ 		test_KErrNone(r);
  		WaitForResult(KErrNotFound);
  		r=gFileMan->Copy(_L("\\EMPTYSRC\\"),_L("\\EMPTYTRG\\"), CFileMan::ERecurse, gStat);
- 		test(r==KErrNone);
+ 		test_KErrNone(r);
  		WaitForResult(KErrNotFound);
  		r=gFileMan->Copy(_L("\\EMPTYSRC"),_L("\\EMPTYTRG\\"), 0, gStat);
- 		test(r==KErrNone);
+ 		test_KErrNone(r);
  		WaitForResult(KErrNotFound);
  		r=gFileMan->Copy(_L("\\EMPTYSRC"),_L("\\EMPTYTRG\\"), CFileMan::ERecurse, gStat);
- 		test(r==KErrNone);
+ 		test_KErrNone(r);
  		WaitForResult(KErrNotFound);
  		}
  	RmDir(_L("\\EMPTYSRC\\"));
@@ -3365,48 +3385,48 @@
 	MakeFile(_L("Dummyfile"));
 	test.Next(_L("Test illegal names"));
 	r=gFileMan->Attribs(_L(":C:"),0,0,TTime(0),0);
-	test(r==KErrBadName);
+	test_Equal(KErrBadName, r);
 	r=gFileMan->Copy(_L(":C:"),_L("newname"),0);
-	test(r==KErrBadName);
+	test_Equal(KErrBadName, r);
 	r=gFileMan->Copy(_L("Dummyfile"),_L(":C:"),0);
-	test(r==KErrBadName);
+	test_Equal(KErrBadName, r);
 	r=gFileMan->Delete(_L(":C:"),0);
-	test(r==KErrBadName);
+	test_Equal(KErrBadName, r);
 	r=gFileMan->Move(_L(":C:"),_L("newname"),0);
-	test(r==KErrBadName);
+	test_Equal(KErrBadName, r);
 	r=gFileMan->Move(_L("dummyFile"),_L(":C:"),0);
-	test(r==KErrBadName);
+	test_Equal(KErrBadName, r);
 	r=gFileMan->Rename(_L(":C:"),_L("newname"),0);
-	test(r==KErrBadName);
+	test_Equal(KErrBadName, r);
 	r=gFileMan->Rename(_L("DummyFile"),_L(":C:"),0);
-	test(r==KErrBadName);
+	test_Equal(KErrBadName, r);
 	r=gFileMan->RmDir(_L("\\:C:\\"));
-	test(r==KErrBadName);
+	test_Equal(KErrBadName, r);
 
 	r=gFileMan->Attribs(_L("::C:"),0,0,TTime(0),0);
-	test(r==KErrBadName);
+	test_Equal(KErrBadName, r);
 	r=gFileMan->Copy(_L("::C:"),_L("newname"),0);
-	test(r==KErrBadName);
+	test_Equal(KErrBadName, r);
 	r=gFileMan->Copy(_L("Dummyfile"),_L("::C:"),0);
-	test(r==KErrBadName);
+	test_Equal(KErrBadName, r);
 	r=gFileMan->Delete(_L("::C:"),0);
-	test(r==KErrBadName);
+	test_Equal(KErrBadName, r);
 	r=gFileMan->Move(_L("::C:"),_L("newname"),0);
-	test(r==KErrBadName);
+	test_Equal(KErrBadName, r);
 	r=gFileMan->Move(_L("dummyFile"),_L("::C:"),0);
-	test(r==KErrBadName);
+	test_Equal(KErrBadName, r);
 	r=gFileMan->Rename(_L("::C:"),_L("newname"),0);
-	test(r==KErrBadName);
+	test_Equal(KErrBadName, r);
 	r=gFileMan->Rename(_L("DummyFile"),_L("::C:"),0);
-	test(r==KErrBadName);
+	test_Equal(KErrBadName, r);
 	r=gFileMan->RmDir(_L("::C:"));
-	test(r==KErrBadName);
+	test_Equal(KErrBadName, r);
 	r=TheFs.Delete(_L("DummyFile"));
-	test(r==KErrNone);
+	test_KErrNone(r);
 	// test copying two files with identical names that do not exist
 	_LIT(KNonExistent,"\\azzzz.txt");
 	r=gFileMan->Copy(KNonExistent,KNonExistent,0);
-	test(r==KErrNotFound);
+	test_Equal(KErrNotFound, r);
 	}
 
 LOCAL_C void TestNameMangling()
@@ -3427,10 +3447,10 @@
 	MakeFile(_L("\\F32-TST\\TFMAN\\NAMEMANGLER\\SRC\\zyx.abcdefghijk.defgh"));
 
 	TInt r=gFileMan->Copy(_L("\\F32-TST\\TFMAN\\NAMEMANGLER\\SRC\\*.*"),_L("\\F32-TST\\TFMAN\\NAMEMANGLER\\TRG\\*.*"));
-	test(r==KErrNone);
+	test_KErrNone(r);
 	Compare(_L("\\F32-TST\\TFMAN\\NAMEMANGLER\\SRC\\*"),_L("\\F32-TST\\TFMAN\\NAMEMANGLER\\TRG\\*"));
 	r=gFileMan->Delete(_L("\\F32-TST\\TFMAN\\NAMEMANGLER\\TRG\\*.*"));
-	test(r==KErrNone);
+	test_KErrNone(r);
 	}
 
 LOCAL_C void TestLongNames()
@@ -3460,7 +3480,7 @@
 	longRootDirNameA+=longFileNameA;
 	longRootDirNameA+=_L("\\");
 	TInt r=TheFs.MkDir(longRootDirNameA);
-	test(r==KErrNone || r==KErrAlreadyExists);
+	test_Value(r, r==KErrNone || r==KErrAlreadyExists);
 	// Second folder
 	TFileName longFileNameB;
 	longFileNameB.SetLength(longFileLength);
@@ -3469,7 +3489,7 @@
 	longRootDirNameB+=longFileNameB;
 	longRootDirNameB+=_L("\\");
 	r=TheFs.MkDir(longRootDirNameB);
-	test(r==KErrNone || r==KErrAlreadyExists);
+	test_Value(r, r==KErrNone || r==KErrAlreadyExists);
 	
 	TInt longFilePtrLength = KMaxFileName-3; // We do not want the trailing backslash
 	TPtrC ptrLongFileA(longRootDirNameA.Ptr(),longFilePtrLength);
@@ -3480,42 +3500,42 @@
 	// This test will return KErrGeneral because the new path will exceed the maximum length
 	// See KMaxFileName
 	r=gFileMan->Move(ptrLongFileA,ptrLongFileB);
-	test(r==KErrGeneral);
+	test_Equal(KErrGeneral, r);
 	
 	r=gFileMan->RmDir(longRootDirNameA);
-	test(r==KErrNone);
+	test_KErrNone(r);
 	r=gFileMan->Rename(ptrLongFileB,ptrLongFileA);
-	test(r==KErrNone);
+	test_KErrNone(r);
 	r=gFileMan->RmDir(longRootDirNameB);
-	test(r==KErrPathNotFound);
+	test_Equal(KErrPathNotFound, r);
 	r=gFileMan->RmDir(longRootDirNameA);
-	test(r==KErrNone);
+	test_KErrNone(r);
 
 	TFileName longSubDirName=_L("\\Files\\");
 	TPtrC longSubDirFileName(longFileNameA.Ptr(),longFilePtrLength-longSubDirName.Length());
 	longSubDirName+=longSubDirFileName;
 	longSubDirName+=_L("\\");
 	r=TheFs.MkDirAll(longSubDirName);
-	test(r==KErrNone);
+	test_KErrNone(r);
 
 	CDir* dirList;
 	r=TheFs.GetDir(longSubDirName,KEntryAttMaskSupported,0,dirList);
-	test(r==KErrNone);
-	test(dirList->Count()==0);
+	test_KErrNone(r);
+	test_Equal(0, dirList->Count());
 	delete dirList;
 
 	TPtrC ptrLongSubDirSrc(longSubDirName.Ptr(),longSubDirName.Length()-1);
 	TPtrC ptrLongSubDirTrg(longRootDirNameA.Ptr(),longRootDirNameA.Length()-1);
 	r=gFileMan->Copy(ptrLongSubDirSrc,ptrLongSubDirTrg);
-	test(r==KErrNone);
+	test_KErrNone(r);
 	r=TheFs.MkDir(longRootDirNameB);
-	test(r==KErrNone);
+	test_KErrNone(r);
 	r=gFileMan->Move(ptrLongSubDirSrc,longRootDirNameB);
-	test(r==KErrBadName);
+	test_Equal(KErrBadName, r);
 	r=TheFs.RmDir(longRootDirNameB);
-	test(r==KErrNone);
-	test(TheFs.RmDir(longSubDirName) == KErrNone);
-	test(TheFs.RmDir(_L("\\Files\\")) == KErrNone);
+	test_KErrNone(r);
+	test_KErrNone(TheFs.RmDir(longSubDirName));
+	test_KErrNone(TheFs.RmDir(_L("\\Files\\")));
 	gFileMan->SetObserver(gObserver);
 	}
 
@@ -3533,14 +3553,14 @@
 	MakeFile(_L("\\F32-TST\\TFMAN\\FILEATT\\SRC\\systemarchive.def"),KEntryAttArchive|KEntryAttSystem);
 
 	TInt r=gFileMan->Copy(_L("\\F32-TST\\TFMAN\\FILEATT\\SRC\\*.*"),_L("\\F32-TST\\TFMAN\\FILEATT\\TRG\\*.*"));
-	test(r==KErrNone);
+	test_KErrNone(r);
 	Compare(_L("\\F32-TST\\TFMAN\\FILEATT\\SRC\\*.*"),_L("\\F32-TST\\TFMAN\\FILEATT\\TRG\\*"));
 	r=gFileMan->Attribs(_L("\\F32-TST\\TFMAN\\FILEATT\\SRC\\*"),0,KEntryAttReadOnly,TTime(0));
-	test(r==KErrNone);
+	test_KErrNone(r);
 	r=gFileMan->Attribs(_L("\\F32-TST\\TFMAN\\FILEATT\\TRG\\*"),0,KEntryAttReadOnly,TTime(0));
-	test(r==KErrNone);
+	test_KErrNone(r);
 	r=gFileMan->RmDir(_L("\\F32-TST\\TFMAN\\FILEATT\\"));
-	test(r==KErrNone);
+	test_KErrNone(r);
 	}	
 
 class CFileManObserverContinue : public CBase, public MFileManObserver
@@ -3589,30 +3609,30 @@
 	MakeFile(_L("\\F32-TST\\TFMAN\\FILECOPY\\asdf.asdf"),bufPtr);
 	RFile f;
 	TInt r=f.Open(TheFs,_L("\\F32-TST\\TFMAN\\FILECOPY\\asdf.asdf"),EFileRead|EFileShareReadersOnly);
-	test(r==KErrNone);
+	test_KErrNone(r);
 	r=gFileMan->Copy(_L("\\F32-TST\\TFMAN\\FILECOPY\\asdf.asdf"),_L("\\F32-TST\\TFMAN\\FILECOPY\\xxxx.xxxx"));
-	test(r==KErrNone);
+	test_KErrNone(r);
 	f.Close();
 	r=f.Open(TheFs,_L("\\F32-TST\\TFMAN\\FILECOPY\\xxxx.xxxx"),EFileRead);
-	test(r==KErrNone);
+	test_KErrNone(r);
 	TBuf8<256*sizeof(TText)> temp;
 	r=f.Read(temp);
-	test(r==KErrNone);
+	test_KErrNone(r);
 	test(temp==bufPtr);
 	r=f.Read(temp);
-	test(r==KErrNone);
-	test(temp.Length()==0);
+	test_KErrNone(r);
+	test_Equal(0, temp.Length());
 	f.Close();
 
 	r=f.Open(TheFs,_L("\\F32-TST\\TFMAN\\FILECOPY\\asdf.asdf"),EFileRead);
-	test(r==KErrNone);
+	test_KErrNone(r);
 	r=gFileMan->Copy(_L("\\F32-TST\\TFMAN\\FILECOPY\\asdf.asdf"),_L("\\F32-TST\\TFMAN\\FILECOPY\\xxxx.xxxx"));
-	test(r==KErrInUse);
+	test_Equal(KErrInUse, r);
 	f.Close();
 
 	gFileMan->SetObserver(gObserver);
 	r=gFileMan->RmDir(_L("\\F32-TST\\TFMAN\\FILECOPY\\"));
-	test(r==KErrNone);
+	test_KErrNone(r);
 	delete fManObserver;
 	}
 
@@ -3651,41 +3671,41 @@
 
 	// Move directory containing files and subdirs with different attributes
 	r = gFileMan->Move(source, KDest, 0);
-	test(r==KErrNone);
+	test_KErrNone(r);
 	
 	// Check that the files and subdirs have moved and have the correct attributes
 	TEntry entry;
 	src = KDest;
 	src.Append(_L("file1"));
 	r = TheFs.Entry(src, entry);
-	test(r == KErrNone);
+	test_KErrNone(r);
 	test(entry.iAtt&KEntryAttReadOnly);
 
 	src = KDest;
 	src.Append(_L("file2"));
 	r = TheFs.Entry(src, entry);
-	test(r == KErrNone);
+	test_KErrNone(r);
 	test(entry.iAtt&KEntryAttHidden);
 
 	src = KDest;
 	src.Append(_L("file3"));
 	r = TheFs.Entry(src, entry);
-	test(r == KErrNone);
+	test_KErrNone(r);
 	test(entry.iAtt&KEntryAttSystem);
 
 	src = source;
 	src.Append(_L("subdir1\\"));
 	r = gFileMan->Move(src, source, 0);
-	test(r == KErrNone);
+	test_KErrNone(r);
 
 	r = TheFs.RmDir(src);
-	test(r==KErrNone);
+	test_KErrNone(r);
 	src = source;
 	src.Append(_L("file4"));
 	r = TheFs.Delete(src);
-	test(r==KErrNone);
+	test_KErrNone(r);
 	r = TheFs.RmDir(source);
-	test(r==KErrNone);
+	test_KErrNone(r);
 	RmDir(KDest);	
 	}
 
@@ -3739,7 +3759,7 @@
 	CheckFileExists(trgDirFile,KErrNone);
 
 	RmDir(trgDir);
-	test(TheFs.Delete(trgFile) == KErrNone);	
+	test_KErrNone(TheFs.Delete(trgFile));	
 
 	TestINC101844(); // Test move files and subdirs with different attributes
 	}
@@ -3782,15 +3802,15 @@
 //
 	{
 	TInt lastError = iFileMan->GetLastError();
-	test(lastError == KErrNone);
+	test_KErrNone(lastError);
 
 	TFileName srcfile;
 	iFileMan->GetCurrentSource(srcfile);
 	
 	TInt action = iFileMan->CurrentAction();
-	test(action == CFileMan::EMove   ||
-		 action == CFileMan::EDelete ||
-		 action == CFileMan::ERmDir);
+	test_Value(action,  action == CFileMan::EMove   ||
+                        action == CFileMan::EDelete ||
+                        action == CFileMan::ERmDir);
 		
 	iCurrentStep--;
 	return(iCurrentStep ? MFileManObserver::EContinue : MFileManObserver::EAbort);
@@ -3927,30 +3947,30 @@
 	MakeFile(_L("\\F32-TST\\TFMAN\\CPMV\\TWO.BAD"));
 
 	TInt r=gFileMan->Copy(_L("\\F32-TST\\TFMAN\\TWO.*"), _L("\\F32-TST\\TFMAN\\THREE.*"), CFileMan::ERecurse);
-	test(r==KErrNone);
+	test_KErrNone(r);
 
 	CheckFileExists(_L("\\F32-TST\\TFMAN\\CPMV\\THREE.TXT"), KErrNone);
 	CheckFileExists(_L("\\F32-TST\\TFMAN\\CPMV\\THREE.GOD"), KErrNone);
 	CheckFileExists(_L("\\F32-TST\\TFMAN\\CPMV\\THREE.BAD"), KErrNone);
 	r=gFileMan->Delete(_L("\\F32-TST\\TFMAN\\CPMV\\THREE.*"));
-	test(r==KErrNone);
+	test_KErrNone(r);
 
 	MakeFile(_L("\\F32-TST\\TFMAN\\CPMV\\TWO2\\TWO__1.TXT"));
 	MakeFile(_L("\\F32-TST\\TFMAN\\CPMV\\TWO2\\TWO__2.TXT"));
 
 	// copy and rename dir
 	r=gFileMan->Copy(_L("\\F32-TST\\TFMAN\\CPMV\\TWO2"), _L("\\F32-TST\\TFMAN\\CPMV\\THREE"), CFileMan::ERecurse);
-	test(r==KErrNone);
+	test_KErrNone(r);
 	Compare(_L("\\F32-TST\\TFMAN\\CPMV\\TWO2\\*"), _L("\\F32-TST\\TFMAN\\CPMV\\THREE\\*"));
 
 	// copy and move into another dir
 	r=gFileMan->Copy(_L("\\F32-TST\\TFMAN\\CPMV\\TWO2"), _L("\\F32-TST\\TFMAN\\CPMV\\THREE\\TWO"), CFileMan::ERecurse);
-	test(r==KErrNone);
+	test_KErrNone(r);
 	Compare(_L("\\F32-TST\\TFMAN\\CPMV\\TWO2\\*"), _L("\\F32-TST\\TFMAN\\CPMV\\THREE\\TWO\\*"));
 
 	// copy and rename files and dirs in current dir
 	r=gFileMan->Copy(_L("\\F32-TST\\TFMAN\\CPMV\\TWO*"), _L("\\F32-TST\\TFMAN\\CPMV\\THREE*"), CFileMan::ERecurse);
-	test(r==KErrNone);
+	test_KErrNone(r);
 	//	Compare(_L("\\F32-TST\\TFMAN\\CPMV\\TWO2\\*"), _L("\\F32-TST\\TFMAN\\CPMV\\THREE2\\*"));
 
 	CheckFileExists(_L("\\F32-TST\\TFMAN\\CPMV\\ONE\\THREEO.TWO"), KErrNone);
@@ -4002,33 +4022,33 @@
 	gFileMan->SetObserver(NULL);
 	// Attribs
 	r = gFileMan->Attribs(KDir, 0, 0, 0, CFileMan::ERecurse);
-	test(r==KErrNone);
+	test_KErrNone(r);
 
 	// Move
 	r = gFileMan->Move(KFile1, KFile2, CFileMan::ERecurse);
-	test(r==KErrAlreadyExists);
+	test_Equal(KErrAlreadyExists, r);
 
 	r = gFileMan->Move(KFile1, KFile2, CFileMan::ERecurse | CFileMan::EOverWrite);
-	test(r==KErrNone);
+	test_KErrNone(r);
 
 	// Copy
 	r = gFileMan->Copy(KFile2, KFile1, CFileMan::ERecurse);
-	test(r==KErrNone);
+	test_KErrNone(r);
 
 	// Rename
 	r = gFileMan->Rename(KFile1, KFile2, 0);
-	test(r==KErrAlreadyExists);
+	test_Equal(KErrAlreadyExists, r);
 
 	r = gFileMan->Rename(KFile1, KFile2, CFileMan::EOverWrite);
-	test(r==KErrNone);
+	test_KErrNone(r);
 
 	// Delete
 	r = gFileMan->Delete(KFile2, CFileMan::ERecurse);
-	test(r==KErrNone);
+	test_KErrNone(r);
 
 	// RmDir
 	r = gFileMan->RmDir(KDir);
-	test(r==KErrNone);
+	test_KErrNone(r);
 	
 	gFileMan->SetObserver(gObserver);
 	}
@@ -4158,11 +4178,11 @@
 	// Verify src contents after move operation
 	CDir *dir = NULL;
 	err = TheFs.GetDir(srcPath, KEntryAttMaskSupported, ESortNone, dir);
-	test(6 == dir->Count());
+	test_Equal(6, dir->Count());
 	delete dir;
 	// Verify dest contents after move operation
 	err = TheFs.GetDir(trgPath, KEntryAttMaskSupported, ESortNone, dir);
-	test(3 == dir->Count());
+	test_Equal(3, dir->Count());
 	delete dir;
 	
 	// Recursive move with "\\" at the end of srcPath
@@ -4179,11 +4199,11 @@
 	
 	// Verify src has no content
 	err = TheFs.GetDir(srcPath, KEntryAttMaskSupported, ESortNone, dir);
-	test(0 == dir->Count());
+	test_Equal(0, dir->Count());
 	delete dir;
 	// Verify dest contents after move operation
 	err = TheFs.GetDir(trgPath, KEntryAttMaskSupported, ESortNone, dir);
-	test(9 == dir->Count());
+	test_Equal(9, dir->Count());
 	delete dir;
 	
 	// Recursive move without "\\" at the end of srcPath
@@ -4204,10 +4224,10 @@
 	srcPath.Append(KPathDelimiter);
 	// Verify src doesnt not exist
 	err = gFileMan->RmDir(srcPath);
-	test(err==KErrPathNotFound); // KErrPathNotFound expected as src has been moved to dest
+	test_Equal(KErrPathNotFound, err); // KErrPathNotFound expected as src has been moved to dest
 	// Verify dest after move operation
 	err = TheFs.GetDir(trgPath, KEntryAttMaskSupported, ESortNone, dir);
-	test(1 == dir->Count());
+	test_Equal(1, dir->Count());
 	delete dir;
 		
 	// clean up before leaving
@@ -4310,7 +4330,7 @@
 	TheFs.SetAllocFailure(gAllocFailOff);
 
 	TInt uid;
-	test(HAL::Get(HAL::EMachineUid,uid)==KErrNone);
+	test_KErrNone(HAL::Get(HAL::EMachineUid,uid));
 	TBool doTargetTests =  (!IsTestingLFFS() && 
 							uid!=HAL::EMachineUid_Cogent && 
 							uid!=HAL::EMachineUid_IQ80310 && 
@@ -4384,12 +4404,12 @@
 #ifndef __WINS__
 	RThread t;
 	TThreadStackInfo stack;
-	test(t.StackInfo(stack)==KErrNone);
+	test_KErrNone(t.StackInfo(stack));
 	TestStackUsage(0, stack);
 #endif
 
 	Cleanup();
 	DeleteTestDirectory();
-	test(TheFs.RmDir(_L("\\F32-TST\\")) == KErrNone);
+	test_KErrNone(TheFs.RmDir(_L("\\F32-TST\\")));
 	}
 
--- a/kerneltest/f32test/server/t_locate.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kerneltest/f32test/server/t_locate.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -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) )
@@ -541,24 +541,29 @@
 	entry=(*dir)[0];
 	test(entry.iName.MatchF(_L("FILE.AAA"))!=KErrNotFound);
 	delete dir;
+	
 	r=finder.FindWildByPath(_L("*FILE.AAA"), &gPath1, dir);
 	test(r==KErrNone);
 	test(dir->Count()==1);
 	entry=(*dir)[0];
 	test(entry.iName.MatchF(_L("FILE.AAA"))!=KErrNotFound);
 	delete dir;
+	
 	r=finder.FindWildByPath(_L("FILE.AAA*"), &gPath1, dir);
 	test(r==KErrNone);
 	test(dir->Count()==1);
 	entry=(*dir)[0];
 	test(entry.iName.MatchF(_L("FILE.AAA"))!=KErrNotFound);
 	delete dir;
+
+    
 	r=finder.FindWildByPath(_L("CONFUSED.DOG"), &gPath1, dir);
 	test(r==KErrNone);
 	test(dir->Count()==1);
 	entry=(*dir)[0];
 	test(entry.iName.MatchF(_L("CONFUSED.DOG"))!=KErrNotFound);
 	delete dir;
+
 	r=finder.FindWildByPath(_L("*CONFUSED.DOG"), &gPath1, dir);
 	test(r==KErrNone);
 	test(dir->Count()==1);
@@ -993,10 +998,119 @@
 
 	}
 
+//---------------------------------------------------------------------------------------
+/**
+    Test that callinng TFindFile methods that allocate CDir objects doesn't lead to memory leaks if some error occurs.
+*/
+void TestFailures()
+    {
+
+	test.Next(_L("Test TFindFile failures\n"));	
+
+#ifndef _DEBUG
+    test.Printf(_L("This test can't be performed in UREL mode, skipping\n"));
+    return;	
+#else
+
+	TFindFile finder(TheFs);
+	CDir* pDir;
+	TInt nRes;
+    TInt cnt=0;
+
+    _LIT(KPath, "\\F32-TST\\LOCTEST\\");
+
+    const TInt KMyError = -756; //-- specific error code we will simulate
+    
+    //------------------------------------
+    test.Printf(_L("Test FindWildByPath failures\n"));	
+    
+    __UHEAP_MARK;
+    nRes = finder.FindWildByPath(_L("*"), &gPath1, pDir);
+    test(nRes == KErrNone);
+    test(pDir && pDir->Count() > 1);
+    delete pDir;
+
+ 
+    for(cnt = 0; ;cnt++)
+        {
+        nRes =TheFs.SetErrorCondition(KMyError, cnt);
+        test(nRes == KErrNone);
+
+        pDir = (CDir*)0xaabbccdd;
+        nRes = finder.FindWildByPath(_L("*"), &gPath1, pDir);
+        
+        //-- on error the memory allocated internally for CDir shall be freed and the pointer CDir* shall be set to NULL 
+        if(nRes == KErrNone)
+            {
+            test.Printf(_L("Test FindWildByPath->FindWild() failures\n"));	
+            test(pDir && pDir->Count() > 1);
+            delete pDir;
+            pDir = (CDir*)0xaabbccdd;
+
+            TheFs.SetErrorCondition(KMyError);
+            nRes = finder.FindWild(pDir);
+            test(nRes != KErrNone);
+            test(pDir == NULL); 
+            
+            break;
+            }
+        else
+            {
+            test(pDir == NULL);
+            }
+
+        }
+
+   __UHEAP_MARKEND;
+   TheFs.SetErrorCondition(KErrNone);
 
 
+   //------------------------------------
+   test.Printf(_L("Test FindWildByDir failures\n"));	
+    
+   __UHEAP_MARK;
+   nRes = finder.FindWildByDir(_L("*"), KPath, pDir);
+   test(nRes == KErrNone);
+   test(pDir && pDir->Count() > 1);
+   delete pDir;
+   
+   for(cnt = 0; ;cnt++)
+        {
+        nRes =TheFs.SetErrorCondition(KMyError, cnt);
+        test(nRes == KErrNone);
 
-GLDEF_C void CallTestsL()
+        pDir = (CDir*)0xaabbccdd;
+        nRes = finder.FindWildByDir(_L("*"), KPath, pDir);
+        
+        //-- on error the memory allocated internally for CDir shall be freed and the pointer CDir* shall be set to NULL  
+        if(nRes == KErrNone)
+            {
+            test.Printf(_L("Test FindWildByDir->FindWild() failures\n"));	
+            test(pDir && pDir->Count() > 1);
+            delete pDir;
+            pDir = (CDir*)0xaabbccdd;
+
+            TheFs.SetErrorCondition(KMyError);
+            nRes = finder.FindWild(pDir);
+            test(nRes != KErrNone);
+            test(pDir == NULL);
+            
+            break;
+            }
+        else
+            {
+            test(pDir == NULL);
+            }
+
+        }
+
+   __UHEAP_MARKEND;
+   TheFs.SetErrorCondition(KErrNone);
+#endif
+}
+
+//---------------------------------------------------------------------------------------
+void CallTestsL()
 //
 // Do all tests
 //
@@ -1026,6 +1140,8 @@
 
 		CreateTestDirectory(_L("\\F32-TST\\LOCTEST\\"));
 		MakeLocateTestDirectoryStructure();
+		
+        TestFailures();
 		Test1();
 		Test2();
 		Test3();
--- a/kerneltest/f32test/server/t_main.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kerneltest/f32test/server/t_main.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -662,16 +662,26 @@
 	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);
-	test.Printf(_L("Requests in total at start=%d\n"),orgValues.iTotalCount);
+	test.Printf(_L("Requests at start: CloseQ %d FreeQ %d total %d peak %d\n"), 
+		orgValues.iCloseCount, orgValues.iFreeCount, orgValues.iTotalCount, orgValues.iRequestCountPeak);
 
 	// File cache
 
@@ -702,15 +712,89 @@
 	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);
 	test_KErrNone(r);
 	
-	test.Printf(_L("Requests on close queue at end=%d\n"),values.iCloseCount);
-	test.Printf(_L("Requests on free queue at end=%d\n"),values.iFreeCount);
-	test.Printf(_L("Requests dynamically allocated at end=%d\n"),values.iAllocated);
-	test.Printf(_L("Requests in total at end=%d\n"),values.iTotalCount);
+	test.Printf(_L("Requests at end: CloseQ %d FreeQ %d total %d peak %d\n"), 
+		values.iCloseCount, values.iFreeCount, values.iTotalCount, values.iRequestCountPeak);
+	test.Printf(_L("Operations at end: FreeQ %d total %d peak=%d\n"),
+		values.iOpFreeCount, values.iOpRequestCount, values.iOpRequestCountPeak);
 	
 	test(orgValues.iCloseCount==values.iCloseCount);
 	test(orgValues.iAllocated == values.iAllocated);
@@ -723,42 +807,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	Tue Feb 02 01:24:03 2010 +0200
+++ b/kerneltest/f32test/server/t_rename.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -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	Tue Feb 02 01:24:03 2010 +0200
+++ b/kerneltest/f32test/shostmassstorage/msman/app/cdisplay.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -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	Tue Feb 02 01:24:03 2010 +0200
+++ b/kerneltest/f32test/shostmassstorage/msman/app/cdisplay.h	Fri Apr 16 16:24:37 2010 +0300
@@ -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/msman/app/husbconsapp.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kerneltest/f32test/shostmassstorage/msman/app/husbconsapp.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -26,7 +26,6 @@
 #include <f32file.h>
 
 #include "rusbhostmsdevice.h"
-#include "rusbhostmslogicalunit.h"
 
 #include <d32usbdi_hubdriver.h>
 #include "usbtypes.h"
--- a/kerneltest/f32test/shostmassstorage/msman/src/cusbhost.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kerneltest/f32test/shostmassstorage/msman/src/cusbhost.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -23,7 +23,6 @@
 
 #include "usbtypes.h"
 #include "rusbhostmsdevice.h"
-#include "rusbhostmslogicalunit.h"
 #include "rextfilesystem.h"
 #include "cusbmsmountmanager.h"
 
--- a/kerneltest/f32test/shostmassstorage/msman/src/cusbhostao.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kerneltest/f32test/shostmassstorage/msman/src/cusbhostao.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -13,18 +13,6 @@
 // Description:
 //
 
-//#include <d32usbdi.h>
-//#include <d32otgdi.h>
-//#include <d32usbdescriptors.h>
-//#include <d32usbtransfers.h>
-
-
-//#include "rusbhostmslogicalunit.h"
-//
-//
-//
-//
-
 #include <e32base.h>
 #include <f32file.h>
 #include <d32usbdi_hubdriver.h>
--- a/kerneltest/f32test/shostmassstorage/msman/src/rextfilesystem.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kerneltest/f32test/shostmassstorage/msman/src/rextfilesystem.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -16,7 +16,6 @@
 #include <f32file.h>
 
 #include "rusbhostmsdevice.h"
-#include "rusbhostmslogicalunit.h"
 #include "rextfilesystem.h"
 #include "tmslog.h"
 
--- a/kerneltest/f32test/shostmassstorage/testclient/usbtestmsclient/cmassstoragemountcb.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kerneltest/f32test/shostmassstorage/testclient/usbtestmsclient/cmassstoragemountcb.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -220,280 +220,6 @@
 	delete hDes;
 	}
 
-/**
-Make sure that the file system is fat.
-*/
-TBool CMassStorageMountCB::ValidateBootSector()
-	{
-	__FNLOG("CMassStorageMountCB::ValidateBootSector");
-
-	TFatBootSector bootSector;
-	TInt r=ReadBootSector(bootSector);
-	__PRINT1(_L("CMassStorageMountCB::MountL - ReadBootSector returned %d"),r);
-	if (r != KErrNone)
-		{
-		return EFalse;
-		}
-
-	__PRINT(_L("\nBootSector info"));
-	__PRINT8BIT1(_L("FAT type = %S"),bootSector.FileSysType());
-	__PRINT8BIT1(_L("Vendor ID = %S"),bootSector.VendorId());
-	__PRINT1(_L("BytesPerSector %d"),bootSector.BytesPerSector());
-	__PRINT1(_L("SectorsPerCluster %d"),bootSector.SectorsPerCluster());
-	__PRINT1(_L("ReservedSectors %d"),bootSector.ReservedSectors());
-	__PRINT1(_L("NumberOfFats %d"),bootSector.NumberOfFats());
-	__PRINT1(_L("RootDirEntries %d"),bootSector.RootDirEntries());
-	__PRINT1(_L("Total Sectors = %d"),bootSector.TotalSectors());
-	__PRINT1(_L("MediaDescriptor = 0x%x"),bootSector.MediaDescriptor());
-	__PRINT1(_L("FatSectors %d"),bootSector.FatSectors());
-	__PRINT1(_L("SectorsPerTrack %d"),bootSector.SectorsPerTrack());
-	__PRINT1(_L("NumberOfHeads %d"),bootSector.NumberOfHeads());
-	__PRINT1(_L("HugeSectors %d"),bootSector.HugeSectors());
-	__PRINT1(_L("Fat32 Sectors %d"),bootSector.FatSectors32());
-	__PRINT1(_L("Fat32 Flags %d"),bootSector.FATFlags());
-	__PRINT1(_L("Fat32 Version Number %d"),bootSector.VersionNumber());
-	__PRINT1(_L("Root Cluster Number %d"),bootSector.RootClusterNum());
-	__PRINT1(_L("FSInfo Sector Number %d"),bootSector.FSInfoSectorNum());
-	__PRINT1(_L("Backup Boot Rec Sector Number %d"),bootSector.BkBootRecSector());
-	__PRINT1(_L("PhysicalDriveNumber %d"),bootSector.PhysicalDriveNumber());
-	__PRINT1(_L("ExtendedBootSignature %d"),bootSector.ExtendedBootSignature());
-	__PRINT1(_L("UniqueID %d"),bootSector.UniqueID());
-	__PRINT8BIT1(_L("VolumeLabel %S"),bootSector.VolumeLabel());
-	__PRINT8BIT1(_L("FileSysType %S\n"),bootSector.FileSysType());
-
-    iUniqueID=bootSector.UniqueID();
-	iIs16BitFat=bootSector.Is16BitFat();
-
-	iIs32BitFat=bootSector.Is32BitFat();
-	switch (DetermineFatType(bootSector))
-		{
-		case 12:
-			iIs16BitFat = EFalse;
-			iIs32BitFat = EFalse;
-			break;
-		case 16:
-			iIs16BitFat = ETrue;
-			iIs32BitFat = EFalse;
-			break;
-		case 32:
-			iIs16BitFat = EFalse;
-			iIs32BitFat = ETrue;
-			break;
-		default:
-			return EFalse;
-		}
-
-	TInt sectorsPerCluster=bootSector.SectorsPerCluster();
-	if (!IsPowerOfTwo(sectorsPerCluster))
-		return EFalse;
-
-	TInt sectorSizeLog2=Log2(bootSector.BytesPerSector());
-	if (sectorSizeLog2<0 || !IsPowerOfTwo(bootSector.BytesPerSector()))
-		return EFalse;
-
-	TInt firstFatSector=bootSector.ReservedSectors();
-	if (firstFatSector<1)
-		return EFalse;
-
-	TInt fatSizeInBytes;
-	if(iIs32BitFat)
-		{
-		fatSizeInBytes=bootSector.FatSectors32()*bootSector.BytesPerSector();
-		if (fatSizeInBytes<bootSector.BytesPerSector())
-			return EFalse;
-		}
-	else
-		{
-		fatSizeInBytes=bootSector.FatSectors()*bootSector.BytesPerSector();
-		if (fatSizeInBytes<bootSector.BytesPerSector())
-			return EFalse;
-
-		TInt rootDirectorySector=firstFatSector+bootSector.FatSectors()*bootSector.NumberOfFats();
-		if (rootDirectorySector<3)
-			return EFalse;
-
-		TInt rootDirSizeInBytes=bootSector.RootDirEntries()*KSizeOfFatDirEntry;
-		TInt numOfRootDirSectors=(rootDirSizeInBytes+(1<<sectorSizeLog2)-1)>>sectorSizeLog2;
-		TInt rootDirEnd=(rootDirectorySector+numOfRootDirSectors)<<sectorSizeLog2;
-		if (rootDirEnd<(4<<sectorSizeLog2))
-			return EFalse;
-		}
-
-
-	TInt totalSectors=bootSector.TotalSectors();
-	if (totalSectors==0)
-		totalSectors=bootSector.HugeSectors();
-	if (totalSectors<5)
-		return EFalse;
-
-	TInt numberOfFats=bootSector.NumberOfFats();
-	if (numberOfFats<1)
-		return EFalse;
-
-	return ETrue;
-	}
-
-/**
-Read non aligned boot data from media into TFatBootSector structure
-
-@param aBootSector refrence to TFatBootSector populate
-@return Media read error code
-*/
-TInt CMassStorageMountCB::ReadBootSector(TFatBootSector& aBootSector)
-	{
-	__FNLOG("CMassStorageMountCB::ReadBootSector");
-	TInt pos=0;
-	TUint8 data[KSizeOfFatBootSector];
-    TPtr8 buf(&data[0],KSizeOfFatBootSector);
-    TInt r=LocalDrive()->Read(0,KSizeOfFatBootSector,buf);
-	if (r!=KErrNone)
-		{
-		__PRINT1(_L("LocalDrive::Read() failed - %d"),r);
-		return(r);
-		}
-//	0	TUint8 iJumpInstruction[3]
-	Mem::Copy(&aBootSector.iJumpInstruction,&data[pos],3);
-	pos+=3;
-// 3	TUint8 iVendorId[KVendorIdSize]
-	Mem::Copy(&aBootSector.iVendorId,&data[pos],KVendorIdSize);
-	pos+=KVendorIdSize;
-// 11	TUint16 iBytesPerSector
-	Mem::Copy(&aBootSector.iBytesPerSector,&data[pos],2);
-	pos+=2;
-// 13	TUint8 sectorsPerCluster
-	Mem::Copy(&aBootSector.iSectorsPerCluster,&data[pos],1);
-	pos+=1;
-// 14	TUint16 iReservedSectors
-	Mem::Copy(&aBootSector.iReservedSectors,&data[pos],2);
-	pos+=2;
-// 16	TUint8 numberOfFats
-	Mem::Copy(&aBootSector.iNumberOfFats,&data[pos],1);
-	pos+=1;
-// 17	TUint16 iRootDirEntries
-	Mem::Copy(&aBootSector.iRootDirEntries,&data[pos],2);
-	pos+=2;
-// 19	TUint16 totalSectors
-	Mem::Copy(&aBootSector.iTotalSectors,&data[pos],2);
-	pos+=2;
-// 21	TUint8 iMediaDescriptor
-	Mem::Copy(&aBootSector.iMediaDescriptor,&data[pos],1);
-	pos+=1;
-// 22	TUint16 iFatSectors
-	Mem::Copy(&aBootSector.iFatSectors,&data[pos],2);
-	pos+=2;
-// 24	TUint16 iSectorsPerTrack
-	Mem::Copy(&aBootSector.iSectorsPerTrack,&data[pos],2);
-	pos+=2;
-// 26	TUint16 iNumberOfHeads
-	Mem::Copy(&aBootSector.iNumberOfHeads,&data[pos],2);
-	pos+=2;
-// 28	TUint32 iHiddenSectors
-	Mem::Copy(&aBootSector.iHiddenSectors,&data[pos],4);
-	pos+=4;
-// 32	TUint32 iHugeSectors
-	Mem::Copy(&aBootSector.iHugeSectors,&data[pos],4);
-	pos+=4;
-
-	if(aBootSector.iRootDirEntries == 0)	//indicates we have FAT32 volume
-		{
-		__PRINT(_L("\nFile system thinks Fat32"));
-
-		//36 TUint32 iFatSectors32
-		Mem::Copy(&aBootSector.iFatSectors32, &data[pos],4);
-		pos+=4;
-		//40 TUint16 iFATFlags
-		Mem::Copy(&aBootSector.iFATFlags, &data[pos],2);
-		pos+=2;
-		//42 TUint16 iVersionNumber
-		Mem::Copy(&aBootSector.iVersionNumber, &data[pos],2);
-		pos+=2;
-		//44 TUint32 iRootClusterNum
-		Mem::Copy(&aBootSector.iRootClusterNum, &data[pos],4);
-		pos+=4;
-		//48 TUint16 iFSInfoSectorNum
-		Mem::Copy(&aBootSector.iFSInfoSectorNum, &data[pos],2);
-		pos+=2;
-		//50 TUint16 iBkBootRecSector
-		Mem::Copy(&aBootSector.iBkBootRecSector, &data[pos],2);
-		pos+=(2+12);//extra 12 for the reserved bytes
-		}
-
-// 36|64	TUint8 iPhysicalDriveNumber
-	Mem::Copy(&aBootSector.iPhysicalDriveNumber,&data[pos],1);
-	pos+=1;
-// 37|65	TUint8 iReserved
-	Mem::Copy(&aBootSector.iReserved,&data[pos],1);
-	pos+=1;
-// 38|66	TUint8 iExtendedBootSignature
-	Mem::Copy(&aBootSector.iExtendedBootSignature,&data[pos],1);
-	pos+=1;
-// 39|67	TUint32 iUniqueID
-	Mem::Copy(&aBootSector.iUniqueID,&data[pos],4);
-	pos+=4;
-// 43|71	TUint8 iVolumeLabel[KVolumeLabelSize]
-	Mem::Copy(&aBootSector.iVolumeLabel,&data[pos],KVolumeLabelSize);
-	pos+=KVolumeLabelSize;
-// 54|82	TUint8 iFileSysType[KFileSysTypeSize]
-	Mem::Copy(&aBootSector.iFileSysType,&data[pos],KFileSysTypeSize);
-// 62|90
-
-	return(KErrNone);
-	}
-
-/**
-Work out if we have a FAT12|16|32 volume.
-Returns 12, 16 or 32 as appropriate.
-Returns 0 if can't be calculated (invalid values)
-*/
-TInt CMassStorageMountCB::DetermineFatType(TFatBootSector& aBootSector)
-	{
-	TUint32 ressectors = aBootSector.ReservedSectors();
-
-	if (aBootSector.SectorsPerCluster() < 1)
-		return 0;
-
-	if (aBootSector.RootDirEntries() != 0)
-		{
-		TUint32 rootdirbytes;
-		rootdirbytes = aBootSector.RootDirEntries() * 32 + aBootSector.BytesPerSector() - 1;
-		ressectors += rootdirbytes / aBootSector.BytesPerSector();
-		}
-
-	if (aBootSector.FatSectors() != 0)
-		ressectors += aBootSector.NumberOfFats() * aBootSector.FatSectors();
-	else
-		ressectors += aBootSector.NumberOfFats() * aBootSector.FatSectors32();
-
-	TUint32 totalsectors;
-	if (aBootSector.TotalSectors() != 0)
-		totalsectors = aBootSector.TotalSectors();
-	else
-		totalsectors = aBootSector.HugeSectors();
-
-	if (ressectors < 1 || totalsectors < 1)
-		return 0;
-
-	TUint32 datasec;
-	datasec = totalsectors - ressectors;
-
-	TUint32 countofclusters;
-	countofclusters = datasec / aBootSector.SectorsPerCluster();
-
-	__PRINT1(_L("CFatMountCB: Count of clusters = %d\n"), countofclusters);
-
-	if (countofclusters < 4085)
-		{
-		return 12;
-		}
-	else if (countofclusters < 65525)
-		{
-		return 16;
-		}
-	else
-		{
-		return 32;
-		}
-	}
 
 TInt CMassStorageMountCB::ReMount()
 	{
--- a/kerneltest/f32test/shostmassstorage/testclient/usbtestmsclient/inc/cmassstoragefilesystem.h	Tue Feb 02 01:24:03 2010 +0200
+++ b/kerneltest/f32test/shostmassstorage/testclient/usbtestmsclient/inc/cmassstoragefilesystem.h	Fri Apr 16 16:24:37 2010 +0300
@@ -35,7 +35,6 @@
     };
 
 
-
 /**
 Mass Storage Filesystem class.
 Only supports creating a new mount. Calling NewFileL, NewDirL and NewFormatL
@@ -82,8 +81,6 @@
 	CUsbMassStorageController* iMassStorageController;
 	TBool iRunning;
     TLunToDriveMap iDriveMap;
-
-
 	};
 
 #endif // __CMASSSTORAGEFILESYSTEM_H__
--- a/kerneltest/f32test/shostmassstorage/testclient/usbtestmsclient/inc/cmassstoragemountcb.h	Tue Feb 02 01:24:03 2010 +0200
+++ b/kerneltest/f32test/shostmassstorage/testclient/usbtestmsclient/inc/cmassstoragemountcb.h	Fri Apr 16 16:24:37 2010 +0300
@@ -25,7 +25,6 @@
 #ifndef __CMASSSTORAGEMOUNTCB_H__
 #define __CMASSSTORAGEMOUNTCB_H__
 
-#include <f32fsys.h>
 
 /**
 Mass Storage Mount.
@@ -34,7 +33,6 @@
 ControlIO is also supported for debug builds and returns KErrNotSupported for Release builds.
 @internalTechnology
 */
-class TFatBootSector;
 class CMassStorageMountCB : public CLocDrvMountCB
 	{
 public:
@@ -65,208 +63,14 @@
 	CMassStorageMountCB(const TLunToDriveMap& aDriveMapping);
 	void WritePasswordData();
 	TInt DriveNumberToLun(TInt aDriveNumber);
-	TBool ValidateBootSector();
-	TInt ReadBootSector(TFatBootSector& aBootSector);
-	TInt DetermineFatType(TFatBootSector& aBootSector);
 	TInt CheckDriveNumberL();
 
     TBool IsPowerOfTwo(TInt aNum);
     TInt Log2(TInt aNum);
 
 private:
-	TBool iIs16BitFat;
-	TBool iIs32BitFat;
 	const TLunToDriveMap& iDriveMapping;
 	};
 
-const TInt KSizeOfFatBootSector	= 90;
-const TInt KVendorIdSize = 8;
-const TInt KVolumeLabelSize = 11;
-const TInt KFileSysTypeSize = 8;
-const TInt KBootSectorSignature = 0xAA55;
-const TInt KSizeOfFatDirEntry = 32;
-
-/**
-Boot sector parameter block, enables access to all file system parameters.
-Data is populated at mount time from the BPB sector
-@internalTechnology
-*/
-class TFatBootSector
-	{
-public:
-	inline const TPtrC8 VendorId() const;
-	inline TUint16 BytesPerSector() const;
-	inline TInt SectorsPerCluster() const;
-	inline TInt ReservedSectors() const;
-	inline TInt NumberOfFats() const;
-	inline TInt RootDirEntries() const;
-	inline TInt TotalSectors() const;
-	inline TUint8 MediaDescriptor() const;
-	inline TInt FatSectors() const;
-	inline TInt SectorsPerTrack() const;
-	inline TInt NumberOfHeads() const;
-	inline TInt HiddenSectors() const;
-	inline TInt HugeSectors() const;
-	inline TInt PhysicalDriveNumber() const;
-	inline TInt ExtendedBootSignature() const;
-	inline TUint32 UniqueID() const;
-	inline const TPtrC8 VolumeLabel() const;
-	inline const TPtrC8 FileSysType() const;
-	inline TInt BootSectorSignature() const;
-	inline void SetJumpInstruction();
-	inline void SetVendorID(const TDesC8& aDes);
-	inline void SetBytesPerSector(TInt aBytesPerSector);
-	inline void SetSectorsPerCluster(TInt aSectorsPerCluster);
-	inline void SetReservedSectors(TInt aReservedSectors);
-	inline void SetNumberOfFats(TInt aNumberOfFats);
-	inline void SetRootDirEntries(TInt aRootDirEntries);
-	inline void SetTotalSectors(TInt aTotalSectors);
-	inline void SetMediaDescriptor(TUint8 aMediaDescriptor);
-	inline void SetFatSectors(TInt aFatSectors);
-	inline void SetSectorsPerTrack(TInt aSectorsPerTrack);
-	inline void SetNumberOfHeads(TInt aNumberOfHeads);
-	inline void SetHiddenSectors(TUint32 aHiddenSectors);
-	inline void SetHugeSectors(TUint32 aTotalSectors);
-	inline void SetPhysicalDriveNumber(TInt aPhysicalDriveNumber);
-	inline void SetReservedByte(TUint8 aReservedByte);
-	inline void SetExtendedBootSignature(TInt anExtendedBootSignature);
-	inline void SetUniqueID(TUint32 anUniqueID);
-	inline void SetVolumeLabel(const TDesC8& aDes);
-	inline void SetFileSysType(const TDesC8& aDes);
-
-	inline void SetFatSectors32(TUint32	aFatSectors32);
-	inline void SetFATFlags(TUint16 aFATFlags);
-	inline void SetVersionNumber(TUint16	aVersionNumber);
-	inline void SetRootClusterNum(TUint32 aRootCusterNum);
-	inline void SetFSInfoSectorNum(TUint16 aFSInfoSectorNum);
-	inline void SetBkBootRecSector(TUint16 aBkBootRecSector);
-	inline TUint32 FatSectors32() const;
-	inline TUint16 FATFlags() const;
-	inline TUint16 VersionNumber() const;
-	inline TUint32 RootClusterNum() const;
-	inline TUint16 FSInfoSectorNum() const;
-	inline TUint16 BkBootRecSector() const;
-public:
-	inline TBool Is16BitFat();
-	inline TBool Is32BitFat();
-	inline TInt FirstFatSectorPos();
-	inline TInt RootDirStartSector();
-	inline TInt FirstFreeSector();
-public:
-	/**
-	Jump instruction used for bootable volumes
-	*/
-    TUint8 iJumpInstruction[3];
-	/**
-	Vendor ID of the file system that formatted the volume
-	*/
-    TUint8 iVendorId[KVendorIdSize];
-	/**
-	Bytes per sector
-	*/
-    TUint16 iBytesPerSector;
-	/**
-	Sectors per cluster ratio
-	*/
-    TUint8 iSectorsPerCluster;
-	/**
-	Number of reserved sectors on the volume
-	*/
-    TUint16 iReservedSectors;
-	/**
-	Number of Fats on the volume
-	*/
-    TUint8 iNumberOfFats;
-	/**
-	Number of entries allowed in the root directory, specific to Fat12/16, zero for FAT32
-	*/
-    TUint16 iRootDirEntries;
-	/**
-	Total sectors on the volume, zero for FAT32
-	*/
-    TUint16 iTotalSectors;
-	/**
-	Media descriptor
-	*/
-    TUint8 iMediaDescriptor;
-	/**
-	Sectors used for the Fat table, zero for FAT32
-	*/
-    TUint16 iFatSectors;
-	/**
-	Sectors per track
-	*/
-    TUint16 iSectorsPerTrack;
-	/**
-	Number of heads
-	*/
-    TUint16 iNumberOfHeads;
-	/**
-	Number of hidden sectors in the volume
-	*/
-    TUint32 iHiddenSectors;
-	/**
-	Total sectors in the volume, Used if totalSectors > 65535
-	*/
-    TUint32 iHugeSectors;
-
-	/**
-	Start of additional elements @ offset 36 for FAT32
-	Sectors in Fat table for 32 bit volume
-	*/
-	TUint32	iFatSectors32;
-	/**
-	Fat flags
-	*/
-	TUint16 iFATFlags;
-	/**
-	Version number of the file system
-	*/
-	TUint16	iVersionNumber;
-	/**
-	Cluster number of the root directory
-	*/
-	TUint32 iRootClusterNum;
-	/**
-	Sector number containing the FSIInfo structure
-	*/
-	TUint16 iFSInfoSectorNum;
-	/**
-	Backup boot sector
-	*/
-	TUint16 iBkBootRecSector;
-	/**
-	Reserved space
-	End of Fat32 Only parameters section
-	*/
-	TUint8	iReserved2[12];
-
-	/**
-	Physical drive number, not used in Symbian OS
-	*/
-	TUint8 iPhysicalDriveNumber;
-	/**
-	Reserved byte
-	*/
-    TUint8 iReserved;
-	/**
-	Extended boot signiture
-	*/
-    TUint8 iExtendedBootSignature;
-	/**
-	Unique volume ID
-	*/
-    TUint32 iUniqueID;
-	/**
-	The volume's label
-	*/
-    TUint8 iVolumeLabel[KVolumeLabelSize];
-	/**
-	File system type
-	*/
-	TUint8 iFileSysType[KFileSysTypeSize];
-	};
-
-#include "tfatbootsector.inl"
 
 #endif //__CMASSSTORAGEMOUNTCB_H__
--- a/kerneltest/f32test/shostmassstorage/testclient/usbtestmsclient/inc/tfatbootsector.inl	Tue Feb 02 01:24:03 2010 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,460 +0,0 @@
-// 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:
-// Inline methods of TFatBootSector class.
-// 
-//
-
-
-
-
-/**
- @file
- @internalTechnology
- 
- Returns Sectors in Fat table for 32 bit volume
- 
- @return iFatSectors32
-*/
-inline TUint32 TFatBootSector::FatSectors32() const	
-	{return iFatSectors32;}
-/**
-Fat flags
-
-@return iFATFlags
-*/
-inline TUint16 TFatBootSector::FATFlags() const		
-	{return iFATFlags;}
-/**
-Version number of the file system
-
-@return iVersionNumber
-*/
-inline TUint16 TFatBootSector::VersionNumber() const		
-	{return iVersionNumber;}
-/**
-Cluster number of the root directory
-
-@return iRootClusterNum
-*/
-inline TUint32 TFatBootSector::RootClusterNum() const	
-	{return iRootClusterNum;}
-/**
-Sector number containing the FSIInfo structure
-
-@return iFSInfoSectorNum
-*/
-inline TUint16 TFatBootSector::FSInfoSectorNum() const
-	{return iFSInfoSectorNum;}
-/**
-Backup boot sector
-
-@return iBkBootRecSector
-*/
-inline TUint16 TFatBootSector::BkBootRecSector() const
-	{return iBkBootRecSector;}
-/**
-Sets the number of sectors in Fat table for 32 bit volume
-
-@param aFatSectors32
-*/
-inline void TFatBootSector::SetFatSectors32(TUint32	aFatSectors32)
-	{iFatSectors32 = aFatSectors32;}
-/**
-Sets the Fat flags
-
-@param aFATFlags
-*/
-inline void TFatBootSector::SetFATFlags(TUint16 aFATFlags)
-	{iFATFlags = aFATFlags;}
-/**
-Sets the version number of the file system
-
-@param aVersionNumber
-*/
-inline void TFatBootSector::SetVersionNumber(TUint16 aVersionNumber)
-	{iVersionNumber = aVersionNumber;}
-/**
-Sets the cluster number of the root directory
-
-@param aRootClusterNum
-*/
-inline void TFatBootSector::SetRootClusterNum(TUint32 aRootClusterNum)	
-	{iRootClusterNum = aRootClusterNum;}
-/**
-Set the sector number containing the FSIInfo structure
-
-@param aFSInfoSectorNum
-*/
-inline void TFatBootSector::SetFSInfoSectorNum(TUint16 aFSInfoSectorNum)
-	{iFSInfoSectorNum = aFSInfoSectorNum;}
-/**
-Set the backup boot sector
-
-@param aBkBootRecSector
-*/
-inline void TFatBootSector::SetBkBootRecSector(TUint16 aBkBootRecSector)
-	{iBkBootRecSector = aBkBootRecSector;}	
-/**
-Quick test as to whether the volume is Fat32
-
-@return True for Fat32
-*/
-inline TBool TFatBootSector::Is32BitFat()
-	{return(iRootDirEntries==0);}
-/**
-Returns the vendor ID of the file system that formatted the volume
-
-@return A descriptor containing the vendor ID 
-*/
-inline const TPtrC8 TFatBootSector::VendorId() const
-	{return TPtrC8(iVendorId,KVendorIdSize);}
-/**
-Return the bytes per sector
-
-@return iBytesPerSector
-*/
-inline TUint16 TFatBootSector::BytesPerSector() const
-	{return iBytesPerSector;}
-/**
-Returns the sectors per cluster ratio
-
-@return iSectorsPerCluster
-*/
-inline TInt TFatBootSector::SectorsPerCluster() const
-	{return iSectorsPerCluster;}
-/**
-Returns the number of reserved sectors on the volume
-
-@return iReservedSectors
-*/
-inline TInt TFatBootSector::ReservedSectors() const
-	{return iReservedSectors;}
-/**
-Returns the number of Fats on the volume
-
-@return iNumberOfFats
-*/
-inline TInt TFatBootSector::NumberOfFats() const
-	{return iNumberOfFats;}
-/**
-Returns the number of entries allowed in the root directory, specific to Fat12/16, zero for FAT32
-
-@return iRootDirEntries
-*/
-inline TInt TFatBootSector::RootDirEntries() const
-	{return iRootDirEntries;}
-/**
-Returns the total sectors on the volume, zero for FAT32
-
-@return iTotalSectors
-*/
-inline TInt TFatBootSector::TotalSectors() const
-	{return iTotalSectors;}
-/**
-Returns the media descriptor
-
-@return iMediaDescriptor
-*/
-inline TUint8 TFatBootSector::MediaDescriptor() const
-	{return iMediaDescriptor;}
-/**
-Returns sectors used for the Fat table, zero for FAT32
-
-@return iFatSectors
-*/
-inline TInt TFatBootSector::FatSectors() const
-	{return iFatSectors;}
-/**
-Returns sectors per track
-
-@return iSectorsPerTrack
-*/
-inline TInt TFatBootSector::SectorsPerTrack() const
-	{return iSectorsPerTrack;}
-/**
-Returns the number of heads 
-
-@return iNumberOfHeads
-*/
-inline TInt TFatBootSector::NumberOfHeads() const
-	{return iNumberOfHeads;}
-/**
-Returns the number of hidden sectors in the volume
-
-@return iHiddenSectors
-*/
-inline TInt TFatBootSector::HiddenSectors() const
-	{return iHiddenSectors;}
-/**
-Returns total sectors in the volume, Used if totalSectors > 65535
-
-@return iHugeSectors
-*/
-inline TInt TFatBootSector::HugeSectors() const
-	{return iHugeSectors;}
-/**
-Returns the physical drive number, not used in Symbian OS
-
-@return iPhysicalDriveNumber
-*/
-inline TInt TFatBootSector::PhysicalDriveNumber() const
-	{return iPhysicalDriveNumber;}
-/**
-Returns the extended boot signiture
-
-@return iExtendedBootSignature
-*/
-inline TInt TFatBootSector::ExtendedBootSignature() const
-	{return iExtendedBootSignature;}
-/**
-Returns the unique volume ID
-
-@return iUniqueID
-*/
-inline TUint32 TFatBootSector::UniqueID() const
-	{return iUniqueID;}
-/**
-Returns the volume's label
-
-@return A descriptor containing the volume label
-*/
-inline const TPtrC8 TFatBootSector::VolumeLabel() const
-	{return TPtrC8(iVolumeLabel,KVolumeLabelSize);}
-/**
-Returns the file system type
-
-@return A descriptor containing the file system type
-*/
-inline const TPtrC8 TFatBootSector::FileSysType() const
-	{return TPtrC8(iFileSysType,KFileSysTypeSize);}
-/**
-Returns the boot sector signiture
-
-@return KBootSectorSignature
-*/
-inline TInt TFatBootSector::BootSectorSignature() const
-	{return KBootSectorSignature;}
-/**
-Set the jump instruction 
-*/
-inline void TFatBootSector::SetJumpInstruction()
-	{iJumpInstruction[0]=0xE9;iJumpInstruction[2]=0x90;}
-/**
-Set the vendor ID of the file system that formatted the volume
-
-@param aDes Descriptor containing the Vendor ID
-*/
-inline void TFatBootSector::SetVendorID(const TDesC8& aDes)
-	{
-	__ASSERT_DEBUG(aDes.Length()<=KVendorIdSize,User::Panic(_L("FATFILESYS"),1));
-	TPtr8 buf(iVendorId,KVendorIdSize);
-	buf=aDes;
-	}
-/**
-Sets the bytes per sector 
-
-@param aBytesPerSector Number of bytes per sector
-*/
-inline void TFatBootSector::SetBytesPerSector(TInt aBytesPerSector)
-	{
-	__ASSERT_DEBUG(!(aBytesPerSector&~KMaxTUint16),User::Panic(_L("FATFILESYS"),1));
-	iBytesPerSector=(TUint16)aBytesPerSector;
-	}
-/**
-Set the sectors per cluster ratio
-
-@param aSectorsPerCluster Number of sectors per cluster
-*/
-inline void TFatBootSector::SetSectorsPerCluster(TInt aSectorsPerCluster)
-	{
-	__ASSERT_DEBUG(!(aSectorsPerCluster&~KMaxTUint8),User::Panic(_L("FATFILESYS"),1));
-	iSectorsPerCluster=(TUint8)aSectorsPerCluster;
-	}
-/**
-Sets the number of reserved sectors on the volume
-
-@param aReservedSectors Number of reserved sectors
-*/
-inline void TFatBootSector::SetReservedSectors(TInt aReservedSectors)
-	{
-	__ASSERT_DEBUG(!(aReservedSectors&~KMaxTUint16),User::Panic(_L("FATFILESYS"),1));
-	iReservedSectors=(TUint16)aReservedSectors;
-	}
-/**
-Sets the number of Fats on the volume
-
-@param aNumberOfFats Number of fats
-*/
-inline void TFatBootSector::SetNumberOfFats(TInt aNumberOfFats)
-	{
-	__ASSERT_DEBUG(!(aNumberOfFats&~KMaxTUint8),User::Panic(_L("FATFILESYS"),1));
-	iNumberOfFats=(TUint8)aNumberOfFats;
-	}
-/**
-Number of entries allowed in the root directory, specific to Fat12/16, zero for FAT32
-
-@param aRootDirEntries
-*/
-inline void TFatBootSector::SetRootDirEntries(TInt aRootDirEntries)
-	{
-	__ASSERT_DEBUG(!(aRootDirEntries&~KMaxTUint16),User::Panic(_L("FATFILESYS"),1));
-	iRootDirEntries=(TUint16)aRootDirEntries;
-	}
-/**
-Total sectors on the volume, zero for FAT32
-
-@param aTotalSectors Total number of sectors
-*/
-inline void TFatBootSector::SetTotalSectors(TInt aTotalSectors)
-	{
-	__ASSERT_DEBUG(!(aTotalSectors&~KMaxTUint16),User::Panic(_L("FATFILESYS"),1));
-	iTotalSectors=(TUint16)aTotalSectors;
-	}
-/**
-Set the media descriptor
-
-@param aMediaDescriptor
-*/
-inline void TFatBootSector::SetMediaDescriptor(TUint8 aMediaDescriptor)
-	{iMediaDescriptor=aMediaDescriptor;}
-/**
-Sectors used for the Fat table, zero for FAT32
-
-@param aFatSectors Number of Fat sectors
-*/
-inline void TFatBootSector::SetFatSectors(TInt aFatSectors)
-	{
-	__ASSERT_DEBUG(!(aFatSectors&~KMaxTUint16),User::Panic(_L("FATFILESYS"),1));
-	iFatSectors=(TUint16)aFatSectors;
-	}
-/**
-Set the sectors per track
-
-@param aSectorsPerTrack Number of sectors per track
-*/
-inline void TFatBootSector::SetSectorsPerTrack(TInt aSectorsPerTrack)
-	{
-	__ASSERT_DEBUG(!(aSectorsPerTrack&~KMaxTUint16),User::Panic(_L("FATFILESYS"),1));
-	iSectorsPerTrack=(TUint16)aSectorsPerTrack;
-	}
-/**
-Set the number of heads
-
-@param aNumberOfHeads Number of heads
-*/
-inline void TFatBootSector::SetNumberOfHeads(TInt aNumberOfHeads)
-	{
-	__ASSERT_DEBUG(!(aNumberOfHeads&~KMaxTUint16),User::Panic(_L("FATFILESYS"),1));
-	iNumberOfHeads=(TUint16)aNumberOfHeads;
-	}
-/**
-Set the number of hidden sectors in the volume
-
-@param aHiddenSectors Number of hidden sectors
-*/
-inline void TFatBootSector::SetHiddenSectors(TUint32 aHiddenSectors)
-	{
-	iHiddenSectors=(TUint32)(aHiddenSectors);
-	}
-/**
-Set the total sectors in the volume, Used if totalSectors > 65535
-
-@param aHugeSectors
-*/
-inline void TFatBootSector::SetHugeSectors(TUint32 aHugeSectors)
-	{iHugeSectors=aHugeSectors;}
-/**
-Physical drive number, not used in Symbian OS
-
-@param aPhysicalDriveNumber Physical drive number 
-*/
-inline void TFatBootSector::SetPhysicalDriveNumber(TInt aPhysicalDriveNumber)
-	{
-	__ASSERT_DEBUG(!(aPhysicalDriveNumber&~KMaxTUint8),User::Panic(_L("FATFILESYS"),1));
-	iPhysicalDriveNumber=(TUint8)aPhysicalDriveNumber;
-	}
-/**
-Set the reserved byte value
-
-@param aReservedByte Value for reserved byte
-*/
-inline void TFatBootSector::SetReservedByte(TUint8 aReservedByte)
-	{iReserved=aReservedByte;}
-/**
-Set the extended boot signiture
-
-@param anExtendedBootSignature The extended boot signiture
-*/
-inline void TFatBootSector::SetExtendedBootSignature(TInt anExtendedBootSignature)
-	{
-	__ASSERT_DEBUG(!(anExtendedBootSignature&~KMaxTUint8),User::Panic(_L("FATFILESYS"),1));
-	iExtendedBootSignature=(TUint8)anExtendedBootSignature;
-	}
-/**
-Set the unique volume ID
-
-@param anUniqueID Set the unique ID
-*/
-inline void TFatBootSector::SetUniqueID(TUint32 anUniqueID)
-	{iUniqueID=anUniqueID;}
-/**
-Set the volume's label
-
-@param aDes A descriptor containg the volume label
-*/
-inline void TFatBootSector::SetVolumeLabel(const TDesC8& aDes)
-	{
-	__ASSERT_DEBUG(aDes.Length()<=KVolumeLabelSize,User::Panic(_L("FATFILESYS"),1));
-	TPtr8 buf(iVolumeLabel,KVolumeLabelSize);
-	buf=aDes;
-	}
-/**
-Set the file system type
-
-@param aDes A descriptor containing the file system type
-*/
-inline void TFatBootSector::SetFileSysType(const TDesC8& aDes)
-	{
-	__ASSERT_DEBUG(aDes.Length()<=8,User::Panic(_L("FATFILESYS"),1));
-	TPtr8 buf(iFileSysType,8);
-	buf=aDes;
-	}
-/**
-Tests if the volume is Fat 16 or not
-
-@return True if the volume is Fat16
-*/
-inline TBool TFatBootSector::Is16BitFat()
-	{return(FileSysType()==_L8("FAT16   "));}
-/**
-Returns the position of the first sector of the first Fat
-
-@return The first Fat sector's byte position
-*/
-inline TInt TFatBootSector::FirstFatSectorPos()
-	{return(ReservedSectors()*BytesPerSector());}
-/**
-Returns the start sector number of the root directory
-
-@return Start sector number of the root directory
-*/
-inline TInt TFatBootSector::RootDirStartSector()
-	{return(ReservedSectors()+FatSectors()*NumberOfFats());}
-/**
-Returns the sector number of the first sector after the root directory 
-
-@return 
-*/
-inline TInt TFatBootSector::FirstFreeSector()
-	{return(RootDirStartSector()+(RootDirEntries()*KSizeOfFatDirEntry+BytesPerSector()-1)/BytesPerSector());}
--- a/kerneltest/f32test/shostmassstorage/testclient/usbtestmsclient/transport/cbulkonlytransport.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kerneltest/f32test/shostmassstorage/testclient/usbtestmsclient/transport/cbulkonlytransport.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -928,7 +928,7 @@
                     DataOutReadRequest(deviceDataLength);
                     }
 #else
-				DataOutRead(deviceDataLength);
+				DataOutReadRequest(deviceDataLength);
 #endif
 				return;
 				}
--- a/kerneltest/f32test/smassstorage/scripts/usbinterop1.pl	Tue Feb 02 01:24:03 2010 +0200
+++ b/kerneltest/f32test/smassstorage/scripts/usbinterop1.pl	Fri Apr 16 16:24:37 2010 +0300
@@ -2,7 +2,7 @@
 # Copyright (c) 2004-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"
+# under the terms of "Eclipse Public License v1.0"
 # which accompanies this distribution, and is available
 # at the URL "http://www.eclipse.org/legal/epl-v10.html".
 #
--- a/kerneltest/f32test/smassstorage/scripts/usbinterop2.pl	Tue Feb 02 01:24:03 2010 +0200
+++ b/kerneltest/f32test/smassstorage/scripts/usbinterop2.pl	Fri Apr 16 16:24:37 2010 +0300
@@ -2,7 +2,7 @@
 # Copyright (c) 2004-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"
+# under the terms of "Eclipse Public License v1.0"
 # which accompanies this distribution, and is available
 # at the URL "http://www.eclipse.org/legal/epl-v10.html".
 #
--- a/kerneltest/f32test/smassstorage/scripts/usbperformance.pl	Tue Feb 02 01:24:03 2010 +0200
+++ b/kerneltest/f32test/smassstorage/scripts/usbperformance.pl	Fri Apr 16 16:24:37 2010 +0300
@@ -2,7 +2,7 @@
 # Copyright (c) 2006-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"
+# under the terms of "Eclipse Public License v1.0"
 # which accompanies this distribution, and is available
 # at the URL "http://www.eclipse.org/legal/epl-v10.html".
 #
--- a/kerneltest/f32test/smassstorage/scripts/usbperformance_multifile.pl	Tue Feb 02 01:24:03 2010 +0200
+++ b/kerneltest/f32test/smassstorage/scripts/usbperformance_multifile.pl	Fri Apr 16 16:24:37 2010 +0300
@@ -2,7 +2,7 @@
 # Copyright (c) 2006-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"
+# under the terms of "Eclipse Public License v1.0"
 # which accompanies this distribution, and is available
 # at the URL "http://www.eclipse.org/legal/epl-v10.html".
 #
--- a/kerneltest/f32test/smassstorage/src/t_ms_fsunit.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kerneltest/f32test/smassstorage/src/t_ms_fsunit.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -21,11 +21,8 @@
 */
 
 #include <f32file.h>
+#include <f32fsys.h>
 #include <e32test.h>
-#include <e32std.h>
-#include <e32std_private.h>
-#include <e32svr.h>
-#include <hal.h>
 #include "t_ms_main.h"
 #include "t_ms_common.h"
 #include "cmassstoragefilesystem.h"
@@ -268,7 +265,6 @@
 EXPORT_C CLocDrvMountCB::~CLocDrvMountCB()
 
 	{
-	__PRINT1(_L("CLocDrvMountCB::~CLocDrvMountCB() 0x%x"),this);
 	if(iProxyDrive)
 		delete(iProxyDrive);
 	}
--- a/kerneltest/f32test/smassstorage/src/t_ms_mountstart.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/kerneltest/f32test/smassstorage/src/t_ms_mountstart.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -701,6 +701,8 @@
    		fs.NotifyDismount(removalDrvNo, trsClientComplete, EFsDismountNotifyClients);
 		test(trsClientComplete == KRequestPending);
 
+		fs.NotifyDismountCancel(trsClientComplete);
+
 		fs.Close();
 		dismountFs1.Close();
 	}
--- a/package_definition.xml	Tue Feb 02 01:24:03 2010 +0200
+++ b/package_definition.xml	Fri Apr 16 16:24:37 2010 +0300
@@ -3,7 +3,7 @@
   <package id="kernelhwsrv" name="Kernel and Hardware Services" levels="hw-if adaptation framework test">
     <collection id="brdbootldr" name="Board Boot Loader" level="hw-if">
       <component id="ubootldr" name="Boot Loader" introduced="9.2" purpose="optional">
-        <unit mrp="brdbootldr/ubootldr/base_ubootldr.mrp"/>
+        <unit bldFile="brdbootldr/ubootldr" mrp="brdbootldr/ubootldr/base_ubootldr.mrp"/>
       </component>
     </collection>
     <collection id="bsptemplate" name="Board Support Package Template" level="hw-if">
--- a/userlibandfileserver/domainmgr/group/base_domain.mrp	Tue Feb 02 01:24:03 2010 +0200
+++ b/userlibandfileserver/domainmgr/group/base_domain.mrp	Fri Apr 16 16:24:37 2010 +0300
@@ -1,3 +1,18 @@
+#
+# 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 "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: 
+#
 # component name "Domain Manager"
 
 component	base_domain
--- a/userlibandfileserver/fileserver/automounter/base_f32_automounter.mrp	Tue Feb 02 01:24:03 2010 +0200
+++ b/userlibandfileserver/fileserver/automounter/base_f32_automounter.mrp	Fri Apr 16 16:24:37 2010 +0300
@@ -1,3 +1,18 @@
+#
+# 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 "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: 
+#
 # component name "exFAT File System"
 
 component   base_f32_automounter
--- a/userlibandfileserver/fileserver/estart/base_f32_estart.mrp	Tue Feb 02 01:24:03 2010 +0200
+++ b/userlibandfileserver/fileserver/estart/base_f32_estart.mrp	Fri Apr 16 16:24:37 2010 +0300
@@ -1,3 +1,18 @@
+#
+# 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 "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: 
+#
 # component name "EStart"
 
 component	base_f32_estart
--- a/userlibandfileserver/fileserver/etshell/base_f32_eshell.mrp	Tue Feb 02 01:24:03 2010 +0200
+++ b/userlibandfileserver/fileserver/etshell/base_f32_eshell.mrp	Fri Apr 16 16:24:37 2010 +0300
@@ -1,3 +1,18 @@
+#
+# 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 "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: 
+#
 # component name "Text Shell"
 
 component	base_f32_eshell
--- a/userlibandfileserver/fileserver/etshell/ts_com.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/userlibandfileserver/fileserver/etshell/ts_com.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -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)
@@ -1107,8 +1110,30 @@
 	//-- Print out information about file system installed
 	if(aFlags & EFSInfo)
     {
+        //-- print out drive properties
+        Buf.Format(_L("\nDrive %c: No:%d"), 'A'+aDrvNum, aDrvNum);
         
-        apConsole->Printf(_L("\nDrive %c: number:%d\n"), 'A'+aDrvNum, aDrvNum);
+        //-- find out if the drive is synchronous / asynchronous
+        TPckgBuf<TBool> drvSyncBuf;
+        nRes = aFs.QueryVolumeInfoExt(aDrvNum, EIsDriveSync, drvSyncBuf);
+        if(nRes == KErrNone)
+        {
+            Buf.AppendFormat(_L(", Sync:%d"), drvSyncBuf() ? 1:0);        
+        }
+
+        //-- find out if drive runs a rugged FS (debug mode only)
+        const TInt KControlIoIsRugged=4;
+        TUint8 ruggedFS;
+        TPtr8 pRugged(&ruggedFS, 1, 1);
+        nRes=aFs.ControlIo(aDrvNum, KControlIoIsRugged, pRugged);
+        if(nRes == KErrNone)
+        {
+            Buf.AppendFormat(_L(", Rugged:%d"), ruggedFS ? 1:0);        
+        }
+
+        Buf.Append(_L("\n"));
+        apConsole->Printf(Buf);
+
 
 	    //-- print the FS name
 	    if(aFs.FileSystemName(Buf, aDrvNum) == KErrNone)
@@ -1151,19 +1176,36 @@
 
 
 
-            //-- print out FileSystem volume finalisation info
+            
             if(bVolumeOK && (aFlags & EFSInfoEx))
             {
-
+                Buf.Zero();
+
+                //-- print out FileSystem volume finalisation info
                 TPckgBuf<TBool> boolPckg;
                 nRes = aFs.QueryVolumeInfoExt(aDrvNum, EIsDriveFinalised, boolPckg);
                 if(nRes == KErrNone)
                 {
                     if(boolPckg() >0)
-                        apConsole->Printf(_L("Volume Finalised\n"));
+                        Buf.Copy(_L("Volume: Finalised"));
                     else
-                        apConsole->Printf(_L("Volume Not finalised\n"));
+                        Buf.Copy(_L("Volume: Not finalised"));
                 }
+
+                //-- print out cluster size that FS reported
+                TVolumeIOParamInfo volIoInfo;
+                nRes = aFs.VolumeIOParam(aDrvNum, volIoInfo);
+                if(nRes == KErrNone && volIoInfo.iClusterSize >= 512)
+                {
+                    Buf.AppendFormat(_L(", Cluster Sz:%d"), volIoInfo.iClusterSize);
+                }
+
+                if(Buf.Length())
+                {
+                    Buf.Append(_L("\n"));
+                    apConsole->Printf(Buf);    
+                }
+
             }
 	    }
     }//if(aFlags & EFSInfo)
--- a/userlibandfileserver/fileserver/fs_utils/filesystem_utils.inl	Tue Feb 02 01:24:03 2010 +0200
+++ b/userlibandfileserver/fileserver/fs_utils/filesystem_utils.inl	Fri Apr 16 16:24:37 2010 +0300
@@ -54,7 +54,10 @@
 inline TBool IsPowerOf2(TUint32 aVal)
     {
     if (aVal==0)
+        {
+        ASSERT(0);
         return EFalse;
+        }
 
     return !(aVal & (aVal-1));
     }
@@ -67,7 +70,10 @@
 inline TBool IsPowerOf2_64(TUint64 aVal)
     {
     if (aVal==0)
+        {
+        ASSERT(0);
         return EFalse;
+        }
 
     return !(aVal & (aVal-1));
 
--- a/userlibandfileserver/fileserver/group/base_f32.mrp	Tue Feb 02 01:24:03 2010 +0200
+++ b/userlibandfileserver/fileserver/group/base_f32.mrp	Fri Apr 16 16:24:37 2010 +0300
@@ -1,3 +1,18 @@
+#
+# 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 "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: 
+#
 # component name "File Server"
 
 component	base_f32
--- a/userlibandfileserver/fileserver/group/release.txt	Tue Feb 02 01:24:03 2010 +0200
+++ b/userlibandfileserver/fileserver/group/release.txt	Fri Apr 16 16:24:37 2010 +0300
@@ -1,3 +1,201 @@
+Version 2.00.3020
+=================
+(Made by vfebvre 08/03/2010)
+
+1.	niccox
+	1.	PDEF144805 Transcend flash drive not recognised 
+
+2.	dlyokhin
+	1.	PDEF144751 FAT: unable to mount volume larger than 1TB  
+
+
+Version 2.00.3019
+=================
+(Made by vfebvre 04/03/2010)
+
+1.	dlyokhin
+	1.	PDEF144780  exFAT: T_chkUID test failure  
+
+
+Version 2.00.3018
+=================
+(Made by vfebvre 03/03/2010)
+
+1.	niccox
+	1.	DEF144738 Initialisation of MaxLun if USB device stalls request
+
+
+Version 2.00.3017
+=================
+(Made by vfebvre 02/03/2010)
+
+1.	dlyokhin
+	1.	DEF144683 TUint32 overflow in CFatFileCB::DoExpandFileL()
+
+
+Version 2.00.3016
+=================
+(Made by vfebvre 26/02/2010)
+
+1.	famustaf
+	1.	PDEF144638 Missing Trap in a non-leaving function.
+
+2.	frhofman
+	1.	DEF144651: Revert IsFileOpen() behaviour to perform file existance check
+
+3.	dlyokhin
+	1.	PDEF144599 FAT leaf directory cache should be enabled by default  
+	2.	DEF144629 Better checks in CFat16FixedCache code  
+
+
+Version 2.00.3015
+=================
+(Made by vfebvre 25/02/2010)
+
+1.	niccox
+	1.	DEF144571 remove redundant bootsector code from smassstorage
+
+
+Version 2.00.3014
+=================
+(Made by vfebvre 23/02/2010)
+
+1.	jsucksmi
+	1.	PDEF144223:Emulated removable drive X is not present in tb10.1(MSF00326) and tb9.2(1014) 
+
+
+Version 2.00.3013
+=================
+(Made by vfebvre 19/02/2010)
+
+1.	dlyokhin
+	1.	DEF144487: FAT FS should allow skipping file timestamp update on data flushing
+
+
+Version 2.00.3012
+=================
+(Made by vfebvre 18/02/2010)
+
+1.	famustaf
+	1.	DEF144437 Optimise TParseBase::AddDir() to not use TFileName
+
+2.	migubarr
+	1.	PDEF144408: File Server request cache is not big enough for S60 
+
+
+Version 2.00.3011
+=================
+(Made by vfebvre 11/02/2010)
+
+1.	dlyokhin
+	1.	PDEF144357 VFAT interoperability: LFN entries padding is wrong
+
+
+Version 2.00.3010
+=================
+(Made by vfebvre 09/02/2010)
+
+1.	kaduan
+	1.	DEF144138:  Unwanted directory cache change caused performance regression 
+
+2.	dlyokhin
+	1.	PDEF144270 potential memory leak in TFindFile::FindWildByDir()  
+
+
+Version 2.00.3009
+=================
+(Made by vfebvre 05/02/2010)
+
+1.	niccox
+	1.	PDEF144293 Add ModeSense10 support to USB MS Client
+
+
+Version 2.00.3008
+=================
+(Made by vfebvre 03/02/2010)
+
+1.	migubarr
+	1.	PDEF144173: Small FAT32 partitions on large media can sometimes be formatted incorrectly 
+
+
+Version 2.00.3007
+=================
+(Made by vfebvre 28/01/2010)
+
+1.	famustaf
+	1.	DEF144032 Change tests in t_fman to use __E32TEST_EXTENSION__
+
+2.	hengrant
+	1.	DEFECT FIX: DEF144005 New Memory & File Server Coverity Defects
+		Fix 3 Coverity Issues
+
+
+Version 2.00.3006
+=================
+(Made by vfebvre 21/01/2010)
+
+1.	dlyokhin
+	1.	PDEF143792 FAT: renaming many files in a directory corrupts short file names  
+
+
+Version 2.00.3005
+=================
+(Made by vfebvre 19/01/2010)
+
+1.	necliffo
+	1.	DEF143911 WDP: T_locate fails on VASCO 
+
+
+Version 2.00.3004
+=================
+(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.3003
+=================
+(Made by vfebvre 15/01/2010)
+
+1.	niccox
+	1.	DEF143785 USB Host MS does not handle non-mass-storage drive correctly
+	2.	MINOR_CHANGE hostusbmsapp support for different screen sizes
+
+2.	kaduan
+	1.	PDEF143820: File system caching should be turned off on the S60 emulator 
+
+3.	migubarr
+	1.	PDEF143787: t_ms_mountstart fails on H4 and VASCO
+
+
+Version 2.00.3002
+=================
+(Made by vfebvre 13/01/2010)
+
+1.	kaduan
+	1.	PDEF143778 T_HANDSHARE failed on NE1_TB_ARMV5.UDEB.SMPPAGE image
+
+2.	dlyokhin
+	1.	DEF143404 FAT: deleting VFAT entryset is not optimal
+
+
+Version 2.00.3001
+=================
+(Made by vfebvre 12/01/2010)
+
+1.	niccox
+	1.	MINOR_CHANGE usbtestclient corrections
+
+
+Version 2.00.3000
+=================
+(Made by vfebvre 07/01/2010)
+
+1.	niccox
+	1.	DEF143508 Host USB ModeSense10 command does not decode ModeDataLength
+
+
 Version 2.00.2026
 =================
 (Made by vfebvre 17/12/2009)
--- a/userlibandfileserver/fileserver/inc/f32dbg.h	Tue Feb 02 01:24:03 2010 +0200
+++ b/userlibandfileserver/fileserver/inc/f32dbg.h	Fri Apr 16 16:24:37 2010 +0300
@@ -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;
@@ -191,10 +194,17 @@
 class TIOCacheValues
 	{ 
 public:
-	TInt iFreeCount;	// number of requests on free queue
-	TInt iCloseCount;	// number of requests on close queue
-	TInt iAllocated;	// number of dynamically allocated requests
-	TInt iTotalCount;	// number of permanently & dynamically allocated requests
+	TInt iFreeCount;	// current number of requests on free queue
+	TInt iCloseCount;	// current number of requests on close queue
+	TInt iAllocated;	// no longer used
+	TInt iTotalCount;	// current number of requests
+	TInt iRequestCountPeak;	// peak number of requests, i.e. peak value reached by iTotalCount
+
+
+	// the same again but for the OperationAllocator
+	TInt iOpFreeCount;
+	TInt iOpRequestCount;
+	TInt iOpRequestCountPeak;
 	};
 
 class TFileCacheStats
--- a/userlibandfileserver/fileserver/inc/f32file.h	Tue Feb 02 01:24:03 2010 +0200
+++ b/userlibandfileserver/fileserver/inc/f32file.h	Fri Apr 16 16:24:37 2010 +0300
@@ -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 */
@@ -3028,7 +3029,7 @@
 
 
 
-class TFindFile
+
 /**
 @publishedAll
 @released
@@ -3055,6 +3056,7 @@
 be searched must match.  
  
 */
+class TFindFile
 	{
 public:
 	IMPORT_C TFindFile(RFs& aFs);
@@ -3073,6 +3075,7 @@
 	TInt DoFindInDir();
 	TInt DoFindNextInPath();
 	TInt DoFindNextInDriveList();
+    TInt CallSafe(TInt aResult);
 private:
 	RFs* const iFs;
 	TParse iFile;
--- a/userlibandfileserver/fileserver/inc/f32ver.h	Tue Feb 02 01:24:03 2010 +0200
+++ b/userlibandfileserver/fileserver/inc/f32ver.h	Fri Apr 16 16:24:37 2010 +0300
@@ -58,6 +58,6 @@
 
 @see TVersion
 */
-const TInt KF32BuildVersionNumber=2026;
+const TInt KF32BuildVersionNumber=3020;
 //
 #endif
--- a/userlibandfileserver/fileserver/scomp/base_f32_scomp.mrp	Tue Feb 02 01:24:03 2010 +0200
+++ b/userlibandfileserver/fileserver/scomp/base_f32_scomp.mrp	Fri Apr 16 16:24:37 2010 +0300
@@ -1,3 +1,18 @@
+#
+# 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 "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: 
+#
 # component name "Composite File System"
 
 component	base_f32_scomp
--- a/userlibandfileserver/fileserver/sfat/base_f32_sfat.mrp	Tue Feb 02 01:24:03 2010 +0200
+++ b/userlibandfileserver/fileserver/sfat/base_f32_sfat.mrp	Fri Apr 16 16:24:37 2010 +0300
@@ -1,3 +1,18 @@
+#
+# 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 "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: 
+#
 # component name "FAT File System"
 
 component	base_f32_sfat
--- a/userlibandfileserver/fileserver/sfat/sl_fat16.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/userlibandfileserver/fileserver/sfat/sl_fat16.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -82,37 +82,49 @@
         iSectorsPerFat=MaxFat16Sectors();
         }
     
-    // Ensure cluster size is a multiple of the block size
-    TInt blockSizeInSectors = aCaps.iBlockSize >> iSectorSizeLog2;
-    __PRINT1(_L("blockSizeInSectors: %d"),blockSizeInSectors);
-    ASSERT(blockSizeInSectors == 0 || IsPowerOf2(blockSizeInSectors));
-    if (blockSizeInSectors != 0 && IsPowerOf2(blockSizeInSectors))
-        {
-        __PRINT1(_L("iSectorsPerCluster (old): %d"),iSectorsPerCluster);
-        AdjustClusterSize(blockSizeInSectors);
-        __PRINT1(_L("iSectorsPerCluster (new): %d"),iSectorsPerCluster);
-        }
-    
-    // Align first data sector on an erase block boundary if
-    // (1) the iEraseBlockSize is specified
-    // (2) the start of the partition is already aligned to an erase block boundary, 
-    //     i.e. iHiddenSectors is zero or a multiple of iEraseBlockSize
-    __PRINT1(_L("iHiddenSectors: %d"),iHiddenSectors);
-    TInt eraseblockSizeInSectors = aCaps.iEraseBlockSize >> iSectorSizeLog2;
-    __PRINT1(_L("eraseblockSizeInSectors: %d"),eraseblockSizeInSectors);
-    ASSERT(eraseblockSizeInSectors == 0 || IsPowerOf2(eraseblockSizeInSectors));    
-    ASSERT(eraseblockSizeInSectors == 0 || eraseblockSizeInSectors >= blockSizeInSectors);
-    if ((eraseblockSizeInSectors != 0) &&
-        (iHiddenSectors % eraseblockSizeInSectors == 0) &&  
-        (IsPowerOf2(eraseblockSizeInSectors)) &&
-        (eraseblockSizeInSectors >= blockSizeInSectors))
-        {
-        TInt r = AdjustFirstDataSectorAlignment(eraseblockSizeInSectors);
-        ASSERT(r == KErrNone);
-        (void) r;
-        }
-    __PRINT1(_L("iReservedSectors: %d"),iReservedSectors);
-    __PRINT1(_L("FirstDataSector: %d"), FirstDataSector());
+	const TFatType fatType = SuggestFatType();
+
+	// Ensure cluster size is a multiple of the block size
+	TInt blockSizeInSectors = aCaps.iBlockSize >> iSectorSizeLog2;
+	__PRINT1(_L("blockSizeInSectors: %d"),blockSizeInSectors);
+	ASSERT(blockSizeInSectors == 0 || IsPowerOf2(blockSizeInSectors));
+	if (blockSizeInSectors != 0 && IsPowerOf2(blockSizeInSectors))
+		{
+		__PRINT1(_L("iSectorsPerCluster    (old): %d"),iSectorsPerCluster);
+		AdjustClusterSize(blockSizeInSectors);
+		__PRINT1(_L("iSectorsPerCluster    (new): %d"),iSectorsPerCluster);
+		}
+
+
+	for (; iSectorsPerCluster>1; iSectorsPerCluster>>= 1)
+		{
+		// Align first data sector on an erase block boundary if
+		// (1) the iEraseBlockSize is specified
+		// (2) the start of the partition is already aligned to an erase block boundary, 
+		//     i.e. iHiddenSectors is zero or a multiple of iEraseBlockSize
+		__PRINT1(_L("iHiddenSectors: %d"),iHiddenSectors);
+		TInt eraseblockSizeInSectors = aCaps.iEraseBlockSize >> iSectorSizeLog2;
+		__PRINT1(_L("eraseblockSizeInSectors: %d"),eraseblockSizeInSectors);
+		ASSERT(eraseblockSizeInSectors == 0 || IsPowerOf2(eraseblockSizeInSectors));	
+		ASSERT(eraseblockSizeInSectors == 0 || eraseblockSizeInSectors >= blockSizeInSectors);
+		if ((eraseblockSizeInSectors != 0) &&
+			(iHiddenSectors % eraseblockSizeInSectors == 0) &&	
+			(IsPowerOf2(eraseblockSizeInSectors)) &&
+			(eraseblockSizeInSectors >= blockSizeInSectors))
+			{
+			TInt r = AdjustFirstDataSectorAlignment(eraseblockSizeInSectors);
+			ASSERT(r == KErrNone);
+			(void) r;
+			}
+		__PRINT1(_L("iReservedSectors: %d"),iReservedSectors);
+		__PRINT1(_L("FirstDataSector: %d"), FirstDataSector());
+
+		// If we've shrunk the number of clusters by so much that it's now invalid for this FAT type
+		// then we need to decrease the cluster size and try again, otherwise we're finshed.
+		if (SuggestFatType() == fatType)
+			break;
+		}
+	__PRINT1(_L("iSectorsPerCluster  (final): %d"),iSectorsPerCluster);
 
     return KErrNone;
     }
@@ -124,11 +136,11 @@
     }
 
 void CFatFormatCB::AdjustClusterSize(TInt aRecommendedSectorsPerCluster)
-    {
-    const TInt KMaxSecPerCluster = 64;  // 32K
-    while (aRecommendedSectorsPerCluster > iSectorsPerCluster && iSectorsPerCluster <= (KMaxSecPerCluster/2))
-        iSectorsPerCluster<<= 1;
-    }
+	{
+    const TInt KMaxSecPerCluster = 64;	// 32K
+	while (aRecommendedSectorsPerCluster > iSectorsPerCluster && iSectorsPerCluster <= (KMaxSecPerCluster/2))
+		iSectorsPerCluster<<= 1;
+	}
 
 // AdjustFirstDataSectorAlignment()
 // Attempts to align the first data sector on an erase block boundary by modifying the
--- a/userlibandfileserver/fileserver/sfat32/base_f32_sfat32.mrp	Tue Feb 02 01:24:03 2010 +0200
+++ b/userlibandfileserver/fileserver/sfat32/base_f32_sfat32.mrp	Fri Apr 16 16:24:37 2010 +0300
@@ -1,3 +1,18 @@
+#
+# 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 "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: 
+#
 # component name "FAT32 File System"
 
 component	base_f32_sfat32
--- a/userlibandfileserver/fileserver/sfat32/common_constants.h	Tue Feb 02 01:24:03 2010 +0200
+++ b/userlibandfileserver/fileserver/sfat32/common_constants.h	Fri Apr 16 16:24:37 2010 +0300
@@ -115,12 +115,12 @@
 const TUint8 KEntryErasedMarker=0xE5;           ///< Erased entry marker for a directory entry
 
 
-const TInt EOF_32Bit =0x0fffffff;   ///< End of cluster chain value for Fat32
-const TInt EOF_16Bit =0xffff;       ///< End of cluster chain value for Fat16
-const TInt EOF_12Bit =0xfff;        ///< End of cluster chain value for Fat12
-const TInt KBad_32Bit=0x0ffffff7;   ///< Bad cluster value for Fat32
-const TInt KBad_16Bit=0xfff7;       ///< Bad cluster value for Fat16
-const TInt KBad_12Bit=0xff7;        ///< bad cluster value for Fat12
+const TUint EOF_32Bit =0x0fffffff;   ///< End of cluster chain value for Fat32
+const TUint EOF_16Bit =0xffff;       ///< End of cluster chain value for Fat16
+const TUint EOF_12Bit =0xfff;        ///< End of cluster chain value for Fat12
+const TUint KBad_32Bit=0x0ffffff7;   ///< Bad cluster value for Fat32
+const TUint KBad_16Bit=0xfff7;       ///< Bad cluster value for Fat16
+const TUint KBad_12Bit=0xff7;        ///< bad cluster value for Fat12
 
 const TUint   KSpareCluster = 0;          ///< FAT entry value for the spare cluster
 const TUint32 KFatFirstSearchCluster = 2; ///< FAT usable clusters start from 2; FAT[0] and FAT[1] are reserved
--- a/userlibandfileserver/fileserver/sfat32/fat_config.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/userlibandfileserver/fileserver/sfat32/fat_config.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -64,7 +64,7 @@
 
 
 //=======================================================================================================================
-//-- FAT directory cache settings
+//-- plain old FAT directory cache settings
 //=======================================================================================================================
 //-- FAT_DirCache <CacheSizeKB>,<Log2(max page size)>
 //-- e.g:   FAT_DirCache 16,12
@@ -102,10 +102,10 @@
 //=======================================================================================================================
 //-- A leaf directory cache for Fat volumes
 _LIT8(KPN_FAT_LeafDirCache, "FAT_LeafDirCacheSize"); 
-static const TUint32 KDef_KLeafDirCacheSize = 1;    //-- default number of the most recently visited leaf dirs to be cached
+static const TUint32 KDef_KLeafDirCacheSize = 32;    //-- default number of the most recently visited leaf dirs to be cached
 
 //=======================================================================================================================
-//-- New directory cache settings
+//-- DP directory cache settings
 //=======================================================================================================================
 //-- New directory cache uses the global cache memory manager for dynamic size allocation
 _LIT8(KPN_FAT_DynamicDirCacheMin, "FAT_DirCacheSizeMin"); 
@@ -116,12 +116,6 @@
                                                                 //  maximal size Log2, 2^14 (16K) by default
 
 
-
-
-
-
-
-
 //########################################################################################################################
 
 
@@ -358,6 +352,7 @@
 #ifdef _DEBUG
 
     ASSERT(iInitialised);
+    __PRINT(_L("\n\n"));
     __PRINT(_L("#>- TFatConfig parameters:\n"));
 
     DoDumpUintParam(KPN_ScanDrvSkipFinalisedVolume, iScanDrvSkipFinalisedVolume);
@@ -376,6 +371,12 @@
     DoDumpUintParam(_L8("FAT_32Cache RdGr Log2"), iFat32LRUCacheReadGrLog2);
     DoDumpUintParam(_L8("FAT_32Cache WrGr Log2"), iFat32LRUCacheWriteGrLog2);
 
+    
+    DoDumpUintParam(KPN_FAT_LeafDirCache,       iLeafDirCacheSize);
+    DoDumpUintParam(KPN_FAT_DynamicDirCacheMin, iDynamicDirCacheSizeMinKB);
+    DoDumpUintParam(KPN_FAT_DynamicDirCacheMax, iDynamicDirCacheSizeMaxKB);
+    DoDumpUintParam(_L8("DynamicDirCacheMaxPageSizeLog2"), iDynamicDirCacheMaxPageSizeLog2);
+
     __PRINT(_L("#>------ end -------<#\n\n"));
 
 #endif
--- a/userlibandfileserver/fileserver/sfat32/fat_dir_entry.h	Tue Feb 02 01:24:03 2010 +0200
+++ b/userlibandfileserver/fileserver/sfat32/fat_dir_entry.h	Fri Apr 16 16:24:37 2010 +0300
@@ -29,7 +29,7 @@
 
 
 const TInt      KFatDirNameSize         = 11;   ///< Dos directory/File name length
-const TInt      KVFatEntryAttribute     = 0x0F;  ///< VFat entry attribute setting
+const TUint     KVFatEntryAttribute     = 0x0F;  ///< VFat entry attribute setting
 const TUint8    KDotEntryByte           = 0x2e;  ///< Dot value for self and parent pointer directory entries
 const TUint8    KBlankSpace             = 0x20;  ///< Blank space in a directory entry
 const TInt      KSizeOfFatDirEntryLog2  = 5;     ///< Log2 of size in bytes of a Fat directry entry 
@@ -74,42 +74,57 @@
     inline void InitZ();
 
     inline const TPtrC8 Name() const;
-    inline TInt Attributes() const;
+    inline void SetName(const TDesC8& aDes);
+
+    inline TUint Attributes() const;
+    inline void SetAttributes(TUint anAtt);
+
     inline TTime Time(TTimeIntervalSeconds aOffset) const;
-    inline TInt StartCluster() const;
+    inline void SetTime(TTime aTime, TTimeIntervalSeconds aOffset);
+    inline TBool IsTimeTheSame(TTime aTime, TTimeIntervalSeconds aOffset) const; 
+    
+
+    inline TUint32 StartCluster() const;
+    inline void SetStartCluster(TUint32 aStartCluster);
+
     inline TUint32 Size() const;
+    inline void SetSize(TUint32 aFilesize);
+
     inline TBool IsErased() const;
+    inline void SetErased();
+
     inline TBool IsCurrentDirectory() const;
+    inline void SetCurrentDirectory();
+
     inline TBool IsParentDirectory() const;
+    inline void SetParentDirectory();
+
     inline TBool IsEndOfDirectory() const;
+    inline void SetEndOfDirectory();
+
     inline TBool IsGarbage() const;
-    inline void SetName(const TDesC8& aDes);
-    inline void SetAttributes(TInt anAtt);
-    inline void SetTime(TTime aTime, TTimeIntervalSeconds aOffset);
+    
     inline void SetCreateTime(TTime aTime, TTimeIntervalSeconds aOffset);
-    inline void SetStartCluster(TInt aStartCluster);
-    inline void SetSize(TUint32 aFilesize);
-    inline void SetErased();
-    inline void SetCurrentDirectory();
-    inline void SetParentDirectory();
-    inline void SetEndOfDirectory();
-    inline TUint RuggedFatEntryId() const;
+
+    inline TUint16 RuggedFatEntryId() const;
     inline void  SetRuggedFatEntryId(TUint16 aId);
 
-public:
-    void InitializeAsVFat(TUint8 aCheckSum);
-    void SetVFatEntry(const TDesC& aName,TInt aRemainderLen);
+    inline TInt NumFollowing() const;
+    inline TUint8 CheckSum() const;
+
+    void SetVFatEntry(const TDesC& aName, TUint aRemainderLen, TUint8 aCheckSum);
     void ReadVFatEntry(TDes16& aVBuf) const;
+    
     inline TBool IsLongNameStart() const;
     inline TBool IsVFatEntry() const;
-    inline TInt NumFollowing() const;
-    inline TUint8 CheckSum() const;
 
 
 public:
     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	Tue Feb 02 01:24:03 2010 +0200
+++ b/userlibandfileserver/fileserver/sfat32/fat_dir_entry.inl	Fri Apr 16 16:24:37 2010 +0300
@@ -53,7 +53,7 @@
 /**
 @return The attributes for the Directory entry
 */
-inline TInt TFatDirEntry::Attributes() const
+inline TUint TFatDirEntry::Attributes() const
     {return pDir->iAttributes;}
 /**
 @param aOffset This offset will be subtracted from the returned time.
@@ -67,7 +67,7 @@
 /**
 @return The Start cluster for the file or directory for this entry 
 */
-inline TInt TFatDirEntry::StartCluster() const      
+inline TUint32 TFatDirEntry::StartCluster() const      
     {
     const TUint16 KStClustMaskHi = 0x0FFF;  
     return ((pDir->iStartClusterHi & KStClustMaskHi) << 16) | pDir->iStartClusterLo;
@@ -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
 */
@@ -114,7 +117,7 @@
 
 @param anAtts The file or directory attributes
 */
-inline void TFatDirEntry::SetAttributes(TInt anAtts)
+inline void TFatDirEntry::SetAttributes(TUint anAtts)
     {
     __ASSERT_DEBUG(!(anAtts&~KMaxTUint8),Fault(EFatBadDirEntryParameter));
     pDir->iAttributes=(TUint8)anAtts;
@@ -144,7 +147,7 @@
 
 @param aStartCluster The start cluster number
 */
-inline void TFatDirEntry::SetStartCluster(TInt aStartCluster)
+inline void TFatDirEntry::SetStartCluster(TUint32 aStartCluster)
     {
     pDir->iStartClusterLo=(TUint16)(aStartCluster);
     pDir->iStartClusterHi=(TUint16)(aStartCluster >> 16);
@@ -155,39 +158,41 @@
 @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
     Uses 1 byte from "Last Access Date" field, offset 19. Hack.
 */
-TUint TFatDirEntry::RuggedFatEntryId() const
+TUint16 TFatDirEntry::RuggedFatEntryId() const
     {
     return pDir->iReserved2;
     }
@@ -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
 */
@@ -237,6 +243,28 @@
 
 
 
+//-----------------------------------------------------------------------------
+/**
+    Checks if the entry has the same "modification time" as given (with 2 seconds granularity precision, see FAT specs). 
+    
+    @param  aTime   time to check
+    @param  aOffset time offset
+
+    @return ETrue if the given time+offset is the same (with 2 second granularity) as the one set in the entry.
+*/
+inline TBool TFatDirEntry::IsTimeTheSame(TTime aTime, TTimeIntervalSeconds aOffset) const
+    {
+    aTime+=aOffset;
+
+    const TUint16 time = (TUint16)DosTimeFromTTime(aTime);
+    if(time != pDir->iTime)
+        return EFalse;
+
+    const TUint16 date = (TUint16)DosDateFromTTime(aTime);
+    return (date == pDir->iDate);
+    }
+
+
 #endif //FAT_DIR_ENTRY_INL
 
 
--- a/userlibandfileserver/fileserver/sfat32/fat_table32.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/userlibandfileserver/fileserver/sfat32/fat_table32.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -264,35 +264,39 @@
 //-----------------------------------------------------------------------------
 
 /**
-Count the number of contiguous cluster from a start cluster
+    Count the number of continuous cluster from a start cluster in FAT table.
 
 @param aStartCluster cluster to start counting from
-@param anEndCluster contains the end cluster number upon return
+    @param  aEndCluster     contains the end cluster number upon return
 @param aMaxCount Maximum cluster required
-@leave System wide error values
-@return Number of contiguous clusters from aStartCluster.
+    @return Number of continuous clusters from aStartCluster.
 */
-TInt CFatTable::CountContiguousClustersL(TUint32 aStartCluster,TInt& anEndCluster,TUint32 aMaxCount) const
+TUint32 CFatTable::CountContiguousClustersL(TUint32 aStartCluster, TUint32& aEndCluster, TUint32 aMaxCount) const
 	{
 	__PRINT2(_L("CFatTable::CountContiguousClustersL() start:%d, max:%d"),aStartCluster, aMaxCount);
-	TUint32 clusterListLen=1;
-	TInt endCluster=aStartCluster;
-	TInt64 endClusterPos=DataPositionInBytes(endCluster);
-	while (clusterListLen<aMaxCount)
-		{
-		TInt oldCluster=endCluster;
-		TInt64 oldClusterPos=endClusterPos;
-		if (GetNextClusterL(endCluster)==EFalse || (endClusterPos=DataPositionInBytes(endCluster))!=(oldClusterPos+(1<<iOwner->ClusterSizeLog2())))
-			{
-			endCluster=oldCluster;
-			break;
-			}
-		clusterListLen++;
-		}
-	anEndCluster=endCluster;
-	return(clusterListLen);
+
+    ASSERT(ClusterNumberValid(aStartCluster));
+
+    TUint32 currClusterNo = aStartCluster;
+    
+    TUint32 clusterListLen;
+    for(clusterListLen=1; clusterListLen < aMaxCount; ++clusterListLen)
+        {
+        TUint32 nextClusterNo = currClusterNo;
+
+        if(!GetNextClusterL(nextClusterNo))
+            break; //-- end of cluster chain
+            
+        if(nextClusterNo != currClusterNo+1)
+            break; //-- not the next cluster
+      
+        currClusterNo = nextClusterNo;
+        }
+
+    aEndCluster = aStartCluster+clusterListLen-1;
+
+    return clusterListLen;
 	}	
-
 //-----------------------------------------------------------------------------
 
 /**
@@ -303,7 +307,7 @@
 
     @leave KErrDiskFull + system wide error codes
 */
-void CFatTable::ExtendClusterListL(TUint32 aNumber,TInt& aCluster)
+void CFatTable::ExtendClusterListL(TUint32 aNumber, TUint32& aCluster)
 	{
 	__PRINT2(_L("CFatTable::ExtendClusterListL() num:%d, clust:%d"), aNumber, aCluster);
 	__ASSERT_DEBUG(aNumber>0,Fault(EFatBadParameter));
@@ -385,9 +389,9 @@
 		User::Leave(KErrDiskFull);
 		}
 
-	TInt firstCluster = aNearestCluster = AllocateSingleClusterL(aNearestCluster);
+	TUint32 firstCluster = aNearestCluster = AllocateSingleClusterL(aNearestCluster);
 	if (aNumber>1)
-		ExtendClusterListL(aNumber-1, (TInt&)aNearestCluster);
+		ExtendClusterListL(aNumber-1, aNearestCluster);
 
     return(firstCluster);
 	}	
@@ -491,7 +495,7 @@
     TUint32 cntFreedClusters = 0;
 
     TUint32 currCluster = aCluster;
-    TInt    nextCluster = aCluster;
+    TUint32 nextCluster = aCluster;
 
     for(;;)
     {
@@ -1740,7 +1744,7 @@
     @param aCluster number to read, contains next cluster upon return
     @return False if end of cluster chain
 */
-TBool CFatTable::GetNextClusterL(TInt& aCluster) const
+TBool CFatTable::GetNextClusterL(TUint32& aCluster) const
     {
 	__PRINT1(_L("CAtaFatTable::GetNextClusterL(%d)"), aCluster);
     
--- a/userlibandfileserver/fileserver/sfat32/inc/fat_table32.h	Tue Feb 02 01:24:03 2010 +0200
+++ b/userlibandfileserver/fileserver/sfat32/inc/fat_table32.h	Fri Apr 16 16:24:37 2010 +0300
@@ -160,8 +160,10 @@
     TInt64 DataPositionInBytes(TUint32 aCluster) const;
     void FreeClusterListL(TUint32 aCluster);
     TUint32 AllocateSingleClusterL(TUint32 aNearestCluster);
-    void ExtendClusterListL(TUint32 aNumber,TInt& aCluster);
+    void ExtendClusterListL(TUint32 aNumber, TUint32& aCluster);
     TUint32 AllocateClusterListL(TUint32 aNumber,TUint32 aNearestCluster);
+    
+    virtual TUint32 CountContiguousClustersL(TUint32 aStartCluster, TUint32& anEndCluster, TUint32 aMaxCount) const;
 
 private:
     CRamFatTable(CFatMountCB& aOwner);
--- a/userlibandfileserver/fileserver/sfat32/inc/sl_bpb.h	Tue Feb 02 01:24:03 2010 +0200
+++ b/userlibandfileserver/fileserver/sfat32/inc/sl_bpb.h	Fri Apr 16 16:24:37 2010 +0300
@@ -30,7 +30,7 @@
 const TInt KVolumeLabelSize			=11;    ///< Volume lable size
 const TInt KFileSysTypeSize			=8;     ///< File system type parameter size
 const TInt KVendorIdSize			=8;     ///< Vendor ID parameter size
-const TInt KBootSectorSignature		=0xAA55;///< File system Boot sector signiture
+const TUint16 KBootSectorSignature	=0xAA55;///< File system Boot sector signiture
 const TInt KFat16VolumeLabelPos 	=43;    ///< Position of volume lable in BPB for Fat12/16
 const TInt KFat32VolumeLabelPos		=71;    ///< Position of volume lable in BPB for Fat32
 const TInt KSizeOfFatBootSector     = 90;   ///< Size in bytes of Boot sector parameter block (BPB) 
@@ -57,23 +57,23 @@
 	//-- simple getters / setters
     inline const TPtrC8 VendorId() const;
 	inline TUint16 BytesPerSector() const;
-	inline TInt SectorsPerCluster() const;
-	inline TInt ReservedSectors() const;
-	inline TInt NumberOfFats() const;
-	inline TInt RootDirEntries() const;
-	inline TInt TotalSectors() const;
+	inline TUint8 SectorsPerCluster() const;
+	inline TUint16 ReservedSectors() const;
+	inline TUint8 NumberOfFats() const;
+	inline TUint16 RootDirEntries() const;
+	inline TUint16 TotalSectors() const;
 	inline TUint8 MediaDescriptor() const;
-	inline TInt FatSectors() const;
-	inline TInt SectorsPerTrack() const;
-	inline TInt NumberOfHeads() const;
-	inline TInt HiddenSectors() const;
-	inline TInt HugeSectors() const;
-	inline TInt PhysicalDriveNumber() const;
-	inline TInt ExtendedBootSignature() const;
+	inline TUint16 FatSectors() const;
+	inline TUint16 SectorsPerTrack() const;
+	inline TUint16 NumberOfHeads() const;
+	inline TUint32 HiddenSectors() const;
+	inline TUint32 HugeSectors() const;
+	inline TUint8 PhysicalDriveNumber() const;
+	inline TUint8 ExtendedBootSignature() const;
 	inline TUint32 UniqueID() const;
 	inline const TPtrC8 VolumeLabel() const;
 	inline const TPtrC8 FileSysType() const;
-	inline TInt BootSectorSignature() const;
+	inline TUint16 BootSectorSignature() const;
 	inline TUint32 FatSectors32() const;	
 	inline TUint16 FATFlags() const;		
 	inline TUint16 VersionNumber() const;		
@@ -83,21 +83,21 @@
 
 	inline void SetJumpInstruction();
 	inline void SetVendorID(const TDesC8& aDes);
-	inline void SetBytesPerSector(TInt aBytesPerSector);
-	inline void SetSectorsPerCluster(TInt aSectorsPerCluster);
-	inline void SetReservedSectors(TInt aReservedSectors);
-	inline void SetNumberOfFats(TInt aNumberOfFats);
-	inline void SetRootDirEntries(TInt aRootDirEntries);
-	inline void SetTotalSectors(TInt aTotalSectors);
+	inline void SetBytesPerSector(TUint16 aBytesPerSector);
+	inline void SetSectorsPerCluster(TUint aSectorsPerCluster);
+	inline void SetReservedSectors(TUint aReservedSectors);
+	inline void SetNumberOfFats(TUint8 aNumberOfFats);
+	inline void SetRootDirEntries(TUint16 aRootDirEntries);
+	inline void SetTotalSectors(TUint aTotalSectors);
 	inline void SetMediaDescriptor(TUint8 aMediaDescriptor);
-	inline void SetFatSectors(TInt aFatSectors);
-	inline void SetSectorsPerTrack(TInt aSectorsPerTrack);
-	inline void SetNumberOfHeads(TInt aNumberOfHeads);
+	inline void SetFatSectors(TUint aFatSectors);
+	inline void SetSectorsPerTrack(TUint16 aSectorsPerTrack);
+	inline void SetNumberOfHeads(TUint16 aNumberOfHeads);
 	inline void SetHiddenSectors(TUint32 aHiddenSectors);
 	inline void SetHugeSectors(TUint32 aTotalSectors);
 	inline void SetPhysicalDriveNumber(TInt aPhysicalDriveNumber);
 	inline void SetReservedByte(TUint8 aReservedByte);
-	inline void SetExtendedBootSignature(TInt anExtendedBootSignature);
+	inline void SetExtendedBootSignature(TUint8 anExtendedBootSignature);
 	inline void SetUniqueID(TUint32 anUniqueID);
 	inline void SetVolumeLabel(const TDesC8& aDes);
 	inline void SetFileSysType(const TDesC8& aDes);
--- a/userlibandfileserver/fileserver/sfat32/inc/sl_bpb.inl	Tue Feb 02 01:24:03 2010 +0200
+++ b/userlibandfileserver/fileserver/sfat32/inc/sl_bpb.inl	Fri Apr 16 16:24:37 2010 +0300
@@ -131,35 +131,35 @@
 
 @return iSectorsPerCluster
 */
-inline TInt TFatBootSector::SectorsPerCluster() const
+inline TUint8 TFatBootSector::SectorsPerCluster() const
 	{return iSectorsPerCluster;}
 /**
 Returns the number of reserved sectors on the volume
 
 @return iReservedSectors
 */
-inline TInt TFatBootSector::ReservedSectors() const
+inline TUint16 TFatBootSector::ReservedSectors() const
 	{return iReservedSectors;}
 /**
 Returns the number of Fats on the volume
 
 @return iNumberOfFats
 */
-inline TInt TFatBootSector::NumberOfFats() const
+inline TUint8 TFatBootSector::NumberOfFats() const
 	{return iNumberOfFats;}
 /**
 Returns the number of entries allowed in the root directory, specific to Fat12/16, zero for FAT32
 
 @return iRootDirEntries
 */
-inline TInt TFatBootSector::RootDirEntries() const
+inline TUint16 TFatBootSector::RootDirEntries() const
 	{return iRootDirEntries;}
 /**
 Returns the total sectors on the volume, zero for FAT32
 
 @return iTotalSectors
 */
-inline TInt TFatBootSector::TotalSectors() const
+inline TUint16 TFatBootSector::TotalSectors() const
 	{return iTotalSectors;}
 /**
 Returns the media descriptor
@@ -173,49 +173,49 @@
 
 @return iFatSectors
 */
-inline TInt TFatBootSector::FatSectors() const
+inline TUint16 TFatBootSector::FatSectors() const
 	{return iFatSectors;}
 /**
 Returns sectors per track
 
 @return iSectorsPerTrack
 */
-inline TInt TFatBootSector::SectorsPerTrack() const
+inline TUint16 TFatBootSector::SectorsPerTrack() const
 	{return iSectorsPerTrack;}
 /**
 Returns the number of heads 
 
 @return iNumberOfHeads
 */
-inline TInt TFatBootSector::NumberOfHeads() const
+inline TUint16 TFatBootSector::NumberOfHeads() const
 	{return iNumberOfHeads;}
 /**
 Returns the number of hidden sectors in the volume
 
 @return iHiddenSectors
 */
-inline TInt TFatBootSector::HiddenSectors() const
+inline TUint32 TFatBootSector::HiddenSectors() const
 	{return iHiddenSectors;}
 /**
 Returns total sectors in the volume, Used if totalSectors > 65535
 
 @return iHugeSectors
 */
-inline TInt TFatBootSector::HugeSectors() const
+inline TUint32 TFatBootSector::HugeSectors() const
 	{return iHugeSectors;}
 /**
 Returns the physical drive number, not used in Symbian OS
 
 @return iPhysicalDriveNumber
 */
-inline TInt TFatBootSector::PhysicalDriveNumber() const
+inline TUint8 TFatBootSector::PhysicalDriveNumber() const
 	{return iPhysicalDriveNumber;}
 /**
 Returns the extended boot signiture
 
 @return iExtendedBootSignature
 */
-inline TInt TFatBootSector::ExtendedBootSignature() const
+inline TUint8 TFatBootSector::ExtendedBootSignature() const
 	{return iExtendedBootSignature;}
 /**
 Returns the unique volume ID
@@ -243,7 +243,7 @@
 
 @return KBootSectorSignature
 */
-inline TInt TFatBootSector::BootSectorSignature() const
+inline TUint16 TFatBootSector::BootSectorSignature() const
 	{return KBootSectorSignature;}
 /**
 Set the jump instruction 
@@ -266,17 +266,17 @@
 
 @param aBytesPerSector Number of bytes per sector
 */
-inline void TFatBootSector::SetBytesPerSector(TInt aBytesPerSector)
+inline void TFatBootSector::SetBytesPerSector(TUint16 aBytesPerSector)
 	{
 	__ASSERT_DEBUG(!(aBytesPerSector&~KMaxTUint16),Fault(EFatBadBootSectorParameter));
-	iBytesPerSector=(TUint16)aBytesPerSector;
+	iBytesPerSector=aBytesPerSector;
 	}
 /**
 Set the sectors per cluster ratio
 
 @param aSectorsPerCluster Number of sectors per cluster
 */
-inline void TFatBootSector::SetSectorsPerCluster(TInt aSectorsPerCluster)
+inline void TFatBootSector::SetSectorsPerCluster(TUint aSectorsPerCluster)
 	{
 	__ASSERT_DEBUG(!(aSectorsPerCluster&~KMaxTUint8),Fault(EFatBadBootSectorParameter));
 	iSectorsPerCluster=(TUint8)aSectorsPerCluster;
@@ -286,7 +286,7 @@
 
 @param aReservedSectors Number of reserved sectors
 */
-inline void TFatBootSector::SetReservedSectors(TInt aReservedSectors)
+inline void TFatBootSector::SetReservedSectors(TUint aReservedSectors)
 	{
 	__ASSERT_DEBUG(!(aReservedSectors&~KMaxTUint16),Fault(EFatBadBootSectorParameter));
 	iReservedSectors=(TUint16)aReservedSectors;
@@ -296,27 +296,27 @@
 
 @param aNumberOfFats Number of fats
 */
-inline void TFatBootSector::SetNumberOfFats(TInt aNumberOfFats)
+inline void TFatBootSector::SetNumberOfFats(TUint8 aNumberOfFats)
 	{
 	__ASSERT_DEBUG(!(aNumberOfFats&~KMaxTUint8),Fault(EFatBadBootSectorParameter));
-	iNumberOfFats=(TUint8)aNumberOfFats;
+	iNumberOfFats=aNumberOfFats;
 	}
 /**
 Number of entries allowed in the root directory, specific to Fat12/16, zero for FAT32
 
 @param aRootDirEntries
 */
-inline void TFatBootSector::SetRootDirEntries(TInt aRootDirEntries)
+inline void TFatBootSector::SetRootDirEntries(TUint16 aRootDirEntries)
 	{
 	__ASSERT_DEBUG(!(aRootDirEntries&~KMaxTUint16),Fault(EFatBadBootSectorParameter));
-	iRootDirEntries=(TUint16)aRootDirEntries;
+	iRootDirEntries=aRootDirEntries;
 	}
 /**
 Total sectors on the volume, zero for FAT32
 
 @param aTotalSectors Total number of sectors
 */
-inline void TFatBootSector::SetTotalSectors(TInt aTotalSectors)
+inline void TFatBootSector::SetTotalSectors(TUint aTotalSectors)
 	{
 	__ASSERT_DEBUG(!(aTotalSectors&~KMaxTUint16),Fault(EFatBadBootSectorParameter));
 	iTotalSectors=(TUint16)aTotalSectors;
@@ -333,7 +333,7 @@
 
 @param aFatSectors Number of Fat sectors
 */
-inline void TFatBootSector::SetFatSectors(TInt aFatSectors)
+inline void TFatBootSector::SetFatSectors(TUint aFatSectors)
 	{
 	__ASSERT_DEBUG(!(aFatSectors&~KMaxTUint16),Fault(EFatBadBootSectorParameter));
 	iFatSectors=(TUint16)aFatSectors;
@@ -343,20 +343,20 @@
 
 @param aSectorsPerTrack Number of sectors per track
 */
-inline void TFatBootSector::SetSectorsPerTrack(TInt aSectorsPerTrack)
+inline void TFatBootSector::SetSectorsPerTrack(TUint16 aSectorsPerTrack)
 	{
 	__ASSERT_DEBUG(!(aSectorsPerTrack&~KMaxTUint16),Fault(EFatBadBootSectorParameter));
-	iSectorsPerTrack=(TUint16)aSectorsPerTrack;
+	iSectorsPerTrack=aSectorsPerTrack;
 	}
 /**
 Set the number of heads
 
 @param aNumberOfHeads Number of heads
 */
-inline void TFatBootSector::SetNumberOfHeads(TInt aNumberOfHeads)
+inline void TFatBootSector::SetNumberOfHeads(TUint16 aNumberOfHeads)
 	{
 	__ASSERT_DEBUG(!(aNumberOfHeads&~KMaxTUint16),Fault(EFatBadBootSectorParameter));
-	iNumberOfHeads=(TUint16)aNumberOfHeads;
+	iNumberOfHeads=aNumberOfHeads;
 	}
 /**
 Set the number of hidden sectors in the volume
@@ -373,7 +373,9 @@
 @param aHugeSectors
 */
 inline void TFatBootSector::SetHugeSectors(TUint32 aHugeSectors)
-	{iHugeSectors=aHugeSectors;}
+	{
+    iHugeSectors=aHugeSectors;
+    }
 /**
 Physical drive number, not used in Symbian OS
 
@@ -390,16 +392,19 @@
 @param aReservedByte Value for reserved byte
 */
 inline void TFatBootSector::SetReservedByte(TUint8 aReservedByte)
-	{iReserved=aReservedByte;}
+	{
+    iReserved=aReservedByte;
+    }
+
 /**
 Set the extended boot signiture
 
 @param anExtendedBootSignature The extended boot signiture
 */
-inline void TFatBootSector::SetExtendedBootSignature(TInt anExtendedBootSignature)
+inline void TFatBootSector::SetExtendedBootSignature(TUint8 anExtendedBootSignature)
 	{
 	__ASSERT_DEBUG(!(anExtendedBootSignature&~KMaxTUint8),Fault(EFatBadBootSectorParameter));
-	iExtendedBootSignature=(TUint8)anExtendedBootSignature;
+	iExtendedBootSignature=anExtendedBootSignature;
 	}
 /**
 Set the unique volume ID
--- a/userlibandfileserver/fileserver/sfat32/inc/sl_scandrv.h	Tue Feb 02 01:24:03 2010 +0200
+++ b/userlibandfileserver/fileserver/sfat32/inc/sl_scandrv.h	Fri Apr 16 16:24:37 2010 +0300
@@ -82,6 +82,9 @@
         EClusterAlreadyInUse,   ///< 2  cross-linked cluster chain
         EBadClusterValue,       ///< 3  also means "lost cluster"
         EInvalidEntrySize,      ///< 4  size of file/directory does not correspond to the cluster chain length
+        EEntrySetIncomplete,    ///< 5  incomplete VFAT entryset
+        EEntryBadAtt,           ///< 6  incorrect entry attributes
+
         
         EUnknownError = 95,     ///< unknown error
 
@@ -116,12 +119,12 @@
 
 	TUint32 ReadFatL(TUint aClusterNum) ;
 	void FindSameStartClusterL();
-	TInt FindStartClusterL(TInt aDirCluster);
+	TInt FindStartClusterL(TUint32 aDirCluster);
 	void CheckDirStructureL();
 	void CheckDirL(TUint32 aCluster);
 	void ProcessEntryL(const TFatDirEntry& aEntry);
 	TInt CheckEntryClusterL(const TFatDirEntry& aEntry, const TEntryPos& aEntryPos);
-	void RecordClusterChainL(TInt aCluster,TUint aSizeInBytes);
+	void RecordClusterChainL(TUint32 aCluster,TUint aSizeInBytes);
 	TBool MoveToVFatEndL(TEntryPos& aPos,TFatDirEntry& aEntry,TInt& aDirLength);
 	TBool IsValidVFatEntry(const TFatDirEntry& aEntry,TInt prevNum)const;
 	TBool IsDosEntry(const TFatDirEntry& aEntry)const;
--- a/userlibandfileserver/fileserver/sfat32/inc/sl_std.h	Tue Feb 02 01:24:03 2010 +0200
+++ b/userlibandfileserver/fileserver/sfat32/inc/sl_std.h	Fri Apr 16 16:24:37 2010 +0300
@@ -63,16 +63,17 @@
 class TEntryPos
 	{
 public:
-	TEntryPos() {}
-	TEntryPos(TInt aCluster,TUint aPos) : iCluster(aCluster), iPos(aPos) {}
+	TEntryPos() : iCluster(EOF_32Bit), iPos(0) {}
+	TEntryPos(TUint 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;
-	TUint iPos;
+	TUint32 iCluster;
+	TUint32 iPos;
 	};
 
 
@@ -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(); 
@@ -198,7 +204,7 @@
     virtual void InvalidateCacheL(TInt64 /*aPos*/,TUint32 /*aLength*/) {};
 
 	virtual void FreeClusterListL(TUint32 aCluster);
-	virtual void ExtendClusterListL(TUint32 aNumber,TInt& aCluster);
+	virtual void ExtendClusterListL(TUint32 aNumber, TUint32& aCluster);
 	
     virtual TUint32 AllocateSingleClusterL(TUint32 aNearestCluster);
 	virtual TUint32 AllocateClusterListL(TUint32 aNumber,TUint32 aNearestCluster);
@@ -212,13 +218,15 @@
     virtual void InitializeL();
     virtual TBool ConsistentState() const {return ETrue;} //-- dummy
 
+    virtual TUint32 CountContiguousClustersL(TUint32 aStartCluster, TUint32& anEndCluster, TUint32 aMaxCount) const;
+
     //-----------------------------------------------------------------
     //-- non-virtual interface
-    TBool GetNextClusterL(TInt& aCluster) const;
+    TBool GetNextClusterL(TUint32& aCluster) const;
     void WriteFatEntryEofL(TUint32 aFatIndex);
 
     void MarkAsBadClusterL(TUint32 aCluster);
-    TInt CountContiguousClustersL(TUint32 aStartCluster,TInt& anEndCluster, TUint32 aMaxCount) const;
+    
     
     inline TUint32 MaxEntries() const;
     
@@ -491,14 +499,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;
         };
 
 
@@ -512,17 +518,17 @@
 
 	inline TBool ReadOnly(void) const;
     inline void  SetReadOnly(TBool aReadOnlyMode);
-	inline TInt StartCluster(const TFatDirEntry & anEntry) const;
+	inline TUint32 StartCluster(const TFatDirEntry & anEntry) const;
 	inline CRawDisk& RawDisk() const;
 	inline CFatFileSystem& FatFileSystem() const;
 	inline CFatTable& FAT() const;
-	inline TInt ClusterSizeLog2() const;
-	inline TInt SectorSizeLog2() const;
-	inline TInt TotalSectors() const;
-	inline TInt SectorsPerCluster() const;
-	inline TInt ClusterBasePosition() const;
-    inline TInt RootDirectorySector() const;
-    inline TUint RootDirEnd() const;
+	inline TUint32 ClusterSizeLog2() const;
+	inline TUint32 SectorSizeLog2() const;
+	inline TUint32 TotalSectors() const;
+	inline TUint32 SectorsPerCluster() const;
+	inline TUint32 ClusterBasePosition() const;
+    inline TUint32 RootDirectorySector() const;
+    inline TUint32 RootDirEnd() const;
     inline TUint32 RootClusterNum() const;
 
 	inline TFatType FatType() const;
@@ -530,29 +536,33 @@
     inline TBool Is32BitFat() const;
 
 	inline TUint32 MaxClusterNumber() const;
-	inline TInt StartOfFatInBytes() const;
+	inline TUint32 StartOfFatInBytes() const;
     inline TUint32 FirstFatSector() const;
 
-	inline TInt NumberOfFats() const;
-	inline TInt FatSizeInBytes() const;
-	inline TInt ClusterRelativePos(TInt aPos) const;
-	inline TUint StartOfRootDirInBytes() const;
+	inline TUint32 NumberOfFats() const;
+	inline TUint32 FatSizeInBytes() const;
+	inline TUint32 ClusterRelativePos(TUint32 aPos) const;
+	inline TUint32 StartOfRootDirInBytes() const;
 	inline TUint32 UsableClusters() const;
-	inline TBool IsBadCluster(TInt aCluster) const;
+    inline TBool ClusterNumberValid(TUint32 aClusterNo) const;
+	inline TBool IsBadCluster(TUint32 aCluster) const;
+	
 	inline TBool IsRuggedFSys() const;
 	inline void SetRuggedFSys(TBool aVal);
+	inline TUint32 AtomicWriteGranularityLog2() const;
+
 	
-	inline TInt RootIndicator() const;
+	inline TUint32 RootIndicator() const;
 	
     inline TBool IsRootDir(const TEntryPos &aEntry) const;
 	inline CAsyncNotifier* Notifier() const;
 	inline TDriveInterface& DriveInterface() const;
 
-    inline TBool IsEndOfClusterCh(TInt aCluster) const;
-	inline void SetEndOfClusterCh(TInt &aCluster) const;
+    inline TBool IsEndOfClusterCh(TUint32 aCluster) const;
+	inline void SetEndOfClusterCh(TUint32 &aCluster) const;
 
     
-    void ReadUidL(TInt aCluster,TEntry& anEntry) const;
+    void ReadUidL(TUint32 aCluster,TEntry& anEntry) const;
 	
     void ReadDirEntryL(const TEntryPos& aPos,TFatDirEntry& aDirEntry) const;
 	void WriteDirEntryL(const TEntryPos& aPos,const TFatDirEntry& aDirEntry);
@@ -561,7 +571,8 @@
     void DirWriteL(const TEntryPos& aPos,const TDesC8& aDes);
 
 	void ReadFromClusterListL(TEntryPos& aPos,TInt aLength,const TAny* aTrg,const RMessagePtr2& aMessage,TInt anOffset) const;
-	void WriteToClusterListL(TEntryPos& aPos,TInt aLength,const TAny* aSrc,const RMessagePtr2& aMessage,TInt anOffset, TInt& aBadcluster, TInt &aGoodcluster);
+    void WriteToClusterListL(TEntryPos& aPos,TInt aLength,const TAny* aSrc,const RMessagePtr2& aMessage,TInt anOffset, TUint& aBadcluster, TUint& aGoodcluster);
+	
 	void MoveToNextEntryL(TEntryPos& aPos) const;
 	void MoveToDosEntryL(TEntryPos& aPos,TFatDirEntry& anEntry) const;
 	void EnlargeL(TInt aSize);
@@ -662,6 +673,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;
@@ -671,14 +700,16 @@
     void FindEntryStartL(const TDesC& aName,TUint anAtt,TFatDirEntry& anEntry,TEntryPos& aPos) const;
 
 	void CheckFatForLoopsL(const TFatDirEntry& anEntry) const;
-	void DoCheckFatForLoopsL(TInt aCluster,TInt& aPreviousCluster,TInt& aChangePreviousCluster,TInt& aCount) const;
+	void DoCheckFatForLoopsL(TUint32 aCluster, TUint32& aPreviousCluster, TUint32& aChangePreviousCluster, TUint32& aCount) const;
     void InitializeL(const TLocalDriveCaps& aLocDrvCaps, TBool aIgnoreFSInfo=EFalse);
+
 	void DoReadFromClusterListL(TEntryPos& aPos,TInt aLength,const TAny* aTrg,const RMessagePtr2& aMessage,TInt anOffset) const;
-	void DoWriteToClusterListL(TEntryPos& aPos,TInt aLength,const TAny* aSrc,const RMessagePtr2& aMessage,TInt anOffset, TInt aLastcluster, TInt& aBadcluster, TInt& aGoodcluster);
-	TBool IsUniqueNameL(const TShortName& aName,TInt aDirCluster);
+    void DoWriteToClusterListL(TEntryPos& aPos,TInt aLength,const TAny* aSrc,const RMessagePtr2& aMessage,TInt anOffset, TUint aLastcluster, TUint& aBadcluster, TUint& aGoodcluster);
+
+	TBool IsUniqueNameL(const TShortName& aName, TUint32 aDirCluster);
 	TBool FindShortNameL(const TShortName& aName,TEntryPos& anEntryPos);
 	void ReplaceClashingNameL(const TShortName& aNewName,const TEntryPos& anEntryPos);
-    TBool GenerateShortNameL(TInt aDirCluster,const TDesC& aLongName,TShortName& aShortName, TBool aForceRandomize=EFalse);
+    TBool GenerateShortNameL(TUint32 aDirCluster,const TDesC& aLongName,TShortName& aShortName, TBool aForceRandomize=EFalse);
     TInt FindLeafDirL(const TDesC& aName, TLeafDirData& aLeafDir) const;
 	
 	TInt GetDirEntry(TEntryPos& aPos,TFatDirEntry& aDosEntry,TFatDirEntry& aStartEntry,TDes& aLongFileName) const;
@@ -687,9 +718,9 @@
 	void WriteDirEntryL(TEntryPos& aPos,const TFatDirEntry& aFatDirEntry,const TDesC& aLongFileName);
 	void EraseDirEntryL(TEntryPos aPos,const TFatDirEntry& anEntry);
 	void EraseDirEntryL(const TEntryPos& aPos);
-	void InitializeFirstDirClusterL(TInt aCluster,TInt aParentCluster);
+	void InitializeFirstDirClusterL(TUint32 aCluster, TUint32 aParentCluster);
 	void AddDirEntryL(TEntryPos& aPos,TInt aNameLength);
-	void ZeroDirClusterL(TInt aCluster);
+	void ZeroDirClusterL(TUint32 aCluster);
 	
     TInt DoWriteBootSector(TInt64 aMediaPos, const TFatBootSector& aBootSector) const;
 	TInt DoReadBootSector(TInt64 aMediaPos, TFatBootSector& aBootSector) const;
@@ -698,8 +729,8 @@
     TInt WriteFSInfoSector(TInt64 aMediaPos, const TFSInfo& aFSInfo) const;
 	TInt ReadFSInfoSector(TInt64 aMediaPos, TFSInfo& aFSInfo) const;
 
-    TBool IsDirectoryEmptyL(TInt aCluster);
-	void ExtendClusterListZeroedL(TInt aNumber,TInt& aCluster);
+    TBool IsDirectoryEmptyL(TUint32 aCluster);
+	void ExtendClusterListZeroedL(TUint32 aNumber, TUint32& aCluster);
 	void WritePasswordData();
 	
     void WriteVolumeLabelL(const TDesC8& aVolumeLabel) const;
@@ -742,12 +773,10 @@
     TUint32  iFatEocCode;       ///< End Of Cluster Chain code, 0xff8 for FAT12, 0xfff8 for FAT16, and 0xffffff8 for FAT32 
 
     CLeafDirCache* iLeafDirCache;	///< A cache for most recently visited directories, only valid when limit is set bigger than 1
-    HBufC* iLastLeafDir;        	///< The last visited directory, only valid when limit of iLeafDirCache is less than 1 
-    TInt iLastLeafDirCluster;   	///< Cluster number of the last visited cluster, only valid when limit of iLeafDirCache is less than 1
 
 	TFatVolParam iVolParam;         ///< FAT volume parameters, populated form the boot sector values.
     
-	TInt iFirstFreeByte;            ///< First free byte in media (start of the data area on the volume)
+	TUint32 iFirstFreeByte;         ///< First free byte in media (start of the data area on the volume)
 	TUint32 iUsableClusters;        ///< Number of usable cluster on the volume 
 	
     CFatTable* iFatTable;           ///< Pointer to the volume Fat 
@@ -756,7 +785,6 @@
     CAsyncNotifier* iNotifier;  ///< Async notifier for notifying user of Fat error conditions 
 
     XDriveInterface iDriverInterface; ///< the object representing interface to the drive, provides read/write access and notifiers
-    TInt            iChkDiscRecLevel; ///< Check disk recursion level counter. A temporary measure. 
 	TFatConfig      iFatConfig;       ///< FAT parametrers from estart.txt
 
 	XFileCreationHelper iFileCreationHelper;
@@ -788,7 +816,7 @@
 	};
 
 
-
+//---------------------------------------------------------------------------------------------------------------------------------
 
 /**
 Fat file system file subsession implmentation, provides all that is required of a plug in
@@ -809,10 +837,7 @@
 	void FlushAllL();
 public:
 	void CheckPosL(TUint aPos);
-	void SetL(const TFatDirEntry& aFatDirEntry,TShare aShare,const TEntryPos& aPos);
-	void CreateSeekIndex();
-	
-    inline TBool IsSeekIndex() const;	
+	void SetupL(const TFatDirEntry& aFatDirEntry, const TEntryPos& aFileDosEntryPos);
 	
 	// from MBlockMapInterface
 	TInt BlockMap(SBlockMapInfo& aInfo, TInt64& aStartPos, TInt64 aEndPos);
@@ -833,26 +858,58 @@
 
 
     void FlushStartClusterL();
-	TInt SeekToPosition(TInt aNewCluster,TInt aClusterOffset);
-	void SetSeekIndexValueL(TInt aFileCluster,TInt aStoredCluster);
+	TInt SeekToPosition(TUint aNewCluster, TUint aClusterOffset);
+	void SetSeekIndexValueL(TUint aFileCluster,TUint aStoredCluster);
 	void ResizeIndex(TInt aNewMult,TUint aNewSize);
 	TInt CalcSeekIndexSize(TUint aSize);
 	TBool IsSeekBackwards(TUint aPos);
 	void ClearIndex(TUint aNewSize);
-	void DoSetSizeL(TUint aSize,TBool aIsSizeWrite);
+	void DoSetSizeL(TUint aSize, TBool aForceCachesFlush);
 	void WriteFileSizeL(TUint aSize);
 
+    //----------------------------
+    inline TUint32 FCB_StartCluster() const;
+    inline TUint32 FCB_FileSize() const; 
+
+    inline void  FCB_SetStartCluster(TUint32 aVal);
+    inline void  FCB_SetFileSize(TUint32 aVal);  
+
+    inline TBool FileAttModified() const;
+    inline void  IndicateFileAttModified(TBool aModified);
+    
+    inline TBool FileSizeModified() const;
+    inline void  IndicateFileSizeModified(TBool aModified);
+
+    inline TBool FileTimeModified() const;
+    inline void  IndicateFileTimeModified(TBool aModified);
+
+    //----------------------------
+
+	void CreateSeekIndex();
+
+    void DoShrinkFileToZeroSizeL();
+    void DoShrinkFileL(TUint32  aNewSize, TBool aForceCachesFlush);
+    void DoExpandFileL(TUint32 aNewSize, TBool aForceCachesFlush);
+
+
 private:
 
 	TUint32* iSeekIndex;    ///< Seek index into file
 	TInt iSeekIndexSize;    ///< size of seek index
-	TInt iStartCluster;     ///< Start cluster number of file
+	
+    TUint     iStartCluster;     ///< Start cluster number of file
 	TEntryPos iCurrentPos;  ///< Current position in file data
-	TEntryPos iFileDirPos;  ///< File directory entry position
-	TBool iFileSizeModified; 
+	
+    TEntryPos iFileDosEntryPos;  ///< File DOS dir. entry position
+	
+    TBool iFileSizeModified :1;  ///< flag, indicating that file size was modified and needs to be flushed onto the media (see FlushL())
+    TBool iFileTimeModified :1;  ///< flag, indicating that file modification time was modified and needs to be flushed onto the media (see FlushL())
+
 	};
 
 
+
+//---------------------------------------------------------------------------------------------------------------------------------
 /**
 Fat file system directory subsession implmentation, provides all that is required of a plug in
 file system directory as well as Fat specific functionality
@@ -906,12 +963,12 @@
 	void InitializeFormatDataL();
 	void DoZeroFillMediaL(TInt64 aStartPos, TInt64 aEndPos);
 
-    TInt InitFormatDataForVariableSizeDisk(TInt aDiskSizeInSectors);
-	TInt InitFormatDataForFixedSizeDiskNormal(TInt aDiskSizeInSectors, const TLocalDriveCapsV6& aCaps);
+    TInt InitFormatDataForVariableSizeDisk(TUint aDiskSizeInSectors);
+	TInt InitFormatDataForFixedSizeDiskNormal(TUint aDiskSizeInSectors, const TLocalDriveCapsV6& aCaps);
 	TInt InitFormatDataForFixedSizeDiskCustom(const TLDFormatInfo& aFormatInfo);
-    TInt InitFormatDataForFixedSizeDiskUser(TInt aDiskSizeInSectors);
-	void AdjustClusterSize(TInt aRecommendedSectorsPerCluster);
-	TInt AdjustFirstDataSectorAlignment(TInt aBlockSize);
+    TInt InitFormatDataForFixedSizeDiskUser(TUint aDiskSizeInSectors);
+	void AdjustClusterSize(TUint aRecommendedSectorsPerCluster);
+	TInt AdjustFirstDataSectorAlignment(TUint aBlockSize);
 	TInt FirstDataSector() const;
 
 	TInt HandleCorrupt(TInt aError);
@@ -919,9 +976,11 @@
     void TranslateL();
     TInt DoTranslate(TPtr8& aBuf, RArray<TInt>& aArray);
     void RecordOldInfoL();
-	TInt MaxFat12Sectors() const;
-	TInt MaxFat16Sectors() const;
-	TUint32 MaxFat32Sectors() const;
+	
+    TUint MaxFat12Sectors() const;
+	TUint MaxFat16Sectors() const;
+	TUint MaxFat32Sectors() const;
+	
 	inline TBool Is16BitFat() const;
 	inline TBool Is32BitFat() const;
 	inline CFatMountCB& FatMount();
@@ -931,19 +990,20 @@
 private:
 	
     TBool   iVariableSize;      ///< Flag to indicat if we are dealing with a variable size volume
-	TInt    iBytesPerSector;    ///< Byte per sector of media
+	
+    TUint16 iBytesPerSector;    ///< Byte per sector of media
     TInt    iSectorSizeLog2;    ///< Sector size in log2
-	TInt    iNumberOfFats;      ///< Number of Fats the volume will contain
-	TInt    iReservedSectors;   ///< Number of reserved sectors in the volume
-	TInt    iRootDirEntries;    ///< Nummer of root directory entries the root dir will have, specific to Fat12/16 volumes
-	TInt    iSectorsPerCluster; ///< Sector per cluster ration the volume will be formatted with
-	TInt    iSectorsPerFat;     ///< Number of sectors the Fat uses
-	TInt    iMaxDiskSectors;    ///< number of sectors the volume has
+	TUint8  iNumberOfFats;      ///< Number of Fats the volume will contain
+	TUint   iReservedSectors;   ///< Number of reserved sectors in the volume
+	TUint16 iRootDirEntries;    ///< Nummer of root directory entries the root dir will have, specific to Fat12/16 volumes
+	TUint   iSectorsPerCluster; ///< Sector per cluster ration the volume will be formatted with
+	TUint   iSectorsPerFat;     ///< Number of sectors the Fat uses
+	TUint32 iMaxDiskSectors;    ///< number of sectors the volume has
 	TFormatInfo iFormatInfo;    ///< format information for a custom format
 	TBuf8<16>   iFileSystemName;///< Buffer to contain the volume name 
 	TInt    iHiddenSectors;     ///< Number of hidden sectors in the volume
-	TInt    iNumberOfHeads;     ///< Number of heads the media device has, not used so far as only used on solid state media.
-	TInt    iSectorsPerTrack;   ///< Number of sectors the media device has, not used so far as only used on solid state media.
+	TUint16 iNumberOfHeads;     ///< Number of heads the media device has, not used so far as only used on solid state media.
+	TUint16 iSectorsPerTrack;   ///< Number of sectors the media device has, not used so far as only used on solid state media.
 	TUint32 iRootClusterNum;    ///< cluster number used for root directory, Fat32 specific
 	TUint32 iCountOfClusters;   ///< Count of clusters on the media
     RArray<TInt> iBadClusters;  ///< Array of bad cluster numbers
@@ -1047,7 +1107,7 @@
 @param the length in characters of the name
 @return the number of VFat entries required
 */
-TInt NumberOfVFatEntries(TInt aNameLength);
+TUint NumberOfVFatEntries(TUint aNameLength);
 /**
 Calculates the check sum for a standard directory entry
 
--- a/userlibandfileserver/fileserver/sfat32/inc/sl_std.inl	Tue Feb 02 01:24:03 2010 +0200
+++ b/userlibandfileserver/fileserver/sfat32/inc/sl_std.inl	Fri Apr 16 16:24:37 2010 +0300
@@ -38,47 +38,70 @@
     return (iCluster == aRhs.iCluster && iPos == aRhs.iPos);
     }
 
+/** set "end of directory" indicator*/
+void TEntryPos::SetEndOfDir()
+    {
+    iCluster = EOF_32Bit;
+    }
+
 
 //---------------------------------------------------------------------------------------------------------------------------------
 // class CFatMountCB
 
-inline TInt CFatMountCB::RootDirectorySector() const
-    {return iVolParam.RootDirectorySector();}
+
+/** @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
 
-inline TUint CFatMountCB::RootDirEnd() const
-    {return iVolParam.RootDirEnd();}
+    return (aClusterNo >= KFatFirstSearchCluster) && (aClusterNo < UsableClusters()+KFatFirstSearchCluster); 
+    }
+
+
+inline TUint32 CFatMountCB::RootDirectorySector() const
+    {
+    return iVolParam.RootDirectorySector();
+    }
+
+inline TUint32 CFatMountCB::RootDirEnd() const
+    {
+    return iVolParam.RootDirEnd();
+    }
 
 inline TUint32 CFatMountCB::RootClusterNum() const
-    {return iVolParam.RootClusterNum(); }        
+    {
+    return iVolParam.RootClusterNum();
+    }        
 
 
-inline TInt CFatMountCB::StartCluster(const TFatDirEntry & anEntry) const
+inline TUint32 CFatMountCB::StartCluster(const TFatDirEntry & anEntry) const
 	{
 	if(Is32BitFat())	
 		return anEntry.StartCluster();
 	else
-		return 0xFFFF&anEntry.StartCluster();
+		return anEntry.StartCluster() & 0xFFFF;
 	}
 
 /**
 returns true for root dir on Fat12/16 (fixed root dir versions of Fat) false on fat32 
 this function is used to handle special cases for reading/writing the root directory on FAT via the use of cluster zero.
 
-@param aEntry position on volume being queried
-@return Whether Root dir position or not
+    @param entryPos     directory entry position
+    @return ETrue       if entryPos belongs to the FAT12/16 root directory
 */
-TBool CFatMountCB::IsRootDir(const TEntryPos &aEntry) const
+TBool CFatMountCB::IsRootDir(const TEntryPos &entryPos) const
 	{
-	if(Is32BitFat())
-		return EFalse;
-	else
-		return((aEntry.iCluster==0) ? (TBool)ETrue : (TBool)EFalse);	
+	//-- for FAT12/16 cluster 0 means "root directory"
+    return !(Is32BitFat() || entryPos.iCluster);
 	}
 /**
 Indicates the root directory cluster, For Fat12/16 root is always indicated by cluster number zero, on Fat32 the is a root cluster number
 @return The root cluster indicator
 */
-TInt CFatMountCB::RootIndicator() const
+TUint32 CFatMountCB::RootIndicator() const
 	{
 	if(Is32BitFat())
         return iVolParam.RootClusterNum();
@@ -88,24 +111,34 @@
 
 
 /** @return Log2 of cluster size on volume */
-TInt CFatMountCB::ClusterSizeLog2() const
-    {return(iVolParam.ClusterSizeLog2());}
+TUint32 CFatMountCB::ClusterSizeLog2() const
+    {
+    return(iVolParam.ClusterSizeLog2());
+    }
 
 /** @return Log2 of media sector size  */
-TInt CFatMountCB::SectorSizeLog2() const
-    {return(iVolParam.SectorSizeLog2());}
+TUint32 CFatMountCB::SectorSizeLog2() const
+    {
+    return(iVolParam.SectorSizeLog2());
+    }
 
 /** @return sector per cluster */
-TInt CFatMountCB::SectorsPerCluster() const
-    {return(1<<(iVolParam.ClusterSizeLog2()-iVolParam.SectorSizeLog2()));}
+TUint32 CFatMountCB::SectorsPerCluster() const
+    {
+    return(1<<(iVolParam.ClusterSizeLog2()-iVolParam.SectorSizeLog2()));
+    }
 
 /** @return the base position of a cluster */
-TInt CFatMountCB::ClusterBasePosition() const
-	{return(iFirstFreeByte);}
+TUint32 CFatMountCB::ClusterBasePosition() const
+	{
+    return(iFirstFreeByte);
+    }
 
 /** @return the offset into a cluster of a byte address */
-TInt CFatMountCB::ClusterRelativePos(TInt aPos) const
-	{return(aPos&((1<<ClusterSizeLog2())-1));}
+TUint32 CFatMountCB::ClusterRelativePos(TUint32 aPos) const
+	{
+    return(aPos & ((1<<ClusterSizeLog2())-1));
+    }
 
 /**
 Calculates the maximum number of clusters
@@ -115,29 +148,42 @@
     {return(TotalSectors()>>(ClusterSizeLog2()-SectorSizeLog2()));}
 
 /** @return the the total sectors on volume */
-TInt CFatMountCB::TotalSectors() const
-    {return iVolParam.TotalSectors();}
+TUint32 CFatMountCB::TotalSectors() const
+    {
+    return iVolParam.TotalSectors();
+    }
 
 /** @return total size of a Fat in bytes */
-TInt CFatMountCB::FatSizeInBytes() const
-    {return iVolParam.FatSizeInBytes();}
+TUint32 CFatMountCB::FatSizeInBytes() const
+    {
+    return iVolParam.FatSizeInBytes();
+    }
 
 /** @return first sector of the Fat */
 TUint32 CFatMountCB::FirstFatSector() const
-    {return iVolParam.FirstFatSector();}
+    {
+    return iVolParam.FirstFatSector();
+    }
 
 /** @return the byte offset of the Fat */
-TInt CFatMountCB::StartOfFatInBytes() const
-	{return(FirstFatSector()<<SectorSizeLog2());}
+TUint32 CFatMountCB::StartOfFatInBytes() const
+	{
+    return(FirstFatSector()<<SectorSizeLog2());
+    }
 
 /** @return Number of Fats used by the volume */
-TInt CFatMountCB::NumberOfFats() const
-    {return iVolParam.NumberOfFats();}
+TUint32 CFatMountCB::NumberOfFats() const
+    {
+    return iVolParam.NumberOfFats();
+    }
 
 
 /** @return refrence to the fat table owned by the mount */
 CFatTable& CFatMountCB::FAT() const
-	{return(*iFatTable);}
+	{
+    return(*iFatTable);
+    }
+
 /**
     @return refrence to the file system object that has produced this CFatMountCB
 */
@@ -154,30 +200,52 @@
 /**
 @return ETrue if aCluster value is bad cluster marker defined in FAT specification
 */
-TBool CFatMountCB::IsBadCluster(TInt aCluster) const
-	{return Is32BitFat() ? aCluster==0xFFFFFF7 : Is16BitFat() ? aCluster==0xFFF7 : aCluster==0xFF7;}
+TBool CFatMountCB::IsBadCluster(TUint32 aCluster) const
+	{
+    return Is32BitFat() ? aCluster==0xFFFFFF7 : Is16BitFat() ? aCluster==0xFFF7 : aCluster==0xFF7;
+    }
 
 /**
 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(Media 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
-	{return(iUsableClusters);}
+    {
+    return(iUsableClusters);
+    }
 
 
-TUint CFatMountCB::StartOfRootDirInBytes() const
-    {return iVolParam.RootDirectorySector()<<SectorSizeLog2();}
+TUint32 CFatMountCB::StartOfRootDirInBytes() const
+    {
+    return iVolParam.RootDirectorySector()<<SectorSizeLog2();
+    }
 
 
 /** @return FAT type for this mount */
@@ -199,7 +267,9 @@
 }
 
 CAsyncNotifier* CFatMountCB::Notifier() const
-	{return iNotifier;}	
+	{
+    return iNotifier;
+    }	
 
 
 
@@ -315,29 +385,40 @@
     @param  aCluster FAT table entry (cluster number) to check
     @return ETrue    if aCluster is a EOC for the FAT type being used by CFatMountCB
 */
-TBool CFatMountCB::IsEndOfClusterCh(TInt aCluster) const
+TBool CFatMountCB::IsEndOfClusterCh(TUint32 aCluster) const
 	{
     ASSERT(iFatEocCode);
-
-    if((TUint32)aCluster >= iFatEocCode)
-        return ETrue;
+    ASSERT((TUint32)aCluster <= iFatEocCode+7); //-- aCluster value is always masked accordingly.
 
-    ASSERT((TUint32)aCluster <= iFatEocCode+7);
-
-	return EFalse;
+    return (aCluster >= iFatEocCode);
     }
 
 /**
     Sets "End of Cluster Chain" value in aCluster depending on the FAT type.
     @param aCluster cluster to set to end of chain marker
 */
-void CFatMountCB::SetEndOfClusterCh(TInt &aCluster) const
+void CFatMountCB::SetEndOfClusterCh(TUint32 &aCluster) const
 	{
     ASSERT(iFatEocCode);
     aCluster = iFatEocCode+7;
 	}
 
 
+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
 /**
@@ -434,12 +515,72 @@
 TInt CFatFileCB::ClusterSizeLog2()
 	{return(FatMount().ClusterSizeLog2());}
 
-/*
- Note: this replaces SeekIndex() which was only used in sl_mnt
- to verify whether the seek index had been created/initialised
+
+//---------------------------------------------------------------------------------------------------------------------------------
+TBool CFatFileCB::FileSizeModified() const 
+    {
+    return iFileSizeModified;
+    }  
+
+void CFatFileCB::IndicateFileSizeModified(TBool aModified) 
+    {
+    iFileSizeModified = aModified;
+    }
+
+//-----------------------------------------------------------------------------
+/** @return ETrue if file attributes' 'Modified' flag is set*/
+TBool CFatFileCB::FileAttModified() const 
+    {
+    return (Att() & KEntryAttModified);
+    }   
+
+/** 
+    Set or reset a flag indicating that file attributes had beed modified
+    @param aModified ETrue means that attributes are modified
 */
-inline TBool CFatFileCB::IsSeekIndex() const
-{return (iSeekIndex==NULL?(TBool)EFalse:(TBool)ETrue); }
+
+void  CFatFileCB::IndicateFileAttModified(TBool aModified)
+    {
+    if(aModified)
+        iAtt |= KEntryAttModified;
+    else
+        iAtt &= ~KEntryAttModified;
+    }
+
+TUint32 CFatFileCB::FCB_StartCluster() const
+    {
+    return iStartCluster;
+    }
+
+
+void CFatFileCB::FCB_SetStartCluster(TUint32 aVal)
+    {
+    ASSERT(aVal == 0 || (aVal >= KFatFirstSearchCluster));
+    iStartCluster = aVal;
+    }
+
+/** @return file size from CFileCB */
+TUint32 CFatFileCB::FCB_FileSize() const
+    {
+    return Size();
+    } 
+
+/** set file size in the CFileCB*/
+void CFatFileCB::FCB_SetFileSize(TUint32 aVal)
+    {
+    SetSize(aVal);
+    } 
+
+TBool CFatFileCB::FileTimeModified() const 
+    {
+    return iFileTimeModified;
+    }
+
+void  CFatFileCB::IndicateFileTimeModified(TBool aModified)
+    {
+    iFileTimeModified = aModified;
+    }
+
 
 
 //---------------------------------------------------------------------------------------------------------------------------------
--- a/userlibandfileserver/fileserver/sfat32/ram_fat_table32.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/userlibandfileserver/fileserver/sfat32/ram_fat_table32.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -287,7 +287,7 @@
 
 /**
     Copy memory with filling the source buffer with zeroes. Target and source buffers can overlap.
-    Used on RAMDrive srinking in order to wipe data from the file that is being deleted.
+    Used on RAMDrive shrinking in order to wipe data from the file that is being deleted.
     
     @param   aTrg       pointer to the target address
     @param   aSrc       pointer to the destination address
@@ -391,7 +391,7 @@
     
     if (aNumber>1)
 	    {//-- if this part leaves (e.g. fail to expand the RAM drive), we will need to handle the first allocated EOC
-    	TRAPD(nRes, ExtendClusterListL(aNumber-1, (TInt&)aNearestCluster));
+    	TRAPD(nRes, ExtendClusterListL(aNumber-1, aNearestCluster));
         if(nRes != KErrNone)
             {
             __PRINT1(_L("CRamFatTable::AllocateClusterListL:ExtendClusterListL() failed with %d") ,nRes);
@@ -431,7 +431,7 @@
     @param aCluster     starting cluster number / ending cluster number after
     @leave KErrDiskFull + system wide error codes
 */
-void CRamFatTable::ExtendClusterListL(TUint32 aNumber, TInt& aCluster)
+void CRamFatTable::ExtendClusterListL(TUint32 aNumber, TUint32& aCluster)
     {
     __PRINT2(_L("CRamFatTable::ExtendClusterListL(%d, %d)"), aNumber, aCluster);
     __ASSERT_DEBUG(aNumber>0,Fault(EFatBadParameter));
@@ -479,8 +479,8 @@
         return; // File has no cluster allocated
 
     const TInt clusterShift=iOwner->ClusterSizeLog2();
-    TInt startCluster=aCluster;
-    TInt endCluster=0;
+    TUint32 startCluster=aCluster;
+    TUint32 endCluster=0;
     TInt totalFreed=0;
     TLinAddr srcEnd=0;
 
@@ -628,5 +628,27 @@
 #endif
     }
 
+TUint32 CRamFatTable::CountContiguousClustersL(TUint32 aStartCluster, TUint32& aEndCluster, TUint32 aMaxCount) const
+	{
+	__PRINT2(_L("CRamFatTable::CountContiguousClustersL() start:%d, max:%d"),aStartCluster, aMaxCount);
+	TUint32 clusterListLen=1;
+	TUint32 endCluster=aStartCluster;
+	TInt64 endClusterPos=DataPositionInBytes(endCluster);
+	while (clusterListLen<aMaxCount)
+		{
+		TInt oldCluster=endCluster;
+		TInt64 oldClusterPos=endClusterPos;
+		if (GetNextClusterL(endCluster)==EFalse || (endClusterPos=DataPositionInBytes(endCluster))!=(oldClusterPos+(1<<iOwner->ClusterSizeLog2())))
+			{
+			endCluster=oldCluster;
+			break;
+			}
+		clusterListLen++;
+		}
+	aEndCluster=endCluster;
+	
+    return(clusterListLen);
+    }
 
 
+
--- a/userlibandfileserver/fileserver/sfat32/sl_bpb32.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/userlibandfileserver/fileserver/sfat32/sl_bpb32.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -62,7 +62,7 @@
         if(TotalSectors() >0 && HugeSectors() >0 )
             goto Invalid; //-- values clash
 
-        const TUint32 totSectors = Max(TotalSectors(), HugeSectors());
+        const TUint32 totSectors = Max((TUint32)TotalSectors(), HugeSectors());
         const TUint32 rootDirStartSec =  ReservedSectors() + FatSectors()*NumberOfFats(); //-- root directory start sector
 
         if(FatSectors() < 1 || rootDirStartSec < 3 || RootDirEntries() < 1 || totSectors < 5)
@@ -228,11 +228,11 @@
     __PRINT1(_L("FatSectors:%d"),FatSectors());
     __PRINT1(_L("SectorsPerTrack:%d"),SectorsPerTrack());
     __PRINT1(_L("NumberOfHeads:%d"),NumberOfHeads());
-    __PRINT1(_L("HugeSectors:%d"),HugeSectors());
-    __PRINT1(_L("Fat32 Sectors:%d"),FatSectors32());
+    __PRINT1(_L("HugeSectors:%u"),HugeSectors());
+    __PRINT1(_L("Fat32 Sectors:%u"),FatSectors32());
     __PRINT1(_L("Fat32 Flags:%d"),FATFlags());
     __PRINT1(_L("Fat32 Version Number:%d"),VersionNumber());
-    __PRINT1(_L("Root Cluster Number:%d"),RootClusterNum());
+    __PRINT1(_L("Root Cluster Number:%u"),RootClusterNum());
     __PRINT1(_L("FSInfo Sector Number:%d"),FSInfoSectorNum());
     __PRINT1(_L("Backup Boot Rec Sector Number:%d"),BkBootRecSector());
     __PRINT1(_L("PhysicalDriveNumber:%d"),PhysicalDriveNumber());
@@ -256,7 +256,7 @@
     {
 
     //-- check iBytesPerSector validity; it shall be one of: 512,1024,2048,4096
-    if(!IsPowerOf2(iBytesPerSector) || iBytesPerSector < 512 ||  iBytesPerSector > 4096)
+    if(iBytesPerSector < 512 ||  iBytesPerSector > 4096 || !IsPowerOf2(iBytesPerSector))
         return EInvalid; //-- invalid iBytesPerSector value
 
     //-- check iSectorsPerCluster validity, it shall be one of: 1,2,4,8...128
@@ -326,14 +326,14 @@
 TUint32 TFatBootSector::VolumeTotalSectorNumber() const
 {
     __ASSERT_DEBUG(IsValid(), Fault(EFatBadBootSectorParameter));
-    return TotalSectors() >0 ? (TUint32)TotalSectors() : (TUint32)HugeSectors();
+    return TotalSectors() >0 ? TotalSectors() : HugeSectors();
 }
 
 /** @return FAT-type independent number of sectors in one FAT */
 TUint32 TFatBootSector::TotalFatSectors() const
 {
     __ASSERT_DEBUG(IsValid(), Fault(EFatBadBootSectorParameter));
-    return FatSectors() >0 ? (TUint32)FatSectors() : FatSectors32();
+    return FatSectors() >0 ? FatSectors() : FatSectors32();
 }
 
 
--- a/userlibandfileserver/fileserver/sfat32/sl_cache.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/userlibandfileserver/fileserver/sfat32/sl_cache.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -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	Tue Feb 02 01:24:03 2010 +0200
+++ b/userlibandfileserver/fileserver/sfat32/sl_cache.h	Fri Apr 16 16:24:37 2010 +0300
@@ -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	Tue Feb 02 01:24:03 2010 +0200
+++ b/userlibandfileserver/fileserver/sfat32/sl_dir_cache.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -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;
@@ -157,7 +159,8 @@
 	// allocate as many permanently locked pages as there are threads - plus one
 	// otherwise DoMakePageMRU() won't work properly with only one thread
     //-- At present moment the size of TDrive thread pool is 1 (1 drive thread in a pool)
-	iPermanentlyAllocatedPageCount = 1; 
+	const TUint KThreadCount = 1;
+	iPermanentlyAllocatedPageCount = KThreadCount + 1; 
 
 	if (iPermanentlyAllocatedPageCount > iMinSizeInPages)
 		iMinSizeInPages = iPermanentlyAllocatedPageCount;
@@ -174,10 +177,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 +341,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 +381,8 @@
 
 	// always make writting events MRU
 	DoMakePageMRU(aPos);
-    return;
+    
+    return pPage;
 	}
 
 /**
@@ -407,11 +411,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 +469,6 @@
             {
             WriteDataOntoSinglePageL(currMediaPos, pData, dataLen);
             }
-        }// else(dataLen <= bytesToPageEnd)
-
 
     //-- write data to the media
     const TInt nErr = iDrive.WriteCritical(aPos,aDes);
@@ -449,6 +477,11 @@
         InvalidateCache();
         User::Leave(nErr);
         }
+
+
+        }// else(dataLen <= bytesToPageEnd)
+
+
 	}
 
 /**
@@ -518,7 +551,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 +568,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 +583,6 @@
 	else if (pPage)
 		{
 		__PRINT1(_L("CDynamicDirCache::PosCached: page(0x%lx) on Locked Queue!"), aPos);
-	    aCachedPosStart = pPage->StartPos();
 		return pPage->PageSizeInBytes();
 		}
 
@@ -649,6 +680,9 @@
 	{
 //	__PRINT1(_L("MakePageMRU (%lx)"), aPos);
 //	__PRINT4(_L("Current Cache State: iLockedQCount=%d, iUnlockedQCount=%d, iLookupTbl=%d, iMaxSizeInPages=%d"), iLockedQCount, iUnlockedQCount, iLookupTable.Count(), iMaxSizeInPages);
+	// check there are at least two locked pages
+	ASSERT(iLockedQCount > 1);
+	
 	// check the MRU page first, if it is already the MRU page, we can return immediately
 	TInt64 pageStartMedPos = CalcPageStartPos(aPos);
 	if (!iLockedQ.IsEmpty())
@@ -787,7 +821,7 @@
 		return activePage;
 		}
 
-	__PRINT2(_L("CDynamicDirCache::UpdateActivePageL(aPos=%lx, active=%lx)"), aPos, activePage->StartPos());
+	//__PRINT2(_L("CDynamicDirCache::UpdateActivePageL(aPos=%lx, active=%lx)"), aPos, activePage->StartPos());
 
 	activePage->Deque();
 	LookupTblRemove(activePage->StartPos());
@@ -919,46 +953,49 @@
 @see CDynamicDirCache::Control()
 */
 void CDynamicDirCache::Dump()
-	{
-	__PRINT(_L("======== CDynamicDirCache::Dump ========="));
-	if (!iLockedQ.IsEmpty())
-		{
-		TDblQueIter<TDynamicDirCachePage> q(iLockedQ);
-		q.SetToFirst();
-		TInt i = 0;
-		while((TDynamicDirCachePage*)q)
-			{
-			TDynamicDirCachePage* pP = q++;
-			__PRINT5(_L("=== CDynamicDirCache::iLockedQ\t[%4d](pos=%lx, locked=%d, valid=%d, size=%u)"), i++, pP->StartPos(), pP->IsLocked(), pP->IsValid(), pP->PageSizeInBytes());
-			}
-		}
-	if (!iUnlockedQ.IsEmpty())
-		{
-		TDblQueIter<TDynamicDirCachePage> q(iUnlockedQ);
-		q.SetToFirst();
-		TInt i = 0;
-		while((TDynamicDirCachePage*)q)
-			{
-			TDynamicDirCachePage* pP = q++;
-			__PRINT5(_L("=== CDynamicDirCache::iUnlockedQ\t[%4d](pos=%lx, locked=%d, valid=%d, size=%u)"), i++, pP->StartPos(), pP->IsLocked(), pP->IsValid(), pP->PageSizeInBytes());
-			}
-		}
+    {
+    __PRINT(_L("======== CDynamicDirCache::Dump ========="));
+    if (!iLockedQ.IsEmpty())
+        {
+        TDblQueIter<TDynamicDirCachePage> q(iLockedQ);
+        q.SetToFirst();
+        TInt i = 0;
+        while((TDynamicDirCachePage*)q)
+            {
+            TDynamicDirCachePage* pP = q++;
+            __PRINT5(_L("=== CDynamicDirCache::iLockedQ      [%4d](pos=%lx, locked=%d, valid=%d, size=%u)"), i++, pP->StartPos(), pP->IsLocked(), pP->IsValid(), pP->PageSizeInBytes());
+            }
+        }
+    __PRINT(_L("=== CDynamicDirCache:: --------------------"));
 
-	if (iLookupTable.Count())
-		{
-		TInt i = 0;
-		THashSetIter<TLookupEntry> iter(iLookupTable);
-		TLookupEntry* pEntry;
-		pEntry = (TLookupEntry*) iter.Next();
-		while(pEntry)
-			{
-			TDynamicDirCachePage* pP = pEntry->iPage;
-			__PRINT5(_L("=== CDynamicDirCache::iLookupTable\t[%4d](pos=%lx, locked=%d, valid=%d, size=%u)"), i++, pP->StartPos(), pP->IsLocked(), pP->IsValid(), pP->PageSizeInBytes());
-			pEntry = (TLookupEntry*) iter.Next();
-			};
-		}
-	__PRINT(_L("===========================================\n"));
-	}
+    if (!iUnlockedQ.IsEmpty())
+        {
+        TDblQueIter<TDynamicDirCachePage> q(iUnlockedQ);
+        q.SetToFirst();
+        TInt i = 0;
+        while((TDynamicDirCachePage*)q)
+            {
+            TDynamicDirCachePage* pP = q++;
+            __PRINT5(_L("=== CDynamicDirCache::iUnlockedQ    [%4d](pos=%lx, locked=%d, valid=%d, size=%u)"), i++, pP->StartPos(), pP->IsLocked(), pP->IsValid(), pP->PageSizeInBytes());
+            }
+        }
+    __PRINT(_L("=== CDynamicDirCache:: --------------------"));
+
+    if (iLookupTable.Count())
+        {
+        TInt i = 0;
+        THashSetIter<TLookupEntry> iter(iLookupTable);
+        TLookupEntry* pEntry;
+        pEntry = (TLookupEntry*) iter.Next();
+        while(pEntry)
+            {
+            TDynamicDirCachePage* pP = pEntry->iPage;
+            __PRINT5(_L("=== CDynamicDirCache::iLookupTable  [%4d](pos=%lx, locked=%d, valid=%d, size=%u)"), i++, pP->StartPos(), pP->IsLocked(), pP->IsValid(), pP->PageSizeInBytes());
+            pEntry = (TLookupEntry*) iter.Next();
+            };
+        }
+    __PRINT(_L("===========================================\n"));
+    }
 #endif //_DEBUG
 
 /**
--- a/userlibandfileserver/fileserver/sfat32/sl_dir_cache.h	Tue Feb 02 01:24:03 2010 +0200
+++ b/userlibandfileserver/fileserver/sfat32/sl_dir_cache.h	Fri Apr 16 16:24:37 2010 +0300
@@ -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	Tue Feb 02 01:24:03 2010 +0200
+++ b/userlibandfileserver/fileserver/sfat32/sl_disk.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -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	Tue Feb 02 01:24:03 2010 +0200
+++ b/userlibandfileserver/fileserver/sfat32/sl_drv.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -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_fatcache.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/userlibandfileserver/fileserver/sfat32/sl_fatcache.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -396,8 +396,17 @@
     //__PRINT1(_L("#-CFat16FixedCache::ReadEntryL() FAT idx:%d"), aIndex);
     ASSERT(aIndex >= KFatFirstSearchCluster &&  aIndex < (FatSize() >> KFat16EntrySzLog2));
 
-    //-- calculate page index in the array
-    const TInt pgIdx = aIndex >> (PageSizeLog2()-KFat16EntrySzLog2);
+    //-- calculate page index in the array. Theoretically, aIndex can't be wrong because it is checked by the caller;
+    //-- but in some strange situations (malformed volume ?) aIndex might get bigger than number of usable clusters.
+    const TUint pgIdx = aIndex >> (PageSizeLog2()-KFat16EntrySzLog2);
+    
+    if(pgIdx >= (TUint)iPages.Count())
+        {
+        __PRINT1(_L("#-CFat16FixedCache::ReadEntryL() FAT idx:%d #1"), aIndex);
+        ASSERT(0);
+        User::Leave(KErrCorrupt);
+        }
+    
     CFat16FixedCachePage *pPage = iPages[pgIdx];
     
     TUint32 entry = KMaxTUint;
@@ -436,8 +445,17 @@
 
     SetDirty(ETrue);
 
-    //-- calculate page index in the array
-    const TInt pgIdx = aIndex >> (PageSizeLog2()-KFat16EntrySzLog2);
+    //-- calculate page index in the array. Theoretically, aIndex can't be wrong because it is checked by the caller;
+    //-- but in some strange situations (malformed volume ?) aIndex might get bigger than number of usable clusters.
+    const TUint pgIdx = aIndex >> (PageSizeLog2()-KFat16EntrySzLog2);
+    
+    if(pgIdx >= (TUint)iPages.Count())
+        {
+        __PRINT2(_L("#-CFat16FixedCache::WriteEntryL() FAT idx:%d, val:%d #1"), aIndex, aEntry);
+        ASSERT(0);
+        User::Leave(KErrCorrupt);
+        }
+
     CFat16FixedCachePage *pPage = iPages[pgIdx];
 
     if(!pPage)
--- a/userlibandfileserver/fileserver/sfat32/sl_fatmisc32.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/userlibandfileserver/fileserver/sfat32/sl_fatmisc32.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -39,12 +39,12 @@
 
 @return The number of sectors
 */
-TUint32 CFatFormatCB::MaxFat32Sectors() const
+TUint CFatFormatCB::MaxFat32Sectors() const
 	{
 	TUint32 calc1 = iMaxDiskSectors - iReservedSectors;
 	TUint32 calc2 = (256 * iSectorsPerCluster) + iNumberOfFats;
 	calc2 = calc2 >> 1;
-	return (calc1 + (calc2 - 1))/calc2;
+	return ((calc1 + (calc2 - 1))/calc2);
 	}
 
 
@@ -76,7 +76,7 @@
 @param  aDiskSizeInSectors Size of volume in sectors
 @return system-wide error code
 */
-TInt  CFatFormatCB::InitFormatDataForFixedSizeDiskNormal(TInt aDiskSizeInSectors, const TLocalDriveCapsV6& aCaps)
+TInt  CFatFormatCB::InitFormatDataForFixedSizeDiskNormal(TUint aDiskSizeInSectors, const TLocalDriveCapsV6& aCaps)
 	{
 	__PRINT1(_L("CFatFormatCB::InitFormatDataForFixedSizeDiskNormal() sectors:%d"), aDiskSizeInSectors);
     
@@ -117,11 +117,13 @@
 	else if(aDiskSizeInSectors<1048576) // >= 16Mb - FAT16   < (1048576) 512MB
 		{
 		iFileSystemName=KFileSystemName16;
-		TInt minSectorsPerCluster=(aDiskSizeInSectors+KMaxFAT16Entries-1)/KMaxFAT16Entries;
+		TUint minSectorsPerCluster=(aDiskSizeInSectors+KMaxFAT16Entries-1)/KMaxFAT16Entries;
 		iRootDirEntries=512;
 		iSectorsPerCluster=1;
+		
 		while (minSectorsPerCluster>iSectorsPerCluster)
 			iSectorsPerCluster<<=1;
+
 		iSectorsPerFat=MaxFat16Sectors();
 		}
 	else	//use FAT32
@@ -142,37 +144,49 @@
 		
 		}
 
+	const TFatType fatType = SuggestFatType();
+
 	// Ensure cluster size is a multiple of the block size
 	TInt blockSizeInSectors = aCaps.iBlockSize >> iSectorSizeLog2;
 	__PRINT1(_L("blockSizeInSectors: %d"),blockSizeInSectors);
 	ASSERT(blockSizeInSectors == 0 || IsPowerOf2(blockSizeInSectors));
 	if (blockSizeInSectors != 0 && IsPowerOf2(blockSizeInSectors))
 		{
-		__PRINT1(_L("iSectorsPerCluster	(old): %d"),iSectorsPerCluster);
+		__PRINT1(_L("iSectorsPerCluster    (old): %d"),iSectorsPerCluster);
 		AdjustClusterSize(blockSizeInSectors);
-		__PRINT1(_L("iSectorsPerCluster	(new): %d"),iSectorsPerCluster);
+		__PRINT1(_L("iSectorsPerCluster    (new): %d"),iSectorsPerCluster);
 		}
 
-	// Align first data sector on an erase block boundary if
-	// (1) the iEraseBlockSize is specified
-	// (2) the start of the partition is already aligned to an erase block boundary, 
-	//     i.e. iHiddenSectors is zero or a multiple of iEraseBlockSize
-	__PRINT1(_L("iHiddenSectors: %d"),iHiddenSectors);
-	TInt eraseblockSizeInSectors = aCaps.iEraseBlockSize >> iSectorSizeLog2;
-	__PRINT1(_L("eraseblockSizeInSectors: %d"),eraseblockSizeInSectors);
-	ASSERT(eraseblockSizeInSectors == 0 || IsPowerOf2(eraseblockSizeInSectors));	
-	ASSERT(eraseblockSizeInSectors == 0 || eraseblockSizeInSectors >= blockSizeInSectors);
-	if ((eraseblockSizeInSectors != 0) &&
-		(iHiddenSectors % eraseblockSizeInSectors == 0) &&	
-		(IsPowerOf2(eraseblockSizeInSectors)) &&
-		(eraseblockSizeInSectors >= blockSizeInSectors))
+
+	for (; iSectorsPerCluster>1; iSectorsPerCluster>>= 1)
 		{
-		TInt r = AdjustFirstDataSectorAlignment(eraseblockSizeInSectors);
-		ASSERT(r == KErrNone);
-		(void) r;
+		// Align first data sector on an erase block boundary if
+		// (1) the iEraseBlockSize is specified
+		// (2) the start of the partition is already aligned to an erase block boundary, 
+		//     i.e. iHiddenSectors is zero or a multiple of iEraseBlockSize
+		__PRINT1(_L("iHiddenSectors: %d"),iHiddenSectors);
+		TInt eraseblockSizeInSectors = aCaps.iEraseBlockSize >> iSectorSizeLog2;
+		__PRINT1(_L("eraseblockSizeInSectors: %d"),eraseblockSizeInSectors);
+		ASSERT(eraseblockSizeInSectors == 0 || IsPowerOf2(eraseblockSizeInSectors));	
+		ASSERT(eraseblockSizeInSectors == 0 || eraseblockSizeInSectors >= blockSizeInSectors);
+		if ((eraseblockSizeInSectors != 0) &&
+			(iHiddenSectors % eraseblockSizeInSectors == 0) &&	
+			(IsPowerOf2(eraseblockSizeInSectors)) &&
+			(eraseblockSizeInSectors >= blockSizeInSectors))
+			{
+			TInt r = AdjustFirstDataSectorAlignment(eraseblockSizeInSectors);
+			ASSERT(r == KErrNone);
+			(void) r;
+			}
+		__PRINT1(_L("iReservedSectors: %d"),iReservedSectors);
+		__PRINT1(_L("FirstDataSector: %d"), FirstDataSector());
+
+		// If we've shrunk the number of clusters by so much that it's now invalid for this FAT type
+		// then we need to decrease the cluster size and try again, otherwise we're finshed.
+		if (SuggestFatType() == fatType)
+			break;
 		}
-	__PRINT1(_L("iReservedSectors: %d"),iReservedSectors);
-	__PRINT1(_L("FirstDataSector: %d"), FirstDataSector());
+	__PRINT1(_L("iSectorsPerCluster  (final): %d"),iSectorsPerCluster);
 
     return KErrNone;
 	}
@@ -183,34 +197,36 @@
     return iHiddenSectors + iReservedSectors + iNumberOfFats*iSectorsPerFat + rootDirSectors;
 	}
 
-void CFatFormatCB::AdjustClusterSize(TInt aRecommendedSectorsPerCluster)
+void CFatFormatCB::AdjustClusterSize(TUint aRecommendedSectorsPerCluster)
 	{
-    const TInt KMaxSecPerCluster = 64;	// 32K
+    const TUint KMaxSecPerCluster = 64;	// 32K
+
 	while (aRecommendedSectorsPerCluster > iSectorsPerCluster && iSectorsPerCluster <= (KMaxSecPerCluster/2))
 		iSectorsPerCluster<<= 1;
+
 	}
 
 // AdjustFirstDataSectorAlignment()
 // Attempts to align the first data sector on an erase block boundary by modifying the
 // number of reserved sectors.
-TInt CFatFormatCB::AdjustFirstDataSectorAlignment(TInt aEraseBlockSizeInSectors)
+TInt CFatFormatCB::AdjustFirstDataSectorAlignment(TUint aEraseBlockSizeInSectors)
 	{
 	const TBool bFat16 = Is16BitFat();
     const TBool bFat32 = Is32BitFat();
 
 	// Save these 2 values in the event of a convergence failure; this should 
 	// hopefully never happen, but we will cater for this in release mode to be safe,
-	TInt reservedSectorsSaved = iReservedSectors;
-	TInt sectorsPerFatSaved = iSectorsPerFat;
+	TUint reservedSectorsSaved = iReservedSectors;
+	TUint sectorsPerFatSaved = iSectorsPerFat;
 
-	TInt reservedSectorsOld = 0;
+	TUint reservedSectorsOld = 0;
 
 	// zero for FAT32
-	TInt rootDirSectors = (iRootDirEntries * KSizeOfFatDirEntry + (iBytesPerSector-1)) / iBytesPerSector;
-	TInt fatSectors = 0;
+	TUint rootDirSectors = (iRootDirEntries * KSizeOfFatDirEntry + (iBytesPerSector-1)) / iBytesPerSector;
+	TUint fatSectors = 0;
 
-	TInt KMaxIterations = 10;
-	TInt n;
+	TUint KMaxIterations = 10;
+	TUint n;
 	for (n=0; n<KMaxIterations && reservedSectorsOld != iReservedSectors; n++)
 		{
 		reservedSectorsOld = iReservedSectors;
@@ -225,7 +241,7 @@
 		iReservedSectors = (nBlocks * aEraseBlockSizeInSectors) - rootDirSectors - fatSectors;
 		}
 	
-	ASSERT(iReservedSectors >= (TInt) (bFat32 ? KDefFat32ResvdSec : KDefFatResvdSec));
+	ASSERT(iReservedSectors >= (bFat32 ? KDefFat32ResvdSec : KDefFatResvdSec));
 
 	if ((FirstDataSector() & (aEraseBlockSizeInSectors-1)) == 0)
 		{
@@ -302,7 +318,7 @@
 		bootSector.SetFatSectors(iSectorsPerFat);
 		bootSector.SetRootDirEntries(iRootDirEntries);
 
-		if (iMaxDiskSectors<=(TInt)KMaxTUint16)
+		if (iMaxDiskSectors<=KMaxTUint16)
 			{
 			bootSector.SetTotalSectors(iMaxDiskSectors);
 			bootSector.SetHugeSectors(0);
@@ -556,7 +572,7 @@
     @param  aDiskSizeInSectors disk size in sectors
     @return system-wide error code
 */
-TInt CFatFormatCB::InitFormatDataForFixedSizeDiskUser(TInt aDiskSizeInSectors)
+TInt CFatFormatCB::InitFormatDataForFixedSizeDiskUser(TUint aDiskSizeInSectors)
 	{
     __PRINT1(_L("CFatFormatCB::InitFormatDataForFixedSizeDiskUser() sectors:%d"), aDiskSizeInSectors);
     Dump_TLDFormatInfo(iSpecialInfo());
@@ -579,8 +595,8 @@
         iReservedSectors = iSpecialInfo().iReservedSectors;
 
 
-    const TInt KMaxSecPerCluster    = 64; 
-	const TInt KDefaultSecPerCluster= 8;   //-- default value, if the iSpecialInfo().iSectorsPerCluster isn't specified
+    const TUint KMaxSecPerCluster    = 64; 
+	const TUint KDefaultSecPerCluster= 8;   //-- default value, if the iSpecialInfo().iSectorsPerCluster isn't specified
 
     iSectorsPerCluster = iSpecialInfo().iSectorsPerCluster;
     if(iSectorsPerCluster <= 0)
@@ -601,23 +617,23 @@
         }
 	else if (aDiskSizeInSectors < 8192) // < 4MB
         {
-        iSectorsPerCluster = Min(iSectorsPerCluster, 2);
+        iSectorsPerCluster = Min((TUint32)iSectorsPerCluster, (TUint32)2);
 		iRootDirEntries = 256;
         }
 	else if (aDiskSizeInSectors < 32768) // < 16MB
         {
-        iSectorsPerCluster = Min(iSectorsPerCluster, 4);
+        iSectorsPerCluster = Min((TUint32)iSectorsPerCluster, (TUint32)4);
 		iRootDirEntries = 512;
         }
 	else if (aDiskSizeInSectors < 1048576) // < 512MB
         {
-        iSectorsPerCluster = Min(iSectorsPerCluster, 8);
+        iSectorsPerCluster = Min((TUint32)iSectorsPerCluster, (TUint32)8);
 		iRootDirEntries = 512;
         }
     else // FAT32
 		{
         iRootDirEntries = 512;
-        iSectorsPerCluster = Min(iSectorsPerCluster, KMaxSecPerCluster);
+        iSectorsPerCluster = Min((TUint32)iSectorsPerCluster, (TUint32)KMaxSecPerCluster);
         }
 
 
@@ -807,14 +823,15 @@
 		sizeofFatAndRootDir = iSectorsPerFat*iNumberOfFats + ((iRootDirEntries*KSizeOfFatDirEntry+(1<<iSectorSizeLog2)-1)>>iSectorSizeLog2);
     else
         sizeofFatAndRootDir = (iRootClusterNum-2) * iSectorsPerCluster;
-    TInt firstFreeSector = iReservedSectors + sizeofFatAndRootDir;
+
+    TUint firstFreeSector = iReservedSectors + sizeofFatAndRootDir;
 
     // Check in rare case that corrupt in critical area
     // which includes bootsector, FAT table, (and root dir if not FAT32)
     TInt i, r;
     for (i=0; i<iBadSectors.Count(); ++i)
         {
-        TInt badSector = iBadSectors[i];
+        const TUint badSector = iBadSectors[i];
         // Check in rare case that corrupt in critical area
         // which includes bootsector, FAT table, (and root dir if not FAT32)
         if (firstFreeSector > badSector)
--- a/userlibandfileserver/fileserver/sfat32/sl_file.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/userlibandfileserver/fileserver/sfat32/sl_file.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -25,13 +25,12 @@
 
 CFatFileCB::CFatFileCB()
 	{
-
 	__PRINT1(_L("CFatFileCB created 0x%x"),this);
 	}
 
 CFatFileCB::~CFatFileCB()
 	{
-	__PRINT1(_L("CFatFileCB deleted 0x%x"),this);
+	__PRINT1(_L("~CFatFileCB deleted 0x%x"),this);
 
     //-- a nasty trick to find out if the CFatFileCB is in consistent state on the moment of destruction.
     //-- Because of OOM conditions CFatFileCB might not be fully constructed and to be deleted, while FlushAll()
@@ -39,9 +38,12 @@
     const CMountCB* pMount  = &Mount();
     if(pMount)
         {//-- do some finalisation work if CMountCB is valid
-        if (iAtt&KEntryAttModified)
+        if(FileAttModified())
+            {
+            IndicateFileTimeModified(ETrue); //-- this will force writing file modification time to the media on Flush
             TRAP_IGNORE(FlushAllL());
         }
+        }
 
     delete[] iSeekIndex;
 	}
@@ -59,10 +61,10 @@
 
 	Mem::FillZ(iSeekIndex, sizeof(TUint32) * KSeekIndexSize);
 
-	iSeekIndexSize=CalcSeekIndexSize(Size());
+	iSeekIndexSize=CalcSeekIndexSize(FCB_FileSize());
 	}
 
-TInt CFatFileCB::SeekToPosition(TInt aNewRelCluster,TInt aClusterOffset)
+TInt CFatFileCB::SeekToPosition(TUint aNewRelCluster, TUint aClusterOffset)
 //
 // Use the seek index to set iCurrentPos.iCluster as close as possible to aNewRelCluster
 // Return aNewRelCluster-aCurrentPos.iCluster
@@ -81,7 +83,7 @@
 		return(aClusterOffset);
 	if (seekPos<0)
 		{
-		iCurrentPos.iCluster=iStartCluster;
+		iCurrentPos.iCluster=FCB_StartCluster();
 		return(aNewRelCluster);
 		}
 
@@ -89,7 +91,7 @@
 	return(aNewRelCluster-((seekPos+1)<<iSeekIndexSize));
 	}
 
-void CFatFileCB::SetSeekIndexValueL(TInt aRelCluster,TInt aStoredCluster)
+void CFatFileCB::SetSeekIndexValueL(TUint aRelCluster, TUint aStoredCluster)
 //
 // Sets a value in the seekindex
 //
@@ -122,19 +124,22 @@
 	__PRINT1(_L("CFatFileCB::CheckPosL(%d)"), aPos);
 	if (aPos==iCurrentPos.iPos)
 		return;
-    __ASSERT_DEBUG(aPos <= (TUint)Size(), Fault(EFatFilePosBeyondEnd));
+    __ASSERT_DEBUG(aPos <= FCB_FileSize(), Fault(EFatFilePosBeyondEnd));
 
-	if (iFileSizeModified && IsSeekBackwards(aPos))
+	if (FileSizeModified() && IsSeekBackwards(aPos))
 		FlushDataL(); 
 	
 	TUint newRelCluster=aPos>>ClusterSizeLog2();
 	if ( aPos && (aPos==(newRelCluster<<ClusterSizeLog2())) )
 		newRelCluster--;
 	TUint oldRelCluster=iCurrentPos.iPos>>ClusterSizeLog2();
+	
 	if ( iCurrentPos.iPos && (iCurrentPos.iPos==(oldRelCluster<<ClusterSizeLog2())) )
 		oldRelCluster--;	
+	
 	TInt clusterOffset=newRelCluster-oldRelCluster;
-	TInt oldCluster=iCurrentPos.iCluster;
+	TUint32 oldCluster=iCurrentPos.iCluster;
+
 	iCurrentPos.iPos=aPos;
 	if (clusterOffset==0)
 		return;
@@ -147,7 +152,7 @@
 		}
 	if (clusterOffset==-1 && seekOffset!=1)
 		{ // Check previous cluster
-		TInt cluster=oldCluster-1;
+		TUint32 cluster=oldCluster-1;
 		if (FAT().GetNextClusterL(cluster) && cluster==oldCluster)
 			{
             iCurrentPos.iCluster=oldCluster-1;
@@ -157,7 +162,7 @@
 	if (seekOffset<0)
 		{
 		seekOffset=newRelCluster;
-		iCurrentPos.iCluster=iStartCluster;
+		iCurrentPos.iCluster=FCB_StartCluster();
 		}
 	while (seekOffset--)
 		{
@@ -172,30 +177,60 @@
 		}
 	}
 
-void CFatFileCB::SetL(const TFatDirEntry& aFatDirEntry,TShare aShare,const TEntryPos& aPos)
-//
-// Initialize FileCB from entry data
-//
+//-----------------------------------------------------------------------------
+/** 
+    Initialize FileCB from file's entry data.
+    
+    @param  aFatDirEntry        this file DOS dir entry.
+    @param  aFileDosEntryPos    this file DOS entry dir. iterator in the parent directory.
+*/
+void CFatFileCB::SetupL(const TFatDirEntry& aFatDirEntry, const TEntryPos& aFileDosEntryPos)
 	{
+	__PRINT1(_L("CFatFileCB::SetupL[0x%x]"), this);
+	
 
-	__PRINT(_L("CFatFileCB::SetL"));
-	SetSize(aFatDirEntry.Size()); 
+    //-- set up a file control block
 	iCurrentPos.iCluster= FatMount().StartCluster(aFatDirEntry);
-	iStartCluster=iCurrentPos.iCluster;
 	iCurrentPos.iPos=0;
-	iAtt=aFatDirEntry.Attributes();
-	iModified= aFatDirEntry.Time(FatMount().TimeOffset());
-	iShare=aShare;
-	iFileDirPos=aPos;
+	
+    SetAtt(aFatDirEntry.Attributes());
+	SetModified(aFatDirEntry.Time(FatMount().TimeOffset()));
+    
+    FCB_SetStartCluster(iCurrentPos.iCluster);
+    FCB_SetFileSize(aFatDirEntry.Size()); 
+
+	iFileDosEntryPos = aFileDosEntryPos;
 
     SetMaxSupportedSize(KMaxSupportedFatFileSize);
+
+    //-- create seek index
+    ASSERT(!iSeekIndex);
+    CreateSeekIndex();
+    if(!iSeekIndex)
+        User::Leave(KErrNoMemory);
+
+    
+    IndicateFileAttModified(EFalse);
+    IndicateFileSizeModified(EFalse);
+    IndicateFileTimeModified(EFalse);
 	}
 
 //-----------------------------------------------------------------------------
-// from CFileCB::MExtendedFileInterface
+/**
+    Read data from the file.
+    
+    @param  aFilePos    start read position within a file
+    @param  aLength     how many bytes to read; on return will be how many bytes actually read
+    @param  aDes        local buffer desctriptor
+    @param  aMessage    from file server, used to write data to the buffer in different address space.
+    @param  aDesOffset  offset within data descriptor where the data will be copied
+
+    @leave on media read error
+
+*/
 void CFatFileCB::ReadL(TInt64 aPos,TInt& aLength, TDes8* aDes, const RMessagePtr2& aMessage, TInt aOffset)
 	{
-	__PRINT2(_L("CFatFileCB::ReadL aFilePos=%LU aLength=%d"),aPos,aLength);
+	__PRINT3(_L("CFatFileCB::ReadL[0x%x] pos=%LU len=%d"), this, aPos, aLength);
 	
     if((TUint64)aPos > KMaxSupportedFatFileSize-1)
         User::Leave(KErrNotSupported);  //-- max. position in the file is 0xFFFFFFFE
@@ -205,7 +240,7 @@
 	CheckPosL(I64LOW(aPos));
 	
 	const TUint startPos = iCurrentPos.iPos;
-	const TUint curSize  = (TUint)Size();
+	const TUint curSize  = FCB_FileSize();
 	const TUint length   = (TUint)aLength;
 	
 	if((startPos + length > curSize) || (startPos > startPos + length) )
@@ -222,10 +257,22 @@
 	}
 
 //-----------------------------------------------------------------------------
-// from CFileCB::MExtendedFileInterface
+/**
+    Write data to the file.
+    
+    @param  aFilePos    start write position within a file
+    @param  aLength     how many bytes to write; on return contain amount of data actually written
+    @param  aDes        local buffer desctriptor
+    @param  aMessage    from file server, used to write data to the media from different address space.
+    @param  aDesOffset  offset within data descriptor 
+
+    @leave on media read error
+
+*/
 void CFatFileCB::WriteL(TInt64 aPos,TInt& aLength,const TDesC8* aSrc,const RMessagePtr2& aMessage, TInt aOffset)
 	{
-	__PRINT2(_L("CFatFileCB::WriteL aFilePos=%LU aLength=%d"),aPos,aLength);
+	__PRINT3(_L("CFatFileCB::WriteL[0x%x] pos=%LU len=%d"), this, aPos, aLength);
+
 	// FAT supports 32 bits only for file size
    	TUint64 endPos = aPos + aLength;
    	if(endPos > KMaxSupportedFatFileSize)
@@ -236,17 +283,17 @@
     const TUint pos = I64LOW(aPos);
   	CheckPosL(pos);
   	
-	const TUint startCluster = (TUint)iStartCluster;
+	const TUint startCluster = FCB_StartCluster();
 	const TUint length       = (TUint)aLength;
 	
 	endPos = iCurrentPos.iPos + length; 
-	if ((endPos           > (TUint)Size()) ||
+	if ((endPos           > FCB_FileSize()) ||
 	    (iCurrentPos.iPos > endPos)         ) // Overflow condition 
 		DoSetSizeL(iCurrentPos.iPos+length,EFalse);
    	
 	TUint startPos=iCurrentPos.iPos;
-	TInt badcluster=0;
-	TInt goodcluster=0;
+	TUint badcluster=0;
+	TUint goodcluster=0;
    	
 	TRAPD(ret, FatMount().WriteToClusterListL(iCurrentPos,aLength,aSrc,aMessage,aOffset,badcluster, goodcluster));
    	
@@ -254,9 +301,11 @@
 		{
         if(startCluster == 0)
 			{ //Empty File, revert all the clusters allocated.
-			TInt cluster = iStartCluster;
-			iStartCluster = 0;
-			SetSize(0);
+			const TUint32 cluster = FCB_StartCluster();
+			FCB_SetStartCluster(0);
+			FCB_SetFileSize(0);
+			IndicateFileSizeModified(ETrue);
+            
 			FlushAllL();
 
 			iCurrentPos.iCluster = 0;
@@ -267,14 +316,14 @@
 			}
 		else
 			{ //Calculate the clusters required based on file size, revert extra clusters if allocated.
-			const TUint curSize = (TUint)Size();
+			const TUint curSize = FCB_FileSize();
 			TUint ClustersNeeded = curSize >> ClusterSizeLog2();
 			if(curSize > (ClustersNeeded << ClusterSizeLog2()))
 				{
 				ClustersNeeded++;
 				}
 
-			TInt cluster = iStartCluster;
+			TUint32 cluster = FCB_StartCluster();
 			while(--ClustersNeeded)
 				{
 				FAT().GetNextClusterL(cluster);
@@ -296,14 +345,14 @@
 
 	if(badcluster != 0)
 		{
-		if(iStartCluster == badcluster)
+		if(FCB_StartCluster() == badcluster)
 			{
-			iStartCluster = goodcluster;
+            FCB_SetStartCluster(goodcluster);
 			FlushStartClusterL();
 			}
 		else
 			{
-			TInt aCluster = iStartCluster;
+			TUint32 aCluster = FCB_StartCluster();
 			do
 				{
                 if((TUint)badcluster == FAT().ReadL(aCluster))
@@ -318,7 +367,7 @@
 		}
 	aLength=iCurrentPos.iPos-startPos;
 
-	if(FatMount().IsRuggedFSys() && pos+(TUint)aLength>(TUint)Size())
+	if(FatMount().IsRuggedFSys() && pos+(TUint)aLength > FCB_FileSize())
 		{
 		WriteFileSizeL(pos+aLength);
 		}
@@ -441,169 +490,228 @@
 	}
 
 //-----------------------------------------------------------------------------
-
+/**
+    Set file size.
+    @param aSize new file size.
+*/
 void CFatFileCB::SetSizeL(TInt64 aSize)
 	{
-	__PRINT(_L("CFatFileCB::SetSizeL"));
+	__PRINT2(_L("CFatFileCB::SetSizeL[0x%x] sz=%LU"), this, aSize);
 	
-	// FAT supports 32 bits only for file size
+	//-- max. file size for FAT is 4GB-1
 	if (I64HIGH(aSize))
 		User::Leave(KErrNotSupported);
 
-	if(FatMount().IsRuggedFSys())
-		DoSetSizeL(I64LOW(aSize),ETrue);
-	else
-		DoSetSizeL(I64LOW(aSize),EFalse);
+    DoSetSizeL(I64LOW(aSize), FatMount().IsRuggedFSys());
 	}
 
 
 void CFatFileCB::SetSizeL(TInt aSize)
-//
-// Envelope function around DoSetSizeL to enable aSize to
-// be written to disk for rugged fat file system
-//
 	{
 	SetSizeL(TInt64(aSize));
 	}
 
-void CFatFileCB::DoSetSizeL(TUint aSize,TBool aIsSizeWrite)
-//
-// Extend or truncate the file.
-// Expects the modified attribute and iSize are set afterwards.
-// Does not alter iCurrentPos, the current file position.
-// Writes size of file to disk if aIsSizeWrite set
-//
+//-----------------------------------------------------------------------------
+/**
+    Shrink file to zero size.
+*/
+void CFatFileCB::DoShrinkFileToZeroSizeL()
+    {
+	    ASSERT(FCB_FileSize());
+        ASSERT(FileSizeModified());
+        
+            ClearIndex(0); //-- clear seek index array
+		
+        //-- update file dir. entry
+        const TUint32 cluster = FCB_StartCluster();
+		FCB_SetStartCluster(0);
+		FCB_SetFileSize(0);
+			FlushAllL();
+		
+        //-- free cluster list. 
+			CheckPosL(0);
+			FAT().FreeClusterListL(cluster);
+			FAT().FlushL();
+			}
+
+//-----------------------------------------------------------------------------
+/*
+    Shrink file to smaller size, but > 0
+
+    @param aNewSize new file size
+    @param aForceCachesFlush if ETrue, all file/FAT caches will be flushed 
+*/
+void CFatFileCB::DoShrinkFileL(TUint32 aNewSize, TBool aForceCachesFlush)
+		{
+    ASSERT(FileSizeModified());
+    ASSERT(FCB_FileSize() > aNewSize && aNewSize);
+	
+    if(aForceCachesFlush)		
+        WriteFileSizeL(aNewSize); //-- write file size directly to its dir. entry
+
+	CheckPosL(aNewSize);
+	
+    TUint32 cluster=iCurrentPos.iCluster;
+		if (FAT().GetNextClusterL(cluster))
+	    {//-- truncate the cluster chain
+			FAT().WriteFatEntryEofL(iCurrentPos.iCluster);
+			FAT().FreeClusterListL(cluster);
+			}
+		
+    ClearIndex(aNewSize);
+		FAT().FlushL();
+		}
+	
+//-----------------------------------------------------------------------------
+/**
+    Expand a file.
+	
+    @param aNewSize new file size.
+    @param aForceCachesFlush if ETrue, all file/FAT caches will be flushed
+*/
+void CFatFileCB::DoExpandFileL(TUint32 aNewSize, TBool aForceCachesFlush)
+		{
+    ASSERT(FCB_FileSize() < aNewSize);
+    ASSERT(FileSizeModified());
+
+    const TUint32 KClusterSzLog2  = ClusterSizeLog2();
+    const TUint32 newSizeClusters = (TUint32)(((TUint64)aNewSize + Pow2(KClusterSzLog2) - 1) >> KClusterSzLog2);
+
+
+	//-- expanding a file
+	if (FCB_StartCluster() == 0)
+		{//-- the initial file size is 0 (no cluster chain)
+         
+        ClearIndex(0); //-- clear seek index array
+        //-- FAT().FreeClusterHint() will give us a hint of the last free cluster
+        const TUint32 tempStartCluster=FAT().AllocateClusterListL(newSizeClusters, FAT().FreeClusterHint()); 
+		FAT().FlushL();
+
+		iCurrentPos.iCluster=tempStartCluster;
+		FCB_SetStartCluster(tempStartCluster);
+		FCB_SetFileSize(aNewSize);
+		FlushAllL();
+		}
+	else
+		{
+		const TUint curSize = FCB_FileSize(); 
+	    const TUint32 oldSizeClusters = ((curSize + Pow2(KClusterSzLog2) - 1) >> KClusterSzLog2);
+        ASSERT(newSizeClusters >= oldSizeClusters);
+		const TUint newClusters = newSizeClusters-oldSizeClusters;	//-- Number of clusters we need to append to the existing cluster chain
+		if (newClusters)
+			{
+			TEntryPos currentPos=iCurrentPos;
+			CheckPosL(FCB_FileSize());
+			FAT().ExtendClusterListL(newClusters,iCurrentPos.iCluster);
+			iCurrentPos=currentPos;
+			}
+	
+		FAT().FlushL();
+		
+        if(aForceCachesFlush)			// write file size if increasing
+			WriteFileSizeL(aNewSize);
+		}
+
+	}
+
+//-----------------------------------------------------------------------------
+/**
+    Set file size. This can involve extending/truncating file's cluster chain.
+    @param  aSize               new file size
+    @param  aForceCachesFlush   if ETrue, all changes in metadata will go to the media immediately. 
+                                it is used in Rugged FAT mode.
+*/
+void CFatFileCB::DoSetSizeL(TUint aSize, TBool aForceCachesFlush)
 	{
-	__PRINT2(_L("CFatFileCB::DoSetSizeL sz:%d, fileWrite=%d"),aSize ,aIsSizeWrite);
+	__PRINT4(_L("CFatFileCB::DoSetSizeL[0x%x] sz:%d, oldSz:%d, flush:%d"), this, aSize, FCB_FileSize(), aForceCachesFlush);
 
     FatMount().CheckStateConsistentL();
     FatMount().CheckWritableL();
 
 	
 	// Can not change the file size if it is clamped
-	if(Mount().IsFileClamped(MAKE_TINT64(0,iStartCluster)) > 0)
+	if(Mount().IsFileClamped(MAKE_TINT64(0,FCB_StartCluster())) > 0)
 		User::Leave(KErrInUse);
 	
-	iFileSizeModified=ETrue;
+	if(aSize == FCB_FileSize())
+        return;
+
+    IndicateFileSizeModified(ETrue);
 
 	TInt newIndexMult=CalcSeekIndexSize(aSize);
 	if (iSeekIndex!=NULL && newIndexMult!=iSeekIndexSize)
 		ResizeIndex(newIndexMult,aSize);
-	if (aSize == 0)
-		{
-		if (Size() != 0)
-			{
-            ClearIndex(0); //-- clear seek index array
-			TInt cluster=iStartCluster;
-			iStartCluster = 0;
-			SetSize(0);
-			FlushAllL();
-			CheckPosL(0);
-			FAT().FreeClusterListL(cluster);
-			FAT().FlushL();
-			}
-		return;
-		}
-	if (aSize<(TUint)Size())
+
+	//-------------------------------------------
+    //-- shrinking file to 0 size
+    if(aSize == 0)
+        {
+        DoShrinkFileToZeroSizeL();
+        return;
+        }
+
+    //-------------------------------------------
+	//-- shrinking file to non-zero size
+    if (aSize < FCB_FileSize())
 		{
-		if(aIsSizeWrite)		// write file size if decreasing
-				WriteFileSizeL(aSize);
-		CheckPosL(aSize);
-		TInt cluster=iCurrentPos.iCluster;
-		if (FAT().GetNextClusterL(cluster))
-			{
-			FAT().WriteFatEntryEofL(iCurrentPos.iCluster);
-			FAT().FreeClusterListL(cluster);
-			}
-		ClearIndex(aSize);
-		FAT().FlushL();
-		return;
-		}
-	
-	TUint newSize=aSize>>ClusterSizeLog2();	//	Number of clusters we now need
-	if (aSize > (newSize<<ClusterSizeLog2()))
-		newSize++;	//	File size is not an exact multiple of cluster size
-					//	Increment the number of clusters required to accomodate tail
-	
-	if (iStartCluster==0)
-		{
-        //-- FAT().FreeClusterHint() will give us a hint of the last free cluster
-        ClearIndex(0); //-- clear seek index array
-        TInt tempStartCluster=FAT().AllocateClusterListL(newSize, FAT().FreeClusterHint());
-		FAT().FlushL();
-		iCurrentPos.iCluster=tempStartCluster;
-		iStartCluster=tempStartCluster;
-		SetSize(aSize);
-		FlushAllL();
-		}
-	else
-		{
-		const TUint curSize = (TUint)Size(); 
-		TUint oldSize=curSize>>ClusterSizeLog2();	//	Number of clusters we had previously
-		if (curSize>(oldSize<<ClusterSizeLog2()))
-			oldSize++;
-	
-		TInt newClusters=newSize-oldSize;	//	Number of clusters we need to prepare
-		if (newClusters)
-			{
-			TEntryPos currentPos=iCurrentPos;
-			CheckPosL(Size());
-			FAT().ExtendClusterListL(newClusters,iCurrentPos.iCluster);
-			iCurrentPos=currentPos;
-			}
-		FAT().FlushL();
-		if(aIsSizeWrite)			// write file size if increasing
-			WriteFileSizeL(aSize);
-		}
+        DoShrinkFileL(aSize, aForceCachesFlush);
+        return;
+        }
+    
+    //-------------------------------------------
+	//-- expanding a file
+    DoExpandFileL(aSize, aForceCachesFlush);
+
 	}
 
 //-----------------------------------------------------------------------------
 /**
-    Set the entry's attributes and modified time.
+    Set file entry details, like file attributes and modified time
+    This method doesn't write data to the media immediately, instead, all modified data are cached and can be flushed later 
+    in FlushAllL()
+
+    @param  aTime           file modification time (and last access as well)
+    @param  aSetAttMask     file attributes OR mask
+    @param  aClearAttMask   file attributes AND mask
+
 */
 void CFatFileCB::SetEntryL(const TTime& aTime,TUint aSetAttMask,TUint aClearAttMask)
 	{
-	__PRINT(_L("CFatFileCB::SetEntryL"));
+	__PRINT1(_L("CFatFileCB::SetEntryL[0x%x]"), this);
     
     FatMount().CheckStateConsistentL();
     FatMount().CheckWritableL();
 
-	TUint setAttMask=aSetAttMask&KEntryAttMaskSupported;
+    //-- change file attributes
+    const TUint setAttMask = (aSetAttMask & KEntryAttMaskSupported); //-- supported attributes to set
+    TUint newAtt = Att();
+
 	if (setAttMask|aClearAttMask)
 		{
-		iAtt|=setAttMask;
-		iAtt&=(~aClearAttMask);
+        newAtt |= setAttMask;
+        newAtt &= ~aClearAttMask;
+        SetAtt(newAtt);
+        IndicateFileAttModified(ETrue); //-- indicate that file attributes have changed
 		}
+    
+    //-- set file entry modification time if required
 	if (aSetAttMask&KEntryAttModified)
-		iModified=aTime;
-	iAtt|=KEntryAttModified;
+	{
+        SetModified(aTime);        //-- set file modified time
+        IndicateFileAttModified(ETrue); //-- indicate that file attributes have changed
+        IndicateFileTimeModified(ETrue); //-- this will force writing file mod. time to the media on Flush
+        }
+
 	}
 
-/**
-    This is a RuggedFAT - specific method. Writes file size to the corresponding field of this
-    file direcrory entry.
-*/
-void CFatFileCB::WriteFileSizeL(TUint aSize)
-	{
-	__PRINT(_L("CFatFileCB::WriteFileSizeL"));
-	TEntryPos entryPos=iFileDirPos;
-	entryPos.iPos+=_FOFF(SFatDirEntry,iSize);
-	TPtrC8 size((TUint8*)&aSize,sizeof(TUint));
-	
-    //-- use directory cache when dealing with directories
-    FatMount().DirWriteL(entryPos,size);
-	iFileSizeModified=EFalse;
-    }
 
 //-----------------------------------------------------------------------------
 /** 
-    Flush file size, attributes, time etc. to the media.
-    It doesn't matter if whole directory entry is being written of only part of it. Anyway, a single DOS
-    dir. entry always fits into 1 sector.
+    The same as FlushAllL(). This method is called from RFile::Flush()
 */
 void CFatFileCB::FlushDataL()
 	{
-	__PRINT(_L("CFatFileCB::FlushDataL"));
+	__PRINT1(_L("CFatFileCB::FlushDataL[0x%x]"), this);
     FlushAllL();
 	}
 
@@ -613,7 +721,13 @@
 */
 void CFatFileCB::FlushAllL()
 	{
-	__PRINT(_L("CFatFileCB::FlushAllL()"));
+
+    //-- define this symbol in order to enable legacy behaviour, i.e. compulsory updating file dir. entry on flush.
+    //-- otherwise the FlushAllL() will update the file dir. entry only if it differs from what is on the media, i.e.
+    //-- file size, start cluster, attributes and modification timestamp
+    #define ALWAYS_UPDATE_ENTRY_ON_FLUSH
+
+	__PRINT1(_L("CFatFileCB::FlushAllL[0x%x]"), this);
 
     if (Mount().IsCurrentMount()==EFalse)
 		User::Leave(KErrDisMounted);
@@ -621,21 +735,58 @@
     FatMount().CheckStateConsistentL();
     FatMount().CheckWritableL();
 
+	if(!FileSizeModified() && !FileAttModified() && !FileTimeModified())
+        return; //-- nothing has changed in the file entry at all
+
+
+    //-- read file dir. entry
 	TFatDirEntry entry;
-	FatMount().ReadDirEntryL(iFileDirPos,entry);
+	FatMount().ReadDirEntryL(iFileDosEntryPos,entry);
 	__ASSERT_ALWAYS(entry.IsEndOfDirectory()==EFalse,User::Leave(KErrCorrupt));
-	entry.SetAttributes(iAtt&KEntryAttMaskSupported);
-	entry.SetSize(Size());
-	entry.SetTime(iModified, FatMount().TimeOffset());
-	entry.SetStartCluster(iStartCluster);
+
+    //-- the problem with KEntryAttModified here is that the file server uses this flag to 
+    //-- deal with dirty file data. This means that this flag can be set even if there were no changes
+    //-- in file time and attributes. Just check if any of the entry field has changed at all
+    
+    TBool bUpdateDirEntry = ETrue;
+    const TTimeIntervalSeconds  timeOffset = FatMount().TimeOffset();
+
+#ifndef ALWAYS_UPDATE_ENTRY_ON_FLUSH
+    
+    TBool bTimeModified = FileTimeModified();  //-- check if file modifiication time has been changed explicitly
+    if(bTimeModified)
+        {//-- additional check; for FAT entry modification time has 2 sec. granularity.
+        bTimeModified = !entry.IsTimeTheSame(iModified, timeOffset);
+        }
 
-	TBool setNotify = FatMount().GetNotifyUser();
+    if(!bTimeModified)
+      if(//-- TS is the same as on the media, check other entry fields
+        (entry.Attributes() == (Att() & KEntryAttMaskSupported)) && //-- file attributes have not changed
+        (entry.Size() == FCB_FileSize()) &&                         //-- file size hasn't changed
+        (entry.StartCluster() == FCB_StartCluster())                //-- file start cluster hasn't changed 
+        )               
+        {
+        bUpdateDirEntry = EFalse; //-- no need to update file dir. entry
+        }
+
+#endif //#ifndef ALWAYS_UPDATE_ENTRY_TS_ON_FLUSH
+
+    if(bUpdateDirEntry)
+        {//-- write entry to the media
+	    __PRINT(_L("  CFatFileCB::FlushAllL #1"));
+        entry.SetAttributes(Att() & KEntryAttMaskSupported);
+	    entry.SetSize(FCB_FileSize());
+	    entry.SetTime(iModified, timeOffset);
+	    
+        entry.SetStartCluster(FCB_StartCluster());
+
+	    const TBool setNotify = FatMount().GetNotifyUser();
 	if(setNotify)
 		{
 		FatMount().SetNotifyOff();	// do not launch a notifier
 		}
 
-	TRAPD(ret, FatMount().WriteDirEntryL(iFileDirPos,entry));
+	    TRAPD(ret, FatMount().WriteDirEntryL(iFileDosEntryPos,entry));
 	
 	if(setNotify)
 		{
@@ -643,8 +794,14 @@
 		}
 
 	User::LeaveIfError(ret);
-	iAtt&=(~KEntryAttModified);
-	iFileSizeModified=EFalse;
+
+        IndicateFileSizeModified(EFalse);
+        IndicateFileTimeModified(EFalse);
+	    }
+
+
+        //-- KEntryAttModified must be reset anyway
+        IndicateFileAttModified(EFalse); 
 	}
 
 //-----------------------------------------------------------------------------
@@ -663,7 +820,7 @@
     const TPtrC fileName = RemoveTrailingDots(aNewName); //-- remove trailing dots from the name
 
 
-	FatMount().DoRenameOrReplaceL(*iFileName, fileName, CFatMountCB::EModeRename,iFileDirPos);
+	FatMount().DoRenameOrReplaceL(*iFileName, fileName, CFatMountCB::EModeRename, iFileDosEntryPos);
 	
     AllocBufferL(iFileName, fileName);
 	
@@ -712,7 +869,7 @@
 	aInfo.iBlockStartOffset = fatMount.ClusterRelativePos(iCurrentPos.iPos);
 	aInfo.iBlockGranularity = 1 << FatMount().ClusterSizeLog2();
 	const TUint myStartPos = iCurrentPos.iPos;
-	if ( myStartPos + length > (TUint)Size())
+	if ( myStartPos + length > FCB_FileSize())
 		return KErrArgument;
 
 	TRAP(r, FatMount().BlockMapReadFromClusterListL(iCurrentPos, length, aInfo));
@@ -720,7 +877,7 @@
 		return r;
 
 	aStartPos = iCurrentPos.iPos;
-	if ((I64LOW(aStartPos) == (TUint)Size()) || ( I64LOW(aStartPos) == (myStartPos + length)))
+	if ((I64LOW(aStartPos) == FCB_FileSize()) || ( I64LOW(aStartPos) == (myStartPos + length)))
 		return KErrCompletion;
 	else
 		return KErrNone;
@@ -756,17 +913,37 @@
 */
 void CFatFileCB::FlushStartClusterL()
 	{
-	__PRINT(_L("CFatFileCB::FlushStartClusterL"));
+	__PRINT1(_L("CFatFileCB::FlushStartClusterL[0x%x]"), this);
 
     CFatMountCB& mount = FatMount();
     TFatDirEntry dirEntry;
     
-    mount.ReadDirEntryL(iFileDirPos, dirEntry);      //-- read this file's dir. entry
-    dirEntry.SetStartCluster(iStartCluster);         //-- set new start cluster
-    mount.WriteDirEntryL(iFileDirPos, dirEntry);//-- write the entry back
+    mount.ReadDirEntryL(iFileDosEntryPos, dirEntry); //-- read this file's dir. entry
+    dirEntry.SetStartCluster(FCB_StartCluster());    //-- set new start cluster
+    mount.WriteDirEntryL(iFileDosEntryPos, dirEntry);//-- write the entry back
 	}
 
 
+/**
+    This is a RuggedFAT - specific method. Writes file size to the corresponding field of its file directory entry.
+*/
+void CFatFileCB::WriteFileSizeL(TUint aSize)
+	{
+	__PRINT2(_L("CFatFileCB::WriteFileSizeL[0x%x], sz:%d"), this, aSize);
+
+    CFatMountCB& mount = FatMount();
+    TFatDirEntry dirEntry;
+
+    mount.ReadDirEntryL(iFileDosEntryPos, dirEntry); //-- read this file's dir. entry
+    dirEntry.SetSize(aSize);                         //-- set new size
+    mount.WriteDirEntryL(iFileDosEntryPos, dirEntry);//-- write the entry back
+
+    IndicateFileSizeModified(EFalse);
+    }
+
+
 
 
 
+
+
--- a/userlibandfileserver/fileserver/sfat32/sl_fmt.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/userlibandfileserver/fileserver/sfat32/sl_fmt.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -51,24 +51,24 @@
 	iBadClusters.Close();
 	}
 
-TInt CFatFormatCB::MaxFat16Sectors() const
-//
-// Calculate the size of a 16 bit FAT
-//
+/**
+    Calculate the size of a 16 bit FAT
+*/
+TUint CFatFormatCB::MaxFat16Sectors() const
 	{
-	
-	TInt fatSizeInBytes=(2*iMaxDiskSectors)/iSectorsPerCluster+(iBytesPerSector-1);
+	const TUint32 fatSizeInBytes=(2*iMaxDiskSectors)/iSectorsPerCluster+(iBytesPerSector-1);
 	return(fatSizeInBytes/iBytesPerSector);
 	}
 
-TInt CFatFormatCB::MaxFat12Sectors() const
-//
-// Calculate the size of a 12 bit FAT
-//
+
+/**
+    Calculate the size of a 12 bit FAT
+*/
+TUint CFatFormatCB::MaxFat12Sectors() const
 	{
+	const TUint32 maxDiskClusters=iMaxDiskSectors/iSectorsPerCluster;
+	const TUint32 fatSizeInBytes=maxDiskClusters+(maxDiskClusters>>1)+(iBytesPerSector-1);
 	
-	TInt maxDiskClusters=iMaxDiskSectors/iSectorsPerCluster;
-	TInt fatSizeInBytes=maxDiskClusters+(maxDiskClusters>>1)+(iBytesPerSector-1);
 	return(fatSizeInBytes/iBytesPerSector);
 	}
 
@@ -205,15 +205,17 @@
     @param  aDiskSizeInSectors volume size in sectors
     @return standard error code
 */
-TInt  CFatFormatCB::InitFormatDataForVariableSizeDisk(TInt aDiskSizeInSectors)
+TInt  CFatFormatCB::InitFormatDataForVariableSizeDisk(TUint aDiskSizeInSectors)
 	{
 	iNumberOfFats=2; // 1 FAT 1 Indirection table (FIT)
 	iReservedSectors=1;
 	iRootDirEntries=2*(4*KDefaultSectorSize)/sizeof(SFatDirEntry);
-	TInt minSectorsPerCluster=(aDiskSizeInSectors+KMaxFAT16Entries-1)/KMaxFAT16Entries;
+	TUint minSectorsPerCluster=(aDiskSizeInSectors+KMaxFAT16Entries-1)/KMaxFAT16Entries;
 	iSectorsPerCluster=1;
+
 	while (minSectorsPerCluster>iSectorsPerCluster)
 		iSectorsPerCluster<<=1;
+
 	__PRINT1(_L("iSectorsPerCluster = %d"),iSectorsPerCluster);
 	iSectorsPerFat=MaxFat16Sectors();
 	__PRINT1(_L("iSectorsPerFat = %d"),iSectorsPerFat);
@@ -277,7 +279,10 @@
     TPtr8 readBufPtr(readBuf, size);
     RArray<TInt> newArray;
     TInt r = DoTranslate(readBufPtr, newArray);
+    
     delete[] readBuf;
+    readBuf = NULL;
+
     newArray.Close();
     User::LeaveIfError(r);
     }
--- a/userlibandfileserver/fileserver/sfat32/sl_leafdir_cache.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/userlibandfileserver/fileserver/sfat32/sl_leafdir_cache.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -235,6 +235,7 @@
 CLeafDirTree::CLeafDirTree(TUint32 aSize)
 :iSize(aSize)
 	{
+	__PRINT2(_L("CLeafDirTree created[0x%x] sz:%d"), this, aSize);
 	}
 
 _LIT(KRootDirPath, "\\");
@@ -254,6 +255,8 @@
 */
 CLeafDirTree::~CLeafDirTree()
 	{
+	__PRINT1(_L("~CLeafDirTree[0x%x]"), this);
+
 	Reset();
 	delete iRoot;
 	iLruList.Close();
--- a/userlibandfileserver/fileserver/sfat32/sl_mnt.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/userlibandfileserver/fileserver/sfat32/sl_mnt.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -304,11 +304,6 @@
     	{
         iLeafDirCache->Reset();
     	}
-    else
-    	{
-        User::Free(iLastLeafDir);
-        iLastLeafDir=NULL;
-    	}
 	}
 
 //-------------------------------------------------------------------------------------------------------------------
@@ -843,7 +838,7 @@
     @param  aStartCluster   this entry start cluster number
     @param  aParentCluster  parent entry start cluster number
 */
-void CFatMountCB::InitializeFirstDirClusterL(TInt aStartCluster,TInt aParentCluster)
+void CFatMountCB::InitializeFirstDirClusterL(TUint32 aStartCluster, TUint32 aParentCluster)
     {
     const TUint32 KClusterSz= 1<<ClusterSizeLog2();
     const TUint32 KMaxBufSz = KClusterSz;           //-- max. nuffer size is a cluster
@@ -1064,6 +1059,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 +1145,7 @@
 
 		    if (iFileCreationHelper.GetValidatedShortName(shortName) == KErrNotFound)
 		    	{
-		        GenerateShortNameL(aNewName_DosEntryPos.Cluster(), ptrNewName, shortName, ETrue);
+		        GenerateShortNameL(aNewName_ParentDirPos.Cluster(), ptrNewName, shortName); 
 		    	}
 
             newDosEntry.SetName(shortName);
@@ -1355,7 +1357,7 @@
 
 //-----------------------------------------------------------------------------------------
 
-void CFatMountCB::DoCheckFatForLoopsL(TInt aCluster, TInt& aPreviousCluster, TInt& aChangePreviousCluster, TInt& aCount) const
+void CFatMountCB::DoCheckFatForLoopsL(TUint32 aCluster, TUint32& aPreviousCluster, TUint32& aChangePreviousCluster, TUint32& aCount) const
 //
 // Check one fat cluster for loops.
 //
@@ -1381,13 +1383,13 @@
 //
     {
 
-    TInt cluster=StartCluster(anEntry);
+    TUint32 cluster = StartCluster(anEntry);
     if (cluster==0 && anEntry.Size()==0)
         return;
 
-    TInt previousCluster=cluster;
-    TInt changePreviousCluster=1;
-    TInt count=0;
+    TUint32 previousCluster=cluster;
+    TUint32 changePreviousCluster=1;
+    TUint32 count=0;
 
 
     for(;;)
@@ -1499,14 +1501,13 @@
         }
 
     CFatFileCB& file=(*((CFatFileCB*)aFile));
-    file.SetL(firstEntry,(TShare)(aMode&KFileShareMask),firstEntryPos);
+    file.SetupL(firstEntry, firstEntryPos);
+
     if (anOpen==EFileReplace && file.Size())
         {
         file.SetSizeL(0);
-        file.SetSize(0);
         }
-    if (file.IsSeekIndex()==EFalse)
-        file.CreateSeekIndex();
+
     if (anOpen==EFileReplace || anOpen==EFileCreate)
         file.SetArchiveAttribute();
 
@@ -1575,10 +1576,10 @@
 
 //-----------------------------------------------------------------------------------------
 
-TBool CFatMountCB::IsDirectoryEmptyL(TInt aCluster)
 //
 // Check aCluster contains no directory entries other than . and ..
 //
+TBool CFatMountCB::IsDirectoryEmptyL(TUint32 aCluster)
     {
 
     __PRINT(_L("CFatMountCB::IsDirectoryEmptyL"));
@@ -1606,13 +1607,13 @@
 /**
     Overwrite as many contiguous file clusters as possible.
 */
-void CFatMountCB::DoWriteToClusterListL(TEntryPos& aPos,TInt aLength,const TAny* aSrc,const RMessagePtr2& aMessage,TInt anOffset, TInt aLastcluster, TInt &aBadcluster, TInt &aGoodcluster)
+void CFatMountCB::DoWriteToClusterListL(TEntryPos& aPos,TInt aLength,const TAny* aSrc,const RMessagePtr2& aMessage,TInt anOffset, TUint aLastcluster, TUint& aBadcluster, TUint& aGoodcluster)
     {
 
     __PRINT(_L("CFatMountCB::DoWriteToClusterListL"));
     __ASSERT_ALWAYS(aPos.Cluster()>=KFatFirstSearchCluster,User::Leave(KErrCorrupt));
 
-    TInt endCluster=0;
+    TUint32 endCluster=0;
 
     const TInt clusterRelativePos=ClusterRelativePos(aPos.iPos);
     const TInt maxClusters=((aLength+clusterRelativePos-1)>>ClusterSizeLog2())+1;
@@ -1638,11 +1639,11 @@
     if(r == KErrNone && errinf().iReasonCode == TErrorInfo::EBadSector) // GetLastErrorInfo succeded and Last Error was caused by bad sector
         {
 
-        const TInt badcluster = (TInt)(((dataStart + errinf().iErrorPos) - ClusterBasePosition())>>ClusterSizeLog2())+KFatFirstSearchCluster;
-              TInt goodcluster = FAT().AllocateSingleClusterL(badcluster);
+        const TUint32 badcluster = (TInt)(((dataStart + errinf().iErrorPos) - ClusterBasePosition())>>ClusterSizeLog2())+KFatFirstSearchCluster;
+              TUint32 goodcluster = FAT().AllocateSingleClusterL(badcluster);
 
         //Calculate cluster number to check whether this write started at the beginning of new cluster or middle of previous cluster.
-        TInt cluster = aPos.iCluster;
+        TUint32 cluster = aPos.iCluster;
         if ( (aPos.iPos) && ((aPos.iPos)==((aPos.iPos >> ClusterSizeLog2())<<ClusterSizeLog2())))
             cluster--;
 
@@ -1735,7 +1736,7 @@
 
 //-----------------------------------------------------------------------------------------
 
-void CFatMountCB::WriteToClusterListL(TEntryPos& aPos,TInt aLength,const TAny* aSrc,const RMessagePtr2& aMessage,TInt anOffset, TInt &aBadcluster, TInt& aGoodcluster)
+void CFatMountCB::WriteToClusterListL(TEntryPos& aPos,TInt aLength,const TAny* aSrc,const RMessagePtr2& aMessage,TInt anOffset, TUint& aBadcluster, TUint& aGoodcluster)
 //
 // Overwrite cluster list.
 //
@@ -1780,7 +1781,7 @@
 
     __PRINT(_L("CFatMountCB::DoReadFromClusterListL"));
 
-    TInt endCluster=0;
+    TUint32 endCluster=0;
 
     const TInt clusterRelativePos=ClusterRelativePos(aPos.iPos);
     const TInt maxClusters=((aLength+clusterRelativePos-1)>>ClusterSizeLog2())+1;
@@ -1853,33 +1854,20 @@
 //
     {
 
-    __PRINT(_L("CFatMountCB::FindLeafDirL"));
+    __PRINT2(_L("CFatMountCB::FindLeafDirL drv:%d, dir:%S"),DriveNumber() ,&aLeafDir);
 
     TLex lex(aName);
     TInt r;
     TEntryPos entryPos(RootIndicator(),0);
 
-    if (iLeafDirCache == NULL)
-    	{
-        TInt leaflen=(iLastLeafDir) ? iLastLeafDir->Length() : 0;
-        TInt namelen=aName.Length();
-        if (leaflen>1 && namelen>=leaflen && *iLastLeafDir==aName.Left(leaflen))
-            {
-            if (leaflen==namelen)
-                return(iLastLeafDirCluster);
-            lex.Inc(leaflen-1);
-            entryPos.iCluster=iLastLeafDirCluster;
-            }
-    	}
-    else
-    	{
-        // Skip root directory
+    ASSERT(iLeafDirCache);
+
         if (iLeafDirCache->CacheCount() > 0 && aName.Length() > 1)
         	{
-        	TInt err = iLeafDirCache->FindInCache(aName, aLeafDir);
+        const TInt err = iLeafDirCache->FindInCache(aName, aLeafDir);
         	if (err == KErrNone)
         		{
-        		ASSERT(aLeafDir.iClusterNum > 0);
+        	ASSERT(ClusterNumberValid(aLeafDir.iClusterNum)); 
         		return aLeafDir.iClusterNum;
         		}
         	else if (err != KErrNotFound)
@@ -1887,23 +1875,27 @@
         		User::LeaveIfError(err);
         		}
         	}
-    	}
-
-    FOREVER
+
+    TFatDirEntry entry;
+    TFileName fileName;
+    TEntryPos startPos;
+    TFatDirEntry startEntry;
+
+    for(;;)
         {
         lex.Inc(); // Skip path delimiter
         lex.Mark();
         r=lex.Remainder().Locate(KPathDelimiter);
+        
         if (r==KErrNotFound)
             r=lex.Remainder().Length();
+        
         if (r==0) // End of the path
             break;
+        
         lex.Inc(r); // Set the token length
-        TFatDirEntry entry;
-
-        TFileName fileName;
-        TEntryPos startPos;
-        TFatDirEntry startEntry;
+        
+        
         DoFindL(lex.MarkedToken(),
         		KEntryAttMatchMask|KEntryAttMatchExclusive,
         		startPos, startEntry, entryPos, entry,
@@ -1914,21 +1906,13 @@
 
         entryPos.iCluster=StartCluster(entry);
         entryPos.iPos=0;
-        }
-
-    if (iLeafDirCache == NULL)
-    	{
-        AllocBufferL(((CFatMountCB*)this)->iLastLeafDir,aName);
-        ((CFatMountCB*)this)->iLastLeafDirCluster=entryPos.iCluster;
-    	}
-    else
-    	{
+        }// for(;;)
+
         if (aName.Length() > 1)
         	{
         	aLeafDir = TLeafDirData(entryPos.iCluster);
             iLeafDirCache->AddToCacheL(aName, aLeafDir);
         	}
-    	}
 
     return entryPos.iCluster;
     }
@@ -1971,8 +1955,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
@@ -1990,7 +1972,7 @@
 
 	TInt numFound = 0;
 	TEntryPos startPos = DosEntryPos1;
-	TInt clusterNum = DosEntryPos1.iCluster;
+	TUint32 clusterNum = DosEntryPos1.iCluster;
 
     for(TUint32 entryCnt=0; entryCnt < maxDirEntries; ++entryCnt)
         {//-- walk through directory cluster list. The loop is limited by maximal number of dir entries
@@ -2021,7 +2003,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);
@@ -2036,7 +2018,7 @@
             for(;;)
                 {
                 StartEntryPos1 = DosEntryPos1;
-                TInt clSave = DosEntryPos1.iCluster; //-- need to save current cluster number because GetDirEntry() & MoveToNextEntryL() can change it
+                TUint32 clSave = DosEntryPos1.iCluster; //-- need to save current cluster number because GetDirEntry() & MoveToNextEntryL() can change it
 
                 //-- get directory entry from the cache. We know that the DosEntryPos1 is cached.
                 nErr = GetDirEntry(DosEntryPos1, DosEntry1, StartEntry1, aFileName);
@@ -2455,10 +2437,10 @@
 
     __PRINT2(_L("CFatMountCB::DoFindL() drv:%d, %S"),Drive().DriveNumber(),&aTrgtName);
 
-    TInt previousCluster=aDosEntryPos.iCluster;
+    TUint32 previousCluster=aDosEntryPos.iCluster;
     TUint previousPosition=aDosEntryPos.iPos;
-    TInt changePreviousCluster=1;
-    TInt count=0;
+    TUint32 changePreviousCluster=1;
+    TUint32 count=0;
 
     TBool trgNameIsWildCard     = EFalse; //-- ETrue if the name we are looking for is a wildcard
     TBool trgNameFullySpecified = ETrue;  //-- ETrue if the name we are looking for doesn't contain wildcards
@@ -2943,7 +2925,7 @@
     Zero fill a cluster
     @param  aCluster cluster number to zero-fill
 */
-void CFatMountCB::ZeroDirClusterL(TInt aCluster)
+void CFatMountCB::ZeroDirClusterL(TUint32 aCluster)
     {
 
     __PRINT1(_L("CFatMountCB::ZeroDirClusterL %d"),aCluster);
@@ -3035,12 +3017,17 @@
 
     const TUint8 entryCheckSum = aDosEntry.CheckSum(); //-- check sum from the 1st VFat entry
 
+    TUint nameChunkOffset = KMaxVFatEntryName*(count-1);
+
     while (count--)
         {
-        TPtr fileNamePtr(&aLongFileName[0]+KMaxVFatEntryName*count,aLongFileName.Length()-KMaxVFatEntryName*count);
+        TPtr fileNamePtr(&aLongFileName[0]+nameChunkOffset, aLongFileName.Length()-nameChunkOffset);
         fileNamePtr.Copy(vBuf);
         if (count==0)
             break; //-- all VFat entries read, only DOS entry remained
+        
+        ASSERT(nameChunkOffset >= (TUint)KMaxVFatEntryName);
+        nameChunkOffset-=KMaxVFatEntryName;
 
         MoveToNextEntryL(aPos);
         ReadDirEntryL(aPos,aDosEntry);
@@ -3155,12 +3142,12 @@
 //-----------------------------------------------------------------------------------------
 
 /** Read the Uid of the entry starting at aCluster */
-void CFatMountCB::ReadUidL(TInt aCluster,TEntry& anEntry) const
+void CFatMountCB::ReadUidL(TUint32 aCluster,TEntry& anEntry) const
     {
 
     __PRINT1(_L("CFatMountCB::ReadUidL(%d)"), aCluster);
 
-    if((TUint)aCluster < KFatFirstSearchCluster || (TUint)aCluster >= UsableClusters()+KFatFirstSearchCluster)
+    if(aCluster < KFatFirstSearchCluster || aCluster >= UsableClusters()+KFatFirstSearchCluster)
         User::Leave(KErrCorrupt);
 
     TBuf8<sizeof(TCheckedUid)> uidBuf;
@@ -3217,10 +3204,10 @@
     if ((TUint)(aPos+aLength)>fileSize)
         aLength=fileSize-aPos;
 
-    TInt cluster=StartCluster(dosEntry);
+    TUint32 cluster=StartCluster(dosEntry);
 	TInt pos = aPos;
 
-    TInt endCluster;
+    TUint32 endCluster;
     TInt clusterSize=1<<ClusterSizeLog2();      //  Size of file clusters
 	TInt readTotal = 0;
 
@@ -3336,14 +3323,16 @@
 
 //-----------------------------------------------------------------------------------------
 
+/**
+    Write a FAT directory entry to disk. Assumes sufficient space has been created for it by AddDirEntry.
+
+    @param  aPos        dir. entry position 
+    @param  aDirEntry   entry data
+*/
 void CFatMountCB::WriteDirEntryL(const TEntryPos& aPos,const TFatDirEntry& aDirEntry)
-//
-// Write a FAT directory entry to disk.
-// Assumes sufficient space has been created for it by AddDirEntry.
-//
     {
 
-    __PRINT(_L("CFatMountCB::WriteDirEntryL"));
+    __PRINT2(_L("CFatMountCB::WriteDirEntryL cl:%d, pos:%d"), aPos.Cluster(), aPos.Pos());
 
     //-- use special interface to access FAT directory file
     DirWriteL(aPos,TPtrC8((TUint8*)&aDirEntry,KSizeOfFatDirEntry));
@@ -3351,15 +3340,13 @@
 
 //-----------------------------------------------------------------------------------------
 
+/**
+    Mark a dir entry as erased
+    @param  aPos dir. entry position 
+*/
 void CFatMountCB::EraseDirEntryL(const TEntryPos& aPos)
-//
-// Mark a dir entry as erased
-//
     {
-
-    __PRINT(_L("CFatMountCB::EraseDirEntryL"));
-    if(!iLeafDirCache && iLastLeafDir)
-        iLastLeafDir->Des().SetLength(0);
+    __PRINT2(_L("CFatMountCB::EraseDirEntryL cl:%d, pos:%d"), aPos.Cluster(), aPos.Pos());
 
     //-- use special interface to access FAT directory file
     DirWriteL(aPos,TPtrC8((TUint8*)&KEntryErasedMarker,sizeof(TUint8)));
@@ -3367,10 +3354,12 @@
 
 //-----------------------------------------------------------------------------------------
 
+/**
+    Read a FAT directory entry 
+    @param  aPos        dir. entry position 
+    @param  aDirEntry   entry data
+*/
 void CFatMountCB::ReadDirEntryL(const TEntryPos& aPos,TFatDirEntry& aDirEntry) const
-//
-// Read a FAT directory entry to disk
-//
     {
 
 //  __PRINT(_L("CFatMountCB::ReadDirEntryL"));
@@ -3515,7 +3504,7 @@
     This method is called for rugged FAT only.
     for parameters see CFatTable::ExtendClusterListL
 */
-void CFatMountCB::ExtendClusterListZeroedL(TInt aNumber,TInt& aCluster)
+void CFatMountCB::ExtendClusterListZeroedL(TUint32 aNumber, TUint32& aCluster)
     {
     __PRINT(_L("CFatMountCB::ExtendClusterListZeroedL"));
     __ASSERT_DEBUG(aNumber>0,Fault(EFatBadParameter));
@@ -3951,28 +3940,24 @@
         User::Leave(KErrNotFound); // Allows maximum number of entries in root directory
         }
 
-    TInt previousCluster= aDosEntryPos.iCluster;
+    TUint32 previousCluster= aDosEntryPos.iCluster;
     TUint previousPosition= aDosEntryPos.iPos;
-    TInt changePreviousCluster=1;
-    TInt count=0;
+    TUint32 changePreviousCluster=1;
+    TUint32 count=0;
 
     TFatDirEntry startEntry;
     TFileName dummyLongName;
 
     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 +3966,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;
         }
     }
@@ -4045,7 +4033,7 @@
     TUint i = 0;
     TInt clusterRelativePos;
     TInt maxClusters;
-    TInt endCluster;
+    TUint32 endCluster;
     TInt clusterListLen;
     TInt readLength;
     TInt temp;
@@ -4196,6 +4184,7 @@
         }
 
     delete pScnDrv;
+    pScnDrv = NULL;
 
     if(chkDskRes != KErrNone)
         {
@@ -4225,7 +4214,7 @@
 
     const TBool bNeedFatRemount = (nScnDrvRes!=KErrNone) || pScnDrv->ProblemsDiscovered();
     delete pScnDrv;
-
+    pScnDrv = NULL;
 
     if(bNeedFatRemount)
         {//-- ScanDrive found and probably fixed some errors.
--- a/userlibandfileserver/fileserver/sfat32/sl_mnt32.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/userlibandfileserver/fileserver/sfat32/sl_mnt32.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -256,7 +256,7 @@
 
         if(tmp != fatEntry)
             {//-- write FAT[1] entry to all available FATs
-                for(TInt i=0; i<NumberOfFats(); ++i)
+                for(TUint32 i=0; i<NumberOfFats(); ++i)
                 {
                 const TInt64 pos = StartOfFatInBytes()+KFatEntrySize+(FatSizeInBytes()*i);
                 User::LeaveIfError(LocalDrive()->Write(pos, ptrFatEntry)); //write FAT32[1] entry
@@ -287,7 +287,7 @@
 
             if(tmp != fatEntry)
                 {//-- write FAT[1] entry to all available FATs
-                for(TInt i=0; i<NumberOfFats(); ++i)
+                for(TUint32 i=0; i<NumberOfFats(); ++i)
                     {
                     const TInt64 pos = StartOfFatInBytes()+KFatEntrySize+(FatSizeInBytes()*i);
                     User::LeaveIfError(LocalDrive()->Write(pos, ptrFatEntry)); //write FAT16[1] entry
@@ -367,7 +367,7 @@
 
     const TInt driveNo = Drive().DriveNumber();
     
-    __PRINT2(_L("CFatMountCB::MountL() drv:%d, forceMount=%d\n"),driveNo,aForceMount);
+    __PRINT3(_L("CFatMountCB::MountL() drv:%d, forceMount=%d, RuggedFAT:%d\n"), driveNo, aForceMount, IsRuggedFSys());
 
     ASSERT(State() == ENotMounted || State() == EDismounted);
     SetState(EMounting);
@@ -476,13 +476,13 @@
 
 
 	    {//-- check if volume geometry looks valid
-        const TInt usableSectors=TotalSectors()-(iFirstFreeByte>>SectorSizeLog2());
+        const TUint32 usableSectors = TotalSectors()-(iFirstFreeByte>>SectorSizeLog2());
 	    iUsableClusters=usableSectors>>(ClusterSizeLog2()-SectorSizeLog2());
 
         const TUint32 KMinClusters = 32; //-- absolute minimum number of clusters on the volume
         const TUint32 KMaxClusters=(TotalSectors()-FirstFatSector()-NumberOfFats()*(FatSizeInBytes()>>SectorSizeLog2())) >> (ClusterSizeLog2()-SectorSizeLog2());
         
-        if(usableSectors <=0 || iUsableClusters < KMinClusters || iUsableClusters > KMaxClusters)
+        if(iUsableClusters < KMinClusters || iUsableClusters > KMaxClusters)
             {
             __PRINT(_L("CFatMountCB::InitializeL() Wrong number of usable cluster/sectors on the volume!"));
             User::Leave(KErrCorrupt);
@@ -493,6 +493,7 @@
 	//-- CFatMountCB parameters might have changed, e.g. after formatting. Reconstruct directory cache with new parameters
 	
     delete iRawDisk;
+    iRawDisk = NULL;
 	iRawDisk=CRawDisk::NewL(*this, aLocDrvCaps);
     iRawDisk->InitializeL();
 
@@ -538,6 +539,7 @@
     //========== create and initialise FAT table 
 	
     delete iFatTable;
+    iFatTable = NULL;
     iFatTable=CFatTable::NewL(*this, aLocDrvCaps);
 
     //-- mount the FAT table. Depending on mount parameters and configuration this method 
@@ -550,19 +552,17 @@
     //-- make a callback, telling FileServer about free space discovered.
     const TInt64 freeSpace = ((TInt64)FAT().NumberOfFreeClusters()) << ClusterSizeLog2();
     SetDiskSpaceChange(freeSpace);
-    //========== create and setup leaf direcotry cache if cache limit is set bigger than one 
 
-	const TUint32 cacheLimit = iFatConfig.LeafDirCacheSize();
-	if (cacheLimit > 1)
+    //========== create and setup leaf direcotry cache
 		{
-		// destroy the old leaf dir cache to avoid memory leak.
+	const TUint32 cacheLimit = Max(iFatConfig.LeafDirCacheSize(), 1lu);
+	
 		delete iLeafDirCache;
+        iLeafDirCache = NULL;
 		iLeafDirCache = CLeafDirCache::NewL(cacheLimit);
 		}
-	else
-		{
-		iLeafDirCache = NULL;
-		}
+
+
     
     __PRINT3(_L("#- CFatMountCB::InitializeL() done. drv:%d, Free clusters:%d, 1st Free cluster:%d"),DriveNumber(), FAT().NumberOfFreeClusters(), FAT().FreeClusterHint());
 
@@ -881,6 +881,7 @@
         nRes = IsFinalised(bFinalised);
         if(nRes == KErrNone)
             {
+            ASSERT(aParam);
             *((TBool*)aParam) = bFinalised;
             }
         
@@ -1047,7 +1048,7 @@
     TInt cluster=StartCluster(dosEntry);	
 	TInt64 pos = aPos;
 	
-    TInt endCluster;
+    TUint32 endCluster;
     TInt clusterSize=1<<ClusterSizeLog2();      //  Size of file clusters
 	TInt readTotal = 0;
 	
--- a/userlibandfileserver/fileserver/sfat32/sl_scan32.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/userlibandfileserver/fileserver/sfat32/sl_scan32.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -277,7 +277,7 @@
 
 	CheckDirStructureL();
 
-    //-- uncomments a line below if you need to compare real and restored FAT tables and print out all differences
+    //-- uncomment a line below if you need to compare real and restored FAT tables and print out all differences
     //CompareFatsL(EFalse);
 
         //timeEnd.UniversalTime(); //-- take end time
@@ -363,7 +363,11 @@
 			}
 		}
 
-	__ASSERT_ALWAYS(err==KErrNone,User::Leave(KErrNotFound));
+    if(err != KErrNone)
+        {
+        __PRINT1(_L("CScanDrive::FindSameStartClusterL() #1 %d"), err);
+        User::Leave(KErrNotFound);
+        }
 	}
 
 //----------------------------------------------------------------------------------------------------
@@ -374,21 +378,32 @@
     @return System wide error value
     @leave 
 */
-TInt CScanDrive::FindStartClusterL(TInt aDirCluster)
+TInt CScanDrive::FindStartClusterL(TUint32 aDirCluster)
 	{
 	__PRINT1(_L("CScanDrive::FindStartCluster dirCluster=%d"),aDirCluster);
-	__ASSERT_ALWAYS(aDirCluster>=iMount->RootIndicator(),User::Leave(KErrCorrupt));
+	
+	if(aDirCluster < (TUint)iMount->RootIndicator() || aDirCluster >= MaxClusters())
+        {
+        __PRINT(_L("CScanDrive::FindStartCluster() #!\n"));
+        IndicateErrorsFound(EBadClusterNumber);
+        User::Leave(KErrCorrupt);
+        }
+
+
 	if(++iRecursiveDepth==KMaxScanDepth)
 		{
 		--iRecursiveDepth;
 		return(KErrNotFound);
 		}
+
 	TEntryPos entryPos(aDirCluster,0);
 	TInt dirEntries=0;
-	FOREVER
+
+	for(;;)
 		{
 		TFatDirEntry entry;
 		ReadDirEntryL(entryPos,entry);
+
 		if(entry.IsParentDirectory()||entry.IsCurrentDirectory()||entry.IsErased())
 			{
 			if(IsEndOfRootDir(entryPos))
@@ -396,12 +411,20 @@
 			MoveToNextEntryL(entryPos);
 			continue;
 			}
+
 		if(entry.IsEndOfDirectory())
 			break;
-		TBool isComplete;
+		
 		TEntryPos vfatPos=entryPos;
-		isComplete=MoveToVFatEndL(entryPos,entry,dirEntries);
-		__ASSERT_ALWAYS(isComplete,User::Leave(KErrBadName));
+		const TBool isComplete = MoveToVFatEndL(entryPos,entry,dirEntries);
+		
+        if(!isComplete)
+            {
+            __PRINT(_L("CScanDrive::FindStartCluster() #2\n"));
+            IndicateErrorsFound(EEntrySetIncomplete);
+            User::Leave(KErrBadName);
+            }
+
 
 		TInt err=CheckEntryClusterL(entry,vfatPos);
 		if(err==KErrNone)
@@ -440,7 +463,7 @@
 	else if(aEntry.Attributes()&KEntryAttDir)
 		return(FindStartClusterL(iMount->StartCluster(aEntry)));
 
-	return(KErrNotFound);
+	return KErrNotFound;
 	}
 
 //----------------------------------------------------------------------------------------------------
@@ -526,6 +549,7 @@
         
         if(!isComplete && CheckDiskMode())
             {//-- broken VFAT entryset; in CheckDisk mode this is the FS error, abort further activity
+                __PRINT(_L("CScanDrive::CheckDirL() #1"));
                 IndicateErrorsFound(EInvalidEntrySize);
                 User::Leave(KErrCorrupt);
             }
@@ -577,13 +601,18 @@
 void CScanDrive::ProcessEntryL(const TFatDirEntry& aEntry)
 	{
 	__PRINT(_L("CScanDrive::ProcessEntryL"));
-	TInt entryAtt=aEntry.Attributes();
+	const TUint entryAtt=aEntry.Attributes();
 
-	__ASSERT_ALWAYS(!(entryAtt&~KEntryAttMaskSupported)&&!aEntry.IsErased(),User::Leave(KErrCorrupt));
+    if((entryAtt & ~KEntryAttMaskSupported) || aEntry.IsErased())
+        {
+        __PRINT1(_L("CScanDrive::ProcessEntryL() wrong entry att: 0x%x"), entryAtt);
+        IndicateErrorsFound(EEntryBadAtt);
+        User::Leave(KErrCorrupt);
+        }
 	
     if(!(entryAtt&(KEntryAttDir|KEntryAttVolume)) && iMount->StartCluster(aEntry)>0)
 		{//-- this is a file with length >0. Check that its cluster chain corresponds to its size
-        RecordClusterChainL(iMount->StartCluster(aEntry),(TUint) aEntry.Size());
+        RecordClusterChainL(iMount->StartCluster(aEntry), aEntry.Size());
         }
 	else if(entryAtt&KEntryAttDir)
 		{//-- this is the directory, walk into it
@@ -601,34 +630,52 @@
     @param aSizeInBytes Size of the file or directory in bytes
     @leave System wide error values
 */
-void CScanDrive::RecordClusterChainL(TInt aCluster, TUint aSizeInBytes)
+void CScanDrive::RecordClusterChainL(TUint32 aCluster, TUint aSizeInBytes)
 	{
 	__PRINT2(_L("CScanDrive::RecordClusterChainL() cl:%d, sz:%d") ,aCluster, aSizeInBytes);
-	__ASSERT_ALWAYS(aCluster>0, User::Leave(KErrCorrupt));
+
+    if(aCluster < KFatFirstSearchCluster || aCluster >= MaxClusters())
+	    {
+        __PRINT(_L("CScanDrive::RecordClusterChainL() #0"));
+        IndicateErrorsFound(EBadClusterNumber);
+        User::Leave(KErrCorrupt);
+        }
 	
     TUint clusterCount;
 	
     if(aSizeInBytes==0)
+		{
 		clusterCount=1;
+        }
 	else
 		{
         const TUint64 tmp = aSizeInBytes + Pow2_64(iMount->ClusterSizeLog2()) - 1;
         clusterCount = (TUint) (tmp >> iMount->ClusterSizeLog2());
         }
 
-	TInt startCluster=aCluster;
+	TUint startCluster=aCluster;
+	
 	while(clusterCount)
 		{
         if(IsClusterUsedL(aCluster))
 			{//-- this cluster already seems to belong to some other object; crosslinked cluster chain. Can't fix it.
-			if(CheckDiskMode())
+                __PRINT1(_L("CScanDrive::RecordClusterChainL #1 %d"),aCluster); 
+            
+            if(CheckDiskMode())
                 {//-- in check disk mode this is a FS error; Indicate error and abort furter scanning
-                __PRINT1(_L("CScanDrive::RecordClusterChainL #1 %d"),aCluster); 
+                __PRINT(_L("CScanDrive::RecordClusterChainL #1.1")); 
                 IndicateErrorsFound(EClusterAlreadyInUse);
                 User::Leave(KErrCorrupt);
                 }
             
-            __ASSERT_ALWAYS(!IsDirError() && iMatching.iStartCluster==0 && aCluster==startCluster,User::Leave(KErrCorrupt));
+            
+            if(IsDirError() || iMatching.iStartCluster > 0 || aCluster != startCluster)
+                {//-- secondary entry into this state
+                __PRINT(_L("CScanDrive::RecordClusterChainL #1.2")); 
+                IndicateErrorsFound(EClusterAlreadyInUse);
+                User::Leave(KErrCorrupt);
+                }
+
 			iMatching.iStartCluster=aCluster;
 			iDirError=EScanMatchingEntry;		//ERROR POINT
             IndicateErrorsFound(EScanDriveDirError); //-- indicate that we have found errors
@@ -637,10 +684,10 @@
 
 		
         if(clusterCount==1)
-			{
+			{//-- we have reached the end of the cluster chain
 			if(!iMount->IsEndOfClusterCh(ReadFatL(aCluster)))
-				{//-- seems to be a rugged FAT artefact; File truncation had failed before and now file length is less than
-                 //-- the corresponding cluster chain shall be. It will be truncated.
+				{//-- seems to be a rugged FAT artefact; File truncation/extension had failed before and now file length is less than
+                 //-- the corresponding cluster chain shall be. It will be truncated to the size recorded in file DOS entry.
 				iTruncationCluster = aCluster;								
                 
                 if(CheckDiskMode())
@@ -660,8 +707,14 @@
 			const TUint clusterVal=ReadFatL(aCluster);
 
             //__PRINT2(_L("#--: %d -> %d"), aCluster, clusterVal); 
-			
-            __ASSERT_ALWAYS(!IsEofF(clusterVal) && clusterVal !=KSpareCluster, User::Leave(KErrCorrupt));
+            if(IsEofF(clusterVal) || clusterVal == KSpareCluster )
+                {//-- unexpected end of the cluster chain (it is shorter than recorded in file dir. entry)
+                __PRINT1(_L("CScanDrive::RecordClusterChainL #3 %d"),clusterVal); 
+                IndicateErrorsFound(EBadClusterValue);
+                User::Leave(KErrCorrupt);
+                }
+
+
 			MarkClusterUsedL(aCluster);
 			aCluster=clusterVal;
 			--clusterCount;
@@ -688,9 +741,16 @@
 		return IsDosEntry(aEntry);
 
 	TInt toFollow=aEntry.NumFollowing();
-	__ASSERT_ALWAYS(toFollow>0 && !aEntry.IsErased(), User::Leave(KErrCorrupt));
 
-	FOREVER
+    if(toFollow <=0 || aEntry.IsErased())
+        {
+        __PRINT1(_L("CScanDrive::MoveToVFatEndL #1 %d"),toFollow);
+        IndicateErrorsFound(EEntrySetIncomplete);
+        User::Leave(KErrCorrupt);
+        }
+
+
+	for(;;)
 		{
 		MoveToNextEntryL(aPos);
 		ReadDirEntryL(aPos,aEntry);
@@ -731,7 +791,7 @@
 */
 TBool CScanDrive::IsDosEntry(const TFatDirEntry& aEntry)const
 	{
-	TBool res = !(aEntry.Attributes()&~KEntryAttMaskSupported) && !aEntry.IsErased() && !aEntry.IsVFatEntry() && !aEntry.IsEndOfDirectory();
+	const TBool res = !(aEntry.Attributes()&~KEntryAttMaskSupported) && !aEntry.IsErased() && !aEntry.IsVFatEntry() && !aEntry.IsEndOfDirectory();
 	return res;
 	} 
 
@@ -746,7 +806,13 @@
 void CScanDrive::AddPartialVFatL(const TEntryPos& aStartPos, const TFatDirEntry& aEntry)
 	{
 	__PRINT2(_L("CScanDrive::AddPartialVFatL cluster=%d pos=%d"),aStartPos.iCluster,aStartPos.iPos);
-	__ASSERT_ALWAYS(!IsDirError(),User::Leave(KErrCorrupt));
+
+    if(IsDirError())
+        {
+        __PRINT(_L("CScanDrive::AddPartialVFatL #1"));
+        User::Leave(KErrCorrupt);
+        }
+
 	iPartEntry.iEntryPos=aStartPos;
 	iPartEntry.iEntry=aEntry;
 	iDirError=EScanPartEntry;
@@ -763,7 +829,14 @@
 TBool CScanDrive::AddMatchingEntryL(const TEntryPos& aEntryPos)
 	{
 	__PRINT2(_L("CScanDrive::AddMatchingEntryL cluster=%d pos=%d"),aEntryPos.iCluster,aEntryPos.iPos);
-	__ASSERT_ALWAYS(iMatching.iStartCluster>0 && iMatching.iCount<KMaxMatchingEntries,User::Leave(KErrCorrupt));
+	
+    if(iMatching.iStartCluster <= 0 || iMatching.iCount >= KMaxMatchingEntries)
+        {
+        __PRINT(_L("CScanDrive::AddMatchingEntryL #1"));
+        User::Leave(KErrCorrupt);
+        }
+
+
 	iMatching.iEntries[iMatching.iCount++]=aEntryPos;
 	return iMatching.iCount==KMaxMatchingEntries;
 	}
@@ -886,10 +959,13 @@
 	if(!IsDosEntry(entry))
 		{
 		TInt toMove=entry.NumFollowing();
+		
 		while(toMove--)
 			MoveToNextEntryL(aVFatPos);
+		
 		ReadDirEntryL(aVFatPos,entry);
 		}
+	
 	return(entry.RuggedFatEntryId());
 	}
 
@@ -916,15 +992,24 @@
 	{
 	
     __PRINT1(_L("CScanDrive::FixMatchingEntryL() start cluster=%d"),iMatching.iStartCluster);
-	__ASSERT_ALWAYS(iMatching.iCount==KMaxMatchingEntries,User::Leave(KErrCorrupt));
+	
+    if(iMatching.iCount != KMaxMatchingEntries)
+        {
+        __PRINT1(_L("CScanDrive::FixMatchingEntryL() #1 %d"), iMatching.iCount);            
+        User::Leave(KErrCorrupt);
+        }
+
 	ASSERT(!CheckDiskMode());
 
-    TInt idOne=GetReservedidL(iMatching.iEntries[0]);
-	TInt idTwo=GetReservedidL(iMatching.iEntries[1]);
+    const TInt idOne=GetReservedidL(iMatching.iEntries[0]);
+	const TInt idTwo=GetReservedidL(iMatching.iEntries[1]);
 	TFatDirEntry entry;
-	TInt num=idOne>idTwo?0:1;
+	
+    const TInt num = idOne>idTwo ? 0:1;
 	ReadDirEntryL(iMatching.iEntries[num],entry);
+
 	iMount->EraseDirEntryL(iMatching.iEntries[num],entry);
+    
     IndicateErrorsFound(EScanDriveDirError); //-- indicate that we have found errors
 	}
 
@@ -964,6 +1049,7 @@
 
 	if(iClusterListArray[iListArrayIndex]==NULL)
 		iClusterListArray[iListArrayIndex]=new(ELeave) RArray<TInt>(KClusterListGranularity);
+
 	iClusterListArray[iListArrayIndex]->Append(aCluster);
 	}
 
@@ -1111,6 +1197,7 @@
 	{
 	if(aClusterNum < KFatFirstSearchCluster || aClusterNum >= MaxClusters())
         {
+        __PRINT1(_L("CScanDrive::ReadFatL() bad cluster:%d\n"),aClusterNum);
         IndicateErrorsFound(EBadClusterNumber);
         User::Leave(KErrCorrupt);
         }
@@ -1129,6 +1216,7 @@
 	{
 	if(aClusterNum < KFatFirstSearchCluster || aClusterNum >= MaxClusters())
         {
+        __PRINT1(_L("CScanDrive::MarkClusterUsedL() bad cluster:%d\n"),aClusterNum);
         IndicateErrorsFound(EBadClusterNumber);
         User::Leave(KErrCorrupt);
         }
@@ -1145,6 +1233,7 @@
 	{
 	if(aClusterNum < KFatFirstSearchCluster || aClusterNum >= MaxClusters())
         {
+        __PRINT1(_L("CScanDrive::IsClusterUsedL() bad cluster:%d\n"),aClusterNum);
         IndicateErrorsFound(EBadClusterNumber);
         User::Leave(KErrCorrupt);
         }
--- a/userlibandfileserver/fileserver/sfat32/sl_utl.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/userlibandfileserver/fileserver/sfat32/sl_utl.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -117,23 +117,16 @@
 	return result;
 	}
 
-TInt NumberOfVFatEntries(TInt aNameLength)
-//
-// Return the number of VFat entries required to describe a filename of length aNameLength
-//
+/**
+    @param  aNameLength file name length
+    @return the number of VFat entries required to describe a filename of length aNameLength
+*/
+TUint NumberOfVFatEntries(TUint aNameLength)
 	{
-	TInt numberOfEntries=0;
-	if (aNameLength%KMaxVFatEntryName)
-		aNameLength++;	//	Include a zero terminator
-//	If aNameLength is a exact multiple of KMaxVFatEntryName, don't bother
-//	with a zero terminator - it just adds an unnecessary directory entry		
-	
-	numberOfEntries=(1+(aNameLength/KMaxVFatEntryName));	
-	
-	if (aNameLength%KMaxVFatEntryName)
-		numberOfEntries++;
-	
-	return(numberOfEntries);
+    ASSERT(aNameLength);
+    //-- 1 compulsory DOS entry included
+    const TUint numberOfEntries=1+(aNameLength + KMaxVFatEntryName - 1) / KMaxVFatEntryName;	
+	return numberOfEntries;
 	}
 
 //-----------------------------------------------------------------------------
--- a/userlibandfileserver/fileserver/sfat32/sl_vfat.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/userlibandfileserver/fileserver/sfat32/sl_vfat.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -30,10 +30,14 @@
 const TUint KExtendedCharStart=0x80;
 const TUint KExtendedCharEnd=0xff;
 
-LOCAL_C TBool IsLegalChar(TChar aCharacter,TBool aAllowWildChars,TBool aUseExtendedChars=EFalse,TBool aInScanDrive=EFalse)
-//
-// Returns ETrue if aCharacter is legal inside a dos filename
-//
+const TUint KMaxVFatEntries = 21; ///< Max possible number of entries in the VFAT entryset
+
+
+//-----------------------------------------------------------------------------
+/**
+    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 +50,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 +59,8 @@
 		}
 	}
 
-LOCAL_C void ReplaceIllegalCharactersL(TDes& aLongName, TUint aCharacterToReplaceWith)
+//-----------------------------------------------------------------------------
+static void ReplaceIllegalCharactersL(TDes& aLongName, TUint aCharacterToReplaceWith)
 	{
 	TBool alreadyFoundExtensionDelimiter=EFalse;
 
@@ -130,10 +136,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 +266,7 @@
 	return shortName;
 	}
 
-
+//-----------------------------------------------------------------------------
 /**
 Check whether a Dos name is legal or not.
 
@@ -271,7 +278,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 +394,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 +402,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 +436,27 @@
 	return EFalse;
 	}
 	
-TBool CFatMountCB::IsUniqueNameL(const TShortName& aName,TInt aDirCluster)
-//
-// Returns ETrue if aName is unique, EFalse if a matching name is found.
-//
+//-----------------------------------------------------------------------------
+/**
+    Returns ETrue if aName is unique, EFalse if a matching name is found.
+*/
+TBool CFatMountCB::IsUniqueNameL(const TShortName& aName, TUint32 aDirCluster)
 	{
 
-	__PRINT(_L("VFAT::CFatMountCB::IsUniqueNameL"));	
+	__PRINT(_L("CFatMountCB::IsUniqueNameL"));	
 	TEntryPos entryPos(aDirCluster,0);
-	if (FindShortNameL(aName,entryPos))
-		return(EFalse);
-	return(ETrue);
+	return ! FindShortNameL(aName,entryPos);
 	}
 
+//-----------------------------------------------------------------------------
+/**
+    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 +477,21 @@
 		}
 	}
 
-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.
-//
+/**
+    Generate a legal dos filename as an alias for aName.
+    @return ETrue if aName is a legal dos name.
+*/
+TBool CFatMountCB::GenerateShortNameL(TUint32 aDirCluster,const TDesC& aName,TShortName& aGeneratedName, TBool aForceRandomize)
 	{
 
-	__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 +561,316 @@
 
 	}
 
-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)
 	{
+    //-- LFN in the last entry must be padded with FFs
+    Mem::Fill(iData,sizeof(iData),0xFF);
 
-	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;
+
+        TUint nRemLen = KMaxVFatEntryName*(numEntries-1);
+
+        while(numEntries)
+            {
+            TFatDirEntry* pEntry = (TFatDirEntry*)(&scratchBuf[posInBuf]);
+            
+            pEntry->SetVFatEntry(aLongName, nRemLen, cksum);  
+
+            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
+            
+            ASSERT(nRemLen >= (TUint)KMaxVFatEntryName);
+            nRemLen -= KMaxVFatEntryName;
+            }
+    
+        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 +881,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 +897,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	Tue Feb 02 01:24:03 2010 +0200
+++ b/userlibandfileserver/fileserver/sfile/sf_dat.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -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	Tue Feb 02 01:24:03 2010 +0200
+++ b/userlibandfileserver/fileserver/sfile/sf_debug.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -450,8 +450,15 @@
 			TIOCacheValues cacheValues;
 			cacheValues.iCloseCount= RequestAllocator::CloseCount();
 			cacheValues.iFreeCount= RequestAllocator::FreeCount();
-			cacheValues.iAllocated=	RequestAllocator::AllocatedCount();
-			cacheValues.iTotalCount= RequestAllocator::TotalCount();
+			cacheValues.iAllocated=	0;	// no longer used
+			cacheValues.iTotalCount= RequestAllocator::RequestCount();
+			cacheValues.iRequestCountPeak = RequestAllocator::RequestCountPeak();
+
+			cacheValues.iOpFreeCount= OperationAllocator::FreeCount();
+			cacheValues.iOpRequestCount= OperationAllocator::RequestCount();
+			cacheValues.iOpRequestCountPeak = OperationAllocator::RequestCountPeak();
+
+
 			TPckgBuf<TIOCacheValues> pkgBuf(cacheValues);
 
 			// ensure we only write what the client buffer can hold -
@@ -579,6 +586,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_ext.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/userlibandfileserver/fileserver/sfile/sf_ext.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -226,14 +226,14 @@
 /** Create drive
 	Ascertain if the drive is mapped to a local drive or a proxy drive, and create the drive
 	as appropriate
-	@param aDriveNumer drive number
-	@return KErrNone on success
-		     KErrArgument is the drive is not mapped to a proxy or a local drive or if the number
-		     is invalid
+	@param	aDriveNumber	drive number
+	@return	KErrNone		on success
+			KErrArgument	if the drive is not mapped to a proxy or a local drive or if the number
+							is invalid
 */
 	{
 	// dunno why we are using TInts instead of TUints here
-	__PRINT(_L("CLocDrvMountCB::CreateLocalDrive()"));
+	__PRINT(_L("CLocDrvMountCB::CreateDrive()"));
 
 	if (aDriveNumber<0 || aDriveNumber>=KMaxDrives) return KErrArgument;
 	TInt r = KErrNone;
@@ -246,10 +246,10 @@
 	else
 		{
 		CExtProxyDrive* pProxyDrive = LocalDrives::GetProxyDrive(aDriveNumber);
-		__ASSERT_ALWAYS(pProxyDrive != NULL,User::Panic(_L("CreateDrive - pProxyDrive == NULL"), -999));
+		__ASSERT_ALWAYS(pProxyDrive != NULL,User::Panic(_L("CreateDrive() - pProxyDrive == NULL"), -999));
 
-		iProxyDrive = CreateProxyDriveL(pProxyDrive, this);
-		__ASSERT_ALWAYS(iProxyDrive != NULL,User::Panic(_L("CreateDrive - CreateProxyDrive returned NULL"), -999));
+		TRAP(r, iProxyDrive = CreateProxyDriveL(pProxyDrive,this));
+		__ASSERT_ALWAYS(r == KErrNone,User::Panic(_L("CreateDrive() - CreateProxyDriveL error"), -999));
 
 		r = InitLocalDrive();
 		}
--- a/userlibandfileserver/fileserver/sfile/sf_file.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/userlibandfileserver/fileserver/sfile/sf_file.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -462,13 +462,24 @@
 
 	__PRINT(_L("TFsIsFileOpen::DoRequestL(CFsRequest* aRequest)"));
 	CFileCB* file;
-	TInt r=aRequest->Drive()->IsFileOpen(aRequest->Src().FullName().Mid(2),file);
-	if (r!=KErrNone)
-		return(r);
-	TBool isOpen = file?(TBool)ETrue:(TBool)EFalse;
+	TInt r = aRequest->Drive()->IsFileOpen(aRequest->Src().FullName().Mid(2), file);
+	if (r != KErrNone)
+		return (r);
+	TBool isOpen = file ? (TBool)ETrue : (TBool)EFalse;
+	if (!isOpen)
+		{
+		// perform the existance check to retain compatibility with old-style clients
+		TEntry e;
+		r = aRequest->Drive()->Entry(aRequest->Src().FullName().Mid(2), e);
+		if (r == KErrNone && e.IsDir())
+			r = KErrArgument;
+		}
+	if (r != KErrNone)
+		return (r);
+
 	TPtrC8 pA((TUint8*)&isOpen,sizeof(TBool));
 	aRequest->WriteL(KMsgPtr1,pA);
-	return(KErrNone);
+	return (KErrNone);
 	}
 
 TInt TFsIsFileOpen::Initialise(CFsRequest* aRequest)
--- a/userlibandfileserver/fileserver/sfile/sf_file_cache_defs.h	Tue Feb 02 01:24:03 2010 +0200
+++ b/userlibandfileserver/fileserver/sfile/sf_file_cache_defs.h	Fri Apr 16 16:24:37 2010 +0300
@@ -26,7 +26,12 @@
 
 // Global file-cache settings 
 const TBool KDefaultGlobalCacheEnabled			= ETrue; 
+#ifdef __WINS__
+// Reduce impact on S60 emulator memory budget
+const TInt KDefaultGlobalCacheSize				= ( 8*1024);	//  8192 K =  8 MBytes - the maximum for all files
+#else
 const TInt KDefaultGlobalCacheSize				= (32*1024);	// 32768 K = 32 MBytes - the maximum for all files
+#endif
 // The maximum amount of locked data allowed for all files
 const TInt KDefaultGlobalCacheMaxLockedSize	= (1*1024);		// 1 Mb maximum locked data
 // Low memory threshold as a percentage of total RAM.
--- a/userlibandfileserver/fileserver/sfile/sf_lepoc.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/userlibandfileserver/fileserver/sfile/sf_lepoc.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -202,14 +202,33 @@
 #ifdef _DEBUG
 	__IF_DEBUG(Printf("processed reloc table (size=%d,pageCount=%d)", iCodeRelocTableSize, pageCount));
 
-	// dump the import fixup table if loader tracing enabled
-	const TUint16* table16 = (const TUint16*)table;
-	const TInt halfWordsInTable = iCodeRelocTableSize / 2;
-	for(i = 0; i < halfWordsInTable; i += 4)
+	// Dump the processed reloc table if loader tracing enabled. The dump is in
+	// two parts; first, the page indexes (1 word per page), then the entries
+	// describing the items to be relocated on each of these pages, formatted
+	// with up to 8 entries per line but starting a new line for each page.
+	// Each of these entries has the relocation type in the first nibble, and
+	// the offset within the page in the remaining 3 nibbles.
+	const TUint32* table32 = (const TUint32*)table;
+	for (i = 0; i <= pageCount; ++i)
+		__IF_DEBUG(Printf("%04x: %08x", i*4, table32[i]));
+
+	for (i = 0; i < pageCount; ++i)
 		{
-		__IF_DEBUG(Printf(
-			"reloc %04x: %04x %04x %04x %04x",
-			i * 2, table16[i+0], table16[i+1], table16[i+2], table16[i+3]));
+		TUint start = table32[i];
+		TInt nbytes = table32[i+1] - start;
+		while (nbytes)
+			{
+			TBuf8<0x100> buf;
+			buf.Format(_L8("%04x:"), start);
+
+			const TUint16* p = (const TUint16*)(table+start);
+			TInt n = nbytes <= 16 ? nbytes : 16;
+			for (nbytes -= n, start += n; n > 0; n -= 2)
+				buf.AppendFormat(_L8(" %04x"), *p++);
+
+			buf.AppendFormat(_L8("\r\n"));
+			__IF_DEBUG(RawPrint(buf));
+			}
 		}
 #endif
 	return KErrNone;
@@ -268,6 +287,18 @@
 		}
 	}
 
+// A version that will work in user or supervisor mode
+void MyPrintf(const char* aFmt, ...)
+	{
+	VA_LIST list;
+	VA_START(list, aFmt);
+	TPtrC8 fmt((const TText8*)aFmt);
+	TBuf8<0x100> buf;
+	buf.AppendFormatList(fmt, list);
+	buf.AppendFormat(_L8("\r\n"));
+	RDebug::RawPrint(buf);
+	VA_END(list);
+	}
 
 /**
 Arguments for svRelocateSection.
@@ -340,29 +371,80 @@
 
 /**
 Fix up the export directory
-Only performed on PE images.  ELF image's exports are marked
-as relocatable and therefore relocated by svRelocateSection when the 
-text section is relocated up
+Only performed on PE images.  ELF image's exports are marked as relocatable
+and therefore relocated by svRelocateSection along with the text section
 */
 TInt svRelocateExports(TAny* aPtr)
 	{
-	E32Image* pI=(E32Image*)aPtr;
-	TUint32* destExport=(TUint32*)pI->iExportDirLoad;
-	TInt i=pI->iExportDirCount;
-	TUint32 codeBase=pI->iCodeRunAddress;
-	while (i-->0)
-		*destExport+++=codeBase;
+	E32Image& exporter = *(E32Image*)aPtr;
+
+	// Dump everything potentially useful that we know about the exporter ...
+	__LDRTRACE(MyPrintf("RelocateExports: paged? %d, iRomImageHeader@%08x, iHeader@%08x",
+						exporter.iUseCodePaging, exporter.iRomImageHeader, exporter.iHeader));
+	__LDRTRACE(MyPrintf("  iCodeLoadAddress %08x, iCodeRunAddress %08x, iCodeSize %x iTextSize %x",
+						exporter.iCodeLoadAddress, exporter.iCodeRunAddress,
+						exporter.iCodeSize, exporter.iTextSize))
+	__LDRTRACE(MyPrintf("  iDataLoadAddress %08x, iDataRunAddress %08x, iDataSize %x iBssSize %x iTotalDataSize %x",
+						exporter.iDataLoadAddress, exporter.iDataRunAddress,
+						exporter.iDataSize, exporter.iBssSize, exporter.iTotalDataSize));
+	__LDRTRACE(MyPrintf("  iCodeDelta, %x iDataDelta %x, iExportDirEntryDelta %x",
+						exporter.iCodeDelta, exporter.iDataDelta, exporter.iExportDirEntryDelta));
+
+	// It turns out that very little of the exporter info is useful! For
+	// example, the required code and data deltas are NOT those provided
+	// by the exporter, nor are the load addresses relevant ... :(
+	//
+	// In the case of a PE-derived image, the entries in the export table
+	// are expressed in terms of offsets into the image file, rather than
+	// locations in memory. Each therefore needs to be relocated by the
+	// difference between its file offset and its run address.
+	//
+	// It is assumed that the code segment appears before the data segment
+	// in the file; therefore, export table entries with values between 0
+	// and (exporter.iCodeSize) refer to the text segment, while higher
+	// values represent references to data addresses. Since the run addresses
+	// of code and data segments may be different, each type of export must
+	// be relocated with respect to the correct section.
+	//
+	// The following express the start and finish of each section in terms of
+	// file offsets and then derive the required adjustments to the entries
+	// in the export table ...
+	TUint32 codeStart = 0;							// compiler whinges if this is 'const' :(
+	const TUint32 codeFinish = codeStart + exporter.iCodeSize;
+	const TUint32 dataStart = codeFinish;
+	const TUint32 dataFinish = dataStart + exporter.iTotalDataSize;
+	const TUint32 codeDelta = exporter.iCodeRunAddress - codeStart;
+	const TUint32 dataDelta = exporter.iDataRunAddress - dataStart;
+
+	TUint32* destExport = (TUint32*)exporter.iExportDirLoad;
+	for (TInt i = exporter.iExportDirCount; --i >= 0; )
+		{
+		TUint32 relocAddr = *destExport;
+		TUint32 newValue;
+		if (relocAddr >= codeStart && relocAddr < codeFinish)
+			newValue = relocAddr + codeDelta;		// points to text/rdata section
+		else if (relocAddr >= dataStart && relocAddr < dataFinish)
+			newValue = relocAddr + dataDelta;		// points to data/bss section
+		else
+			newValue = relocAddr;					// unknown - just leave it alone
+		*destExport++ = newValue;
+
+		__LDRTRACE(MyPrintf("RelocateExports: export %d %08x => %08x %c",
+							exporter.iExportDirCount-i, relocAddr, newValue,
+							(relocAddr >= codeStart && relocAddr < codeFinish) ? 'C' :
+							(relocAddr >= dataStart && relocAddr < dataFinish) ? 'D' : 'X'));
+		}
+
 	return 0;
 	}
 
 
 struct SFixupImportAddressesInfo
 	{
-	TUint32* iIat;
-	TUint32* iExportDir;
-	TUint32 iExportDirEntryDelta;
-	TInt iNumImports;
-	E32Image* iExporter;
+	TUint32* iIat;					// Next part of IAT to be fixed up
+	E32Image* iExporter;			// Module from which we're importing
+	TInt iNumImports;				// Number of imports from this exporter
+
 	/**
 	For demand paging, this points to the buffer which is populated
 	so each page can be fixed up as it is loaded in.
@@ -378,52 +460,104 @@
 Fix up the import address table, used for 'PE derived' executables.
 @param aPtr Pointer to function arguments (SFixupImportAddressesInfo structure).
 			SFixupImportAddressesInfo::iIat is updated by this function.
+
+For a given importer, this function will be called once for each image from which
+objects are imported, and each time it will update the relevant portion of the
+importer's IAT, until all imports from all exporters have been processed.
 */
 TInt svFixupImportAddresses(TAny* aPtr)
 	{
 	SFixupImportAddressesInfo& info = *(SFixupImportAddressesInfo*)aPtr;
-
-	TUint32 maxOrdinal = (TUint32)info.iExporter->iExportDirCount;
-	TUint32 absentOrdinal = (TUint32)info.iExporter->iFileEntryPoint;
-
-	TUint32* exp_dir = info.iExportDir - KOrdinalBase; // address of 0th ordinal
-	TUint32 exp_delta = info.iExportDirEntryDelta;
+	E32Image& exporter = *info.iExporter;
+
+#ifdef _DEBUG
+	__LDRTRACE(MyPrintf(">svFixupImportAddresses %d imports, code@%08x, fixup@%08x exporter@%08x",
+						info.iNumImports, info.iCodeLoadAddress, info.iFixup64, info.iExporter));
+
+	// Dump everything potentially useful that we know about the exporter ...
+	__LDRTRACE(MyPrintf("%S: paged? %d, iRomImageHeader@%08x, iHeader@%08x",
+						&exporter.iFileName, exporter.iUseCodePaging,
+						exporter.iRomImageHeader, exporter.iHeader));
+	__LDRTRACE(MyPrintf("iCodeLoadAddress %08x, iCodeRunAddress %08x, iCodeSize %x iTextSize %x",
+						exporter.iCodeLoadAddress, exporter.iCodeRunAddress,
+						exporter.iCodeSize, exporter.iTextSize))
+	__LDRTRACE(MyPrintf("iDataLoadAddress %08x, iDataRunAddress %08x, iDataSize %x iBssSize %x iTotalDataSize %x",
+						exporter.iDataLoadAddress, exporter.iDataRunAddress,
+						exporter.iDataSize, exporter.iBssSize, exporter.iTotalDataSize));
+	__LDRTRACE(MyPrintf("iCodeDelta, %x iDataDelta %x, iExportDirEntryDelta %x",
+						exporter.iCodeDelta, exporter.iDataDelta, exporter.iExportDirEntryDelta));
+
+	if (exporter.iRomImageHeader)
+		{
+		const TRomImageHeader& rh = *exporter.iRomImageHeader;
+		__LDRTRACE(MyPrintf("ROM: iCodeAddress %08x, iCodeSize %x, iTextSize %x",
+							rh.iCodeAddress, rh.iCodeSize, rh.iTextSize));
+		__LDRTRACE(MyPrintf("ROM: iDataAddress %08x, iDataSize %x, iBssSize %x",
+							rh.iDataAddress, rh.iDataSize, rh.iBssSize));
+		__LDRTRACE(MyPrintf("ROM: iDataBssLinearBase %08x, iTotalDataSize %x",
+							rh.iDataBssLinearBase, rh.iTotalDataSize));
+		}
+
+	if (exporter.iHeader)
+		{
+		const E32ImageHeader& ih = *exporter.iHeader;
+		__LDRTRACE(MyPrintf("HEAD: iCodeBase %08x, iCodeSize %x, iTextSize %x",
+							ih.iCodeBase, ih.iCodeSize, ih.iTextSize));
+		__LDRTRACE(MyPrintf("HEAD: iDataBase %08x, iDataSize %x, iBssSize %x",
+							ih.iDataBase, ih.iDataSize, ih.iBssSize));
+		}
+#endif // _DEBUG
+
+	// 'exportDir' points to the address of the 0th ordinal (symbol name data);
+	// ordinary exports start from ordinal 1
+	const TUint32* const exportDir = (TUint32*)exporter.iExportDirLoad - KOrdinalBase;
+	const TUint32 maxOrdinal = (TUint32)exporter.iExportDirCount;
+	const TUint32 absentOrdinal = (TUint32)exporter.iFileEntryPoint;
 
 	TUint32* iat = info.iIat;
-	TUint32* iatE = iat+info.iNumImports;
-	for(; iat<iatE; ++iat)
+	TUint32* const iatEnd = iat + info.iNumImports;
+	for (; iat < iatEnd; ++iat)
 		{
-		TUint32 imp = *iat;
-		if(imp>maxOrdinal)
+		// Each IAT slot contains the ordinal number of the export to be imported from
+		// the exporter. We use that index to locate the address of the export itself.
+		TUint32 ordinal = *iat;
+		if (ordinal > maxOrdinal)
 			return KErrNotSupported;
 
-		TUint32 writeValue;
-		if(imp==0 && !(info.iExporter->iAttr&ECodeSegAttNmdExpData))
-			{
-			// attempt to import ordinal zero (symbol name data) from an executable
-			// which doesn't export this information, use NULL for imported value in this case...
-			writeValue = NULL;
-			}
-		else
+		// If the import number is 0 (symbol name data), and the exporter doesn't provide
+		// this, we don't regard it as an error; we just skip this block, leaving the
+		// address set to 0. For all other valid cases, we index the export directory to
+		// find the exported object's address (which has already been relocated) ...
+		TUint32 newValue = 0;
+		if (ordinal > 0 || (exporter.iAttr & ECodeSegAttNmdExpData))
 			{
-			// get imported value from exporter...
-			TUint32 exp_addr = exp_dir[imp];
-			if(exp_addr==0 || exp_addr==absentOrdinal)
+			TUint32 expAddr = exportDir[ordinal];
+			if (expAddr == 0 || expAddr == absentOrdinal)
 				return KErrNotSupported;
-			writeValue = exp_addr + exp_delta;
+			// The new value is just the address of the export, no adjustment needed
+			newValue = expAddr;
 			}
 
-		// if not code paging then directly fix up the import...
-		if (info.iFixup64 == 0)
-			*iat = writeValue;
+		__LDRTRACE(MyPrintf("svFixupImportAddresses: import[%d]@%08x is export[%d] == %08x",
+							iat - info.iIat, iat, ordinal, newValue));
+
+		// In non-paged code, we can simply replace the ordinals in the IAT with the
+		// object addresses to which they refer once and for all. However, in a code
+		// paging system, the IAT may be thrown away and later reloaded from the code
+		// image; therefore, we need to save the updates in the buffer pointed to by
+		// 'iFixup64' so that they can be reapplied each time the code page(s)
+		// containing (parts of the) IAT are reloaded. The fixup entries are in the
+		// form of 64-bit words, with the 32-bit address-to-be-fixed-up in the upper
+		// half and the value-to-be-stored-there in the lower half -- the multiple
+		// casts are needed to stop some compilers whinging about converting a
+		// pointer to a 64-bit integral type :(
+		if (!info.iFixup64)
+			*iat = newValue;
 		else
-		// ...otherwise defer until the page is fixed up
-			{
-			TUint64 iat64 = reinterpret_cast<TUint64>(iat);
-			*info.iFixup64++ = (iat64 << 32) | writeValue;
-			}
+			*info.iFixup64++ = ((TUint64)(TUintPtr)iat << 32) | newValue;
 		}
 
+	// Finally, update 'info.iIat' to show which imports have been processed
 	info.iIat = iat;
 	return KErrNone;
 	}
@@ -436,50 +570,155 @@
 TInt svElfDerivedFixupImportAddresses(TAny* aPtr)
 	{
 	SFixupImportAddressesInfo& info = *(SFixupImportAddressesInfo*)aPtr;
-	TUint32 maxOrdinal = (TUint32)info.iExporter->iExportDirCount;
-	TUint32 absentOrdinal = (TUint32)info.iExporter->iFileEntryPoint;
-
-	TUint32* exp_dir = info.iExportDir - KOrdinalBase; // address of 0th ordinal
-	TUint32 exp_delta = info.iExportDirEntryDelta;
-	TUint32 code = info.iCodeLoadAddress;
+	E32Image& exporter = *info.iExporter;
+
+#ifdef _DEBUG
+	__LDRTRACE(MyPrintf(">svElfDerivedFixupImportAddresses %d imports, code@%08x, fixup@%08x exporter@%08x",
+						info.iNumImports, info.iCodeLoadAddress, info.iFixup64, info.iExporter));
+
+	// Dump everything potentially useful that we know about the exporter ...
+	__LDRTRACE(MyPrintf("%S: paged? %d, iRomImageHeader@%08x, iHeader@%08x",
+						&exporter.iFileName, exporter.iUseCodePaging,
+						exporter.iRomImageHeader, exporter.iHeader));
+	__LDRTRACE(MyPrintf("iCodeLoadAddress %08x, iCodeRunAddress %08x, iCodeSize %x iTextSize %x",
+						exporter.iCodeLoadAddress, exporter.iCodeRunAddress,
+						exporter.iCodeSize, exporter.iTextSize))
+	__LDRTRACE(MyPrintf("iDataLoadAddress %08x, iDataRunAddress %08x, iDataSize %x iBssSize %x iTotalDataSize %x",
+						exporter.iDataLoadAddress, exporter.iDataRunAddress,
+						exporter.iDataSize, exporter.iBssSize, exporter.iTotalDataSize));
+	__LDRTRACE(MyPrintf("iCodeDelta, %x iDataDelta %x, iExportDirEntryDelta %x",
+						exporter.iCodeDelta, exporter.iDataDelta, exporter.iExportDirEntryDelta));
+
+	if (exporter.iRomImageHeader)
+		{
+		const TRomImageHeader& rh = *exporter.iRomImageHeader;
+		__LDRTRACE(MyPrintf("ROM: iCodeAddress %08x, iCodeSize %x, iTextSize %x",
+							rh.iCodeAddress, rh.iCodeSize, rh.iTextSize));
+		__LDRTRACE(MyPrintf("ROM: iDataAddress %08x, iDataSize %x, iBssSize %x",
+							rh.iDataAddress, rh.iDataSize, rh.iBssSize));
+		__LDRTRACE(MyPrintf("ROM: iDataBssLinearBase %08x, iTotalDataSize %x",
+							rh.iDataBssLinearBase, rh.iTotalDataSize));
+		}
+
+	if (exporter.iHeader)
+		{
+		const E32ImageHeader& ih = *exporter.iHeader;
+		__LDRTRACE(MyPrintf("HEAD: iCodeBase %08x, iCodeSize %x, iTextSize %x",
+							ih.iCodeBase, ih.iCodeSize, ih.iTextSize));
+		__LDRTRACE(MyPrintf("HEAD: iDataBase %08x, iDataSize %x, iBssSize %x",
+							ih.iDataBase, ih.iDataSize, ih.iBssSize));
+		}
+#endif // _DEBUG
+
+	// Here we calculate the bounds of each section of the exporter, as
+	// code and data exports may have to be offset by different amounts.
+	// Unfortunately, the required information seems to be in several
+	// different places, depending on whether the code is ROM or RAM, etc
+	TUint32 codeStart = exporter.iCodeRunAddress;
+	TUint32 codeEnd = codeStart + exporter.iCodeSize;
+	TUint32 dataStart = exporter.iDataRunAddress;
+	TUint32 dataEnd = dataStart + exporter.iTotalDataSize;
+
+	if (exporter.iRomImageHeader)
+		{
+		const TRomImageHeader& rh = *exporter.iRomImageHeader;
+		codeStart = rh.iCodeAddress;
+		codeEnd = codeStart + rh.iCodeSize;
+		dataStart = rh.iDataBssLinearBase;
+		dataEnd = dataStart + rh.iTotalDataSize;
+		}
+
+	if (exporter.iHeader)
+		{
+		const E32ImageHeader& ih = *exporter.iHeader;
+		codeStart = ih.iCodeBase;
+		codeEnd = codeStart + ih.iCodeSize;
+		dataStart = ih.iDataBase;
+		dataEnd = dataStart + ih.iDataSize + ih.iBssSize;
+		}
+
+	// 'exportDir' points to the address of the 0th ordinal (symbol name data);
+	// ordinary exports start from ordinal 1
+	const TUint32* const exportDir = (TUint32*)exporter.iExportDirLoad - KOrdinalBase;
+	const TUint32 maxOrdinal = (TUint32)exporter.iExportDirCount;
+	const TUint32 absentOrdinal = (TUint32)exporter.iFileEntryPoint;
+
+	const TUint32 codeDelta = exporter.iCodeDelta;
+	const TUint32 dataDelta = exporter.iDataDelta;
+	const TUint32 dirDelta = exporter.iExportDirEntryDelta;
+	TUint8* const codeBase = (TUint8*)info.iCodeLoadAddress;
 
 	TUint32* iol = info.iImportOffsetList;
-	TUint32* iolE = iol+info.iNumImports;
-	for(; iol<iolE; ++iol)
+	TUint32* const iolEnd = iol + info.iNumImports;
+	for(; iol < iolEnd; ++iol)
 		{
-		TUint32* impPtr = (TUint32*)(code+*iol);
-		TUint32 impd = *impPtr;
-		TUint32 imp = impd & 0xffff;
-		TUint32 offset = impd >> 16;
-		if(imp>maxOrdinal)
+		// Whereas the PE format's IAT contains ordinals to be imported, the ELF IOL
+		// (Import Offset List) is a list of offsets (within the importer's code) of
+		// the locations that contain references to imported objects.
+		//
+		// At the start of this process, each such location contains a composite value,
+		// of which the low 16 bits indicate the ordinal to be imported from the
+		// exporter's directory, and the upper 16 provide an optional adjustment to
+		// be added to the imported value.
+		//
+		// This composite value has to be replaced by the actual address of the
+		// object being imported (plus the adjustment factor, if any).
+		TUint32 codeOffset = *iol;
+		TUint32* codePtr = (TUint32*)(codeBase+codeOffset);
+		TUint32 importInfo = *codePtr;
+		TUint32 ordinal = importInfo & 0xffff;
+		TUint32 adjustment = importInfo >> 16;
+		if(ordinal > maxOrdinal)
 			return KErrNotSupported;
 
-		TUint32 writeValue;
-		if(imp==0 && !(info.iExporter->iAttr&ECodeSegAttNmdExpData))
+		// If the import number is 0 (symbol name data), and the exporter doesn't provide
+		// this, we don't regard it as an error; we just skip this block, leaving the
+		// address set to 0. For all other valid cases, we index the export directory to find
+		// the exported object's address (which may OR MAY NOT have already been relocated)
+		TUint32 expAddr = 0;
+		TUint32 newValue = 0;
+		if (ordinal > 0 || (exporter.iAttr & ECodeSegAttNmdExpData))
 			{
-			// attempt to import ordinal zero (symbol name data) from an executable
-			// which doesn't export this information, use NULL for imported value in this case...
-			writeValue = NULL;
+			expAddr = exportDir[ordinal];
+			if(expAddr == 0 || expAddr == absentOrdinal)
+				return KErrNotSupported;
+
+			// If the exporter does not use code paging, then the entries in the export
+			// table will already have been relocated along with its text section. In
+			// the paged case, however, the relocation will have been deferred until the
+			// relevant pages are (re)loaded; therefore, we have to deduce here whether
+			// each export is code or data so that we can apply the correct delta ...
+			TUint32 sectionDelta;
+			if (!exporter.iUseCodePaging)
+				sectionDelta = dirDelta;
+			else if (expAddr >= codeStart && expAddr < codeEnd)
+				sectionDelta = codeDelta;			// points to text/rdata section
+			else if (expAddr >= dataStart && expAddr < dataEnd)
+				sectionDelta = dataDelta;			// points to data/bss section
+			else
+				sectionDelta = dirDelta;			// unknown - assume nonpaged?
+			newValue = expAddr + sectionDelta + adjustment;
 			}
+
+		__LDRTRACE(MyPrintf("svElfDerivedFixupImportAddresses: import[%d] (%08x:%08x) is export[%d] %08x+%08x => %08x",
+							iol - info.iImportOffsetList, codePtr, importInfo, ordinal, expAddr, adjustment, newValue));
+
+		// In non-paged code, we can simply replace the ordinals in the IAT with the
+		// object addresses to which they refer once and for all. However, in a code
+		// paging system, the IAT may be thrown away and later reloaded from the code
+		// image; therefore, we need to save the updates in the buffer pointed to by
+		// 'iFixup64' so that they can be reapplied each time the code page(s)
+		// containing (parts of the) IAT are reloaded. The fixup entries are in the
+		// form of 64-bit words, with the 32-bit address-to-be-fixed-up in the upper
+		// half and the value-to-be-stored-there in the lower half -- the multiple
+		// casts are needed to stop some compilers whinging about converting a
+		// pointer to a 64-bit integral type :(
+		if (!info.iFixup64)
+			*codePtr = newValue;
 		else
-			{
-			// get imported value from exporter...
-			TUint32 exp_addr = exp_dir[imp];
-			if(exp_addr==0 || exp_addr==absentOrdinal)
-				return KErrNotSupported;
-			writeValue = exp_addr + exp_delta + offset;
-			}
-
-		// if not code paging then directly fix up the import...
-		if (info.iFixup64 == 0)
-			*impPtr = writeValue;
-		// ...otherwise defer until the page is fixed up
-		else
-			{
-			TUint64 impPtr64 = reinterpret_cast<TUint64>(impPtr);
-			*info.iFixup64++ = (impPtr64 << 32) | writeValue;
-			}
+			*info.iFixup64++ = ((TUint64)(TUintPtr)codePtr << 32) | newValue;
 		}
+
 	return KErrNone;
 	}
 
@@ -2834,8 +3073,9 @@
 			//	on "new" dlls
 			if (e->iDepCount && !e->iAlreadyLoaded && e->iIsDll)
 				{
-				__IF_DEBUG(Printf("****Go recursive****"));
+				__IF_DEBUG(Printf("****Going recursive****"));
 				r = e->LoadDlls(aArray);
+				__IF_DEBUG(Printf("****Returned from recursion****"));
 				if (r!=KErrNone)
 					{
 					return r;
@@ -2956,8 +3196,6 @@
 			r = exp->ReadExportDirLoad();
 			if (r != KErrNone)
 				return r;
-			info.iExportDir = (TUint32*)exp->iExportDirLoad;
-			info.iExportDirEntryDelta = exp->iExportDirEntryDelta;
 			info.iNumImports = block->iNumberOfImports;
 			info.iExporter = exp;
 
@@ -2976,10 +3214,14 @@
 			if (impfmt == KImageImpFmt_ELF)
 				{
 				info.iImportOffsetList = (TUint32*)(block+1);
+				__IF_DEBUG(Printf("Import format ELF (%08x); info@%08x", impfmt, &info));
 				r = ExecuteInSupervisorMode(&svElfDerivedFixupImportAddresses, &info);
 				}
 			else
+				{
+				__IF_DEBUG(Printf("Import format PE (%08x); info@%08x", impfmt, &info));
 				r = ExecuteInSupervisorMode(&svFixupImportAddresses, &info);
+				}
 
 			if (r != KErrNone)
 				{
@@ -3058,7 +3300,18 @@
 */
 TInt E32Image::BuildImportFixupTable()
 	{
-	__IF_DEBUG(Printf(">BuildImportFixupTable,0x%08x,%d", iFixups, iFixupCount));
+	__IF_DEBUG(Printf(">BuildImportFixupTable,%d@%08x,%08x", iFixupCount, iFixups, iCodeLoadAddress));
+
+#ifdef _DEBUG
+	// Dump the incoming fixup table if loader tracing enabled. Each item is an
+	// (address, value) pair, where the address and the value are 32 bits each.
+	TInt i;
+	for (i = 0; i < iFixupCount; ++i)
+		{
+		TUint64 x = iFixups[i];
+		__IF_DEBUG(Printf("%04x: %08x %08x", i*sizeof(TUint64), I64HIGH(x), I64LOW(x)));
+		}
+#endif	// DEBUG
 
 	// sort the array in address order, to organize by page
 	RArray<TUint64> fixup64ToSort(sizeof(TUint64), iFixups, iFixupCount);
@@ -3070,7 +3323,7 @@
 	// to the word at offset XXX.  (See PREQ1110 Design Sketch v1.0 S3.1.1.2.3.2.)
 
 	TUint32 pageCount = SizeToPageCount(iCodeSize);
-	iImportFixupTableSize = (pageCount+1) * sizeof(TUint32) + iFixupCount * 3 * sizeof(TUint16);
+	iImportFixupTableSize = (pageCount+1)*sizeof(TUint32) + 3*iFixupCount*sizeof(TUint16);
 	iImportFixupTable = (TUint32*) User::Alloc(iImportFixupTableSize);
 	__IF_DEBUG(Printf("iImportFixupTable=0x%08x", iImportFixupTable));
 	if (iImportFixupTable == 0)
@@ -3121,18 +3374,20 @@
 	while (++lastPage <= pageCount)
 		iImportFixupTable[lastPage] = iImportFixupTableSize;
 
-	__IF_DEBUG(Printf("processed table (size=%d,pageCount=%d)", iImportFixupTableSize, pageCount));
-
 #ifdef _DEBUG
-	// dump the import fixup table if loader tracing enabled
+	__IF_DEBUG(Printf("processed fixup table (size=%d,pageCount=%d)", iImportFixupTableSize, pageCount));
+
+	// Dump the processed fixup table if loader tracing enabled. The dump is in two
+	// parts; first, the page indexes (1 word per page), then the entries describing
+	// the items to be relocated, each of which is a 16-bit offset-within-page and a
+	// 32-bit value to be stored there.
+	for (i = 0; i <= (TInt)pageCount; ++i)
+		__IF_DEBUG(Printf("%04x: %08x", i*4, iImportFixupTable[i]));
+
 	const TUint16* table16 = (const TUint16*)iImportFixupTable;
 	const TInt halfWordsInTable = iImportFixupTableSize / 2;
-	for (TInt i = 0; i < halfWordsInTable; i += 4)
-		{
-		__IF_DEBUG(Printf(
-			"%04x: %04x %04x %04x %04x",
-			i * 2, table16[i+0], table16[i+1], table16[i+2], table16[i+3]));
-		}
+	for (i *= 2; i < halfWordsInTable; i += 3)
+		__IF_DEBUG(Printf("%04x: %04x %04x%04x", i*2, table16[i+0], table16[i+2], table16[i+1]));
 #endif
 
 	User::Free(iFixups);
--- a/userlibandfileserver/fileserver/sfile/sf_main.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/userlibandfileserver/fileserver/sfile/sf_main.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -474,7 +474,9 @@
 	KernHeapAllocFailCount=-1;
 #endif
 	
-	TInt r= RequestAllocator::iCacheLock.CreateLocal();
+	TInt r = RequestAllocator::Initialise();
+	__ASSERT_ALWAYS(r==KErrNone,Fault(EFsCacheLockFailure));
+	r = OperationAllocator::Initialise();
 	__ASSERT_ALWAYS(r==KErrNone,Fault(EFsCacheLockFailure));
 	
 	// initialise the TParse pool lock object
@@ -492,7 +494,6 @@
 	r=FsThreadManager::CreateDisconnectThread();
 	__ASSERT_ALWAYS(r==KErrNone,Fault(EMainDisconnectThread));
 
-	RequestAllocator::Initialise();
 
 	//
 	// Install a trap handler
--- a/userlibandfileserver/fileserver/sfile/sf_memory_client.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/userlibandfileserver/fileserver/sfile/sf_memory_client.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -35,7 +35,7 @@
 	const TUint32 segCnt = iTouchedRegionFlag <= iReservedRegionMarkInSegs ? 
 										iReservedRegionMarkInSegs : iTouchedRegionFlag;
 	TInt r = DecommitSegments(iBase, segCnt);
-	if (r != KErrNone)  // this 'if() {}' is to remove build warnings
+    if (r != KErrNone)  // this 'if() {}' is to remove build warnings
 	{
 	ASSERT(0);
 	}
@@ -95,7 +95,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	Tue Feb 02 01:24:03 2010 +0200
+++ b/userlibandfileserver/fileserver/sfile/sf_memory_man.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -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	Tue Feb 02 01:24:03 2010 +0200
+++ b/userlibandfileserver/fileserver/sfile/sf_notify.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -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	Tue Feb 02 01:24:03 2010 +0200
+++ b/userlibandfileserver/fileserver/sfile/sf_obj.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -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_request.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/userlibandfileserver/fileserver/sfile/sf_request.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -27,81 +27,25 @@
 
 CFsClientMessageRequest* RequestAllocator::iFreeHead;				
 CFsClientMessageRequest* RequestAllocator::iCloseHead;
-TInt RequestAllocator::iAllocNum;
-TInt RequestAllocator::iAllocNumOperation;
-TMsgOperation* RequestAllocator::iFreeHeadSupOp;
-
-#if defined(_USE_CONTROLIO) || defined(_DEBUG) || defined(_DEBUG_RELEASE)
-TInt RequestAllocator::iAllocated;
-#endif
+TInt RequestAllocator::iRequestCount;
+TInt RequestAllocator::iFreeCount;
+TInt RequestAllocator::iRequestCountPeak;
 RFastLock RequestAllocator::iCacheLock;
 
-void RequestAllocator::Initialise()
-	{	
-	iFreeHead=NULL;  
-	iCloseHead=NULL; 
-	iAllocNum=0; 
-#if defined(_USE_CONTROLIO) || defined(_DEBUG) || defined(_DEBUG_RELEASE)
-	iAllocated=0;
-#endif
-	iAllocNumOperation=0;
-	iFreeHeadSupOp=NULL;
-	}
+TMsgOperation* OperationAllocator::iFreeHead;				
+TInt OperationAllocator::iRequestCount;
+TInt OperationAllocator::iFreeCount;
+TInt OperationAllocator::iRequestCountPeak;
+RFastLock OperationAllocator::iCacheLock;
 
-TInt RequestAllocator::AllocRequest(TInt aNum)
-//
-//	Allocates a group of request objects
-//
-	{
-    TInt i;
-	if(iAllocNum < KMaxRequestAllocated)
-		{
-		__CACHE_PRINT(_L("RequestAllocator::AllocRequest() Not reached the limit"));
-		CFsClientMessageRequest* list;
-		CFsClientMessageRequest* start;
-		list = new CFsClientMessageRequest[KAllocReqBlock];
-		start = list;
-		if(!list)
-			return KErrNoMemory;
-		
-		// Make sure the constructors are called for every element in the array
-		// - some compilers don't do this
-		for(TInt j=0; j<KAllocReqBlock; j++)
-			{
-			CFsClientMessageRequest* request = &list[j];
-			new(request) CFsClientMessageRequest();
-			}
-
-		iAllocNum += KAllocReqBlock;
-		CFsClientMessageRequest* last;
-		for(i=1;i<KAllocReqBlock;i++)
-			{
-			last = list;
-			list++;
-			last->iNext = list;
-			}
-		list->iNext = iFreeHead;
-		iFreeHead = start;
-		return KErrNone;
-		}
-	else
-		{
-		__CACHE_PRINT1(_L("RequestAllocator::AllocRequest() Limit exceeded Count = %d"),aNum);
-		CFsClientMessageRequest* request;
-		for(i=0;i<aNum;i++)
-			{
-			request=new CFsClientMessageRequest;
-			if(!request)
-				return KErrNoMemory;
-#if defined(_USE_CONTROLIO) || defined(_DEBUG) || defined(_DEBUG_RELEASE)
-			iAllocated++;
-#endif
-			request->SetAllocated();
-			request->iNext=iFreeHead;
-			iFreeHead=request;
-			}
-		return KErrNone;
-		}
+TInt RequestAllocator::Initialise()
+	{	
+	iFreeHead = NULL;  
+	iCloseHead = NULL; 
+	iRequestCount = 0; 
+	iFreeCount = 0;
+	iRequestCountPeak = 0;
+	return iCacheLock.CreateLocal();
 	}
 
 void RequestAllocator::FreeRequest(CFsClientMessageRequest* aRequest)
@@ -109,28 +53,28 @@
 //free request 
 //
 	{
-	__CACHE_PRINT1(_L("PLUGIN: RequestAllocator::FreeRequest for %x"), aRequest);
-	if(aRequest->IsAllocated())
+	__CACHE_PRINT1(_L("RequestAllocator::FreeRequest for %x"), aRequest);
+	ASSERT(aRequest != NULL);
+	iCacheLock.Wait();
+	if (iFreeCount >= KFreeCountMax)
 		{
-		__CACHE_PRINT(_L("RequestAllocator::FreeRequest() Allocated request"));
-		delete(aRequest);
-#if defined(_USE_CONTROLIO) || defined(_DEBUG) || defined(_DEBUG_RELEASE)
-		iAllocated--;
-#endif
-		return;
+		delete aRequest;
+		ASSERT(iRequestCount > 0);
+		iRequestCount--;
 		}
-	
-	__CACHE_PRINT(_L("RequestAllocator::FreeRequest() returning to free list"));
-	iCacheLock.Wait();
-	aRequest->iNext = iFreeHead;
-	iFreeHead=aRequest;
-	aRequest->SetSubstedDrive(NULL);
+	else
+		{
+		aRequest->SetSubstedDrive(NULL);
+		aRequest->iNext = iFreeHead;
+		iFreeHead=aRequest;
+		iFreeCount++;
+		}
 	iCacheLock.Signal();
 	}
 
 void RequestAllocator::OpenSubFailed(CSessionFs* aSession)
 //
-//	Move requst from closed list to free list
+//	Move request from closed list to free list
 //
 	{
 	__ASSERT_DEBUG(iCloseHead!=NULL,Fault(ERequestAllocatorOpenSubFailed)); // On arriving here Close Queue is supposed to be empty
@@ -142,34 +86,39 @@
 	iCacheLock.Wait();
 	CFsClientMessageRequest* rp = iCloseHead;
 	iCloseHead = rp->iNext;
+	iCacheLock.Signal();
 	
 	// dec the number of closed requests owned by this session
 	aSession->CloseRequestCountDec();
 
-	rp->iNext = NULL;
-	if(rp->IsAllocated())
+	__CACHE_PRINT1(_L("RequestAllocator::OpenSubFailed() IsAllocated %d"), rp->IsAllocated());
+	FreeRequest(rp);
+	}
+
+CFsClientMessageRequest* RequestAllocator::GetRequest()
+//
+// Get request from the free queue
+//
+	{
+	CFsClientMessageRequest* request;
+	if (iFreeHead == NULL)
 		{
-		__CACHE_PRINT(_L("RequestAllocator::OpenSubFailed() Allocated request"));
-		delete(rp);
-#if defined(_USE_CONTROLIO) || defined(_DEBUG) || defined(_DEBUG_RELEASE)
-		iAllocated--;
-#endif
+		request = new CFsClientMessageRequest;
+		if (request)
+			{
+			iRequestCount++;
+			iRequestCountPeak = Max(iRequestCountPeak, iRequestCount);
+			}
 		}
 	else
 		{
-		__CACHE_PRINT(_L("RequestAllocator::OpenSubFailed()"));
-		if(iFreeHead)
-			{
-			rp->iNext = iFreeHead;
-			}
-		else
-			{
-			rp->iNext = NULL;
-			}
-
-		iFreeHead = rp;		
+		request = iFreeHead;
+		iFreeHead = iFreeHead->iNext;
+		request->iNext = NULL;
+		iFreeCount--;
+		ASSERT(iFreeCount >= 0);
 		}
-	iCacheLock.Signal();
+	return request;
 	}
 
 TInt RequestAllocator::GetMessageRequest(const TOperation& aOperation,const RMessage2& aMessage,CFsClientMessageRequest* &aRequest)
@@ -181,27 +130,20 @@
 		{
 		__CACHE_PRINT(_L("++RequestAllocator::GetMessageRequest() Open sub-sess"));
 		iCacheLock.Wait();
-		if(iFreeHead == NULL || iFreeHead->iNext == NULL)
-			{
-			if(AllocRequest(2)!= KErrNone)
-				{
-				iCacheLock.Signal();
-				return KErrNoMemory;
-				}
-			}
-		aRequest= iFreeHead;						//get our request from free head
-		iFreeHead = iFreeHead->iNext->iNext;	//set next but one as new free head read for next
 
-		aRequest->iNext->iNext = NULL;				//seperate our request and close from free list
-		CFsClientMessageRequest* CRp = aRequest->iNext;
-		aRequest->iNext = NULL;
-		if(iCloseHead)
+		aRequest = GetRequest();
+		CFsClientMessageRequest* closeRequest = GetRequest();
+		
+		if (aRequest == NULL || closeRequest == NULL)
 			{
-			CRp->iNext = iCloseHead;		//set second one as a reserved (tail) close request
-			iCloseHead = CRp;
+			delete aRequest;
+			delete closeRequest;
+			iCacheLock.Signal();
+			return KErrNoMemory;
 			}
-		else
-			iCloseHead = CRp;
+
+		closeRequest->iNext = iCloseHead;		//set second one as a reserved (tail) close request
+		iCloseHead = closeRequest;
 		
 		((CSessionFs*) aMessage.Session())->CloseRequestCountInc();
 		}
@@ -272,6 +214,7 @@
 			}
 
 		iCacheLock.Wait();
+		ASSERT(iCloseHead);
 		aRequest = iCloseHead;
 		iCloseHead = aRequest->iNext;
 		((CSessionFs*) aMessage.Session())->CloseRequestCountDec();
@@ -289,17 +232,12 @@
 		{
 		__CACHE_PRINT(_L("++RequestAllocator::GetMessageRequest() "));
 		iCacheLock.Wait();
-		if(!iFreeHead)
+		aRequest = GetRequest();
+		if (aRequest == NULL)
 			{
-			if(AllocRequest(1) != KErrNone)
-				{
-				iCacheLock.Signal();
-				return KErrNoMemory; 
-				}
+			iCacheLock.Signal();
+			return KErrNoMemory; 
 			}
-		aRequest = iFreeHead;						
-		iFreeHead = aRequest->iNext;
-		aRequest->iNext= NULL;
 		}
 
 	aRequest->Init();
@@ -322,126 +260,103 @@
 #if defined(_USE_CONTROLIO) || defined(_DEBUG) || defined(_DEBUG_RELEASE)
 TInt RequestAllocator::CloseCount()
 	{TInt count=0;
+	iCacheLock.Wait();
+
 	CFsClientMessageRequest* list=iCloseHead;
 	while(list!=NULL)
 		{
 		count++;
 		list=list->iNext;
 		}
+
+	iCacheLock.Signal();
 	return(count);
 	} 
 TInt RequestAllocator::FreeCount()
 	{
 	TInt count=0;
+	iCacheLock.Wait();
 	CFsClientMessageRequest* list=iFreeHead;
 	while(list!=NULL)
 		{
 		count++;
 		list=list->iNext;
 		}
-	return(count);}
+	ASSERT(count == iFreeCount);
+	iCacheLock.Signal();
+	return(count);
+	}
 #endif
 
-TInt RequestAllocator::AllocOperation()
-//
-//	Allocates a group of TMsgOperation objects
+TInt OperationAllocator::Initialise()
+	{	
+	iFreeHead = NULL;  
+	iRequestCount = 0; 
+	iFreeCount = 0;
+	return iCacheLock.CreateLocal();
+	}
+
+void OperationAllocator::FreeOperation(TMsgOperation* aOperation)
 //
-// Must be called with iCacheLock held
+// free Operation
+//
 	{
-    TInt i;
-	if(iAllocNumOperation < KMaxOperationAllocated)
+	__CACHE_PRINT1(_L("RequestAllocator::FreeOperation() returning %x to free list"), aOperation);
+	ASSERT(aOperation != NULL);
+	iCacheLock.Wait();
+	if (iFreeCount >= KFreeCountMax)
 		{
-		__CACHE_PRINT(_L("RequestAllocator::AllocOperation() Not reached the limit"));
-		TMsgOperation* list;
-		TMsgOperation* start;
-		list = new TMsgOperation[KAllocReqBlock];
-		start = list;
-		if(!list)
-			return KErrNoMemory;
-		
-		for(TInt j=0; j<KAllocReqBlock; j++)
-			{
-			TMsgOperation* request = &list[j];
-			request->iIsAllocated = EFalse;
-			}
-
-		iAllocNumOperation += KAllocReqBlock;
-		TMsgOperation* last;
-		for(i=1;i<KAllocReqBlock;i++)
-			{
-			last = list;
-			list++;
-			last->iNext = list;
-			}
-		list->iNext = iFreeHeadSupOp;
-		iFreeHeadSupOp = start;
-		return KErrNone;
+		delete aOperation;
+		ASSERT(iRequestCount > 0);
+		iRequestCount--;
 		}
 	else
 		{
-		__CACHE_PRINT(_L("RequestAllocator::AllocOperation() Limit exceeded"));
-		TMsgOperation* request;
+		aOperation->iNext = iFreeHead;
+		iFreeHead = aOperation;
+		iFreeCount++;
+		}
 
-		request=new TMsgOperation;
-		if(!request)
-			return KErrNoMemory;
-#if defined(_USE_CONTROLIO) || defined(_DEBUG) || defined(_DEBUG_RELEASE)
-		iAllocated++;
-#endif
-		request->iIsAllocated = ETrue;
-		request->iNext=iFreeHeadSupOp;
-		iFreeHeadSupOp=request;
+	iCacheLock.Signal();
+	}
 
-		return KErrNone;
-		}
-	}
-TInt RequestAllocator::GetOperation(TMsgOperation* &aOperation)
+TInt OperationAllocator::GetOperation(TMsgOperation* &aOperation)
 //
 //	tries to get a pre allocated subop from the cache. Failing that allocates one individualy 
 //	
 	{
 
 	__CACHE_PRINT(_L("RequestAllocator::GetOperation() "));
+
 	iCacheLock.Wait();
-	if(!iFreeHeadSupOp)
+
+	TInt r = KErrNone;
+	if (iFreeHead == NULL)
 		{
-		if(AllocOperation() != KErrNone)
+		aOperation = new TMsgOperation;
+		if (aOperation == NULL)
+			r = KErrNoMemory; 
+		else
 			{
-			iCacheLock.Signal();
-			return KErrNoMemory; 
+			iRequestCount++;
+			iRequestCountPeak = Max(iRequestCountPeak, iRequestCount);
 			}
 		}
-	aOperation = iFreeHeadSupOp;						
-	iFreeHeadSupOp = aOperation->iNext;
-	aOperation->iNext = aOperation->iPrev = NULL;
+	else
+		{
+		aOperation = iFreeHead;
+		iFreeHead = iFreeHead->iNext;
+		iFreeCount--;
+		ASSERT(iFreeCount >= 0);
+		}
+
+	if (aOperation)
+		aOperation->iNext = aOperation->iPrev = NULL;
 
 	iCacheLock.Signal();
-	return KErrNone;
+	return r;
 	}	
 
-void RequestAllocator::FreeOperation(TMsgOperation* aOperation)
-//
-// free Operation
-//
-	{
-	if(aOperation->iIsAllocated)
-		{
-		__CACHE_PRINT(_L("RequestAllocator::FreeOperation() Allocated subop"));
-		delete(aOperation);
-#if defined(_USE_CONTROLIO) || defined(_DEBUG) || defined(_DEBUG_RELEASE)
-		iAllocated--;
-#endif
-		return;
-		}
-	
-	__CACHE_PRINT(_L("RequestAllocator::FreeOperation() returning to free list"));
-	iCacheLock.Wait();
-	aOperation->iNext = iFreeHeadSupOp;	// NB backward link only used when request in in use
-	iFreeHeadSupOp = aOperation;
-
-	iCacheLock.Signal();
-	}
-
 
 CFsRequest::CFsRequest()
 //
@@ -1821,7 +1736,7 @@
 TInt CFsMessageRequest::PushOperation(TFsRequestFunc aCallback, TInt aNextState, TInt aFunction)
 	{
 	TMsgOperation* nextOperation;
-	TInt r = RequestAllocator::GetOperation(nextOperation);
+	TInt r = OperationAllocator::GetOperation(nextOperation);
 	if (r != KErrNone)
 		return r;
 
@@ -1949,7 +1864,7 @@
 			SetOperationFunc(iCurrentOperation->iFunction);
 		}
 
-	RequestAllocator::FreeOperation(currentOperation);
+	OperationAllocator::FreeOperation(currentOperation);
 	}
 
 TMsgOperation& CFsMessageRequest::CurrentOperation()
--- a/userlibandfileserver/fileserver/sfile/sf_ses.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/userlibandfileserver/fileserver/sfile/sf_ses.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -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	Tue Feb 02 01:24:03 2010 +0200
+++ b/userlibandfileserver/fileserver/sfile/sf_std.h	Fri Apr 16 16:24:37 2010 +0300
@@ -1398,9 +1398,10 @@
 	TRequestStatus iStatus;
 	TBool iIsAllocated;
 	};
-const TInt KMaxRequestAllocated		= 45;
-const TInt KMaxOperationAllocated	= KMaxRequestAllocated * 2;
-const TInt KAllocReqBlock=15;
+
+// If the number of requests on the free queue reaches this value then completed requests 
+// are returned to the heap rather than being added to thefree queue
+const TInt KFreeCountMax = 64;
 
 class TParseCon
 	{
@@ -1413,34 +1414,53 @@
 class RequestAllocator
 	{
 public:
+	static TInt Initialise();
+
 	static TInt GetMessageRequest(const TOperation& aOperation,const RMessage2& aMessage,CFsClientMessageRequest* &aRequest);
-	static void FreeRequest(CFsClientMessageRequest* aRequest); // Use the one from cache
+	static void FreeRequest(CFsClientMessageRequest* aRequest);
 	static void OpenSubFailed(CSessionFs* aSession); 
-	static TInt AllocRequest(TInt aNum);
+
+#if defined(_USE_CONTROLIO) || defined(_DEBUG) || defined(_DEBUG_RELEASE)
+	inline static TInt RequestCount();
+	inline static TInt RequestCountPeak();
+	static TInt CloseCount();
+	static TInt FreeCount();
+#endif
+
+private:
+	static CFsClientMessageRequest* GetRequest();
 
-	static TInt AllocOperation();
+private:
+	static RFastLock iCacheLock;
+	static CFsClientMessageRequest* iFreeHead;				
+	static CFsClientMessageRequest* iCloseHead;
+
+	static TInt iRequestCount;			// current number of requests
+	static TInt iFreeCount;				// current number of requests on free queue
+	static TInt iRequestCountPeak;				// maximum value of requests reached
+	};
+
+class OperationAllocator
+	{
+public:
+	static TInt Initialise();
+
 	static TInt GetOperation(TMsgOperation* &aOperation);
 	static void FreeOperation(TMsgOperation* aOperation);
 
-
-	static void Initialise();
 #if defined(_USE_CONTROLIO) || defined(_DEBUG) || defined(_DEBUG_RELEASE)
-	inline static TInt TotalCount();
-	static TInt CloseCount();
-	static TInt FreeCount();
-	inline static TInt AllocatedCount();
-private:
-	static TInt iAllocated;
+	inline static TInt RequestCount();
+	inline static TInt RequestCountPeak();
+	inline static TInt FreeCount();
 #endif
-public:
-	static RFastLock iCacheLock;
+
 private:
-	static TInt iAllocNum;
-	static CFsClientMessageRequest* iFreeHead;				
-	static CFsClientMessageRequest* iCloseHead;
+	static RFastLock iCacheLock;
+	static TMsgOperation* iFreeHead;
 
-	static TInt iAllocNumOperation;
-	static TMsgOperation* iFreeHeadSupOp;
+	static TInt iRequestCount;			// current number of requests
+	static TInt iFreeCount;				// current number of requests on free queue
+	static TInt iRequestCountPeak;				// maximum value of requests reached
 	};
 
 
@@ -1511,6 +1531,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 +1548,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 +1619,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 +1825,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_std.inl	Tue Feb 02 01:24:03 2010 +0200
+++ b/userlibandfileserver/fileserver/sfile/sf_std.inl	Fri Apr 16 16:24:37 2010 +0300
@@ -310,12 +310,19 @@
 
 #if defined(_USE_CONTROLIO) || defined(_DEBUG) || defined(_DEBUG_RELEASE)
 // Class RequestAllocator
-/** returns number of dynamically allocated requests  */
-TInt RequestAllocator::AllocatedCount()
-{ return iAllocated;}
 /** returns number of permanently & dynamically allocated requests  */
-TInt RequestAllocator::TotalCount()
-{ return iAllocated + iAllocNum;}
+TInt RequestAllocator::RequestCount()
+	{ return iRequestCount;}
+TInt RequestAllocator::RequestCountPeak()
+	{ return iRequestCountPeak;}
+
+TInt OperationAllocator::FreeCount()
+	{ return iFreeCount;}
+TInt OperationAllocator::RequestCount()
+	{ return iRequestCount;}
+TInt OperationAllocator::RequestCountPeak()
+	{ return iRequestCountPeak;}
+
 #endif
 
 //---------------------------------------------------------------------------------------------------------------------
--- a/userlibandfileserver/fileserver/sfile/sf_sys.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/userlibandfileserver/fileserver/sfile/sf_sys.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -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/sfsrv/cl_find.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/userlibandfileserver/fileserver/sfsrv/cl_find.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -20,93 +20,104 @@
 #define gPathDelimiter TChar(';')
 enum TMode {EFindByDrives,EFindByDrivesInPath,EFindByPath};
 
-TInt TFindFile::DoFindInDir()
+
 //
 // Look for aFileName in aDir
 //
+TInt TFindFile::DoFindInDir()
 	{
 
-	if (iDir==NULL)
+	if (!iDir)
 		{
 		TEntry entry;
 		TInt r=iFs->Entry(iFile.FullName(),entry);
-		if (r==KErrNone /*|| r==KErrAccessDenied*/)
-			return(KErrNone);
-		else if (r==KErrNoMemory)
+
+		if (r != KErrNone && r != KErrNoMemory && r != KErrPermissionDenied)
+			r = KErrNotFound;
+
 			return r;
-		else if (r==KErrPermissionDenied)
-			return (KErrPermissionDenied);
-		else
-			return(KErrNotFound);
 		}
+	
 	TInt r=iFs->GetDir(iFile.FullName(),KEntryAttMaskSupported|KEntryAttAllowUid,ESortByName,*iDir);
-	if (r==KErrNoMemory)
-		return r;
-	else if (r==KErrPermissionDenied)
-		return r;
-	else if (r!=KErrNone)
-		return(KErrNotFound);
-	if ((*iDir)->Count()==0)
+
+    if(r == KErrNone)
+        {
+        if(!(*iDir)->Count())
+            r = KErrNotFound; //-- empty directory
+        }
+    else if(r != KErrNoMemory && r != KErrPermissionDenied)
+        {
+            r = KErrNotFound;        
+        }
+
+	if (r != KErrNone && iDir)
 		{
 		delete (*iDir);
 		*iDir=NULL;
-		return(KErrNotFound);
 		}
-	else
-		return(KErrNone);
+
+	return r; 
 	}
 
-TInt TFindFile::DoFindNextInPath()
+
 //
 // Look for aFileName along the path and increment aPathPos
 //
+TInt TFindFile::DoFindNextInPath()
 	{
 
 	if (iMode==EFindByDrivesInPath)
 		{
 		TInt r=DoFindNextInDriveList();
-		if (r==KErrNone)
-			return(KErrNone);
 		if (r!=KErrNotFound)
 			return(r);
+
 		iMode=EFindByPath;
 		}
+
 	FOREVER
 		{
 		if (iPath->Length()<iPathPos)
 			return(KErrNotFound);
+
 		TPtrC path(iPath->Ptr()+iPathPos,iPath->Length()-iPathPos);
+
 		TInt r=path.Locate(gPathDelimiter);
+
 		if (r==KErrNotFound)
 			r=path.Length();
+
 		path.Set(path.Ptr(),r);
 		iPathPos+=r+1;
 		TFileName fileName=iFile.NameAndExt();
 		iFile.Set(fileName,&path,NULL);
+
 		if (iFile.FullName().Length()>=2 && iFile.FullName()[1]==KDriveDelimiter)
 			{
 			TInt r=DoFindInDir();
-			if (r==KErrNone)
-				return(KErrNone);
-			if (r!=KErrNotFound)
-				return(r);
+			if (r == KErrNotFound)
 			continue;
+			
+            return(r);
 			}
+		
 		iMode=EFindByDrivesInPath;
 		
 		r=FindByDir(fileName,path);
-		if (r==KErrNone)
-			return(KErrNone);
-		if (r!=KErrNotFound)
+		
+        if (r == KErrNotFound)
+			continue;
+		
 			return(r);
 		}
 
 	}
 
-TInt TFindFile::DoFindNextInDriveList()
+
 //
 // Look for aFileName in all available drives in order
 //
+TInt TFindFile::DoFindNextInDriveList()
 	{
 	
 	TInt found;	
@@ -235,9 +246,12 @@
 		TPtrC path(iFile.Path());
 		fileName.Set(nameAndExt,&path,&drive);
 		iFile=fileName;
+		
 		TInt r=DoFindInDir();
+		
 		if (r==KErrNone)
 			return(KErrNone);
+		
 		if (r!=KErrNotFound)
 			return(r);
 		}	
@@ -246,15 +260,14 @@
 
 
 
-EXPORT_C TFindFile::TFindFile(RFs& aFs)
-	: iFs(&aFs), iPathPos(0), iCurrentDrive(0), iMode(-1), iMatchMask(0)
 /**
 Constructor taking a file server session.
 
 @param aFs File server session.
 */
+EXPORT_C TFindFile::TFindFile(RFs& aFs)
+	               :iFs(&aFs), iPathPos(0), iCurrentDrive(0), iMode(-1), iDir(NULL), iMatchMask(0)
 	{
-	
 	iFile.Set(_L(""),NULL,NULL);
 	}
 
@@ -274,29 +287,25 @@
 	TInt r=iFile.Set(aFileName,NULL,NULL);
 	if (r!=KErrNone)
 		return(r);
+
 	iPath=aPath;
 	iPathPos=0;
 	iMode=EFindByPath;
 	r=DoFindInDir();	
 	
-	
-	if (r==KErrNone)
-		return(KErrNone);
-	if (r!=KErrNotFound)
-		return(r);
-	if ((iPath==NULL) || (iPath->Length()==0))
-		return(KErrNotFound);
-	
-	
+	// if it's not in the current dir and a search path was specified, look there.
+	if (r == KErrNotFound && iPath && iPath->Length())
 	r=DoFindNextInPath();
+
 	return(r);
 	}
 
-TInt TFindFile::DoFindByDir(const TDesC& aFileName,const TDesC& aDir)
+
 //
 // Look for aFileName in aDir on each connected drive
 // Make initial check for aFileName in aDir on current drive
 //
+TInt TFindFile::DoFindByDir(const TDesC& aFileName,const TDesC& aDir)
 	{
 		
 	if (aFileName.Length() <= 0) 
@@ -305,23 +314,24 @@
 	TInt r=iFs->Parse(aFileName,aDir,iFile);
 	if (r!=KErrNone)
 		return(r);
+	
 	TInt searchResult=DoFindInDir();
-	if(searchResult==KErrNoMemory)                       
+	if(searchResult == KErrNoMemory || searchResult == KErrPermissionDenied)
 		return(searchResult);
 	
-	if(searchResult==KErrPermissionDenied)
-		return (KErrPermissionDenied);
-	
 	r=iFs->DriveList(iDrvList,KDriveAttAll);
 	if (r!=KErrNone)
 		return(r);
+	
 	TInt drive;
 	r=RFs::CharToDrive(iFile.Drive()[0],drive);
 	if (r!=KErrNone)
 		return(r);
+
 	iDrvList[drive]=0; // Drive 'drive' has already been searched
 	iCurrentDrive=EDriveY;
 	iMode=EFindByDrives;
+	
 	if (searchResult==KErrNone)
 		return(KErrNone);
 	
@@ -329,10 +339,21 @@
 	return(DoFindNextInDriveList());
 	}
 
+/**
+    internal helper method that deletes the (*iDir) object in the case of errors and assigns NULL to the client's pointer top it.
+*/
+TInt TFindFile::CallSafe(TInt aResult)
+	{
+	if (aResult != KErrNone && iDir)
+		{
+		delete *iDir;
+		*iDir = NULL;
+		iDir = NULL;
+		}
+	return aResult;
+	}
 
 
-
-EXPORT_C TInt TFindFile::FindByPath(const TDesC& aFileName,const TDesC* aPath)
 /**
 Searches for a file/directory in one or more directories in the path.
 
@@ -367,16 +388,16 @@
 @see TFindFile::File
 @see TFindFile::Find
 */
+EXPORT_C TInt TFindFile::FindByPath(const TDesC& aFileName,const TDesC* aPath)
 	{
 
 	iDir=NULL;
-	return(DoFindByPath(aFileName,aPath));
+	return CallSafe(DoFindByPath(aFileName,aPath));
 	}
 
 
 
 
-EXPORT_C TInt TFindFile::FindByDir(const TDesC& aFileName,const TDesC& aDir)
 /**
 Searches for a file/directory in a directory on all available drives.
 
@@ -416,51 +437,50 @@
 @see TFindFile::Find()
 @see TFindFile::SetFindMask()
 */
+EXPORT_C TInt TFindFile::FindByDir(const TDesC& aFileName,const TDesC& aDir)
 	{
 
 	iDir=NULL;
-	return(DoFindByDir(aFileName,aDir));
+	return CallSafe(DoFindByDir(aFileName,aDir));
 	}
 
 
 
 
-EXPORT_C TInt TFindFile::FindWildByPath(const TDesC& aFileName,const TDesC* aPath,CDir*& aDir)
+
 /**
-Searches for one or more files/directories in the directories contained in a
-path list.
+Searches for one or more files/directories in the directories contained in a path list.
 
-Wildcard characters can be specified. The search ends when one or more
-filenames matching aFileName is found, or when every
-directory in the path list has been unsuccessfully searched.
-To begin searching again after a successful match has been made,
-use FindWild().
+Wildcard characters can be specified. The search ends when one or more filenames matching aFileName is found, or when every
+directory in the path list has been unsuccessfully searched. To begin searching again after a successful match has been made, use FindWild().
 
-Using function SetFindMask it is possible to specify a combination of 
-attributes that the drives to be searched must match.
+Using function SetFindMask it is possible to specify a combination of  attributes that the drives to be searched must match.
 
 Notes:
 
-1. The caller of the function is responsible for deleting
-   aDir after the function has returned.
+1. The function sets aDir to NULL, then allocates memory for it before appending entries to the list. Therefore, 
+   aDir should have no memory allocated to it before this function is called, otherwise this memory will become orphaned.
 
-2. Calling TFindFile::File() after a successful search gets the drive letter
-   and directory containing the file(s). The filenames can be retrieved via
-   the array of TEntry::iName objects contained in aDir. If you want to
-   retrieve the fully qualified path of a file, you need to parse the path and
-   the filename.
+2. The caller of the function is responsible for deleting aDir after the function has returned. On error this pointer will be set NULL,
+   thus safe to delete.     
+
+3. Calling TFindFile::File() after a successful search gets the drive letter and directory containing the file(s). 
+   The filenames can be retrieved via the array of TEntry::iName objects contained in aDir. If you want to  retrieve the fully 
+   qualified path of a file, you need to parse the path and the filename.
    
-@param aFileName The filename to search for. May contain wildcards. If
-                 it specifies a directory as well as a filename, then that
+@param aFileName The filename to search for. May contain wildcards. If it specifies a directory as well as a filename, then that
                  directory is searched first.
-@param aPath     List of directories to search. Paths in this list must be
-                 separated by a semicolon character, but a semicolon is not
-                 required after the final path. The directories are searched
-                 in the order in which they occur in the list.
-                 Directories must be fully qualified, including
-                 a drive letter, and the name must end with a backslash.
-@param aDir      On return, contains the entries for all files matching
-				 aFileName in the first directory in which a match occurred.
+
+@param aPath     List of directories to search. Paths in this list must be separated by a semicolon character, but a semicolon is not
+                 required after the final path. The directories are searched in the order in which they occur in the list.
+                 Directories must be fully qualified, including a drive letter, and the name must end with a backslash.
+
+@param aDir      in: a reference to the pointer that will be modified by this method.
+                 
+                 out: On success a pointer to the internally allocated by this method CDir object, which in turn contains the entries for 
+                 all files matching aFileName in the first directory in which a match occurred. In this case this API caller is responsible
+                 for deleting aDir.
+                 If some error occured (including KErrNotFound meaning that nothing found) this pointer will be set to NULL, which is also safe to delete.
 
 @return KErrNone, if one or more matching files was	found;
         KErrNotFound, if no matching file was found in any of the directories.
@@ -471,79 +491,80 @@
 @see TEntry::iName
 @see TFindFile::SetFindMask()
 */
+EXPORT_C TInt TFindFile::FindWildByPath(const TDesC& aFileName,const TDesC* aPath,CDir*& aDir)
 	{
 
 	iDir=&aDir;
-	return(DoFindByPath(aFileName,aPath));
+	*iDir=NULL;
+
+	return CallSafe(DoFindByPath(aFileName,aPath));
 	}
 
 
 
 
-EXPORT_C TInt TFindFile::FindWildByDir(const TDesC& aFileName,const TDesC& aDirPath,CDir*& aDir)
+
 /**
-Searches, using wildcards, for one or more files/directories in a specified
-directory.
+Searches, using wildcards, for one or more files/directories in a specified directory.
 
-If no matching file is found in that directory, all available drives are
-searched in descending alphabetical order, from Y: to A:, and ending
-with the Z: drive.Using function SetFindMask it is possible to specify a 
-combination of attributes that the drives to be searched must match.
+If no matching file is found in that directory, all available drives are searched in descending alphabetical order, from Y: to A:, and ending
+with the Z: drive.Using function SetFindMask it is possible to specify a combination of attributes that the drives to be searched must match.
 
-The search ends when one or more matching filenames are found, or when every 
-available drive has been unsuccessfully searched. To begin searching again 
-after a successful match has been made, use FindWild(). Wildcards may be
-specified in the filename.
+The search ends when one or more matching filenames are found, or when every  available drive has been unsuccessfully searched. 
+To begin searching again after a successful match has been made, use FindWild(). Wildcards may be specified in the filename.
 
 Notes:
 
-1. A drive letter may be specified in aDirPath (or in aFileName). If a drive 
-   is specified, that drive is searched first, followed by the other available 
-   drives, in descending alphabetical order. If no drive is specified, the drive 
-   contained in the session path is searched first.
+1. A drive letter may be specified in aDirPath (or in aFileName). If a drive  is specified, that drive is searched first, 
+   followed by the other available drives, in descending alphabetical order. If no drive is specified, the drive contained in the session 
+   path is searched first.
+
+2. The function sets aDir to NULL, then allocates memory for it before appending entries to the list. Therefore, 
+   aDir should have no memory allocated to it before this function is called, otherwise this memory will become orphaned.
 
-2. The function sets aDir to NULL, then allocates memory for it before appending 
-   entries to the list. Therefore, aDir should have no memory allocated to it 
-   before this function is called, otherwise this memory will become orphaned.
+3. The caller of the function is responsible for deleting aDir after the function has returned. On error this pointer will be set NULL,
+   thus safe to delete.     
 
-3. The caller of this function is responsible for deleting aDir after the function 
-   has returned.
 
-4. Calling TFindFile::File() after a successful search returns the drive letter 
-   and directory containing the file(s). Filenames may be retrieved via the array 
-   of TEntry::iNames contained in aDir. If you want to retrieve the fully 
+4. Calling TFindFile::File() after a successful search returns the drive letter and directory containing the file(s). 
+   Filenames may be retrieved via the array of TEntry::iNames contained in aDir. If you want to retrieve the fully 
    qualified path of a file, you will need to parse the path and the filename.
 
-@param aFileName The filename to search for. May contain wildcards. If a path 
-                 is specified, it overrides the path specified in aDirPath.
-                 If no path is specified, the path contained in aDirPath is
-                 used in the search.
+@param aFileName The filename to search for. May contain wildcards. If a path is specified, it overrides the path specified in aDirPath.
+                 If no path is specified, the path contained in aDirPath is used in the search.
+
 @param aDirPath  Path indicating a directory to search on each drive.
-@param aDir      On return, contains the entries for all files
-                 matching aFileName.
+
+@param aDir      in: a reference to the pointer that will be modified by this method.
+                 
+                 out: On success a pointer to the internally allocated by this method CDir object, which in turn contains the entries for 
+                 all files matching aFileName in the first directory in which a match occurred. In this case this API caller is responsible
+                 for deleting aDir.
+                 If some error occured (including KErrNotFound meaning that nothing found) this pointer will be set to NULL, which is also safe to delete.
                  
 @return KErrNone if one or more matching files was found;
-        KErrNotFound if no matching file was found in the directory on any 
-        of the drives.
+        KErrNotFound if no matching file was found in the directory on any of the drives.
         KErrArgument, if the filename is empty. 
                 
 @see TFindFile::FindWild
 @see TFindFile::File
 @see TFindFile::SetFindMask()
 */
+EXPORT_C TInt TFindFile::FindWildByDir(const TDesC& aFileName,const TDesC& aDirPath,CDir*& aDir)
 	{
-
 	iDir=&aDir;
-	return(DoFindByDir(aFileName,aDirPath));
+    *iDir=NULL;
+	
+	return CallSafe(DoFindByDir(aFileName,aDirPath));
 	}
 
 
 
 
-TInt TFindFile::DoFind()
 //
 // Find the next match
 //
+TInt TFindFile::DoFind()
 	{
 
 	TInt ret=KErrNone;
@@ -565,7 +586,7 @@
 
 
 
-EXPORT_C TInt TFindFile::Find()
+
 /**
 Searches for the next file/directory.
 
@@ -589,6 +610,7 @@
 @see TFindFile::SetFindMask()
 
 */
+EXPORT_C TInt TFindFile::Find()
 	{
 
 //	iDir=NULL;
@@ -598,7 +620,7 @@
 
 
 
-EXPORT_C TInt TFindFile::FindWild(CDir*& aDir)
+
 /**
 Searches for the next file/directory.
 
@@ -609,21 +631,25 @@
 
 Notes:
 
-1. The caller of this function is responsible for deleting aDir after
-   the function has returned 
+1. The function sets aDir to NULL, then allocates memory for it before appending entries to the list. Therefore, 
+   aDir should have no memory allocated to it before this function is called, otherwise this memory will become orphaned.
+
+2. The caller of the function is responsible for deleting aDir after the function has returned. On error this pointer will be set NULL,
+   thus safe to delete.     
+
+3. Calling TFindFile::File() after a successful search, will return the drive letter and the directory containing the file(s).
+   The filenames may be retrieved via the array of TEntry::iName objects contained in aDir. If you want to retrieve the fully qualified
+   path of a file, you will need to parse the path and the filename using the TParse class or derived classes.
 
-2. Calling TFindFile::File() after a successful search, will return
-   the drive letter and the directory containing the file(s).
-   The filenames may be retrieved via the array of TEntry::iName objects
-   contained in aDir. If you want to retrieve the fully qualified
-   path of a file, you will need to parse the path and the filename using
-   the TParse class or derived classes.
-
-@param aDir On return, contains the entries for all matching files found in
-            the next directory.
+@param aDir      in: a reference to the pointer that will be modified by this method.
+                 
+                 out: On success a pointer to the internally allocated by this method CDir object, which in turn contains the entries for 
+                 all files matching aFileName in the first directory in which a match occurred. In this case this API caller is responsible
+                 for deleting aDir.
+                 If some error occured (including KErrNotFound meaning that nothing found) this pointer will be set to NULL, which is also safe to delete.
             
-@return KErrNone, if further occurrences were found;
-        KErrNotFound, if no more matching files were found.
+@return KErrNone      if further occurrences were found;
+        KErrNotFound  if no more matching files were found.
 
 
 @see TParse
@@ -633,15 +659,18 @@
 @see TFindFile::FindWildByDir
 @see TFindFile::SetFindMask()
 */
+EXPORT_C TInt TFindFile::FindWild(CDir*& aDir)
 	{
 
 	iDir=&aDir;
-	return(DoFind());
+    *iDir=NULL;
+
+	return CallSafe(DoFind());
 	}
 
 
 
-EXPORT_C TInt TFindFile::SetFindMask(TUint aMask)
+
 /**
 Can be used in order to specify a combination of drive attributes that the drives 
 to be searched must match. When searching without specifying a mask, all drives, except the 
@@ -653,6 +682,7 @@
         KErrArgument, if the mask supplied is invalid.
 */
 
+EXPORT_C TInt TFindFile::SetFindMask(TUint aMask)
 	 {	
 	 TInt r =ValidateMatchMask(aMask);
 	 if(r!=KErrNone) 
@@ -667,8 +697,5 @@
 	 	return KErrNone;
 	 	
 	 	}
-	 
-	
-											
 	 }
 
--- a/userlibandfileserver/fileserver/sfsrv/cl_parse.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/userlibandfileserver/fileserver/sfsrv/cl_parse.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -302,9 +302,9 @@
 	TInt pos=aName.Locate(KPathDelimiter);
 	if (pos!=KErrNotFound)
 		return(KErrBadName);
-	TFileName n=aName;
-	n.Append(KPathDelimiter);
-	NameBuf().Insert(iField[EName].pos,n);
+	
+	NameBuf().Insert(iField[EName].pos,aName);
+	NameBuf().Insert(iField[EName].pos + aName.Length(),TPtrC16((const TUint16*)(&KPathDelimiter),1));
 	iField[EPath].len=(TUint8)(iField[EPath].len+len);
 	iField[EName].pos=(TUint8)(iField[EName].pos+len);
 	iField[EExt].pos=(TUint8)(len+iField[EExt].pos);
--- a/userlibandfileserver/fileserver/shostmassstorage/base_f32_shostmassstorage.mrp	Tue Feb 02 01:24:03 2010 +0200
+++ b/userlibandfileserver/fileserver/shostmassstorage/base_f32_shostmassstorage.mrp	Fri Apr 16 16:24:37 2010 +0300
@@ -1,3 +1,18 @@
+#
+# 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 "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: 
+#
 # component name "USB Host Mass Storage Server"
 
 component	base_f32_shostmassstorage
--- a/userlibandfileserver/fileserver/shostmassstorage/server/protocol/cmassstoragefsm.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/userlibandfileserver/fileserver/shostmassstorage/server/protocol/cmassstoragefsm.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -1,4 +1,4 @@
-// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 2008-2010 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"
@@ -129,6 +129,7 @@
         User::Leave(KErrNotSupported);
         break;
     default:
+        __SCSIPRINT(_L("INQUIRY Command returned KErrUnknown"));
         User::Leave(KErrUnknown);
         break;
         }
@@ -150,6 +151,7 @@
         User::Leave(KErrNotSupported);
         break;
     default:
+        __SCSIPRINT(_L("INQUIRY Command returned KErrUnknown"));
         User::Leave(KErrUnknown);
         break;
         }
--- a/userlibandfileserver/fileserver/shostmassstorage/server/protocol/cscsiprotocol.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/userlibandfileserver/fileserver/shostmassstorage/server/protocol/cscsiprotocol.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -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	Tue Feb 02 01:24:03 2010 +0200
+++ b/userlibandfileserver/fileserver/shostmassstorage/server/protocol/tscsiblockcmds.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -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);
         }
--- a/userlibandfileserver/fileserver/shostmassstorage/server/shared/msctypes.h	Tue Feb 02 01:24:03 2010 +0200
+++ b/userlibandfileserver/fileserver/shostmassstorage/server/shared/msctypes.h	Fri Apr 16 16:24:37 2010 +0300
@@ -1,4 +1,4 @@
-// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 2008-2010 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"
@@ -47,9 +47,7 @@
 /** Transport layer error code */
 const TInt KErrCommandFailed = 0x100;
 /** Transport layer error code */
-const TInt KErrCommandNotSupported = 0x101;
-/** Transport layer error code */
-const TInt KErrCommandStalled = 0x102;
+const TInt KErrCommandStalled = 0x101;
 
 
 /**
--- a/userlibandfileserver/fileserver/shostmassstorage/server/transport/cbulkonlytransport.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/userlibandfileserver/fileserver/shostmassstorage/server/transport/cbulkonlytransport.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -1,4 +1,4 @@
-// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 2008-2010 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"
@@ -75,7 +75,7 @@
     {
     __MSFNSLOG
 	User::LeaveIfError(iInterface.Open(aInterfaceId));
-	iUsbInterfaceHandler = CUsbInterfaceHandler::NewL(iInterface);
+	iUsbInterfaceHandler = CUsbInterfaceHandler::NewL(iInterface, iBulkPipeIn);
 	InitialiseTransport();
     }
 
@@ -342,14 +342,22 @@
 	r = ProcessInTransferL(dataReceived);
     if (!r)
         {
-
+        TRAP(r, aResp->DecodeL(data));
         if (dataReceived == 0)
             {
+
+            // Some devices are found not to support DataResidue and return zero
+            // bytes received. This state is NOT treated as an error condition
+            // and we assume that all bytes are valid. For SCSI command set
+            // applicable to Mass Storage a device must always return data so
+            // the zero byte condition is not possible with compliant devices.
+            //
+            // List of known non-compliant devices:
+            // 1 Transcend JetFlashV30 VendorID=JetFlash ProductID=TS#GJFV30
+            // (# is device size in G)
+
             __BOTPRINT1(_L("Warning: No data received"), dataReceived);
-            return KErrCommandNotSupported;
             }
-
-        TRAP(r, aResp->DecodeL(data));
         }
 	return r;
 	}
--- a/userlibandfileserver/fileserver/shostmassstorage/server/transport/cusbifacehandler.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/userlibandfileserver/fileserver/shostmassstorage/server/transport/cusbifacehandler.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -1,4 +1,4 @@
-// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 2008-2010 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"
@@ -33,14 +33,15 @@
 #include "debug.h"
 #include "msdebug.h"
 
-CUsbInterfaceHandler* CUsbInterfaceHandler::NewL(RUsbInterface &aInterface)
+CUsbInterfaceHandler* CUsbInterfaceHandler::NewL(RUsbInterface &aInterface, RUsbPipe& aBulkPipeIn)
 	{
-	return new (ELeave) CUsbInterfaceHandler(aInterface);
+	return new (ELeave) CUsbInterfaceHandler(aInterface, aBulkPipeIn);
 	}
 
-CUsbInterfaceHandler::CUsbInterfaceHandler(RUsbInterface &aInterface)
+CUsbInterfaceHandler::CUsbInterfaceHandler(RUsbInterface &aInterface, RUsbPipe& aBulkPipeIn)
 :	CActive(EPriorityStandard),
-	iInterface(aInterface)
+	iInterface(aInterface),
+    iBulkPipeIn(aBulkPipeIn)
 	{
     __MSFNLOG
 	CActiveScheduler::Add(this);
@@ -75,26 +76,20 @@
 
 	if (error == KErrUsbStalled && iState == EGetMaxLun)
         {
-		__BOTPRINT(_L("...KErrUsbStalled"));
-		iState = EReset;
-		Reset();
-		return;
+        // Devices that do not support multiple LUNs may STALL this command
+		__BOTPRINT(_L("...KErrUsbStalled"));		
+        iBulkPipeIn.ClearRemoteStall();
+        error = KErrNone;     
         }
 
-	if (error == KErrNone)
+	else if (error == KErrNone)
         {
 		__BOTPRINT(_L("...KErrNone"));
-
 		if (iState == EGetMaxLun)
             {
 			__BOTPRINT(_L("...sending GetMaxLun response"));
 			*ipGetMaxLun = iBuffer[0];
             }
-		else
-            {
-			__BOTPRINT(_L("...defaulting to 0"));
-			*ipGetMaxLun = 0;
-            }
         }
     else
         {
@@ -117,6 +112,7 @@
 	iBotGetMaxLun = aMessage;
 	iState = EGetMaxLun;
 	ipGetMaxLun = aMaxLun;
+    *ipGetMaxLun = 0;       // default response is MaxLUN=0
 
 	reqDetails.iRequestType = 0xA1;
 	reqDetails.iRequest = 0xFE;
@@ -129,19 +125,3 @@
 	SetActive();
 	}
 
-
-void CUsbInterfaceHandler::Reset()
-	{
-    __MSFNLOG
-	RUsbInterface::TUsbTransferRequestDetails reqDetails;
-	_LIT8(KNullDesC8,"");
-
-	reqDetails.iRequestType = 0x21;
-	reqDetails.iRequest = 0xFF;
-	reqDetails.iValue = 0x0000;
-	reqDetails.iIndex = 0x0000;
-	reqDetails.iFlags = 0x04;		// Short transfer OK
-
-	iInterface.Ep0Transfer(reqDetails, KNullDesC8, (TDes8 &) KNullDesC8, iStatus);
-    SetActive();
-	}
--- a/userlibandfileserver/fileserver/shostmassstorage/server/transport/include/cusbifacehandler.h	Tue Feb 02 01:24:03 2010 +0200
+++ b/userlibandfileserver/fileserver/shostmassstorage/server/transport/include/cusbifacehandler.h	Fri Apr 16 16:24:37 2010 +0300
@@ -1,4 +1,4 @@
-// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 2008-2010 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"
@@ -24,14 +24,14 @@
 class CUsbInterfaceHandler : public CActive
 	{
 public:
-	CUsbInterfaceHandler(RUsbInterface &aInterface);
+    static CUsbInterfaceHandler* NewL(RUsbInterface &aInterface, RUsbPipe& aBulkPipeIn);
+	CUsbInterfaceHandler(RUsbInterface &aInterface, RUsbPipe& aBulkPipeIn);
 	~CUsbInterfaceHandler();
+
 	void GetMaxLun(TLun* aReceiveData, const RMessage2& aMessage);
-	static CUsbInterfaceHandler* NewL(RUsbInterface &aInterface);
-
+	
 private:
 	void RunL();
-	void Reset();
 	void DoCancel();
 
     enum TState
@@ -47,6 +47,7 @@
 	TLun* ipGetMaxLun;
 
 	RUsbInterface& iInterface;
+    RUsbPipe& iBulkPipeIn;
 	TBuf8<1> iBuffer;
 	};
 
--- a/userlibandfileserver/fileserver/smassstorage/base_f32_smassstorage.mrp	Tue Feb 02 01:24:03 2010 +0200
+++ b/userlibandfileserver/fileserver/smassstorage/base_f32_smassstorage.mrp	Fri Apr 16 16:24:37 2010 +0300
@@ -1,3 +1,18 @@
+#
+# 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 "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: 
+#
 # component name "USB Mass Storage File System"
 
 component	base_f32_smassstorage
--- a/userlibandfileserver/fileserver/smassstorage/cmassstoragefilesystem.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/userlibandfileserver/fileserver/smassstorage/cmassstoragefilesystem.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -21,6 +21,8 @@
 */
 
 #include <f32file.h>
+#include <f32ver.h>
+#include "cusbmassstoragecontroller.h"
 #include "cmassstoragefilesystem.h"
 #include "cmassstoragemountcb.h"
 #include "massstoragedebug.h"
--- a/userlibandfileserver/fileserver/smassstorage/cmassstoragemountcb.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/userlibandfileserver/fileserver/smassstorage/cmassstoragemountcb.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -23,10 +23,9 @@
 #include <f32fsys.h>
 #include <f32file.h>
 #include "cmassstoragemountcb.h"
+#include "cusbmassstoragecontroller.h"
 #include "cmassstoragefilesystem.h"
-#include "drivemanager.h"
 #include "massstoragedebug.h"
-#include "massstorageutil.h"
 
 CMassStorageMountCB::CMassStorageMountCB(const RArray<TInt>& aDriveMapping)
     : iDriveMapping(aDriveMapping)
@@ -214,281 +213,6 @@
 	delete hDes;
 	}
 
-/**
-Make sure that the file system is fat.
-*/
-TBool CMassStorageMountCB::ValidateBootSector()
-	{
-	__FNLOG("CMassStorageMountCB::ValidateBootSector");
-
-	TFatBootSector bootSector;
-	TInt r=ReadBootSector(bootSector);
-	__PRINT1(_L("CMassStorageMountCB::MountL - ReadBootSector returned %d"),r);
-	if (r != KErrNone)
-		{
-		return EFalse;
-		}
-
-	__PRINT(_L("\nBootSector info"));
-	__PRINT8BIT1(_L("FAT type = %S"),bootSector.FileSysType());
-	__PRINT8BIT1(_L("Vendor ID = %S"),bootSector.VendorId());
-	__PRINT1(_L("BytesPerSector %d"),bootSector.BytesPerSector());
-	__PRINT1(_L("SectorsPerCluster %d"),bootSector.SectorsPerCluster());
-	__PRINT1(_L("ReservedSectors %d"),bootSector.ReservedSectors());
-	__PRINT1(_L("NumberOfFats %d"),bootSector.NumberOfFats());
-	__PRINT1(_L("RootDirEntries %d"),bootSector.RootDirEntries());
-	__PRINT1(_L("Total Sectors = %d"),bootSector.TotalSectors());
-	__PRINT1(_L("MediaDescriptor = 0x%x"),bootSector.MediaDescriptor());
-	__PRINT1(_L("FatSectors %d"),bootSector.FatSectors());
-	__PRINT1(_L("SectorsPerTrack %d"),bootSector.SectorsPerTrack());
-	__PRINT1(_L("NumberOfHeads %d"),bootSector.NumberOfHeads());
-	__PRINT1(_L("HugeSectors %d"),bootSector.HugeSectors());
-	__PRINT1(_L("Fat32 Sectors %d"),bootSector.FatSectors32());
-	__PRINT1(_L("Fat32 Flags %d"),bootSector.FATFlags());
-	__PRINT1(_L("Fat32 Version Number %d"),bootSector.VersionNumber());
-	__PRINT1(_L("Root Cluster Number %d"),bootSector.RootClusterNum());
-	__PRINT1(_L("FSInfo Sector Number %d"),bootSector.FSInfoSectorNum());
-	__PRINT1(_L("Backup Boot Rec Sector Number %d"),bootSector.BkBootRecSector());
-	__PRINT1(_L("PhysicalDriveNumber %d"),bootSector.PhysicalDriveNumber());
-	__PRINT1(_L("ExtendedBootSignature %d"),bootSector.ExtendedBootSignature());
-	__PRINT1(_L("UniqueID %d"),bootSector.UniqueID());
-	__PRINT8BIT1(_L("VolumeLabel %S"),bootSector.VolumeLabel());
-	__PRINT8BIT1(_L("FileSysType %S\n"),bootSector.FileSysType());
-
-    iUniqueID=bootSector.UniqueID();
-	iIs16BitFat=bootSector.Is16BitFat();
-
-	iIs32BitFat=bootSector.Is32BitFat();
-	switch (DetermineFatType(bootSector))
-		{
-		case 12:
-			iIs16BitFat = EFalse;
-			iIs32BitFat = EFalse;
-			break;
-		case 16:
-			iIs16BitFat = ETrue;
-			iIs32BitFat = EFalse;
-			break;
-		case 32:
-			iIs16BitFat = EFalse;
-			iIs32BitFat = ETrue;
-			break;
-		default:
-			return EFalse;
-		}
-
-	TInt sectorsPerCluster=bootSector.SectorsPerCluster();
-	if (!IsPowerOfTwo(sectorsPerCluster))
-		return EFalse;
-
-	TInt sectorSizeLog2=Log2(bootSector.BytesPerSector());
-	if (sectorSizeLog2<0 || !IsPowerOfTwo(bootSector.BytesPerSector()))
-		return EFalse;
-
-	TInt firstFatSector=bootSector.ReservedSectors();
-	if (firstFatSector<1)
-		return EFalse;
-
-	TInt fatSizeInBytes;
-	if(iIs32BitFat)
-		{
-		fatSizeInBytes=bootSector.FatSectors32()*bootSector.BytesPerSector();
-		if (fatSizeInBytes<bootSector.BytesPerSector())
-			return EFalse;
-		}
-	else
-		{
-		fatSizeInBytes=bootSector.FatSectors()*bootSector.BytesPerSector();
-		if (fatSizeInBytes<bootSector.BytesPerSector())
-			return EFalse;
-
-		TInt rootDirectorySector=firstFatSector+bootSector.FatSectors()*bootSector.NumberOfFats();
-		if (rootDirectorySector<3)
-			return EFalse;
-
-		TInt rootDirSizeInBytes=bootSector.RootDirEntries()*KSizeOfFatDirEntry;
-		TInt numOfRootDirSectors=(rootDirSizeInBytes+(1<<sectorSizeLog2)-1)>>sectorSizeLog2;
-		TInt rootDirEnd=(rootDirectorySector+numOfRootDirSectors)<<sectorSizeLog2;
-		if (rootDirEnd<(4<<sectorSizeLog2))
-			return EFalse;
-		}
-
-
-	TInt totalSectors=bootSector.TotalSectors();
-	if (totalSectors==0)
-		totalSectors=bootSector.HugeSectors();
-	if (totalSectors<5)
-		return EFalse;
-
-	TInt numberOfFats=bootSector.NumberOfFats();
-	if (numberOfFats<1)
-		return EFalse;
-
-	return ETrue;
-	}
-
-/**
-Read non aligned boot data from media into TFatBootSector structure
-
-@param aBootSector refrence to TFatBootSector populate
-@return Media read error code
-*/
-TInt CMassStorageMountCB::ReadBootSector(TFatBootSector& aBootSector)
-	{
-	__FNLOG("CMassStorageMountCB::ReadBootSector");
-	TInt pos=0;
-	TUint8 data[KSizeOfFatBootSector];
-    TPtr8 buf(&data[0],KSizeOfFatBootSector);
-    TInt r=LocalDrive()->Read(0,KSizeOfFatBootSector,buf);
-	if (r!=KErrNone)
-		{
-		__PRINT1(_L("LocalDrive::Read() failed - %d"),r);
-		return(r);
-		}
-//	0	TUint8 iJumpInstruction[3]
-	Mem::Copy(&aBootSector.iJumpInstruction,&data[pos],3);
-	pos+=3;
-// 3	TUint8 iVendorId[KVendorIdSize]
-	Mem::Copy(&aBootSector.iVendorId,&data[pos],KVendorIdSize);
-	pos+=KVendorIdSize;
-// 11	TUint16 iBytesPerSector
-	Mem::Copy(&aBootSector.iBytesPerSector,&data[pos],2);
-	pos+=2;
-// 13	TUint8 sectorsPerCluster
-	Mem::Copy(&aBootSector.iSectorsPerCluster,&data[pos],1);
-	pos+=1;
-// 14	TUint16 iReservedSectors
-	Mem::Copy(&aBootSector.iReservedSectors,&data[pos],2);
-	pos+=2;
-// 16	TUint8 numberOfFats
-	Mem::Copy(&aBootSector.iNumberOfFats,&data[pos],1);
-	pos+=1;
-// 17	TUint16 iRootDirEntries
-	Mem::Copy(&aBootSector.iRootDirEntries,&data[pos],2);
-	pos+=2;
-// 19	TUint16 totalSectors
-	Mem::Copy(&aBootSector.iTotalSectors,&data[pos],2);
-	pos+=2;
-// 21	TUint8 iMediaDescriptor
-	Mem::Copy(&aBootSector.iMediaDescriptor,&data[pos],1);
-	pos+=1;
-// 22	TUint16 iFatSectors
-	Mem::Copy(&aBootSector.iFatSectors,&data[pos],2);
-	pos+=2;
-// 24	TUint16 iSectorsPerTrack
-	Mem::Copy(&aBootSector.iSectorsPerTrack,&data[pos],2);
-	pos+=2;
-// 26	TUint16 iNumberOfHeads
-	Mem::Copy(&aBootSector.iNumberOfHeads,&data[pos],2);
-	pos+=2;
-// 28	TUint32 iHiddenSectors
-	Mem::Copy(&aBootSector.iHiddenSectors,&data[pos],4);
-	pos+=4;
-// 32	TUint32 iHugeSectors
-	Mem::Copy(&aBootSector.iHugeSectors,&data[pos],4);
-	pos+=4;
-
-	if(aBootSector.iRootDirEntries == 0)	//indicates we have FAT32 volume
-		{
-		__PRINT(_L("\nFile system thinks Fat32"));
-
-		//36 TUint32 iFatSectors32
-		Mem::Copy(&aBootSector.iFatSectors32, &data[pos],4);
-		pos+=4;
-		//40 TUint16 iFATFlags
-		Mem::Copy(&aBootSector.iFATFlags, &data[pos],2);
-		pos+=2;
-		//42 TUint16 iVersionNumber
-		Mem::Copy(&aBootSector.iVersionNumber, &data[pos],2);
-		pos+=2;
-		//44 TUint32 iRootClusterNum
-		Mem::Copy(&aBootSector.iRootClusterNum, &data[pos],4);
-		pos+=4;
-		//48 TUint16 iFSInfoSectorNum
-		Mem::Copy(&aBootSector.iFSInfoSectorNum, &data[pos],2);
-		pos+=2;
-		//50 TUint16 iBkBootRecSector
-		Mem::Copy(&aBootSector.iBkBootRecSector, &data[pos],2);
-		pos+=(2+12);//extra 12 for the reserved bytes
-		}
-
-// 36|64	TUint8 iPhysicalDriveNumber
-	Mem::Copy(&aBootSector.iPhysicalDriveNumber,&data[pos],1);
-	pos+=1;
-// 37|65	TUint8 iReserved
-	Mem::Copy(&aBootSector.iReserved,&data[pos],1);
-	pos+=1;
-// 38|66	TUint8 iExtendedBootSignature
-	Mem::Copy(&aBootSector.iExtendedBootSignature,&data[pos],1);
-	pos+=1;
-// 39|67	TUint32 iUniqueID
-	Mem::Copy(&aBootSector.iUniqueID,&data[pos],4);
-	pos+=4;
-// 43|71	TUint8 iVolumeLabel[KVolumeLabelSize]
-	Mem::Copy(&aBootSector.iVolumeLabel,&data[pos],KVolumeLabelSize);
-	pos+=KVolumeLabelSize;
-// 54|82	TUint8 iFileSysType[KFileSysTypeSize]
-	Mem::Copy(&aBootSector.iFileSysType,&data[pos],KFileSysTypeSize);
-// 62|90
-
-	return(KErrNone);
-	}
-
-/**
-Work out if we have a FAT12|16|32 volume.
-Returns 12, 16 or 32 as appropriate.
-Returns 0 if can't be calculated (invalid values)
-*/
-TInt CMassStorageMountCB::DetermineFatType(TFatBootSector& aBootSector)
-	{
-	TUint32 ressectors = aBootSector.ReservedSectors();
-
-	if (aBootSector.SectorsPerCluster() < 1)
-		return 0;
-
-	if (aBootSector.RootDirEntries() != 0)
-		{
-		TUint32 rootdirbytes;
-		rootdirbytes = aBootSector.RootDirEntries() * 32 + aBootSector.BytesPerSector() - 1;
-		ressectors += rootdirbytes / aBootSector.BytesPerSector();
-		}
-
-	if (aBootSector.FatSectors() != 0)
-		ressectors += aBootSector.NumberOfFats() * aBootSector.FatSectors();
-	else
-		ressectors += aBootSector.NumberOfFats() * aBootSector.FatSectors32();
-
-	TUint32 totalsectors;
-	if (aBootSector.TotalSectors() != 0)
-		totalsectors = aBootSector.TotalSectors();
-	else
-		totalsectors = aBootSector.HugeSectors();
-
-	if (ressectors < 1 || totalsectors < 1)
-		return 0;
-
-	TUint32 datasec;
-	datasec = totalsectors - ressectors;
-
-	TUint32 countofclusters;
-	countofclusters = datasec / aBootSector.SectorsPerCluster();
-
-	__PRINT1(_L("CFatMountCB: Count of clusters = %d\n"), countofclusters);
-
-	if (countofclusters < 4085)
-		{
-		return 12;
-		}
-	else if (countofclusters < 65525)
-		{
-		return 16;
-		}
-	else
-		{
-		return 32;
-		}
-	}
-
 TInt CMassStorageMountCB::ReMount()
 	{
 	return KErrNotReady;
--- a/userlibandfileserver/fileserver/smassstorage/inc/cmassstoragefilesystem.h	Tue Feb 02 01:24:03 2010 +0200
+++ b/userlibandfileserver/fileserver/smassstorage/inc/cmassstoragefilesystem.h	Fri Apr 16 16:24:37 2010 +0300
@@ -23,11 +23,9 @@
 #ifndef __CMASSSTORAGEFILESYSTEM_H__
 #define __CMASSSTORAGEFILESYSTEM_H__
 
-#include <f32fsys.h>
-#include <f32ver.h>
-#include <f32file.h>
-#include "cusbmassstoragecontroller.h"
 
+//Forward Declaration
+class CUsbMassStorageController;
 
 /**
 Mass Storage Filesystem class.
@@ -75,8 +73,6 @@
 	CUsbMassStorageController* iMassStorageController;
 	TBool iRunning;
 	RArray<TInt> iMsDrives;
-	
-			
 	};
 
 #endif // __CMASSSTORAGEFILESYSTEM_H__
--- a/userlibandfileserver/fileserver/smassstorage/inc/cmassstoragemountcb.h	Tue Feb 02 01:24:03 2010 +0200
+++ b/userlibandfileserver/fileserver/smassstorage/inc/cmassstoragemountcb.h	Fri Apr 16 16:24:37 2010 +0300
@@ -23,7 +23,6 @@
 #ifndef __CMASSSTORAGEMOUNTCB_H__
 #define __CMASSSTORAGEMOUNTCB_H__
 
-#include <f32fsys.h>
 
 /**
 Mass Storage Mount.
@@ -32,7 +31,6 @@
 ControlIO is also supported for debug builds and returns KErrNotSupported for Release builds.
 @internalTechnology
 */
-class TFatBootSector;
 class CMassStorageMountCB : public CLocDrvMountCB
 	{
 	public:
@@ -63,205 +61,11 @@
 	CMassStorageMountCB(const RArray<TInt>& aDriveMapping);
 	void WritePasswordData();
 	TInt DriveNumberToLun(TInt aDriveNumber);
-	TBool ValidateBootSector();
-	TInt ReadBootSector(TFatBootSector& aBootSector);
-	TInt DetermineFatType(TFatBootSector& aBootSector);
 	TInt CheckDriveNumberL();
 
 	private:
-	TBool iIs16BitFat;
-	TBool iIs32BitFat;
 	const RArray<TInt>& iDriveMapping;
 	};
 
-const TInt KSizeOfFatBootSector	= 90;
-const TInt KVendorIdSize = 8;
-const TInt KVolumeLabelSize = 11;
-const TInt KFileSysTypeSize = 8;
-const TInt KBootSectorSignature = 0xAA55;
-const TInt KSizeOfFatDirEntry = 32;
-
-/**
-Boot sector parameter block, enables access to all file system parameters.
-Data is populated at mount time from the BPB sector
-@internalTechnology
-*/
-class TFatBootSector
-	{
-public:
-	inline const TPtrC8 VendorId() const;
-	inline TUint16 BytesPerSector() const;
-	inline TInt SectorsPerCluster() const;
-	inline TInt ReservedSectors() const;
-	inline TInt NumberOfFats() const;
-	inline TInt RootDirEntries() const;
-	inline TInt TotalSectors() const;
-	inline TUint8 MediaDescriptor() const;
-	inline TInt FatSectors() const;
-	inline TInt SectorsPerTrack() const;
-	inline TInt NumberOfHeads() const;
-	inline TInt HiddenSectors() const;
-	inline TInt HugeSectors() const;
-	inline TInt PhysicalDriveNumber() const;
-	inline TInt ExtendedBootSignature() const;
-	inline TUint32 UniqueID() const;
-	inline const TPtrC8 VolumeLabel() const;
-	inline const TPtrC8 FileSysType() const;
-	inline TInt BootSectorSignature() const;
-	inline void SetJumpInstruction();
-	inline void SetVendorID(const TDesC8& aDes);
-	inline void SetBytesPerSector(TInt aBytesPerSector);
-	inline void SetSectorsPerCluster(TInt aSectorsPerCluster);
-	inline void SetReservedSectors(TInt aReservedSectors);
-	inline void SetNumberOfFats(TInt aNumberOfFats);
-	inline void SetRootDirEntries(TInt aRootDirEntries);
-	inline void SetTotalSectors(TInt aTotalSectors);
-	inline void SetMediaDescriptor(TUint8 aMediaDescriptor);
-	inline void SetFatSectors(TInt aFatSectors);
-	inline void SetSectorsPerTrack(TInt aSectorsPerTrack);
-	inline void SetNumberOfHeads(TInt aNumberOfHeads);
-	inline void SetHiddenSectors(TUint32 aHiddenSectors);
-	inline void SetHugeSectors(TUint32 aTotalSectors);
-	inline void SetPhysicalDriveNumber(TInt aPhysicalDriveNumber);
-	inline void SetReservedByte(TUint8 aReservedByte);
-	inline void SetExtendedBootSignature(TInt anExtendedBootSignature);
-	inline void SetUniqueID(TUint32 anUniqueID);
-	inline void SetVolumeLabel(const TDesC8& aDes);
-	inline void SetFileSysType(const TDesC8& aDes);
-
-	inline void SetFatSectors32(TUint32	aFatSectors32);
-	inline void SetFATFlags(TUint16 aFATFlags);
-	inline void SetVersionNumber(TUint16	aVersionNumber);
-	inline void SetRootClusterNum(TUint32 aRootCusterNum);
-	inline void SetFSInfoSectorNum(TUint16 aFSInfoSectorNum);
-	inline void SetBkBootRecSector(TUint16 aBkBootRecSector);
-	inline TUint32 FatSectors32() const;
-	inline TUint16 FATFlags() const;
-	inline TUint16 VersionNumber() const;
-	inline TUint32 RootClusterNum() const;
-	inline TUint16 FSInfoSectorNum() const;
-	inline TUint16 BkBootRecSector() const;
-public:
-	inline TBool Is16BitFat();
-	inline TBool Is32BitFat();
-	inline TInt FirstFatSectorPos();
-	inline TInt RootDirStartSector();
-	inline TInt FirstFreeSector();
-public:
-	/**
-	Jump instruction used for bootable volumes
-	*/
-    TUint8 iJumpInstruction[3];
-	/**
-	Vendor ID of the file system that formatted the volume
-	*/
-    TUint8 iVendorId[KVendorIdSize];
-	/**
-	Bytes per sector
-	*/
-    TUint16 iBytesPerSector;
-	/**
-	Sectors per cluster ratio
-	*/
-    TUint8 iSectorsPerCluster;
-	/**
-	Number of reserved sectors on the volume
-	*/
-    TUint16 iReservedSectors;
-	/**
-	Number of Fats on the volume
-	*/
-    TUint8 iNumberOfFats;
-	/**
-	Number of entries allowed in the root directory, specific to Fat12/16, zero for FAT32
-	*/
-    TUint16 iRootDirEntries;
-	/**
-	Total sectors on the volume, zero for FAT32
-	*/
-    TUint16 iTotalSectors;
-	/**
-	Media descriptor
-	*/
-    TUint8 iMediaDescriptor;
-	/**
-	Sectors used for the Fat table, zero for FAT32
-	*/
-    TUint16 iFatSectors;
-	/**
-	Sectors per track
-	*/
-    TUint16 iSectorsPerTrack;
-	/**
-	Number of heads
-	*/
-    TUint16 iNumberOfHeads;
-	/**
-	Number of hidden sectors in the volume
-	*/
-    TUint32 iHiddenSectors;
-	/**
-	Total sectors in the volume, Used if totalSectors > 65535
-	*/
-    TUint32 iHugeSectors;
-
-	/**
-	Start of additional elements @ offset 36 for FAT32
-	Sectors in Fat table for 32 bit volume
-	*/
-	TUint32	iFatSectors32;
-	/**
-	Fat flags
-	*/
-	TUint16 iFATFlags;
-	/**
-	Version number of the file system
-	*/
-	TUint16	iVersionNumber;
-	/**
-	Cluster number of the root directory
-	*/
-	TUint32 iRootClusterNum;
-	/**
-	Sector number containing the FSIInfo structure
-	*/
-	TUint16 iFSInfoSectorNum;
-	/**
-	Backup boot sector
-	*/
-	TUint16 iBkBootRecSector;
-	/**
-	Reserved space
-	End of Fat32 Only parameters section
-	*/
-	TUint8	iReserved2[12];
-
-	/**
-	Physical drive number, not used in Symbian OS
-	*/
-	TUint8 iPhysicalDriveNumber;
-	/**
-	Reserved byte
-	*/
-    TUint8 iReserved;
-	/**
-	Extended boot signiture
-	*/
-    TUint8 iExtendedBootSignature;
-	/**
-	Unique volume ID
-	*/
-    TUint32 iUniqueID;
-	/**
-	The volume's label
-	*/
-    TUint8 iVolumeLabel[KVolumeLabelSize];
-	/**
-	File system type
-	*/
-	TUint8 iFileSysType[KFileSysTypeSize];
-	};
-
-#include "tfatbootsector.inl"
 
 #endif //__CMASSSTORAGEMOUNTCB_H__
--- a/userlibandfileserver/fileserver/smassstorage/inc/scsiprot.h	Tue Feb 02 01:24:03 2010 +0200
+++ b/userlibandfileserver/fileserver/smassstorage/inc/scsiprot.h	Fri Apr 16 16:24:37 2010 +0300
@@ -1,4 +1,4 @@
-// Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 2004-2010 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"
@@ -135,7 +135,8 @@
 	}
 
 
-const TUint KModeSenseCommandLength = 4;
+const TUint KModeSense6CommandLength = 4;
+const TUint KModeSense10CommandLength = 8;
 const TUint KReadCapacityCommandLength = 8;
 const TUint KReadFormatCapacitiesCommandLength = 12;
 const TUint KRequestSenseCommandLength = 18;
@@ -156,7 +157,7 @@
 	ETestUnitReady			= 0x00,
 	ERequestSense			= 0x03,
 	EInquiry 				= 0x12,
-	EModeSense				= 0x1A,
+	EModeSense6				= 0x1A,
 	EStartStopUnit			= 0x1B,
 	EPreventMediaRemoval	= 0x1E,
 	EReadFormatCapacities	= 0x23,
@@ -164,6 +165,7 @@
 	ERead10 				= 0x28,
 	EWrite10				= 0x2A,
 	EVerify10				= 0x2f,
+    EModeSense10			= 0x5A,
 	EUndefinedCommand		= 0xFF
 	};
 
@@ -197,7 +199,8 @@
 	TBool HandleRead10(TPtrC8& aData, TUint aLun);
 	TBool HandleWrite10(TPtrC8& aData, TUint aLun);
 	TBool HandleVerify10(TPtrC8& aData, TUint aLun);
-	TBool HandleModeSense(TPtrC8& aData, TUint aLun);
+	TBool HandleModeSense6(TPtrC8& aData, TUint aLun);
+    TBool HandleModeSense10(TPtrC8& aData, TUint aLun);
 	TBool HandleReadFormatCapacities(TUint aLun);
 
 private:
--- a/userlibandfileserver/fileserver/smassstorage/inc/tfatbootsector.inl	Tue Feb 02 01:24:03 2010 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,458 +0,0 @@
-// Copyright (c) 2004-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:
-// Inline methods of TFatBootSector class.
-// 
-//
-
-/**
- @file
- @internalTechnology
- 
- Returns Sectors in Fat table for 32 bit volume
- 
- @return iFatSectors32
-*/
-inline TUint32 TFatBootSector::FatSectors32() const	
-	{return iFatSectors32;}
-/**
-Fat flags
-
-@return iFATFlags
-*/
-inline TUint16 TFatBootSector::FATFlags() const		
-	{return iFATFlags;}
-/**
-Version number of the file system
-
-@return iVersionNumber
-*/
-inline TUint16 TFatBootSector::VersionNumber() const		
-	{return iVersionNumber;}
-/**
-Cluster number of the root directory
-
-@return iRootClusterNum
-*/
-inline TUint32 TFatBootSector::RootClusterNum() const	
-	{return iRootClusterNum;}
-/**
-Sector number containing the FSIInfo structure
-
-@return iFSInfoSectorNum
-*/
-inline TUint16 TFatBootSector::FSInfoSectorNum() const
-	{return iFSInfoSectorNum;}
-/**
-Backup boot sector
-
-@return iBkBootRecSector
-*/
-inline TUint16 TFatBootSector::BkBootRecSector() const
-	{return iBkBootRecSector;}
-/**
-Sets the number of sectors in Fat table for 32 bit volume
-
-@param aFatSectors32
-*/
-inline void TFatBootSector::SetFatSectors32(TUint32	aFatSectors32)
-	{iFatSectors32 = aFatSectors32;}
-/**
-Sets the Fat flags
-
-@param aFATFlags
-*/
-inline void TFatBootSector::SetFATFlags(TUint16 aFATFlags)
-	{iFATFlags = aFATFlags;}
-/**
-Sets the version number of the file system
-
-@param aVersionNumber
-*/
-inline void TFatBootSector::SetVersionNumber(TUint16 aVersionNumber)
-	{iVersionNumber = aVersionNumber;}
-/**
-Sets the cluster number of the root directory
-
-@param aRootClusterNum
-*/
-inline void TFatBootSector::SetRootClusterNum(TUint32 aRootClusterNum)	
-	{iRootClusterNum = aRootClusterNum;}
-/**
-Set the sector number containing the FSIInfo structure
-
-@param aFSInfoSectorNum
-*/
-inline void TFatBootSector::SetFSInfoSectorNum(TUint16 aFSInfoSectorNum)
-	{iFSInfoSectorNum = aFSInfoSectorNum;}
-/**
-Set the backup boot sector
-
-@param aBkBootRecSector
-*/
-inline void TFatBootSector::SetBkBootRecSector(TUint16 aBkBootRecSector)
-	{iBkBootRecSector = aBkBootRecSector;}	
-/**
-Quick test as to whether the volume is Fat32
-
-@return True for Fat32
-*/
-inline TBool TFatBootSector::Is32BitFat()
-	{return(iRootDirEntries==0);}
-/**
-Returns the vendor ID of the file system that formatted the volume
-
-@return A descriptor containing the vendor ID 
-*/
-inline const TPtrC8 TFatBootSector::VendorId() const
-	{return TPtrC8(iVendorId,KVendorIdSize);}
-/**
-Return the bytes per sector
-
-@return iBytesPerSector
-*/
-inline TUint16 TFatBootSector::BytesPerSector() const
-	{return iBytesPerSector;}
-/**
-Returns the sectors per cluster ratio
-
-@return iSectorsPerCluster
-*/
-inline TInt TFatBootSector::SectorsPerCluster() const
-	{return iSectorsPerCluster;}
-/**
-Returns the number of reserved sectors on the volume
-
-@return iReservedSectors
-*/
-inline TInt TFatBootSector::ReservedSectors() const
-	{return iReservedSectors;}
-/**
-Returns the number of Fats on the volume
-
-@return iNumberOfFats
-*/
-inline TInt TFatBootSector::NumberOfFats() const
-	{return iNumberOfFats;}
-/**
-Returns the number of entries allowed in the root directory, specific to Fat12/16, zero for FAT32
-
-@return iRootDirEntries
-*/
-inline TInt TFatBootSector::RootDirEntries() const
-	{return iRootDirEntries;}
-/**
-Returns the total sectors on the volume, zero for FAT32
-
-@return iTotalSectors
-*/
-inline TInt TFatBootSector::TotalSectors() const
-	{return iTotalSectors;}
-/**
-Returns the media descriptor
-
-@return iMediaDescriptor
-*/
-inline TUint8 TFatBootSector::MediaDescriptor() const
-	{return iMediaDescriptor;}
-/**
-Returns sectors used for the Fat table, zero for FAT32
-
-@return iFatSectors
-*/
-inline TInt TFatBootSector::FatSectors() const
-	{return iFatSectors;}
-/**
-Returns sectors per track
-
-@return iSectorsPerTrack
-*/
-inline TInt TFatBootSector::SectorsPerTrack() const
-	{return iSectorsPerTrack;}
-/**
-Returns the number of heads 
-
-@return iNumberOfHeads
-*/
-inline TInt TFatBootSector::NumberOfHeads() const
-	{return iNumberOfHeads;}
-/**
-Returns the number of hidden sectors in the volume
-
-@return iHiddenSectors
-*/
-inline TInt TFatBootSector::HiddenSectors() const
-	{return iHiddenSectors;}
-/**
-Returns total sectors in the volume, Used if totalSectors > 65535
-
-@return iHugeSectors
-*/
-inline TInt TFatBootSector::HugeSectors() const
-	{return iHugeSectors;}
-/**
-Returns the physical drive number, not used in Symbian OS
-
-@return iPhysicalDriveNumber
-*/
-inline TInt TFatBootSector::PhysicalDriveNumber() const
-	{return iPhysicalDriveNumber;}
-/**
-Returns the extended boot signiture
-
-@return iExtendedBootSignature
-*/
-inline TInt TFatBootSector::ExtendedBootSignature() const
-	{return iExtendedBootSignature;}
-/**
-Returns the unique volume ID
-
-@return iUniqueID
-*/
-inline TUint32 TFatBootSector::UniqueID() const
-	{return iUniqueID;}
-/**
-Returns the volume's label
-
-@return A descriptor containing the volume label
-*/
-inline const TPtrC8 TFatBootSector::VolumeLabel() const
-	{return TPtrC8(iVolumeLabel,KVolumeLabelSize);}
-/**
-Returns the file system type
-
-@return A descriptor containing the file system type
-*/
-inline const TPtrC8 TFatBootSector::FileSysType() const
-	{return TPtrC8(iFileSysType,KFileSysTypeSize);}
-/**
-Returns the boot sector signiture
-
-@return KBootSectorSignature
-*/
-inline TInt TFatBootSector::BootSectorSignature() const
-	{return KBootSectorSignature;}
-/**
-Set the jump instruction 
-*/
-inline void TFatBootSector::SetJumpInstruction()
-	{iJumpInstruction[0]=0xE9;iJumpInstruction[2]=0x90;}
-/**
-Set the vendor ID of the file system that formatted the volume
-
-@param aDes Descriptor containing the Vendor ID
-*/
-inline void TFatBootSector::SetVendorID(const TDesC8& aDes)
-	{
-	__ASSERT_DEBUG(aDes.Length()<=KVendorIdSize,User::Panic(_L("FATFILESYS"),1));
-	TPtr8 buf(iVendorId,KVendorIdSize);
-	buf=aDes;
-	}
-/**
-Sets the bytes per sector 
-
-@param aBytesPerSector Number of bytes per sector
-*/
-inline void TFatBootSector::SetBytesPerSector(TInt aBytesPerSector)
-	{
-	__ASSERT_DEBUG(!(aBytesPerSector&~KMaxTUint16),User::Panic(_L("FATFILESYS"),1));
-	iBytesPerSector=(TUint16)aBytesPerSector;
-	}
-/**
-Set the sectors per cluster ratio
-
-@param aSectorsPerCluster Number of sectors per cluster
-*/
-inline void TFatBootSector::SetSectorsPerCluster(TInt aSectorsPerCluster)
-	{
-	__ASSERT_DEBUG(!(aSectorsPerCluster&~KMaxTUint8),User::Panic(_L("FATFILESYS"),1));
-	iSectorsPerCluster=(TUint8)aSectorsPerCluster;
-	}
-/**
-Sets the number of reserved sectors on the volume
-
-@param aReservedSectors Number of reserved sectors
-*/
-inline void TFatBootSector::SetReservedSectors(TInt aReservedSectors)
-	{
-	__ASSERT_DEBUG(!(aReservedSectors&~KMaxTUint16),User::Panic(_L("FATFILESYS"),1));
-	iReservedSectors=(TUint16)aReservedSectors;
-	}
-/**
-Sets the number of Fats on the volume
-
-@param aNumberOfFats Number of fats
-*/
-inline void TFatBootSector::SetNumberOfFats(TInt aNumberOfFats)
-	{
-	__ASSERT_DEBUG(!(aNumberOfFats&~KMaxTUint8),User::Panic(_L("FATFILESYS"),1));
-	iNumberOfFats=(TUint8)aNumberOfFats;
-	}
-/**
-Number of entries allowed in the root directory, specific to Fat12/16, zero for FAT32
-
-@param aRootDirEntries
-*/
-inline void TFatBootSector::SetRootDirEntries(TInt aRootDirEntries)
-	{
-	__ASSERT_DEBUG(!(aRootDirEntries&~KMaxTUint16),User::Panic(_L("FATFILESYS"),1));
-	iRootDirEntries=(TUint16)aRootDirEntries;
-	}
-/**
-Total sectors on the volume, zero for FAT32
-
-@param aTotalSectors Total number of sectors
-*/
-inline void TFatBootSector::SetTotalSectors(TInt aTotalSectors)
-	{
-	__ASSERT_DEBUG(!(aTotalSectors&~KMaxTUint16),User::Panic(_L("FATFILESYS"),1));
-	iTotalSectors=(TUint16)aTotalSectors;
-	}
-/**
-Set the media descriptor
-
-@param aMediaDescriptor
-*/
-inline void TFatBootSector::SetMediaDescriptor(TUint8 aMediaDescriptor)
-	{iMediaDescriptor=aMediaDescriptor;}
-/**
-Sectors used for the Fat table, zero for FAT32
-
-@param aFatSectors Number of Fat sectors
-*/
-inline void TFatBootSector::SetFatSectors(TInt aFatSectors)
-	{
-	__ASSERT_DEBUG(!(aFatSectors&~KMaxTUint16),User::Panic(_L("FATFILESYS"),1));
-	iFatSectors=(TUint16)aFatSectors;
-	}
-/**
-Set the sectors per track
-
-@param aSectorsPerTrack Number of sectors per track
-*/
-inline void TFatBootSector::SetSectorsPerTrack(TInt aSectorsPerTrack)
-	{
-	__ASSERT_DEBUG(!(aSectorsPerTrack&~KMaxTUint16),User::Panic(_L("FATFILESYS"),1));
-	iSectorsPerTrack=(TUint16)aSectorsPerTrack;
-	}
-/**
-Set the number of heads
-
-@param aNumberOfHeads Number of heads
-*/
-inline void TFatBootSector::SetNumberOfHeads(TInt aNumberOfHeads)
-	{
-	__ASSERT_DEBUG(!(aNumberOfHeads&~KMaxTUint16),User::Panic(_L("FATFILESYS"),1));
-	iNumberOfHeads=(TUint16)aNumberOfHeads;
-	}
-/**
-Set the number of hidden sectors in the volume
-
-@param aHiddenSectors Number of hidden sectors
-*/
-inline void TFatBootSector::SetHiddenSectors(TUint32 aHiddenSectors)
-	{
-	iHiddenSectors=(TUint32)(aHiddenSectors);
-	}
-/**
-Set the total sectors in the volume, Used if totalSectors > 65535
-
-@param aHugeSectors
-*/
-inline void TFatBootSector::SetHugeSectors(TUint32 aHugeSectors)
-	{iHugeSectors=aHugeSectors;}
-/**
-Physical drive number, not used in Symbian OS
-
-@param aPhysicalDriveNumber Physical drive number 
-*/
-inline void TFatBootSector::SetPhysicalDriveNumber(TInt aPhysicalDriveNumber)
-	{
-	__ASSERT_DEBUG(!(aPhysicalDriveNumber&~KMaxTUint8),User::Panic(_L("FATFILESYS"),1));
-	iPhysicalDriveNumber=(TUint8)aPhysicalDriveNumber;
-	}
-/**
-Set the reserved byte value
-
-@param aReservedByte Value for reserved byte
-*/
-inline void TFatBootSector::SetReservedByte(TUint8 aReservedByte)
-	{iReserved=aReservedByte;}
-/**
-Set the extended boot signiture
-
-@param anExtendedBootSignature The extended boot signiture
-*/
-inline void TFatBootSector::SetExtendedBootSignature(TInt anExtendedBootSignature)
-	{
-	__ASSERT_DEBUG(!(anExtendedBootSignature&~KMaxTUint8),User::Panic(_L("FATFILESYS"),1));
-	iExtendedBootSignature=(TUint8)anExtendedBootSignature;
-	}
-/**
-Set the unique volume ID
-
-@param anUniqueID Set the unique ID
-*/
-inline void TFatBootSector::SetUniqueID(TUint32 anUniqueID)
-	{iUniqueID=anUniqueID;}
-/**
-Set the volume's label
-
-@param aDes A descriptor containg the volume label
-*/
-inline void TFatBootSector::SetVolumeLabel(const TDesC8& aDes)
-	{
-	__ASSERT_DEBUG(aDes.Length()<=KVolumeLabelSize,User::Panic(_L("FATFILESYS"),1));
-	TPtr8 buf(iVolumeLabel,KVolumeLabelSize);
-	buf=aDes;
-	}
-/**
-Set the file system type
-
-@param aDes A descriptor containing the file system type
-*/
-inline void TFatBootSector::SetFileSysType(const TDesC8& aDes)
-	{
-	__ASSERT_DEBUG(aDes.Length()<=8,User::Panic(_L("FATFILESYS"),1));
-	TPtr8 buf(iFileSysType,8);
-	buf=aDes;
-	}
-/**
-Tests if the volume is Fat 16 or not
-
-@return True if the volume is Fat16
-*/
-inline TBool TFatBootSector::Is16BitFat()
-	{return(FileSysType()==_L8("FAT16   "));}
-/**
-Returns the position of the first sector of the first Fat
-
-@return The first Fat sector's byte position
-*/
-inline TInt TFatBootSector::FirstFatSectorPos()
-	{return(ReservedSectors()*BytesPerSector());}
-/**
-Returns the start sector number of the root directory
-
-@return Start sector number of the root directory
-*/
-inline TInt TFatBootSector::RootDirStartSector()
-	{return(ReservedSectors()+FatSectors()*NumberOfFats());}
-/**
-Returns the sector number of the first sector after the root directory 
-
-@return 
-*/
-inline TInt TFatBootSector::FirstFreeSector()
-	{return(RootDirStartSector()+(RootDirEntries()*KSizeOfFatDirEntry+BytesPerSector()-1)/BytesPerSector());}
-
--- a/userlibandfileserver/fileserver/smassstorage/scsiprot.cpp	Tue Feb 02 01:24:03 2010 +0200
+++ b/userlibandfileserver/fileserver/smassstorage/scsiprot.cpp	Fri Apr 16 16:24:37 2010 +0300
@@ -1,4 +1,4 @@
-// Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 2004-2010 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"
@@ -243,10 +243,14 @@
 			HandleInquiry(aData, aLun);
 			break;
 
-		case EModeSense:
-			HandleModeSense(aData, aLun);
+		case EModeSense6:
+			HandleModeSense6(aData, aLun);
 			break;
 
+        case EModeSense10:
+            HandleModeSense10(aData, aLun);
+            break;
+
 		case EStartStopUnit:
 			HandleStartStopUnit(aData, aLun);
 			break;
@@ -1224,15 +1228,13 @@
 
 @return ETrue if successful.
 */
-TBool CScsiProtocol::HandleModeSense(TPtrC8& aData, TUint aLun)
+TBool CScsiProtocol::HandleModeSense6(TPtrC8& aData, TUint aLun)
 	{
-	__FNLOG("CScsiProtocol::HandleModeSense");
+	__FNLOG("CScsiProtocol::HandleModeSense6");
 
 	TInt pageCode = aData[3] & 0x3F;
 	TUint8 pageControl= static_cast<TUint8>(aData[3] >>6);
 
-	// reserve 4 bytes for Length, Media type, Device-specific parameter and Block descriptor length
-
 	if (pageCode != KAllPages || pageControl == KChangeableValues) 
 		{
 		__PRINT(_L("TSenseInfo::EIllegalRequest,TSenseInfo::EInvalidFieldInCdb"));
@@ -1240,9 +1242,10 @@
 		return EFalse;
 		}
 
+	// reserve 4 bytes for Length, Media type, Device-specific parameter and Block descriptor length
 	TPtr8 writeBuf(NULL, 0);
-	iTransport->GetCommandBufPtr(writeBuf, KModeSenseCommandLength);
-	writeBuf.FillZ(KModeSenseCommandLength);
+	iTransport->GetCommandBufPtr(writeBuf, KModeSense6CommandLength);
+	writeBuf.FillZ(KModeSense6CommandLength);
 
 	if (pageControl != KDefaultValues)
 		{
@@ -1279,3 +1282,63 @@
 	}
 
 
+/**
+Command Parser for the MODE SENSE(10) command (0x5A)
+
+@return ETrue if successful.
+*/
+TBool CScsiProtocol::HandleModeSense10(TPtrC8& aData, TUint aLun)
+	{
+	__FNLOG("CScsiProtocol::HandleModeSense10");
+
+	TInt pageCode = aData[3] & 0x3F;
+	TUint8 pageControl= static_cast<TUint8>(aData[3] >>6);
+
+	if (pageCode != KAllPages || pageControl == KChangeableValues) 
+		{
+		__PRINT(_L("TSenseInfo::EIllegalRequest,TSenseInfo::EInvalidFieldInCdb"));
+		iSenseInfo.SetSense(TSenseInfo::EIllegalRequest,TSenseInfo::EInvalidFieldInCdb);
+		return EFalse;
+		}
+
+	// reserve 8 bytes for Length, Media type, Device-specific parameter and Block descriptor length
+	TPtr8 writeBuf(NULL, 0);
+	iTransport->GetCommandBufPtr(writeBuf, KModeSense10CommandLength);
+	writeBuf.FillZ(KModeSense10CommandLength);
+
+	if (pageControl != KDefaultValues)
+		{
+		//check if drive write protected
+		CMassStorageDrive* drive=GetCheckDrive(aLun);
+		if (drive == NULL)
+			{
+			__PRINT(_L("drive == null"));
+			return EFalse;
+			}
+
+		TLocalDriveCapsV4 driveInfo;
+		TInt err = drive->Caps(driveInfo);
+		if (err != KErrNone)
+			{
+			__PRINT(_L("TSenseInfo::ENotReady"));
+			iSenseInfo.SetSense(TSenseInfo::ENotReady, TSenseInfo::EMediaNotPresent);
+			return EFalse ;
+			}
+
+		if (driveInfo.iMediaAtt & KMediaAttWriteProtected)
+			{
+			writeBuf[3] = 1<<7;  // set SWP bit at the Device Specific parameters
+			}
+		}
+
+	writeBuf[1]=6;  //Sending only Mode parameter header
+
+	TPtrC8 writeBuf1 = writeBuf;
+
+	iTransport->SetupWriteData(writeBuf1);
+
+	return (iSenseInfo.SenseOk());
+	}
+
+
+
--- a/userlibandfileserver/fileserver/srofs/base_f32_srofs.mrp	Tue Feb 02 01:24:03 2010 +0200
+++ b/userlibandfileserver/fileserver/srofs/base_f32_srofs.mrp	Fri Apr 16 16:24:37 2010 +0300
@@ -1,3 +1,18 @@
+#
+# 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 "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: 
+#
 # component name "ROFS File System"
 
 component	base_f32_srofs
--- a/userlibandfileserver/fileserver/srom/base_f32_srom.mrp	Tue Feb 02 01:24:03 2010 +0200
+++ b/userlibandfileserver/fileserver/srom/base_f32_srom.mrp	Fri Apr 16 16:24:37 2010 +0300
@@ -1,3 +1,18 @@
+#
+# 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 "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: 
+#
 # component name "ROM File System"
 
 component	base_f32_srom