summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSteven Kinney <steven.kinney@linaro.org>2013-11-08 13:41:13 -0600
committerSteven Kinney <steven.kinney@linaro.org>2013-11-08 13:41:13 -0600
commitd5836c2a5e7d7eb8a7c637af2bcbe33c2a761ffa (patch)
treef32cb5db0f8e3e7250a3eb273c5fdea4fdf58009
parente0cec187231a1bf8fc12caa0c4f734771cf6fe42 (diff)
parent4c5367d2e2e9426f8dbdf302456df6bef9cb7c86 (diff)
Merge branch 'linaro-topic-arndale' into linaro-tracking-2013.11
-rw-r--r--SamsungPlatformPkg/Apps/Ebl.efibin0 -> 121600 bytes
-rw-r--r--SamsungPlatformPkg/Apps/TestApps/HashServicesTest/HashServicesTest.c54
-rw-r--r--SamsungPlatformPkg/Apps/TestApps/HashServicesTest/HashServicesTest.inf46
-rw-r--r--SamsungPlatformPkg/Apps/TestApps/MiscellaneousServicesTest/MiscellaneousServicesTest.c143
-rw-r--r--SamsungPlatformPkg/Apps/TestApps/MiscellaneousServicesTest/MiscellaneousServicesTest.inf65
-rw-r--r--SamsungPlatformPkg/Apps/TestApps/RngServicesTest/RngServicesTest.c56
-rw-r--r--SamsungPlatformPkg/Apps/TestApps/RngServicesTest/RngServicesTest.inf41
-rw-r--r--SamsungPlatformPkg/Apps/TestApps/TimeServicesTest/TimeServicesTest.c156
-rw-r--r--SamsungPlatformPkg/Apps/TestApps/TimeServicesTest/TimeServicesTest.inf52
-rw-r--r--SamsungPlatformPkg/Apps/TestApps/VariableServicesTestNonSec/VariableServicesTestNonSec.c193
-rw-r--r--SamsungPlatformPkg/Apps/TestApps/VariableServicesTestNonSec/VariableServicesTestNonSec.inf64
-rwxr-xr-xSamsungPlatformPkg/Apps/Tools/fwupdate/fwupdate.c541
-rw-r--r--SamsungPlatformPkg/Apps/Tools/fwupdate/fwupdate_5250.inf54
-rw-r--r--SamsungPlatformPkg/Apps/Tools/mkbl2/5250/fwbl1_5250.binbin0 -> 8192 bytes
-rw-r--r--SamsungPlatformPkg/Apps/Tools/mkbl2/5250/fwbl1_5250_evt1.binbin0 -> 8192 bytes
-rw-r--r--SamsungPlatformPkg/Apps/Tools/mkbl2/5250/fwbl1_5250_evt1_pop.binbin0 -> 8192 bytes
-rw-r--r--SamsungPlatformPkg/Apps/Tools/mkbl2/5250/fwbl2-5250-ddr3-no-tz.binbin0 -> 16384 bytes
-rw-r--r--SamsungPlatformPkg/Apps/Tools/mkbl2/5250/fwbl2-5250-none-evt1-no-tz.binbin0 -> 16384 bytes
-rw-r--r--SamsungPlatformPkg/Apps/Tools/mkbl2/Makefile21
-rwxr-xr-xSamsungPlatformPkg/Apps/Tools/mkbl2/imgburn.sh106
-rw-r--r--SamsungPlatformPkg/Apps/Tools/mkbl2/mkbl2.c88
-rw-r--r--SamsungPlatformPkg/ArndaleBoardPkg/ArndaleBoardPkg.dec43
-rw-r--r--SamsungPlatformPkg/ArndaleBoardPkg/ArndaleBoardPkg.dsc.inc316
-rw-r--r--SamsungPlatformPkg/ArndaleBoardPkg/Debugger_scripts/EBLoadSecSyms.inc15
-rw-r--r--SamsungPlatformPkg/ArndaleBoardPkg/Debugger_scripts/EfiFuncs.inc463
-rw-r--r--SamsungPlatformPkg/ArndaleBoardPkg/Debugger_scripts/rvi_boot_from_ram.inc20
-rw-r--r--SamsungPlatformPkg/ArndaleBoardPkg/Debugger_scripts/rvi_convert_symbols.sh22
-rw-r--r--SamsungPlatformPkg/ArndaleBoardPkg/Debugger_scripts/rvi_hw_setup.inc67
-rw-r--r--SamsungPlatformPkg/ArndaleBoardPkg/Debugger_scripts/rvi_load_symbols.inc21
-rw-r--r--SamsungPlatformPkg/ArndaleBoardPkg/Debugger_scripts/rvi_symbols_macros.inc193
-rw-r--r--SamsungPlatformPkg/ArndaleBoardPkg/Debugger_scripts/rvi_unload_symbols.inc118
-rwxr-xr-xSamsungPlatformPkg/ArndaleBoardPkg/FvbDxe/FvbDxe.c621
-rwxr-xr-xSamsungPlatformPkg/ArndaleBoardPkg/FvbDxe/FvbDxe.inf57
-rw-r--r--SamsungPlatformPkg/ArndaleBoardPkg/Library/ArndaleBoardLib/Exynos5250/Board.c226
-rwxr-xr-xSamsungPlatformPkg/ArndaleBoardPkg/Library/ArndaleBoardLib/Exynos5250/BoardBoot.S468
-rw-r--r--SamsungPlatformPkg/ArndaleBoardPkg/Library/ArndaleBoardLib/Exynos5250/BoardBoot.asm52
-rw-r--r--SamsungPlatformPkg/ArndaleBoardPkg/Library/ArndaleBoardLib/Exynos5250/BoardHelper.S96
-rw-r--r--SamsungPlatformPkg/ArndaleBoardPkg/Library/ArndaleBoardLib/Exynos5250/BoardHelper.asm73
-rwxr-xr-xSamsungPlatformPkg/ArndaleBoardPkg/Library/ArndaleBoardLib/Exynos5250/BoardLib.inf69
-rwxr-xr-xSamsungPlatformPkg/ArndaleBoardPkg/Library/ArndaleBoardLib/Exynos5250/BoardMem.c221
-rw-r--r--SamsungPlatformPkg/ArndaleBoardPkg/Library/ArndaleBoardLib/Exynos5250/BoardSec.c52
-rwxr-xr-xSamsungPlatformPkg/ArndaleBoardPkg/Library/ArndaleBoardLib/Exynos5250/BoardSecLib.inf60
-rw-r--r--SamsungPlatformPkg/ArndaleBoardPkg/Library/ArndaleBoardLib/Exynos5250/dmc_init.c787
-rwxr-xr-xSamsungPlatformPkg/ArndaleBoardPkg/Library/ArndaleBoardLib/Exynos5250/mem_init_ddr3.S412
-rw-r--r--SamsungPlatformPkg/ArndaleBoardPkg/Library/DebugAgentTimerLib/DebugAgentTimerLib.c78
-rw-r--r--SamsungPlatformPkg/ArndaleBoardPkg/Library/DebugAgentTimerLib/DebugAgentTimerLib.inf37
-rwxr-xr-xSamsungPlatformPkg/ArndaleBoardPkg/arndale-Exynos5250.dsc363
-rwxr-xr-xSamsungPlatformPkg/ArndaleBoardPkg/arndale-Exynos5250.fdf397
-rw-r--r--SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/DisplayDxe/DisplayDxe.c692
-rw-r--r--SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/DisplayDxe/DisplayDxe.h277
-rw-r--r--SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/DisplayDxe/DisplayDxe.inf65
-rw-r--r--SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/EthDxe/EthDxe.c788
-rw-r--r--SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/EthDxe/EthDxe.h612
-rw-r--r--SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/EthDxe/EthDxe.inf59
-rw-r--r--SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/Gic400Dxe/PL390Gic.c70
-rw-r--r--SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/Gic400Dxe/PL390GicDxe.c415
-rw-r--r--SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/Gic400Dxe/PL390GicDxe.inf54
-rw-r--r--SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/Gic400Dxe/PL390GicLib.inf28
-rw-r--r--SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/Gic400Dxe/PL390GicNonSec.c44
-rw-r--r--SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/Gic400Dxe/PL390GicSec.c119
-rw-r--r--SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/Gic400Dxe/PL390GicSecLib.inf37
-rw-r--r--SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/Gpio/Gpio.c177
-rw-r--r--SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/Gpio/Gpio.inf46
-rw-r--r--SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/HashDxe/HashDxe.c241
-rw-r--r--SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/HashDxe/HashDxe.h417
-rw-r--r--SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/HashDxe/HashDxe.inf57
-rw-r--r--SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/OhciDxe/ComponentName.c231
-rw-r--r--SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/OhciDxe/ComponentName.h145
-rw-r--r--SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/OhciDxe/Ohci.c2345
-rw-r--r--SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/OhciDxe/Ohci.h229
-rw-r--r--SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/OhciDxe/OhciDebug.c181
-rw-r--r--SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/OhciDxe/OhciDebug.h51
-rw-r--r--SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/OhciDxe/OhciDxe.inf88
-rw-r--r--SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/OhciDxe/OhciQueue.c993
-rw-r--r--SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/OhciDxe/OhciQueue.h395
-rw-r--r--SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/OhciDxe/OhciReg.c292
-rw-r--r--SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/OhciDxe/OhciReg.h286
-rw-r--r--SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/OhciDxe/OhciSched.c1254
-rw-r--r--SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/OhciDxe/OhciSched.h270
-rw-r--r--SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/OhciDxe/UsbHcMem.c564
-rw-r--r--SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/OhciDxe/UsbHcMem.h161
-rw-r--r--SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/PciEmulation/Exynos5_USB.c353
-rw-r--r--SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/PciEmulation/Exynos5_USB2Phy.h114
-rw-r--r--SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/PciEmulation/Exynos5_USB3Drd.h403
-rw-r--r--SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/PciEmulation/Exynos5_USB3Phy.h80
-rw-r--r--SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/PciEmulation/PciEmulation.c684
-rw-r--r--SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/PciEmulation/PciEmulation.h290
-rw-r--r--SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/PciEmulation/PciEmulation.inf64
-rw-r--r--SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/PciEmulation/PciRootBridgeIo.c306
-rw-r--r--SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/RngDxe/RngDxe.c120
-rw-r--r--SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/RngDxe/RngDxe.h40
-rw-r--r--SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/RngDxe/RngDxe.inf49
-rwxr-xr-xSamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/SDHCDxe_EVT1/SDHCDxe.c1348
-rwxr-xr-xSamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/SDHCDxe_EVT1/SDHCDxe.h259
-rwxr-xr-xSamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/SDHCDxe_EVT1/SDHCDxe.inf58
-rwxr-xr-xSamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/SDHCDxe_EVT1/SDHCDxe_5250.c658
-rwxr-xr-xSamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/SDHCDxe_EVT1/SDHCDxe_5250.h323
-rwxr-xr-xSamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/SDHCDxe_EVT1/SDHCDxe_CMD.h165
-rw-r--r--SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/TimerDxe/TimerDxe.c469
-rw-r--r--SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/TimerDxe/TimerDxe.inf54
-rwxr-xr-xSamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/eMMCDxe/eMMCDxe.c1378
-rwxr-xr-xSamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/eMMCDxe/eMMCDxe.h308
-rwxr-xr-xSamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/eMMCDxe/eMMCDxe.inf64
-rwxr-xr-xSamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/eMMCDxe/eMMCDxe_5250.c721
-rwxr-xr-xSamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/eMMCDxe/eMMCDxe_5250.h322
-rwxr-xr-xSamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/eMMCDxe/eMMCDxe_CMD.h165
-rwxr-xr-xSamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/eMMCDxe/eMMC_Fvb.c587
-rwxr-xr-xSamsungPlatformPkg/ExynosPkg/Exynos5250/ExynosPkg.dec101
-rw-r--r--SamsungPlatformPkg/ExynosPkg/Exynos5250/Include/Library/ExynosLib.h42
-rw-r--r--SamsungPlatformPkg/ExynosPkg/Exynos5250/Include/Library/ExynosTimerLib.h56
-rw-r--r--SamsungPlatformPkg/ExynosPkg/Exynos5250/Include/Library/MpParkLib.h51
-rw-r--r--SamsungPlatformPkg/ExynosPkg/Exynos5250/Include/Library/com_dtypes.h186
-rwxr-xr-xSamsungPlatformPkg/ExynosPkg/Exynos5250/Include/Platform/ArmPlatform.h692
-rw-r--r--SamsungPlatformPkg/ExynosPkg/Exynos5250/Include/Platform/Arndale5250.h337
-rwxr-xr-xSamsungPlatformPkg/ExynosPkg/Exynos5250/Include/Platform/Arndale5250_Val.h402
-rw-r--r--SamsungPlatformPkg/ExynosPkg/Exynos5250/Include/Platform/Exynos5250.h730
-rwxr-xr-xSamsungPlatformPkg/ExynosPkg/Exynos5250/Include/Platform/Exynos5250_Evt1.h763
-rw-r--r--SamsungPlatformPkg/ExynosPkg/Exynos5250/Include/Protocol/ExynosGpio.h199
-rw-r--r--SamsungPlatformPkg/ExynosPkg/Exynos5250/Include/Protocol/ExynosRng.h52
-rw-r--r--SamsungPlatformPkg/ExynosPkg/Exynos5250/Library/ExynosLib/ExynosLib.c51
-rw-r--r--SamsungPlatformPkg/ExynosPkg/Exynos5250/Library/ExynosLib/ExynosLib.inf42
-rw-r--r--SamsungPlatformPkg/ExynosPkg/Exynos5250/Library/GdbSerialLib/GdbSerialLib.c118
-rw-r--r--SamsungPlatformPkg/ExynosPkg/Exynos5250/Library/GdbSerialLib/GdbSerialLib.inf40
-rw-r--r--SamsungPlatformPkg/ExynosPkg/Exynos5250/Library/RealTimeClockLib/RealTimeClockLib.c363
-rw-r--r--SamsungPlatformPkg/ExynosPkg/Exynos5250/Library/RealTimeClockLib/RealTimeClockLib.inf42
-rw-r--r--SamsungPlatformPkg/ExynosPkg/Exynos5250/Library/ResetSystemLib/ResetSystemLib.c241
-rw-r--r--SamsungPlatformPkg/ExynosPkg/Exynos5250/Library/ResetSystemLib/ResetSystemLib.inf52
-rwxr-xr-xSamsungPlatformPkg/ExynosPkg/Exynos5250/Library/SerialPortLib/SerialPortLib_Evt1.c159
-rwxr-xr-xSamsungPlatformPkg/ExynosPkg/Exynos5250/Library/SerialPortLib/SerialPortLib_Evt1.inf38
-rw-r--r--SamsungPlatformPkg/ExynosPkg/Exynos5250/Library/TimerLib/TimerLib.c287
-rw-r--r--SamsungPlatformPkg/ExynosPkg/Exynos5250/Library/TimerLib/TimerLib.inf41
-rw-r--r--SamsungPlatformPkg/ExynosPkg/Exynos5250/MemoryInitPei/MemoryInitPeiLib.c182
-rw-r--r--SamsungPlatformPkg/ExynosPkg/Exynos5250/MemoryInitPei/MemoryInitPeiLib.inf69
-rw-r--r--SamsungPlatformPkg/ExynosPkg/Exynos5250/MemoryInitPei/MemoryInitPeim.c157
-rw-r--r--SamsungPlatformPkg/ExynosPkg/Exynos5250/MemoryInitPei/MemoryInitPeim.inf75
-rw-r--r--SamsungPlatformPkg/ExynosPkg/Exynos5250/PlatformPei/PlatformPeiLib.c30
-rw-r--r--SamsungPlatformPkg/ExynosPkg/Exynos5250/PlatformPei/PlatformPeiLib.inf53
-rw-r--r--SamsungPlatformPkg/ExynosPkg/Exynos5250/PlatformPei/PlatformPeim.c138
-rwxr-xr-xSamsungPlatformPkg/ExynosPkg/Exynos5250/PlatformPei/PlatformPeim.inf69
-rw-r--r--SamsungPlatformPkg/ExynosPkg/Exynos5250/Sec/Helper.S84
-rw-r--r--SamsungPlatformPkg/ExynosPkg/Exynos5250/Sec/Helper.asm75
-rw-r--r--SamsungPlatformPkg/ExynosPkg/Exynos5250/Sec/Sec.c222
-rw-r--r--SamsungPlatformPkg/ExynosPkg/Exynos5250/Sec/Sec.inf85
-rw-r--r--SamsungPlatformPkg/ExynosPkg/Exynos5250/Sec/SecEntryPoint.S287
-rw-r--r--SamsungPlatformPkg/ExynosPkg/Exynos5250/Sec/SecEntryPoint.asm112
-rw-r--r--SamsungPlatformPkg/ExynosPkg/Exynos5250/Sec/SecFromTzsw.S13
-rw-r--r--SamsungPlatformPkg/ExynosPkg/Exynos5250/Sec/SecInternal.h75
-rw-r--r--SamsungPlatformPkg/ExynosPkg/Exynos5250/Sec/Smc.c110
-rw-r--r--SamsungPlatformPkg/ExynosPkg/Exynos5250/Sec/Smc.h60
-rw-r--r--SamsungPlatformPkg/Include/Library/PlatformBdsLib.h156
-rw-r--r--SamsungPlatformPkg/Library/PlatformBdsLib/BdsPlatform.c588
-rw-r--r--SamsungPlatformPkg/Library/PlatformBdsLib/BdsPlatform.h130
-rw-r--r--SamsungPlatformPkg/Library/PlatformBdsLib/PlatformBdsLib.inf63
-rw-r--r--SamsungPlatformPkg/Library/PlatformBdsLib/PlatformData.c88
-rwxr-xr-xSamsungPlatformPkg/Logo/Logo.bmpbin0 -> 118838 bytes
-rw-r--r--SamsungPlatformPkg/README48
-rw-r--r--SamsungPlatformPkg/SamsungPlatformPkg.dec42
-rwxr-xr-xSamsungPlatformPkg/build.sh126
-rw-r--r--SamsungPlatformPkg/patches/0001-The-patch-created-to-incorporate-auto-boot-feature.patch150
159 files changed, 36464 insertions, 0 deletions
diff --git a/SamsungPlatformPkg/Apps/Ebl.efi b/SamsungPlatformPkg/Apps/Ebl.efi
new file mode 100644
index 000000000..a5d637329
--- /dev/null
+++ b/SamsungPlatformPkg/Apps/Ebl.efi
Binary files differ
diff --git a/SamsungPlatformPkg/Apps/TestApps/HashServicesTest/HashServicesTest.c b/SamsungPlatformPkg/Apps/TestApps/HashServicesTest/HashServicesTest.c
new file mode 100644
index 000000000..b5b46dc7f
--- /dev/null
+++ b/SamsungPlatformPkg/Apps/TestApps/HashServicesTest/HashServicesTest.c
@@ -0,0 +1,54 @@
+#include <Uefi.h>
+
+#include <Library/UefiLib.h>
+#include <Library/DebugLib.h>
+#include <Library/UefiApplicationEntryPoint.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UncachedMemoryAllocationLib.h>
+
+#include <Protocol/Hash.h>
+#include <Protocol/PciIo.h>
+
+#define NOT_EXTEND 0
+#define EXTEND 1
+
+#define TEST_HASH 0x12345678
+
+EFI_STATUS
+EFIAPI
+HashTestMain (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ EFI_HASH_PROTOCOL *HashProtocol;
+ UINTN HashSize;
+ UINT8 *Message;
+ UINT32 Count, Test[5];
+ EFI_HASH_OUTPUT *Hash;
+
+ DEBUG((EFI_D_ERROR, "[HashTestApps] : HashTestApps\n"));
+
+ for (Count = 0 ; Count < 5; Count++)
+ Test[Count] = TEST_HASH;
+
+ Status = gBS->LocateProtocol(&gEfiHashProtocolGuid, NULL, (VOID **)&HashProtocol);
+ ASSERT_EFI_ERROR(Status);
+
+ HashProtocol->GetHashSize(HashProtocol, &gEfiHashAlgorithmSha1Guid, &HashSize);
+
+ Message = (UINT8 *)UncachedAllocatePool(HashSize);
+ Hash = (EFI_HASH_OUTPUT *)UncachedAllocatePool(sizeof(EFI_HASH_OUTPUT));
+
+ gBS->CopyMem(Hash, Test, sizeof(EFI_SHA1_HASH));
+ gBS->CopyMem(Message, "abc", sizeof("abc"));
+
+ HashProtocol->Hash(HashProtocol, &gEfiHashAlgorithmSha1Guid, EXTEND, Message, (UINT64)sizeof("abc"), Hash);
+
+ DEBUG((EFI_D_ERROR, "[HashResult] : Result = %x\n", (EFI_SHA1_HASH *)Hash->Sha1Hash));
+
+ return Status;
+}
+
diff --git a/SamsungPlatformPkg/Apps/TestApps/HashServicesTest/HashServicesTest.inf b/SamsungPlatformPkg/Apps/TestApps/HashServicesTest/HashServicesTest.inf
new file mode 100644
index 000000000..76b155479
--- /dev/null
+++ b/SamsungPlatformPkg/Apps/TestApps/HashServicesTest/HashServicesTest.inf
@@ -0,0 +1,46 @@
+## @file HashServicesTest.inf
+#
+# Samsung S.LSI HashServicesTest application
+#
+# Copyright (c) 2012-2013, Samsung Electronics Inc. All rights reserved.
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = HashServicesTest
+ FILE_GUID = 95434237-90a5-4cb2-85ff-2300be4520de
+ MODULE_TYPE = UEFI_APPLICATION
+ VERSION_STRING = 1.0
+ ENTRY_POINT = HashTestMain
+
+[Sources]
+ HashServicesTest.c
+
+[Packages]
+ ArmPkg/ArmPkg.dec
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ SamsungPlatformPkg/ExynosPkg/Exynos5250/ExynosPkg.dec
+ SamsungPlatformPkg/ArndaleBoardPkg/ArndaleBoardPkg.dec
+
+[LibraryClasses]
+ UefiApplicationEntryPoint
+ UncachedMemoryAllocationLib
+ UefiLib
+ PcdLib
+ DebugLib
+
+[Protocols]
+ gEfiHashProtocolGuid
+ gEfiPciIoProtocolGuid
+
+[Guids]
+ gEfiHashAlgorithmSha1Guid
+ gEfiHashAlgorithmSha256Guid
diff --git a/SamsungPlatformPkg/Apps/TestApps/MiscellaneousServicesTest/MiscellaneousServicesTest.c b/SamsungPlatformPkg/Apps/TestApps/MiscellaneousServicesTest/MiscellaneousServicesTest.c
new file mode 100644
index 000000000..ac97c5e44
--- /dev/null
+++ b/SamsungPlatformPkg/Apps/TestApps/MiscellaneousServicesTest/MiscellaneousServicesTest.c
@@ -0,0 +1,143 @@
+/** @file MiscellaneousTest.c
+
+ Samsung S.LSI MiscellaneousServices application
+
+ Copyright (c) 2012-2013, Samsung Electronics Inc. All rights reserved.
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+/*=============================================================================
+ EDIT HISTORY
+
+ DateTime: 2012/01/31
+ Author: Jang Young Gun : yg1004.jang@samsung.com
+
+ when who what, where, why
+ -------- --- -----------------------------------------------------------
+ 01/31/12 yg.jang Initial revision
+
+=============================================================================*/
+
+#include <Uefi.h>
+#include <Library/PcdLib.h>
+#include <Library/UefiLib.h>
+#include <Library/UefiApplicationEntryPoint.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+
+EFI_EVENT HelloTimerEvent;
+
+VOID
+EFIAPI print_hello( void )
+{
+ UINT32 Index;
+
+ Index = 0;
+
+ //
+ // Three PCD type (FeatureFlag, UINT32 and String) are used as the sample.
+ //
+ if (FeaturePcdGet (PcdHelloWorldPrintEnable)) {
+ for (Index = 0; Index < PcdGet32 (PcdHelloWorldPrintTimes); Index ++) {
+ //
+ // Use UefiLib Print API to print string to UEFI console
+ //
+ Print ((CHAR16*)PcdGetPtr (PcdHelloWorldPrintString));
+ }
+ }
+}
+
+/**
+ The user Entry Point for Application. The user code starts with this function
+ as the real entry point for the application.
+
+ @param[in] ImageHandle The firmware allocated handle for the EFI image.
+ @param[in] SystemTable A pointer to the EFI System Table.
+
+ @retval EFI_SUCCESS The entry point is executed successfully.
+ @retval other Some error occurs when executing this entry point.
+
+**/
+EFI_STATUS
+EFIAPI
+UefiMain (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ UINTN EventIndex;
+ EFI_STATUS Status;
+ UINT64 BSCounter;
+ UINT64 BSCounterNext;
+ UINT32 RTCounter;
+ UINT32 RTCounterNext;
+
+ do{
+ print_hello();
+
+ //
+ // Create the timer event to implement a timer
+ //
+ Status = gBS->CreateEvent (
+ EVT_TIMER,
+ TPL_NOTIFY,
+ NULL,
+ NULL,
+ &HelloTimerEvent
+ );
+ if(EFI_ERROR (Status)) {
+ break;
+ }
+
+ // Set timer for 1 second
+ AsciiPrint("Registering Timer Event: 1 second relative timer\n");
+ gBS->SetTimer(HelloTimerEvent, TimerRelative, 10000000);
+ AsciiPrint("Waiting for 1 second\n");
+ gBS->WaitForEvent(1, &HelloTimerEvent, &EventIndex);
+ AsciiPrint("1 second timer event signaled\n");
+
+ // Test Stall
+ AsciiPrint("Stalling for 2 seconds\n");
+ gBS->Stall(2000000);
+ AsciiPrint("2 second stall complete\n");
+
+ // Testing GetNextMonotonicCount
+ gBS->GetNextMonotonicCount(&BSCounter);
+ AsciiPrint("Current Monotonic Counter Value: 0x%llx\n", BSCounter);
+ gBS->GetNextMonotonicCount(&BSCounterNext);
+ AsciiPrint("Next Monotonic Counter Value: 0x%llx\n", BSCounterNext);
+ if (BSCounter != (BSCounterNext-1))
+ {
+ Status = EFI_UNSUPPORTED;
+ break;
+ }
+ else
+ {
+ AsciiPrint("Monotonic Counter Test Case Passed\n");
+ }
+
+ // Testing GetNextHighMonotonicCount
+ gRT->GetNextHighMonotonicCount(&RTCounter);
+ AsciiPrint("Current High Monotonic Counter Value: 0x%x\n", RTCounter);
+ gRT->GetNextHighMonotonicCount(&RTCounterNext);
+ AsciiPrint("Next High Monotonic Counter Value: 0x%x\n", RTCounterNext);
+ if (RTCounter != (RTCounterNext-1))
+ {
+ Status = EFI_UNSUPPORTED;
+ break;
+ }
+ else
+ {
+ AsciiPrint("High Monotonic Counter Test Case Passed\n");
+ }
+ }while (0);
+
+ return Status;
+}
diff --git a/SamsungPlatformPkg/Apps/TestApps/MiscellaneousServicesTest/MiscellaneousServicesTest.inf b/SamsungPlatformPkg/Apps/TestApps/MiscellaneousServicesTest/MiscellaneousServicesTest.inf
new file mode 100644
index 000000000..fedf51e88
--- /dev/null
+++ b/SamsungPlatformPkg/Apps/TestApps/MiscellaneousServicesTest/MiscellaneousServicesTest.inf
@@ -0,0 +1,65 @@
+## @file MiscellaneousServicesTest.inf
+#
+# Samsung S.LSI MiscellaneousServices application
+#
+# Copyright (c) 2012-2013, Samsung Electronics Inc. All rights reserved.
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+#==============================================================================
+# EDIT HISTORY
+#
+# DateTime: 2012/01/31
+# Author: Jang Young Gun : yg1004.jang@samsung.com
+#
+# when who what, where, why
+# -------- --- ----------------------------------------------------------
+# 01/31/12 yg.jang Initial revision
+#
+#==============================================================================
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = MiscellaneousServicesTest
+ FILE_GUID = C5066246-9923-4A7C-BA7B-453D7241AF75
+ MODULE_TYPE = UEFI_APPLICATION
+ VERSION_STRING = 1.0
+ ENTRY_POINT = UefiMain
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = ARM
+#
+
+[Sources]
+ MiscellaneousServicesTest.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+
+[LibraryClasses]
+ UefiApplicationEntryPoint
+ UefiLib
+ PcdLib
+
+[Guids]
+
+[Ppis]
+
+[Protocols]
+
+[FeaturePcd]
+ gEfiMdeModulePkgTokenSpaceGuid.PcdHelloWorldPrintEnable
+
+[Pcd]
+ gEfiMdeModulePkgTokenSpaceGuid.PcdHelloWorldPrintString || PcdHelloWorldPrintEnable ## Valid when gEfiMdeModulePkgTokenSpaceGuid.PcdHelloWorldPrintEnable
+ gEfiMdeModulePkgTokenSpaceGuid.PcdHelloWorldPrintTimes || PcdHelloWorldPrintEnable ## Valid when gEfiMdeModulePkgTokenSpaceGuid.PcdHelloWorldPrintEnable
+
diff --git a/SamsungPlatformPkg/Apps/TestApps/RngServicesTest/RngServicesTest.c b/SamsungPlatformPkg/Apps/TestApps/RngServicesTest/RngServicesTest.c
new file mode 100644
index 000000000..8bf0dce13
--- /dev/null
+++ b/SamsungPlatformPkg/Apps/TestApps/RngServicesTest/RngServicesTest.c
@@ -0,0 +1,56 @@
+/** @file
+ Application for Pseudorandom Number Generator Validation.
+
+Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <Uefi.h>
+
+#include <Library/DebugLib.h>
+#include <Library/UefiApplicationEntryPoint.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UncachedMemoryAllocationLib.h>
+
+#include <Protocol/ExynosRng.h>
+
+#define RANDOM_DATA_SIZE 32 /* Bytes */
+
+/**
+ * Validate UEFI pseudorandom number generator
+
+**/
+EFI_STATUS
+EFIAPI
+RngTestMain (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ BOOLEAN Status = EFI_SUCCESS;
+ UINT8 *RandomData;
+ UINT32 count;
+ EFI_RNG_PROTOCOL *RngProtocol;
+
+ DEBUG((EFI_D_ERROR, "UEFI pseudorandom number generator.\n"));
+ DEBUG((EFI_D_ERROR, "Random Generation...\n\n"));
+
+ RandomData = (UINT8 *)UncachedAllocatePool(RANDOM_DATA_SIZE);
+
+ Status = gBS->LocateProtocol(&gSamsungPlatformRngProtocolGuid, NULL, (VOID **)&RngProtocol);
+
+ RngProtocol->RandomBytes(RngProtocol, RandomData, RANDOM_DATA_SIZE);
+
+ for (count = 0; count < (RANDOM_DATA_SIZE >> 2); count++)
+ DEBUG((EFI_D_ERROR, "RandomData[%d] : %x\n", count, *(UINT32 *)((UINT32)RandomData + (count << 2))));
+
+ return Status;
+}
diff --git a/SamsungPlatformPkg/Apps/TestApps/RngServicesTest/RngServicesTest.inf b/SamsungPlatformPkg/Apps/TestApps/RngServicesTest/RngServicesTest.inf
new file mode 100644
index 000000000..02ea76b82
--- /dev/null
+++ b/SamsungPlatformPkg/Apps/TestApps/RngServicesTest/RngServicesTest.inf
@@ -0,0 +1,41 @@
+## @file RngServicesTest.inf
+#
+# Samsung S.LSI TimeServicesTest application
+#
+# Copyright (c) 2012-2013, Samsung Electronics Inc. All rights reserved.
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = RngServicesTest
+ FILE_GUID = 538b842d-61e3-443a-b68a-fb6901d74fae
+ MODULE_TYPE = UEFI_APPLICATION
+ VERSION_STRING = 1.0
+
+ ENTRY_POINT = RngTestMain
+
+[Sources]
+ RngServicesTest.c
+
+[Packages]
+ ArmPkg/ArmPkg.dec
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ SamsungPlatformPkg/ExynosPkg/Exynos5250/ExynosPkg.dec
+ SamsungPlatformPkg/SamsungPlatformPkg.dec
+
+[LibraryClasses]
+ UefiApplicationEntryPoint
+ UncachedMemoryAllocationLib
+ UefiLib
+ DebugLib
+
+[Protocols]
+ gSamsungPlatformRngProtocolGuid
diff --git a/SamsungPlatformPkg/Apps/TestApps/TimeServicesTest/TimeServicesTest.c b/SamsungPlatformPkg/Apps/TestApps/TimeServicesTest/TimeServicesTest.c
new file mode 100644
index 000000000..7e3856c81
--- /dev/null
+++ b/SamsungPlatformPkg/Apps/TestApps/TimeServicesTest/TimeServicesTest.c
@@ -0,0 +1,156 @@
+/** @file TimeServicesTest.c
+
+ Samsung S.LSI TimeServicesTest application
+
+ Copyright (c) 2012-2013, Samsung Electronics Inc. All rights reserved.
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+/*=============================================================================
+ EDIT HISTORY
+
+ DateTime: 2012/01/31
+ Author: Jang Young Gun : yg1004.jang@samsung.com
+
+ when who what, where, why
+ -------- --- -----------------------------------------------------------
+ 01/31/12 yg.jang Initial revision
+
+=============================================================================*/
+
+#include <Uefi.h>
+#include <Library/PcdLib.h>
+#include <Library/UefiLib.h>
+#include <Library/UefiApplicationEntryPoint.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/DebugLib.h>
+
+
+/** Various constant values defined for testing.
+*/
+UINT16 test_year = 2011;
+UINT8 test_month = 5;
+UINT8 test_day = 1;
+UINT8 test_minute = 4;
+UINT8 test_hour = 3;
+UINT8 test_second = 6;
+UINT32 test_nanosecond = 0;
+UINT16 test_timezone = 7;
+UINT8 test_daylight = 0;
+
+/** We test via stalling a defined amount in the seconds.
+*/
+#define STALL_AMOUNT_SECONDS 4
+#define LOWER_BOUND_SECONDS_TEST STALL_AMOUNT_SECONDS - 1
+#define UPPER_BOUND_SECONDS_TEST STALL_AMOUNT_SECONDS + 1
+
+/** Convert seconds into an amount the gBS->Stall function will
+ accept.
+*/
+#define CONVERSION_FACTOR_GBS_STALL 1000000
+
+/**
+ The user Entry Point for Application. The user code starts with this function
+ as the real entry point for the application.
+
+ @param[in] ImageHandle The firmware allocated handle for the EFI image.
+ @param[in] SystemTable A pointer to the EFI System Table.
+
+ @retval EFI_SUCCESS The entry point is executed successfully.
+ @retval other Some error occurs when executing this entry point.
+
+**/
+
+EFI_STATUS
+EFIAPI
+RTCTestMain (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ EFI_TIME time;
+ EFI_TIME_CAPABILITIES time_capabilities;
+
+ BOOLEAN tests_passed = TRUE;
+
+ time.Day = test_day;
+ time.Daylight = test_daylight;
+ time.Hour = test_hour;
+ time.Minute = test_minute;
+ time.Month = test_month;
+ time.Nanosecond = test_nanosecond;
+ time.Second = test_second;
+ time.TimeZone = test_timezone;
+ time.Year = test_year;
+
+
+ AsciiPrint("Setting RTC time to a static value\n");
+ Status = gRT->SetTime(&time);
+ if (Status != EFI_SUCCESS) {
+ tests_passed = FALSE;
+ AsciiPrint("Fatal error during test\n");
+ return Status;
+ }
+ AsciiPrint("Stalling for %d seconds to test incrementation\n", STALL_AMOUNT_SECONDS);
+ Status = gBS->Stall( (STALL_AMOUNT_SECONDS * CONVERSION_FACTOR_GBS_STALL) );
+ if (Status != EFI_SUCCESS) {
+ tests_passed = FALSE;
+ AsciiPrint("Fatal error during test\n");
+ return Status;
+ }
+ AsciiPrint("Getting RTC Time with capabilities\n");
+ Status = gRT->GetTime(&time, &time_capabilities);
+ if (Status != EFI_SUCCESS) {
+ tests_passed = FALSE;
+ AsciiPrint("Fatal error during test\n");
+ return Status;
+ }
+ AsciiPrint("Getting RTC Time without capabilities\n");
+ Status = gRT->GetTime(&time, NULL);
+ if (Status != EFI_SUCCESS) {
+ tests_passed = FALSE;
+ AsciiPrint("Failure during test\n");
+ return Status;
+ }
+
+ AsciiPrint("Now displaying deviations\n");
+ if ((time.Day - test_day != 0)) {
+ AsciiPrint("Deviation in DAY of %d days\n", time.Day - test_day);
+ tests_passed = FALSE;
+ }
+ if ((time.Hour - test_hour != 0)) {
+ AsciiPrint("Deviation in HOUR of %d hours\n", time.Hour - test_hour);
+ tests_passed = FALSE;
+ }
+ if ((time.Minute - test_minute != 0)) {
+ AsciiPrint("Deviation in MINUTE of %d minutes\n", time.Minute - test_minute);
+ tests_passed = FALSE;
+ }
+
+ if ((time.Second - test_second ) > UPPER_BOUND_SECONDS_TEST ||
+ (time.Second - test_second ) < LOWER_BOUND_SECONDS_TEST) {
+ AsciiPrint("Deviation in SECOND of %d seconds\n", time.Second - test_second);
+ tests_passed = FALSE;
+ }
+ if ((time.Year - test_year != 0)) {
+ AsciiPrint("Deviation in YEAR of %d years\n", time.Year - test_year);
+ tests_passed = FALSE;
+ }
+ AsciiPrint("Finished displaying deviations\n");
+ if (tests_passed) {
+ AsciiPrint("All tests completed successfully\n");
+ }
+ else{
+ AsciiPrint("Not all tests passed. Please see the deviations above.\n");
+ }
+ return Status;
+}
diff --git a/SamsungPlatformPkg/Apps/TestApps/TimeServicesTest/TimeServicesTest.inf b/SamsungPlatformPkg/Apps/TestApps/TimeServicesTest/TimeServicesTest.inf
new file mode 100644
index 000000000..e85e1485a
--- /dev/null
+++ b/SamsungPlatformPkg/Apps/TestApps/TimeServicesTest/TimeServicesTest.inf
@@ -0,0 +1,52 @@
+## @file TimeServicesTest.inf
+#
+# Samsung S.LSI TimeServicesTest application
+#
+# Copyright (c) 2012-2013, Samsung Electronics Inc. All rights reserved.
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+#==============================================================================
+# EDIT HISTORY
+#
+# DateTime: 2012/01/31
+# Author: Jang Young Gun : yg1004.jang@samsung.com
+#
+# when who what, where, why
+# -------- --- ----------------------------------------------------------
+# 01/31/12 yg.jang Initial revision
+#
+#==============================================================================
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = TimeServicesTest
+ FILE_GUID = 6E0B9EAA-23E8-4157-A3C0-6A74888EFDA5
+ MODULE_TYPE = UEFI_APPLICATION
+ VERSION_STRING = 1.0
+ ENTRY_POINT = RTCTestMain
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = ARM
+#
+
+[Sources]
+ TimeServicesTest.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+
+[LibraryClasses]
+ UefiApplicationEntryPoint
+ UefiLib
+ PcdLib
+ DebugLib
diff --git a/SamsungPlatformPkg/Apps/TestApps/VariableServicesTestNonSec/VariableServicesTestNonSec.c b/SamsungPlatformPkg/Apps/TestApps/VariableServicesTestNonSec/VariableServicesTestNonSec.c
new file mode 100644
index 000000000..c2d079448
--- /dev/null
+++ b/SamsungPlatformPkg/Apps/TestApps/VariableServicesTestNonSec/VariableServicesTestNonSec.c
@@ -0,0 +1,193 @@
+/** @file VariableServicesTestNonSec.c
+
+ If the Variable services have PcdVariableCollectStatistics set to TRUE then
+ the EFI system table will contain statistical information about variable usage
+ an this utility will print out the information. You can use console redirection
+ to capture the data.
+
+ Copyright (c) 2012 - 2013, Samsung Electronics Inc. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+/*=============================================================================
+ EDIT HISTORY
+
+ DateTime: 2012/01/31
+ Author: Jang Young Gun : yg1004.jang@samsung.com
+
+ when who what, where, why
+ -------- --- -----------------------------------------------------------
+ 01/31/12 yg.jang Initial revision
+
+=============================================================================*/
+
+#include <Uefi.h>
+#include <Library/UefiLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/UefiApplicationEntryPoint.h>
+#include <Guid/VariableFormat.h>
+
+
+/**
+ The user Entry Point for Application. The user code starts with this function
+ as the real entry point for the image goes into a library that calls this
+ function.
+
+
+ @param[in] ImageHandle The firmware allocated handle for the EFI image.
+ @param[in] SystemTable A pointer to the EFI System Table.
+
+ @retval EFI_SUCCESS The entry point is executed successfully.
+ @retval other Some error occurs when executing this entry point.
+
+**/
+EFI_STATUS
+EFIAPI
+UefiMain (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ VARIABLE_INFO_ENTRY *VariableInfo;
+ VARIABLE_INFO_ENTRY *Entry;
+
+ /* For GetNextVariableName */
+ UINTN VariableNameBufferSize;
+ UINTN VariableNameSize;
+ CHAR16 *VariableName;
+ UINTN VariableDataBufferSize;
+ UINTN VariableDataSize;
+ VOID *VariableData;
+ EFI_GUID VendorGuid;
+ UINT32 VariableAttributes;
+ VOID *NewBuffer;
+
+ VariableNameBufferSize = sizeof (CHAR16);
+ VariableNameSize = VariableNameBufferSize;
+ VariableName = AllocateZeroPool (VariableNameSize);
+ VariableDataBufferSize = 0;
+ VariableDataSize = 0;
+ VariableData = NULL;
+ VariableAttributes = 0;
+
+ Status = EfiGetSystemConfigurationTable (&gEfiVariableGuid, (VOID **)&Entry);
+ if (!EFI_ERROR (Status) && (Entry != NULL)) {
+ Print (L"Non-Volatile EFI Variables:\n");
+ VariableInfo = Entry;
+ do {
+ if (!VariableInfo->Volatile) {
+ Print (
+ L"%g R%03d(%03d) W%03d D%03d:%s\n",
+ &VariableInfo->VendorGuid,
+ VariableInfo->ReadCount,
+ VariableInfo->CacheCount,
+ VariableInfo->WriteCount,
+ VariableInfo->DeleteCount,
+ VariableInfo->Name
+ );
+ }
+
+ VariableInfo = VariableInfo->Next;
+ } while (VariableInfo != NULL);
+
+ Print (L"Volatile EFI Variables:\n");
+ VariableInfo = Entry;
+ do {
+ if (VariableInfo->Volatile) {
+ Print (
+ L"%g R%03d(%03d) W%03d D%03d:%s\n",
+ &VariableInfo->VendorGuid,
+ VariableInfo->ReadCount,
+ VariableInfo->CacheCount,
+ VariableInfo->WriteCount,
+ VariableInfo->DeleteCount,
+ VariableInfo->Name
+ );
+ }
+ VariableInfo = VariableInfo->Next;
+ } while (VariableInfo != NULL);
+
+ } else {
+ Print (L"Warning: Variable Dxe driver doesn't enable the feature of statistical information!\n");
+ Print (L"If you want to see this info, please:\n");
+ Print (L" 1. Set PcdVariableCollectStatistics as TRUE\n");
+ Print (L" 2. Rebuild Variable Dxe driver\n");
+ Print (L" 3. Run \"VariableInfo\" cmd again\n");
+
+ }
+
+ Print (L"GetNextVariableName EFI Variables:\n");
+ /* Check GetNextVariableName */
+ do {
+ VariableNameSize = VariableNameBufferSize;
+ Status = gRT->GetNextVariableName(
+ &VariableNameSize,
+ VariableName,
+ &VendorGuid
+ );
+
+ if(Status == EFI_BUFFER_TOO_SMALL) {
+ NewBuffer = AllocatePool (VariableNameSize);
+ CopyMem (NewBuffer, VariableName, VariableNameBufferSize);
+ if(VariableName != NULL) {
+ FreePool (VariableName);
+ }
+ VariableName = NewBuffer;
+ VariableNameBufferSize = VariableNameSize;
+
+ Status = gRT->GetNextVariableName(
+ &VariableNameSize,
+ VariableName,
+ &VendorGuid
+ );
+ }
+
+ if(Status == EFI_NOT_FOUND) {
+ Status = EFI_SUCCESS;
+ break;
+ }
+
+ VariableDataSize = VariableDataBufferSize;
+ Status = gRT->GetVariable(
+ VariableName,
+ &VendorGuid,
+ &VariableAttributes,
+ &VariableDataSize,
+ VariableData
+ );
+ if(Status == EFI_BUFFER_TOO_SMALL) {
+ if(VariableDataBufferSize != 0) {
+ FreePool (VariableData);
+ VariableData = NULL;
+ VariableDataBufferSize = 0;
+ }
+
+ VariableData = AllocatePool (VariableDataSize);
+
+ VariableDataBufferSize = VariableDataSize;
+
+ Status = gRT->GetVariable(
+ VariableName,
+ &VendorGuid,
+ &VariableAttributes,
+ &VariableDataSize,
+ VariableData
+ );
+ }
+
+ Print (L"%.-35g %.-20s : %X\n", &VendorGuid, VariableName, VariableData);
+
+ } while (Status == EFI_SUCCESS);
+
+ return Status;
+}
diff --git a/SamsungPlatformPkg/Apps/TestApps/VariableServicesTestNonSec/VariableServicesTestNonSec.inf b/SamsungPlatformPkg/Apps/TestApps/VariableServicesTestNonSec/VariableServicesTestNonSec.inf
new file mode 100644
index 000000000..643a2afb2
--- /dev/null
+++ b/SamsungPlatformPkg/Apps/TestApps/VariableServicesTestNonSec/VariableServicesTestNonSec.inf
@@ -0,0 +1,64 @@
+## @file VariableServicesTestNonSec.inf
+#
+# Samsung S.LSI VariableServicesTestNonSec application
+#
+# Sample UEFI Application Reference Module.
+# This is a shell application that will display statistical information about variable
+# usage.
+# Note that if Variable Dxe driver doesnt enable the feature by setting PcdVariableCollectStatistics
+# as TRUE, The application will not display variable statistical information.
+#
+# Copyright (c) 2012-2013, Samsung Electronics Inc. All rights reserved.
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+#==============================================================================
+# EDIT HISTORY
+#
+# DateTime: 2012/01/31
+# Author: Jang Young Gun : yg1004.jang@samsung.com
+#
+# when who what, where, why
+# -------- --- ----------------------------------------------------------
+# 01/31/12 yg.jang Initial revision
+#
+#==============================================================================
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = VariableServicesTestNonSec
+ FILE_GUID = 202A2922-8C27-4943-9855-26180BF9F113
+ MODULE_TYPE = UEFI_APPLICATION
+ VERSION_STRING = 1.0
+
+ ENTRY_POINT = UefiMain
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF EBC
+#
+
+[Sources]
+ VariableServicesTestNonSec.c
+
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+
+
+[LibraryClasses]
+ UefiApplicationEntryPoint
+ MemoryAllocationLib
+ BaseMemoryLib
+ UefiLib
+
+[Guids]
+ gEfiVariableGuid ## CONSUMES ## Configuration Table Guid
diff --git a/SamsungPlatformPkg/Apps/Tools/fwupdate/fwupdate.c b/SamsungPlatformPkg/Apps/Tools/fwupdate/fwupdate.c
new file mode 100755
index 000000000..70331c3a6
--- /dev/null
+++ b/SamsungPlatformPkg/Apps/Tools/fwupdate/fwupdate.c
@@ -0,0 +1,541 @@
+#include <Uefi.h>
+#include <Library/PcdLib.h>
+#include <Library/UefiLib.h>
+#include <Library/UefiApplicationEntryPoint.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/EfiFileLib.h>
+#include <Protocol/BlockIo.h>
+#include <Protocol/DiskIo.h>
+
+#define FILE_COPY_CHUNK 0x280000
+#define TZSW_PARTITION_SIZE 0x80000
+#define BLOCK_SIZE 512
+#ifndef MAX_PATH
+#define MAX_PATH 128
+#endif
+
+
+/*
+ * Enumerations for Source type and target device
+ */
+typedef enum _FW_SOURCE_TYPE {
+ SOURCE_MEMORY = 1,
+ SOURCE_FILE = 2
+} FW_SOURCE_TYPE;
+
+typedef enum _FW_BOOT_DEVICE {
+ BOOTDEV_MIN = 0,
+ BOOTDEV_EMMC = 1,
+ BOOTDEV_SDCARD= 2,
+ BOOTDEV_MAX = 3
+} FW_BOOT_DEVICE;
+
+
+/*
+ * Default Settings for FW Update (Moved from PCD)
+ */
+#define DEFAULT_SOURCE_TYPE SOURCE_MEMORY
+#define DEFAULT_TARGET_DEVICE BOOTDEV_EMMC
+#define DEFAULT_BL1_SIZE 15
+#define DEFAULT_BL1_SOURCE_ADDRESS 0x42000000
+#define DEFAULT_UEFI_SOURCE_ADDRESS 0x44000000
+#define DEFAULT_TZSW_SOURCE_ADDRESS 0x45000000
+#define DEFAULT_BL1_SOURCE_FILE L"fs1:\\fwbl1_5250.bin"
+#define DEFAULT_UEFI_SOURCE_FILE L"fs1:\\ARNDALE_EFI.fd"
+#define DEFAULT_TZSW_SOURCE_FILE L"fs1:\\TZSW.bin"
+
+#define BL2_BLOCK_COUNT 32
+
+typedef struct _FW_UPDATE_INFO {
+ FW_SOURCE_TYPE SourceType;
+ UINT32 BL1SourceAddr;
+ UINT32 UEFISourceAddr;
+ UINT32 TZSWSourceAddr;
+ CHAR8 BL1FileName[MAX_PATH];
+ CHAR8 UefiFileName[MAX_PATH];
+ CHAR8 TZSWFileName[MAX_PATH];
+ FW_BOOT_DEVICE TargetMediaID;
+
+} FW_UPDATE_INFO;
+
+
+/* Prototypes of local functions */
+EFI_STATUS GetFirmwareUpdateInfoFromUser(
+ OUT struct _FW_UPDATE_INFO* pFwUpdateInfo);
+VOID SetDefaultFirmwareUpdateInfo(
+ OUT struct _FW_UPDATE_INFO* pFwUpdateInfo);
+
+
+EFI_STATUS GetHIInputInteger (OUT UINTN *Integer);
+EFI_STATUS GetHIInputStr (IN OUT CHAR16 *CmdLine, IN UINTN MaxCmdLine);
+EFI_STATUS GetHIInputHex (OUT UINTN *Integer);
+
+/**
+ The user Entry Point for Application. The user code starts with this function
+ as the real entry point for the application.
+
+ @param[in] ImageHandle The firmware allocated handle for the EFI image.
+ @param[in] SystemTable A pointer to the EFI System Table.
+
+ @retval EFI_SUCCESS The entry point is executed successfully.
+ @retval other Some error occurs when executing this entry point.
+
+**/
+EFI_STATUS
+EFIAPI
+UefiMain (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_OPEN_FILE *Source = NULL;
+ VOID *Buffer = NULL;
+ EFI_HANDLE *HandleBuffer = NULL;
+ EFI_STATUS Status = EFI_SUCCESS;
+ UINTN Size, NumHandles;
+ EFI_BLOCK_IO_PROTOCOL *BlockIo;
+ EFI_DISK_IO_PROTOCOL *DiskIo;
+ UINT32 i;
+
+ UINT32 TargetMediaId;
+
+ /* Start block number for writing bootloader blocks - default value is for eMMC*/
+ UINT32 BL1TargetBlock = 0;
+ UINT32 BL2TargetBlock = 16;
+ UINT32 UEFITargetBlock = 48;
+ UINT32 TZSWTargetBlock = 5216; // 2608K
+
+ struct _FW_UPDATE_INFO fwUpdateInfo;
+
+ /* Get Firmware update information from User */
+ GetFirmwareUpdateInfoFromUser(&fwUpdateInfo);
+
+ /* Set Media ID as user's setting */
+ switch (fwUpdateInfo.TargetMediaID) {
+ case BOOTDEV_EMMC:
+ TargetMediaId = SIGNATURE_32('e','m','m','c');
+ break;
+ case BOOTDEV_SDCARD:
+ TargetMediaId = SIGNATURE_32('s','d','h','c');
+ BL1TargetBlock += 1;
+ break;
+ default:
+ DEBUG((EFI_D_ERROR, "Target Device is unknown device %d\n", fwUpdateInfo.TargetMediaID));
+ return EFI_UNSUPPORTED;
+ }
+
+ /* Workaround: There's a code that increase MediaID of Block IO device when it found,
+ Therefore, to match media ID of the device, target Media ID here should be incresed by 1
+ This is temporary solution, eventually, Block IO device management code should be modified */
+ TargetMediaId ++;
+
+ DEBUG((EFI_D_INFO, "Target Device ID = 0x%x\n", TargetMediaId));
+
+ /* Locating all handles in the system supporting EFI_BLOCK_IO_PROTOCOL */
+ Status = gBS->LocateHandleBuffer(ByProtocol, &gEfiBlockIoProtocolGuid, NULL, &NumHandles, &HandleBuffer);
+
+ DEBUG((EFI_D_INFO, "Number of handles supporting Block IO = %d\n", NumHandles));
+
+ /* Finding out the handle of the SDHC Block IO driver through its Media ID
+ i.e. 0x63686473 (The Media ID can be found in the SDHC DXE driver code) */
+ for(i=0;i<NumHandles;i++) {
+ Status = gBS->HandleProtocol(HandleBuffer[i], &gEfiBlockIoProtocolGuid, (VOID **)&BlockIo);
+ ASSERT_EFI_ERROR(Status);
+
+ DEBUG((EFI_D_ERROR, "Device %d Media ID=0x%x\n", i, BlockIo->Media->MediaId));
+
+ if(BlockIo->Media->MediaId == TargetMediaId)
+ break;
+ }
+
+ if(i == NumHandles) {
+ DEBUG((EFI_D_ERROR, "Cannot find Block IO protocol handle! \n"));
+ goto Exit;
+ }
+
+ /* Locating the Disk IO handle corresponding to the target device Block IO handle
+ (Note: There is a Disk IO handle for every Block IO handle according to Disk IO driver implementation) */
+ Status = gBS->HandleProtocol(HandleBuffer[i], &gEfiDiskIoProtocolGuid, (VOID **)&DiskIo);
+ ASSERT_EFI_ERROR(Status);
+
+ /* Allocating 2MB buffer for impending read operations */
+ Buffer = AllocatePool(FILE_COPY_CHUNK);
+ if (Buffer == NULL) {
+ DEBUG((EFI_D_ERROR, "AllocatePool error.\n"));
+ goto Exit;
+ }
+
+
+ /* for temporally */
+ if (fwUpdateInfo.SourceType == SOURCE_FILE) {
+
+ /* Reading BL1 binary from file system (for example in USB flask disk) into the allocated buffer */
+ Source = EfiOpen(fwUpdateInfo.BL1FileName, EFI_FILE_MODE_READ, 0);
+ if (Source == NULL) {
+ /* TODO: Convert file name which is written in ASCII string to Unicode to print to console */
+ DEBUG((EFI_D_ERROR, "Source file [%s] open error.\n", fwUpdateInfo.BL1FileName));
+ return EFI_NOT_FOUND;
+ }
+
+ Size = EfiTell(Source, NULL);
+
+ DEBUG((EFI_D_ERROR, "File size = %d\n", Size));
+
+ Status = EfiRead(Source, Buffer, &Size);
+ if (EFI_ERROR(Status)) {
+ DEBUG((EFI_D_ERROR, "Read file error %r\n", Status));
+ goto Exit;
+ }
+
+ Status = EfiClose(Source);
+ if (EFI_ERROR(Status)) {
+ DEBUG((EFI_D_ERROR, "Source file close error %r\n", Status));
+ }
+ Source = NULL;
+ } else {
+ if (*((UINT32 *)(fwUpdateInfo.BL1SourceAddr + 0x2000)) == 0xEA000038)
+ {
+ Size = 15 * 1024; // 16 KB
+ DEBUG((EFI_D_ERROR, "Loading BL1 + BLMon (0x%X) (%d) \n", *((UINT32 *)(fwUpdateInfo.BL1SourceAddr + 0x2000)) ,Size));
+ } else {
+ Size = 8 * 1024;
+ DEBUG((EFI_D_ERROR, "Loading BL1 without BLMon (0x%X) (%d) \n", *((UINT32 *)(fwUpdateInfo.BL1SourceAddr + 0x2000)) ,Size));
+ }
+ gBS->CopyMem(Buffer, (VOID *)fwUpdateInfo.BL1SourceAddr, Size );
+ }
+
+ /* Writing BL1 into the SD card starting from block BL1TargetBlock (0 for eMMC, 1 for SD)
+ i.e. offset -> block no. * block size -> 1 x 512 = 512 */
+ Status = DiskIo->WriteDisk(DiskIo, BlockIo->Media->MediaId, (BL1TargetBlock*BLOCK_SIZE), Size, Buffer);
+ ASSERT_EFI_ERROR(Status);
+
+
+ /* BL2 target block should be vary with BL1 size */
+ BL2TargetBlock = BL1TargetBlock + (UINT32)((Size-1) / BLOCK_SIZE) + 1;
+ DEBUG((EFI_D_ERROR, "BL2 Target Block Number is %d\n", BL2TargetBlock));
+
+ if (fwUpdateInfo.SourceType == SOURCE_FILE) {
+
+ /* Reading the new UEFI F/W binary into the allocated buffer */
+ Source = EfiOpen(fwUpdateInfo.UefiFileName, EFI_FILE_MODE_READ, 0);
+ if (Source == NULL) {
+ DEBUG((EFI_D_ERROR, "Source file [%s] open error.\n", fwUpdateInfo.UefiFileName));
+ return EFI_NOT_FOUND;
+ }
+
+ Size = EfiTell(Source, NULL);
+
+ DEBUG((EFI_D_ERROR, "File size = %d\n", Size));
+
+ Status = EfiRead(Source, Buffer, &Size);
+ if (EFI_ERROR(Status)) {
+ DEBUG((EFI_D_ERROR, "Read file error %r\n", Status));
+ goto Exit;
+ }
+ } else {
+ Size = FILE_COPY_CHUNK;
+ gBS->CopyMem( Buffer, (void *) fwUpdateInfo.UEFISourceAddr, Size);
+ }
+
+
+ /* Writing BL2 into the Boot device from BL2 (16 for eMMC, 17 for SD) for upto 32 blocks */
+ {
+ UINT32 checksum, tmp, addr, i;
+
+ addr = (UINT32)Buffer;
+
+ /* Calculating and writing the checksum required for BL2 */
+ for(i=0, checksum=0;i<((14*1024) -4);i++)
+ checksum += *((UINT8 *)addr++);
+
+ tmp = *((UINT32 *)addr);
+ *((UINT32 *)addr) = checksum;
+
+ Status = DiskIo->WriteDisk(DiskIo, BlockIo->Media->MediaId, (BL2TargetBlock*BLOCK_SIZE), (BL2_BLOCK_COUNT*BLOCK_SIZE), Buffer);
+ ASSERT_EFI_ERROR(Status);
+
+ *((UINT32 *)addr) = tmp;
+ }
+
+
+ /* UEFI target block should be vary with BL1 size */
+ UEFITargetBlock = BL2TargetBlock + BL2_BLOCK_COUNT;
+ DEBUG((EFI_D_ERROR, "UEFI Target Block Number is %d\n", UEFITargetBlock));
+
+ /* Finally Writing the new UEFI F/W into the Boot device from UEFITargetBlock (48 for eMMC, 49 for SD) */
+ Status = DiskIo->WriteDisk(DiskIo, BlockIo->Media->MediaId, (UEFITargetBlock*BLOCK_SIZE), Size, Buffer);
+ ASSERT_EFI_ERROR(Status);
+
+
+ if (fwUpdateInfo.SourceType == SOURCE_FILE) {
+
+ /* Reading the new UEFI F/W binary into the allocated buffer */
+ Source = EfiOpen(fwUpdateInfo.TZSWFileName, EFI_FILE_MODE_READ, 0);
+ if (Source == NULL) {
+ DEBUG((EFI_D_ERROR, "Source file [%s] open error.\n", fwUpdateInfo.TZSWFileName));
+ return EFI_NOT_FOUND;
+ }
+
+ Size = EfiTell(Source, NULL);
+
+ DEBUG((EFI_D_ERROR, "File size = %d\n", Size));
+
+ Status = EfiRead(Source, Buffer, &Size);
+ if (EFI_ERROR(Status)) {
+ DEBUG((EFI_D_ERROR, "Read file error %r\n", Status));
+ goto Exit;
+ }
+ } else {
+ Size = TZSW_PARTITION_SIZE;
+ gBS->CopyMem( Buffer, (void *) fwUpdateInfo.TZSWSourceAddr, Size);
+ }
+
+
+ TZSWTargetBlock = UEFITargetBlock + ((FILE_COPY_CHUNK-1) / BLOCK_SIZE) + 1;
+ DEBUG((EFI_D_ERROR, "TZSW Target Block Number is %d\n", TZSWTargetBlock));
+
+ Status = DiskIo->WriteDisk(DiskIo, BlockIo->Media->MediaId, (TZSWTargetBlock * BLOCK_SIZE), Size, Buffer);
+ ASSERT_EFI_ERROR(Status);
+
+Exit:
+ if (Source != NULL) {
+ Status = EfiClose(Source);
+ if (EFI_ERROR(Status)) {
+ DEBUG((EFI_D_ERROR, "Source file close error %r\n", Status));
+ }
+ }
+
+ if (Buffer != NULL) {
+ FreePool(Buffer);
+ }
+
+ return Status;
+}
+
+
+
+/**
+ Get required parameters such as firmware image file name and target device from the user
+
+ @param[out] pFwUpdateInfo Pointer to a structure that has firmware update information
+
+ @retval EFI_SUCCESS This function is executed successfully
+ @retval other Some error occurs while executing this function
+
+**/
+
+EFI_STATUS
+GetFirmwareUpdateInfoFromUser(
+ OUT struct _FW_UPDATE_INFO* pFwUpdateInfo
+ )
+{
+ UINT32 TargetMediaId;
+ UINT32 nInput;
+ CHAR16 InputFileName[MAX_PATH];
+
+
+
+ SetDefaultFirmwareUpdateInfo(pFwUpdateInfo);
+
+
+ /* Derek - 2012. 7. 10 */
+ // Ask to user about Update image source
+ Print(L"Select your update image source location (1: Memory , 2: File) (%d):", pFwUpdateInfo->SourceType);
+ GetHIInputInteger(&nInput);
+ if( (nInput == 1) || (nInput == 2) )
+ pFwUpdateInfo->SourceType = nInput;
+
+ if (pFwUpdateInfo->SourceType == SOURCE_MEMORY) {
+ Print(L"Enter BL1 Source Address (0x%08X) : 0x", pFwUpdateInfo->BL1SourceAddr);
+ GetHIInputHex(&nInput);
+ if (nInput)
+ pFwUpdateInfo->BL1SourceAddr = nInput;
+
+ Print(L"Enter UEFI Source address (0x%08X) : 0x", pFwUpdateInfo->UEFISourceAddr);
+ GetHIInputHex(&nInput);
+ if (nInput)
+ pFwUpdateInfo->UEFISourceAddr = nInput;
+
+ Print(L"Enter TZSW Source address (0x%08X) : 0x", pFwUpdateInfo->TZSWSourceAddr);
+ GetHIInputHex(&nInput);
+ if (nInput)
+ pFwUpdateInfo->TZSWSourceAddr = nInput;
+
+ } else { // Source type is File
+
+ Print(L"Enter BL1 Image File Name (%a):",pFwUpdateInfo->BL1FileName);
+
+ GetHIInputStr(InputFileName, MAX_PATH);
+ if (StrLen (InputFileName) > 0)
+ UnicodeStrToAsciiStr(InputFileName, pFwUpdateInfo->BL1FileName);
+
+
+ Print (L"Enter UEFI File Name (%a): ", pFwUpdateInfo->UefiFileName);
+
+ GetHIInputStr(InputFileName, MAX_PATH);
+ if (StrLen (InputFileName) > 0)
+ UnicodeStrToAsciiStr(InputFileName, pFwUpdateInfo->UefiFileName);
+
+
+ Print (L"Enter TZSW File Name (%a): ", pFwUpdateInfo->TZSWFileName);
+
+ GetHIInputStr(InputFileName, MAX_PATH);
+ if (StrLen (InputFileName) > 0)
+ UnicodeStrToAsciiStr(InputFileName, pFwUpdateInfo->TZSWFileName);
+ }
+
+ Print (L"Select Target Device (1: eMMC, 2: SDCard) (eMMC) :");
+ GetHIInputInteger(&TargetMediaId);
+
+
+
+ if (TargetMediaId > (UINT32)BOOTDEV_MIN && TargetMediaId < (UINT32)BOOTDEV_MAX)
+ pFwUpdateInfo->TargetMediaID = (FW_BOOT_DEVICE)TargetMediaId;
+
+
+ /* Print the final update information on the screen */
+
+ if (pFwUpdateInfo->SourceType == SOURCE_MEMORY) {
+ Print(L"BL1:0x%08X, UEFI:0x%08X and TXSW:0x%08X will be updated on %s\n",
+ pFwUpdateInfo->BL1SourceAddr,
+ pFwUpdateInfo->UEFISourceAddr,
+ pFwUpdateInfo->TZSWSourceAddr,
+ ((pFwUpdateInfo->TargetMediaID == 1)?L"eMMC":L"SD Card"));
+
+ } else {
+ Print(L"BL1:%a, UEFI:%a and TZSW:%a will be updated on %s\n",
+ pFwUpdateInfo->BL1FileName,
+ pFwUpdateInfo->UefiFileName,
+ pFwUpdateInfo->TZSWFileName,
+ ((pFwUpdateInfo->TargetMediaID == 1)?L"eMMC":L"SD Card"));
+ }
+
+
+ return EFI_SUCCESS;
+}
+
+VOID SetDefaultFirmwareUpdateInfo(
+ OUT struct _FW_UPDATE_INFO* pFwUpdateInfo
+ )
+{
+ if (pFwUpdateInfo == NULL)
+ return;
+
+ pFwUpdateInfo->SourceType = DEFAULT_SOURCE_TYPE;
+
+ pFwUpdateInfo->BL1SourceAddr = DEFAULT_BL1_SOURCE_ADDRESS;
+ pFwUpdateInfo->UEFISourceAddr = DEFAULT_UEFI_SOURCE_ADDRESS;
+ pFwUpdateInfo->TZSWSourceAddr = DEFAULT_TZSW_SOURCE_ADDRESS;
+
+ pFwUpdateInfo->TargetMediaID = DEFAULT_TARGET_DEVICE;
+
+ UnicodeStrToAsciiStr(DEFAULT_BL1_SOURCE_FILE, pFwUpdateInfo->BL1FileName);
+ UnicodeStrToAsciiStr(DEFAULT_UEFI_SOURCE_FILE, pFwUpdateInfo->UefiFileName);
+ UnicodeStrToAsciiStr(DEFAULT_TZSW_SOURCE_FILE, pFwUpdateInfo->TZSWFileName);
+
+}
+
+
+
+EFI_STATUS
+EditHIInputStr (
+ IN OUT CHAR16 *CmdLine,
+ IN UINTN MaxCmdLine
+ )
+{
+ UINTN CmdLineIndex;
+ UINTN WaitIndex;
+ CHAR8 Char;
+ EFI_INPUT_KEY Key;
+ EFI_STATUS Status;
+
+ Print (CmdLine);
+
+ for (CmdLineIndex = StrLen (CmdLine); CmdLineIndex < MaxCmdLine; ) {
+ Status = gBS->WaitForEvent (1, &gST->ConIn->WaitForKey, &WaitIndex);
+ ASSERT_EFI_ERROR (Status);
+
+ Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);
+ ASSERT_EFI_ERROR (Status);
+
+ // Unicode character is valid when Scancode is NUll
+ if (Key.ScanCode == SCAN_NULL) {
+ // Scan code is NUll, hence read Unicode character
+ Char = (CHAR8)Key.UnicodeChar;
+ } else {
+ Char = CHAR_NULL;
+ }
+
+ if ((Char == CHAR_LINEFEED) || (Char == CHAR_CARRIAGE_RETURN) || (Char == 0x7f)) {
+ CmdLine[CmdLineIndex] = '\0';
+ Print (L"\n\r");
+
+ return EFI_SUCCESS;
+ } else if ((Key.UnicodeChar == L'\b') || (Key.ScanCode == SCAN_LEFT) || (Key.ScanCode == SCAN_DELETE)){
+ if (CmdLineIndex != 0) {
+ CmdLineIndex--;
+ Print (L"\b \b");
+ }
+ } else if ((Key.ScanCode == SCAN_ESC) || (Char == 0x1B) || (Char == 0x0)) {
+ return EFI_INVALID_PARAMETER;
+ } else {
+ CmdLine[CmdLineIndex++] = Key.UnicodeChar;
+ Print (L"%c", Key.UnicodeChar);
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+GetHIInputStr (
+ IN OUT CHAR16 *CmdLine,
+ IN UINTN MaxCmdLine
+ )
+{
+ EFI_STATUS Status;
+
+ // For a new input just passed an empty string
+ CmdLine[0] = L'\0';
+
+ Status = EditHIInputStr (CmdLine, MaxCmdLine);
+
+ return Status;
+}
+
+EFI_STATUS
+GetHIInputInteger (
+ OUT UINTN *Integer
+ )
+{
+ CHAR16 CmdLine[255];
+ EFI_STATUS Status;
+
+ CmdLine[0] = '\0';
+ Status = EditHIInputStr (CmdLine, 255);
+ if (!EFI_ERROR(Status)) {
+ *Integer = StrDecimalToUintn (CmdLine);
+ }
+
+ return Status;
+}
+
+EFI_STATUS
+GetHIInputHex (
+ OUT UINTN *Integer
+ )
+{
+ CHAR16 CmdLine[255];
+ EFI_STATUS Status;
+
+ CmdLine[0] = '\0';
+ Status = EditHIInputStr (CmdLine, 255);
+ if (!EFI_ERROR(Status)) {
+ *Integer = StrHexToUintn (CmdLine);
+ }
+
+ return Status;
+}
diff --git a/SamsungPlatformPkg/Apps/Tools/fwupdate/fwupdate_5250.inf b/SamsungPlatformPkg/Apps/Tools/fwupdate/fwupdate_5250.inf
new file mode 100644
index 000000000..eb8fbb158
--- /dev/null
+++ b/SamsungPlatformPkg/Apps/Tools/fwupdate/fwupdate_5250.inf
@@ -0,0 +1,54 @@
+## @file
+# Sample UEFI Application Reference EDKII Module
+#
+# This is a sample shell application that will print "UEFI Hello World!" to the
+# UEFI Console based on PCD setting.
+#
+# It demos how to use EDKII PCD mechanism to make code more flexible.
+#
+# Copyright (c) 2008 - 2011, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = fwupdate
+ FILE_GUID = 6987936E-ED34-44db-AE97-1FA5E4ED2116
+ MODULE_TYPE = UEFI_APPLICATION
+ VERSION_STRING = 1.0
+ ENTRY_POINT = UefiMain
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF EBC ARM
+#
+
+[Sources]
+ fwupdate.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ EmbeddedPkg/EmbeddedPkg.dec
+ ArmPkg/ArmPkg.dec
+ SamsungPlatformPkg/ExynosPkg/Exynos5250/ExynosPkg.dec
+ SamsungPlatformPkg/ArndaleBoardPkg/ArndaleBoardPkg.dec
+
+[LibraryClasses]
+ UefiApplicationEntryPoint
+ UefiLib
+ PcdLib
+ EfiFileLib
+
+[Pcd]
+
+
diff --git a/SamsungPlatformPkg/Apps/Tools/mkbl2/5250/fwbl1_5250.bin b/SamsungPlatformPkg/Apps/Tools/mkbl2/5250/fwbl1_5250.bin
new file mode 100644
index 000000000..b7e9b743c
--- /dev/null
+++ b/SamsungPlatformPkg/Apps/Tools/mkbl2/5250/fwbl1_5250.bin
Binary files differ
diff --git a/SamsungPlatformPkg/Apps/Tools/mkbl2/5250/fwbl1_5250_evt1.bin b/SamsungPlatformPkg/Apps/Tools/mkbl2/5250/fwbl1_5250_evt1.bin
new file mode 100644
index 000000000..ad621e501
--- /dev/null
+++ b/SamsungPlatformPkg/Apps/Tools/mkbl2/5250/fwbl1_5250_evt1.bin
Binary files differ
diff --git a/SamsungPlatformPkg/Apps/Tools/mkbl2/5250/fwbl1_5250_evt1_pop.bin b/SamsungPlatformPkg/Apps/Tools/mkbl2/5250/fwbl1_5250_evt1_pop.bin
new file mode 100644
index 000000000..7e0a2c177
--- /dev/null
+++ b/SamsungPlatformPkg/Apps/Tools/mkbl2/5250/fwbl1_5250_evt1_pop.bin
Binary files differ
diff --git a/SamsungPlatformPkg/Apps/Tools/mkbl2/5250/fwbl2-5250-ddr3-no-tz.bin b/SamsungPlatformPkg/Apps/Tools/mkbl2/5250/fwbl2-5250-ddr3-no-tz.bin
new file mode 100644
index 000000000..85c9e482c
--- /dev/null
+++ b/SamsungPlatformPkg/Apps/Tools/mkbl2/5250/fwbl2-5250-ddr3-no-tz.bin
Binary files differ
diff --git a/SamsungPlatformPkg/Apps/Tools/mkbl2/5250/fwbl2-5250-none-evt1-no-tz.bin b/SamsungPlatformPkg/Apps/Tools/mkbl2/5250/fwbl2-5250-none-evt1-no-tz.bin
new file mode 100644
index 000000000..346ac9a6f
--- /dev/null
+++ b/SamsungPlatformPkg/Apps/Tools/mkbl2/5250/fwbl2-5250-none-evt1-no-tz.bin
Binary files differ
diff --git a/SamsungPlatformPkg/Apps/Tools/mkbl2/Makefile b/SamsungPlatformPkg/Apps/Tools/mkbl2/Makefile
new file mode 100644
index 000000000..0d52ece52
--- /dev/null
+++ b/SamsungPlatformPkg/Apps/Tools/mkbl2/Makefile
@@ -0,0 +1,21 @@
+CC=gcc
+
+CFLAGS=-g -Wall
+
+CSRCS = ./mkbl2.c \
+
+OBJS = $(CSRCS:.c=.o)
+
+.SUFFIXES:.c.o
+
+all: mkbl2
+
+testxv: $(OBJS)
+ $(CC) $(CFLAGS) -g -o $@ $(OBJS)
+
+.c.o:
+ $(CC) $(CFLAGS) -g -c -o $@ $<
+
+clean:
+ rm -f mkbl2 $(OBJS)
+
diff --git a/SamsungPlatformPkg/Apps/Tools/mkbl2/imgburn.sh b/SamsungPlatformPkg/Apps/Tools/mkbl2/imgburn.sh
new file mode 100755
index 000000000..dee12604a
--- /dev/null
+++ b/SamsungPlatformPkg/Apps/Tools/mkbl2/imgburn.sh
@@ -0,0 +1,106 @@
+#!/bin/bash
+
+# set the default image filename, this can be overwritten by a parameter
+IMAGE=../../../../Build/Arndale-Exynos/DEBUG_ARMLINUXGCC/FV/ARNDALE_EFI.fd
+
+# set the default SoC, this can be overwritten by a parameter
+SOC=5250
+
+function usage
+{
+ echo "Usage: $0"
+ echo " --disk path to the SD card device to write to, eg /dev/sdd"
+ echo " This can be found by looking at dmesg output"
+ echo " --image The image to write to the SD card"
+ echo " This defaults to:"
+ echo " $IMAGE"
+ echo " --soc Which SoC we are using"
+ echo " This defaults to: 5250"
+}
+
+while [ "$1" != "" ]; do
+ case $1 in
+ -s | --soc )
+ shift
+ SOC=$1
+ ;;
+
+ -d | --disk )
+ shift
+ DISK=$1
+ ;;
+
+ -i | --image )
+ shift
+ IMAGE=$1
+ ;;
+
+ /h | /? | -? | -h | --help )
+ usage
+ exit
+ ;;
+ -* )
+ usage
+ echo "unknown arg $1"
+ exit 1
+ esac
+ shift
+done
+
+echo "Config:"
+echo "IMAGE $IMAGE"
+echo "SoC $SOC"
+echo "DISK $DISK"
+
+
+if [ ! -b "$DISK" ]
+then
+ echo "You must specify a valid --disk option"
+ exit 1
+fi
+
+if [ ! -f $IMAGE ]
+then
+ echo ""
+ echo "ERROR: UEFI image $IMAGE does not exist.."
+ echo ""
+ exit
+fi
+
+# make mkbl2
+if [ ! -f mkbl2 ]
+then
+ make
+fi
+
+# make BL2
+./mkbl2 $IMAGE
+
+if [ ! -f fwbl2.bin ]
+then
+ echo ""
+ echo "ERROR: Failed to create BL2 image."
+ echo ""
+ exit
+fi
+
+# select platform
+if [ "$SOC" = "5250" ]
+then
+ # write BL1
+ dd if=./5250/fwbl1_5250.bin of=$DISK seek=1 count=16
+else
+ echo ""
+ echo "ERROR: Please select platform.."
+ echo ""
+ exit
+fi
+
+
+# write BL2
+dd if=./fwbl2.bin of=$DISK seek=17 count=32
+
+# write bootloader file e.g. u-boot or UEFI firmware image
+dd if=$IMAGE of=$DISK seek=49
+
+sync
diff --git a/SamsungPlatformPkg/Apps/Tools/mkbl2/mkbl2.c b/SamsungPlatformPkg/Apps/Tools/mkbl2/mkbl2.c
new file mode 100644
index 000000000..55d8b3c7e
--- /dev/null
+++ b/SamsungPlatformPkg/Apps/Tools/mkbl2/mkbl2.c
@@ -0,0 +1,88 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+
+
+#define FILE_CHUNK (32*512)
+
+int main (int argc, char* argv[])
+{
+ unsigned char *buffer = NULL;
+ int src_fd = -1;
+ int size, offset;
+ int dest_fd = -1;
+ unsigned int checksum, addr, i;
+
+ buffer = (unsigned char *)malloc(FILE_CHUNK);
+ if(NULL == buffer) {
+ printf("buffer allocation failed\n");
+ goto Exit;
+ }
+
+ src_fd = open(argv[1], O_RDONLY);
+ if(src_fd == -1) {
+ printf("source file(%s) open error\n", argv[1]);
+ goto Exit;
+ }
+
+ offset = lseek(src_fd, 0, SEEK_END);
+ if(offset == -1) {
+ printf("source file seek error SEEK_END\n");
+ goto Exit;
+ }
+
+ printf("source file(%s) size = %d bytes\n", argv[1], offset);
+
+ offset = lseek(src_fd, 0, SEEK_SET);
+ if(offset == -1) {
+ printf("source file seek error SEEK_SET\n");
+ goto Exit;
+ }
+
+ size = read(src_fd, (void *)buffer, FILE_CHUNK);
+ if(size != FILE_CHUNK) {
+ printf("source file read error, size=%d\n", size);
+ goto Exit;
+ }
+
+ addr = (unsigned int)buffer;
+
+ for(i=0, checksum=0;i<((14*1024) -4);i++)
+ checksum += *((unsigned char *)addr++);
+
+ *((unsigned int *)addr) = checksum;
+
+ dest_fd = open("./fwbl2.bin", (O_CREAT|O_RDWR), (S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH));
+ if(dest_fd == -1) {
+ printf("target file(fwbl2.bin) open error\n");
+ goto Exit;
+ }
+
+ size = write(dest_fd, (void *)buffer, FILE_CHUNK);
+ if(size != FILE_CHUNK) {
+ printf("target file write error, size=%d\n", size);
+ goto Exit;
+ }
+
+ offset = lseek(dest_fd, 0, SEEK_END);
+ if(offset == -1) {
+ printf("target file seek error SEEK_END\n");
+ goto Exit;
+ }
+
+ printf("target file(./fwbl2.bin) size = %d bytes\n", offset);
+
+Exit:
+ if(buffer != NULL)
+ free(buffer);
+
+ if(src_fd != -1)
+ close(src_fd);
+
+ if(dest_fd != -1)
+ close(dest_fd);
+
+ return 0;
+}
diff --git a/SamsungPlatformPkg/ArndaleBoardPkg/ArndaleBoardPkg.dec b/SamsungPlatformPkg/ArndaleBoardPkg/ArndaleBoardPkg.dec
new file mode 100644
index 000000000..f8313b734
--- /dev/null
+++ b/SamsungPlatformPkg/ArndaleBoardPkg/ArndaleBoardPkg.dec
@@ -0,0 +1,43 @@
+#/** @file
+# Arm RealView EB package.
+#
+# Copyright (c) 2012, Samsung Electronics Co. All rights reserved.<BR>
+#
+# This program and the accompanying materials are licensed and made
+# available under the terms and conditions of the BSD License which
+# accompanies this distribution.
+# The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#**/
+
+[Defines]
+ DEC_SPECIFICATION = 0x00010005
+ PACKAGE_NAME = ArndalePkg
+ PACKAGE_GUID = 4c9e432c-b84e-44fd-a796-f4545deec144
+ PACKAGE_VERSION = 0.1
+
+################################################################################
+#
+# Include Section - list of Include Paths that are provided by this package.
+# Comments are used for Keywords and Module Types.
+#
+# Supported Module Types:
+# BASE SEC PEI_CORE PEIM DXE_CORE DXE_DRIVER DXE_RUNTIME_DRIVER
+# DXE_SMM_DRIVER DXE_SAL_DRIVER UEFI_DRIVER UEFI_APPLICATION
+#
+################################################################################
+[Includes.common]
+# Include # Root include for the package
+
+[Guids.common] #bc92b024-79f8-11e0-a039-0026b9733e2c
+ gArndaleBoardPkgTokenSpaceGuid = { 0xbc92b024, 0x79f8, 0x11e0, { 0xa0, 0x39, 0x00, 0x26, 0xb9, 0x73, 0x3e, 0x2c} }
+
+[PcdsFeatureFlag.common]
+
+[PcdsFixedAtBuild.common]
+
+[Protocols.common]
diff --git a/SamsungPlatformPkg/ArndaleBoardPkg/ArndaleBoardPkg.dsc.inc b/SamsungPlatformPkg/ArndaleBoardPkg/ArndaleBoardPkg.dsc.inc
new file mode 100644
index 000000000..671ef131a
--- /dev/null
+++ b/SamsungPlatformPkg/ArndaleBoardPkg/ArndaleBoardPkg.dsc.inc
@@ -0,0 +1,316 @@
+#
+# Copyright (c) 2012, Samsung Electronics Co. All rights reserved.
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#
+
+[LibraryClasses.common]
+!if $(TARGET) == RELEASE
+ DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf
+ UncachedMemoryAllocationLib|ArmPkg/Library/UncachedMemoryAllocationLib/UncachedMemoryAllocationLib.inf
+!else
+ DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
+ UncachedMemoryAllocationLib|ArmPkg/Library/UncachedMemoryAllocationLib/UncachedMemoryAllocationLib.inf
+# UncachedMemoryAllocationLib|ArmPkg/Library/DebugUncachedMemoryAllocationLib/DebugUncachedMemoryAllocationLib.inf
+!endif
+ DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf
+
+ BaseLib|MdePkg/Library/BaseLib/BaseLib.inf
+ SynchronizationLib|MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf
+ PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf
+ PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf
+ PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf
+ PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf
+ IoLib|MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf
+ UefiDecompressLib|MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompressLib.inf
+ CpuLib|MdePkg/Library/BaseCpuLib/BaseCpuLib.inf
+
+ UefiLib|MdePkg/Library/UefiLib/UefiLib.inf
+ HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
+ UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf
+ DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf
+ UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf
+ DxeServicesTableLib|MdePkg/Library/DxeServicesTableLib/DxeServicesTableLib.inf
+ UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf
+ UefiApplicationEntryPoint|MdePkg/Library/UefiApplicationEntryPoint/UefiApplicationEntryPoint.inf
+ HiiLib|MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf
+ UefiHiiServicesLib|MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiServicesLib.inf
+
+ UefiRuntimeLib|MdePkg/Library/UefiRuntimeLib/UefiRuntimeLib.inf
+
+ #
+ # Assume everything is fixed at build
+ #
+ PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+
+ # 1/123 faster than Stm or Vstm version
+ #BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
+ BaseMemoryLib|ArmPkg/Library/BaseMemoryLibStm/BaseMemoryLibStm.inf
+
+ # ARM Architectural Libraries
+ CacheMaintenanceLib|ArmPkg/Library/ArmCacheMaintenanceLib/ArmCacheMaintenanceLib.inf
+ DefaultExceptionHandlerLib|ArmPkg/Library/DefaultExceptionHandlerLib/DefaultExceptionHandlerLib.inf
+ CpuExceptionHandlerLib|MdeModulePkg/Library/CpuExceptionHandlerLibNull/CpuExceptionHandlerLibNull.inf
+ ArmDisassemblerLib|ArmPkg/Library/ArmDisassemblerLib/ArmDisassemblerLib.inf
+ DmaLib|ArmPkg/Library/ArmDmaLib/ArmDmaLib.inf
+
+ # EBL Related Libraries
+ EblCmdLib|ArmPlatformPkg/Library/EblCmdLib/EblCmdLib.inf
+ EfiFileLib|EmbeddedPkg/Library/EfiFileLib/EfiFileLib.inf
+ EblAddExternalCommandLib|EmbeddedPkg/Library/EblAddExternalCommandLib/EblAddExternalCommandLib.inf
+ EblNetworkLib|EmbeddedPkg/Library/EblNetworkLib/EblNetworkLib.inf
+
+ #
+ # Uncomment (and comment out the next line) For Samsung Debugger. The Standard IO window
+ # in the debugger will show load and unload commands for symbols. You can cut and paste this
+ # into the command window to load symbols. We should be able to use a script to do this, but
+ # the version of RVD I have does not support scripts accessing system memory.
+ #
+ #PeCoffExtraActionLib|ArmPkg/Library/RvdPeCoffExtraActionLib/RvdPeCoffExtraActionLib.inf
+ PeCoffExtraActionLib|ArmPkg/Library/DebugPeCoffExtraActionLib/DebugPeCoffExtraActionLib.inf
+ #PeCoffExtraActionLib|MdePkg/Library/BasePeCoffExtraActionLibNull/BasePeCoffExtraActionLibNull.inf
+
+ DebugAgentLib|MdeModulePkg/Library/DebugAgentLibNull/DebugAgentLibNull.inf
+ DebugAgentTimerLib|SamsungPlatformPkg/ArndaleBoardPkg/Library/DebugAgentTimerLib/DebugAgentTimerLib.inf
+
+ SemihostLib|ArmPkg/Library/SemihostLib/SemihostLib.inf
+
+ # BDS Libraries
+ BdsLib|ArmPkg/Library/BdsLib/BdsLib.inf
+
+[LibraryClasses.common.SEC]
+ DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf
+ArmPlatformSecLib|ArmPlatformPkg/Library/ArmPlatformSecLibNull/ArmPlatformLibNullSec.inf
+ ArmPlatformSecExtraActionLib|ArmPlatformPkg/Library/DebugSecExtraActionLib/DebugSecExtraActionLib.inf
+ ArmPlatformGlobalVariableLib|ArmPlatformPkg/Library/ArmPlatformGlobalVariableLib/Sec/SecArmPlatformGlobalVariableLib.inf
+
+ DebugAgentLib|ArmPkg/Library/DebugAgentSymbolsBaseLib/DebugAgentSymbolsBaseLib.inf
+ DefaultExceptionHandlerLib|ArmPkg/Library/DefaultExceptionHandlerLib/DefaultExceptionHandlerLibBase.inf
+
+#!ifdef $(EDK2_SKIP_PEICORE)
+ PrePiLib|EmbeddedPkg/Library/PrePiLib/PrePiLib.inf
+ ExtractGuidedSectionLib|EmbeddedPkg/Library/PrePiExtractGuidedSectionLib/PrePiExtractGuidedSectionLib.inf
+ LzmaDecompressLib|IntelFrameworkModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf
+ MemoryAllocationLib|EmbeddedPkg/Library/PrePiMemoryAllocationLib/PrePiMemoryAllocationLib.inf
+ HobLib|EmbeddedPkg/Library/PrePiHobLib/PrePiHobLib.inf
+ PrePiHobListPointerLib|ArmPlatformPkg/Library/PrePiHobListPointerLib/PrePiHobListPointerLib.inf
+ PerformanceLib|MdeModulePkg/Library/PeiPerformanceLib/PeiPerformanceLib.inf
+ PlatformPeiLib|ArmPlatformPkg/PlatformPei/PlatformPeiLib.inf
+ MemoryInitPeiLib|ArmPlatformPkg/MemoryInitPei/MemoryInitPeiLib.inf
+#!endif
+
+ # Trustzone Support
+ ArmTrustedMonitorLib|ArmPlatformPkg/Library/ArmTrustedMonitorLibNull/ArmTrustedMonitorLibNull.inf
+
+[LibraryClasses.common.PEI_CORE]
+ HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
+ PeiServicesLib|MdePkg/Library/PeiServicesLib/PeiServicesLib.inf
+ MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf
+ PeiCoreEntryPoint|MdePkg/Library/PeiCoreEntryPoint/PeiCoreEntryPoint.inf
+ PerformanceLib|MdeModulePkg/Library/PeiPerformanceLib/PeiPerformanceLib.inf
+ ReportStatusCodeLib|MdeModulePkg/Library/PeiReportStatusCodeLib/PeiReportStatusCodeLib.inf
+ OemHookStatusCodeLib|MdeModulePkg/Library/OemHookStatusCodeLibNull/OemHookStatusCodeLibNull.inf
+ PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf
+ UefiDecompressLib|MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompressLib.inf
+ ExtractGuidedSectionLib|MdePkg/Library/PeiExtractGuidedSectionLib/PeiExtractGuidedSectionLib.inf
+
+ ArmPlatformGlobalVariableLib|ArmPlatformPkg/Library/ArmPlatformGlobalVariableLib/Pei/PeiArmPlatformGlobalVariableLib.inf
+ PeiServicesTablePointerLib|ArmPlatformPkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointerLib.inf
+
+[LibraryClasses.common.PEIM]
+ HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
+ PeiServicesLib|MdePkg/Library/PeiServicesLib/PeiServicesLib.inf
+ MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf
+ PeimEntryPoint|MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf
+ PerformanceLib|MdeModulePkg/Library/PeiPerformanceLib/PeiPerformanceLib.inf
+ ReportStatusCodeLib|MdeModulePkg/Library/PeiReportStatusCodeLib/PeiReportStatusCodeLib.inf
+ OemHookStatusCodeLib|MdeModulePkg/Library/OemHookStatusCodeLibNull/OemHookStatusCodeLibNull.inf
+ PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf
+ PeiResourcePublicationLib|MdePkg/Library/PeiResourcePublicationLib/PeiResourcePublicationLib.inf
+ UefiDecompressLib|MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompressLib.inf
+ ExtractGuidedSectionLib|MdePkg/Library/PeiExtractGuidedSectionLib/PeiExtractGuidedSectionLib.inf
+
+ ArmPlatformGlobalVariableLib|ArmPlatformPkg/Library/ArmPlatformGlobalVariableLib/Pei/PeiArmPlatformGlobalVariableLib.inf
+ PeiServicesTablePointerLib|ArmPlatformPkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointerLib.inf
+
+[LibraryClasses.common.DXE_CORE]
+ HobLib|MdePkg/Library/DxeCoreHobLib/DxeCoreHobLib.inf
+ MemoryAllocationLib|MdeModulePkg/Library/DxeCoreMemoryAllocationLib/DxeCoreMemoryAllocationLib.inf
+ DxeCoreEntryPoint|MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.inf
+ ReportStatusCodeLib|IntelFrameworkModulePkg/Library/DxeReportStatusCodeLibFramework/DxeReportStatusCodeLib.inf
+ ExtractGuidedSectionLib|MdePkg/Library/DxeExtractGuidedSectionLib/DxeExtractGuidedSectionLib.inf
+ UefiDecompressLib|MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompressLib.inf
+ DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf
+ PerformanceLib|MdeModulePkg/Library/DxeCorePerformanceLib/DxeCorePerformanceLib.inf
+
+[LibraryClasses.common.DXE_DRIVER]
+ ReportStatusCodeLib|IntelFrameworkModulePkg/Library/DxeReportStatusCodeLibFramework/DxeReportStatusCodeLib.inf
+ DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf
+ SecurityManagementLib|MdeModulePkg/Library/DxeSecurityManagementLib/DxeSecurityManagementLib.inf
+ PerformanceLib|MdeModulePkg/Library/DxePerformanceLib/DxePerformanceLib.inf
+ MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
+ ArmPlatformGlobalVariableLib|ArmPlatformPkg/Library/ArmPlatformGlobalVariableLib/Dxe/DxeArmPlatformGlobalVariableLib.inf
+
+ GenericBdsLib|IntelFrameworkModulePkg/Library/GenericBdsLib/GenericBdsLib.inf
+ PlatformBdsLib|SamsungPlatformPkg/Library/PlatformBdsLib/PlatformBdsLib.inf
+ CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.inf
+
+
+[LibraryClasses.common.UEFI_APPLICATION]
+ UefiDecompressLib|IntelFrameworkModulePkg/Library/BaseUefiTianoCustomDecompressLib/BaseUefiTianoCustomDecompressLib.inf
+ PerformanceLib|MdeModulePkg/Library/DxePerformanceLib/DxePerformanceLib.inf
+ MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
+ HiiLib|MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf
+
+[LibraryClasses.common.UEFI_DRIVER]
+ ReportStatusCodeLib|IntelFrameworkModulePkg/Library/DxeReportStatusCodeLibFramework/DxeReportStatusCodeLib.inf
+ UefiDecompressLib|IntelFrameworkModulePkg/Library/BaseUefiTianoCustomDecompressLib/BaseUefiTianoCustomDecompressLib.inf
+ ExtractGuidedSectionLib|MdePkg/Library/DxeExtractGuidedSectionLib/DxeExtractGuidedSectionLib.inf
+ PerformanceLib|MdeModulePkg/Library/DxePerformanceLib/DxePerformanceLib.inf
+ MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
+
+[LibraryClasses.common.DXE_RUNTIME_DRIVER]
+ HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
+ MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
+ ReportStatusCodeLib|IntelFrameworkModulePkg/Library/DxeReportStatusCodeLibFramework/DxeReportStatusCodeLib.inf
+ CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.inf
+
+[LibraryClasses.ARM]
+ #
+ # It is not possible to prevent the ARM compiler for generic intrinsic functions.
+ # This library provides the instrinsic functions generate by a given compiler.
+ # [LibraryClasses.ARM] and NULL mean link this library into all ARM images.
+ #
+ NULL|ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf
+
+[BuildOptions]
+ RVCT:RELEASE_*_*_CC_FLAGS = -DMDEPKG_NDEBUG
+
+ GCC:RELEASE_*_*_CC_FLAGS = -DMDEPKG_NDEBUG
+
+ XCODE:RELEASE_*_*_CC_FLAGS = -DMDEPKG_NDEBUG
+
+
+################################################################################
+#
+# Pcd Section - list of all EDK II PCD Entries defined by this Platform
+#
+################################################################################
+
+[PcdsFeatureFlag.common]
+ gEfiMdePkgTokenSpaceGuid.PcdComponentNameDisable|TRUE
+ gEfiMdePkgTokenSpaceGuid.PcdDriverDiagnosticsDisable|TRUE
+ gEfiMdePkgTokenSpaceGuid.PcdComponentName2Disable|TRUE
+ gEfiMdePkgTokenSpaceGuid.PcdDriverDiagnostics2Disable|TRUE
+
+ gEmbeddedTokenSpaceGuid.PcdCacheEnable|TRUE
+
+ # Use the Vector Table location in CpuDxe. We will not copy the Vector Table at PcdCpuVectorBaseAddress
+ gArmTokenSpaceGuid.PcdRelocateVectorTable|FALSE
+
+ gEmbeddedTokenSpaceGuid.PcdPrePiProduceMemoryTypeInformationHob|TRUE
+
+ gEfiMdeModulePkgTokenSpaceGuid.PcdTurnOffUsbLegacySupport|TRUE
+
+[PcdsFixedAtBuild.common]
+ gEmbeddedTokenSpaceGuid.PcdPrePiCpuMemorySize|32
+ gEmbeddedTokenSpaceGuid.PcdPrePiCpuIoSize|0
+ gEfiMdePkgTokenSpaceGuid.PcdMaximumUnicodeStringLength|1000000
+ gEfiMdePkgTokenSpaceGuid.PcdMaximumAsciiStringLength|1000000
+ gEfiMdePkgTokenSpaceGuid.PcdMaximumLinkedListLength|1000000
+ gEfiMdePkgTokenSpaceGuid.PcdSpinLockTimeout|10000000
+ gEfiMdePkgTokenSpaceGuid.PcdDebugClearMemoryValue|0xAF
+ gEfiMdePkgTokenSpaceGuid.PcdPerformanceLibraryPropertyMask|1
+ gEfiMdePkgTokenSpaceGuid.PcdPostCodePropertyMask|0
+ gEfiMdePkgTokenSpaceGuid.PcdUefiLibMaxPrintBufferSize|320
+
+ # DEBUG_ASSERT_ENABLED 0x01
+ # DEBUG_PRINT_ENABLED 0x02
+ # DEBUG_CODE_ENABLED 0x04
+ # CLEAR_MEMORY_ENABLED 0x08
+ # ASSERT_BREAKPOINT_ENABLED 0x10
+ # ASSERT_DEADLOOP_ENABLED 0x20
+!if $(TARGET) == RELEASE
+ gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x21
+!else
+ gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x2f
+!endif
+
+ # DEBUG_INIT 0x00000001 // Initialization
+ # DEBUG_WARN 0x00000002 // Warnings
+ # DEBUG_LOAD 0x00000004 // Load events
+ # DEBUG_FS 0x00000008 // EFI File system
+ # DEBUG_POOL 0x00000010 // Alloc & Free's
+ # DEBUG_PAGE 0x00000020 // Alloc & Free's
+ # DEBUG_INFO 0x00000040 // Verbose
+ # DEBUG_DISPATCH 0x00000080 // PEI/DXE Dispatchers
+ # DEBUG_VARIABLE 0x00000100 // Variable
+ # DEBUG_BM 0x00000400 // Boot Manager
+ # DEBUG_BLKIO 0x00001000 // BlkIo Driver
+ # DEBUG_NET 0x00004000 // SNI Driver
+ # DEBUG_UNDI 0x00010000 // UNDI Driver
+ # DEBUG_LOADFILE 0x00020000 // UNDI Driver
+ # DEBUG_EVENT 0x00080000 // Event messages
+ # DEBUG_GCD 0x00100000 // GCD
+ # DEBUG_ERROR 0x80000000 // Error
+ gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x8000000F
+
+ gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|0x07
+
+ gEmbeddedTokenSpaceGuid.PcdEmbeddedAutomaticBootCommand|""
+ #gEmbeddedTokenSpaceGuid.PcdEmbeddedAutomaticBootCommand|"start fs1\:\\efi\\boot\\bootarm.efi"
+ gEmbeddedTokenSpaceGuid.PcdEmbeddedDefaultTextColor|0x07
+ gEmbeddedTokenSpaceGuid.PcdEmbeddedMemVariableStoreSize|0x10000
+
+ #
+ # Optional feature to help prevent EFI memory map fragments
+ # Turned on and off via: PcdPrePiProduceMemoryTypeInformationHob
+ # Values are in EFI Pages (4K). DXE Core will make sure that
+ # at least this much of each type of memory can be allocated
+ # from a single memory range. This way you only end up with
+ # maximum of two fragements for each type in the memory map
+ # (the memory used, and the free memory that was prereserved
+ # but not used).
+ #
+ gArmTokenSpaceGuid.PcdCpuVectorBaseAddress|0x00000000
+
+ gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiACPIReclaimMemory|0
+ gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiACPIMemoryNVS|0
+ gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiReservedMemoryType|0
+ gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesData|80
+ gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesCode|40
+ gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiBootServicesCode|400
+ gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiBootServicesData|800
+ gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiLoaderCode|10
+ gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiLoaderData|0
+
+
+ #
+ # ARM OS Loader
+ #
+ gArmTokenSpaceGuid.PcdArmMachineType|2456
+ gArmPlatformTokenSpaceGuid.PcdDefaultBootDescription|L"Linaro image on SD card"
+ gArmPlatformTokenSpaceGuid.PcdDefaultBootDevicePath|L"VenHw(3A02E7FE-0649-4FB4-BE4F-A862CA1872A9)/HD(2,MBR,0x00000000,0x2000,0x1A000)/uImage"
+ gArmPlatformTokenSpaceGuid.PcdDefaultBootInitrdPath|L"VenHw(3A02E7FE-0649-4FB4-BE4F-A862CA1872A9)/HD(2,MBR,0x00000000,0x2000,0x1A000)/uInitrd"
+ gArmPlatformTokenSpaceGuid.PcdDefaultFdtLocalDevicePath|L"VenHw(3A02E7FE-0649-4FB4-BE4F-A862CA1872A9)/HD(2,MBR,0x00000000,0x2000,0x1A000)/board.dtb"
+ gArmPlatformTokenSpaceGuid.PcdDefaultBootArgument|"root=/dev/mmcblk1p3 rw rootwait console=ttySAC2,115200n8 init --no-log"
+ gArmPlatformTokenSpaceGuid.PcdDefaultBootType|3
+ gArmPlatformTokenSpaceGuid.PcdFdtDevicePath|L"VenHw(3A02E7FE-0649-4FB4-BE4F-A862CA1872A9)/HD(2,MBR,0x00000000,0x2000,0x1A000)/board.dtb"
+
+ # Use the Serial console (ConIn & ConOut) and the Graphic driver (ConOut)
+ gArmPlatformTokenSpaceGuid.PcdDefaultConOutPaths|L"VenHw(D3987D4B-971A-435F-8CAF-4967EB627241)/Uart(115200,8,N,1)/VenPcAnsi();VenHw(9042A9DE-23DC-4A38-96FB-7ADED080516A)"
+ gArmPlatformTokenSpaceGuid.PcdDefaultConInPaths|L"VenHw(D3987D4B-971A-435F-8CAF-4967EB627241)/Uart(115200,8,N,1)/VenPcAnsi()"
+
+ gArmPlatformTokenSpaceGuid.PcdPlatformBootTimeOut|10
+
+ #
+ # Boot Application
+ #
+ gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdShellFile|{ 0x4A, 0x35, 0xEF, 0x3C, 0x7A, 0x3B, 0x19, 0x45, 0xAD, 0x70, 0x72, 0xA1, 0x34, 0x69, 0x83, 0x11 }
diff --git a/SamsungPlatformPkg/ArndaleBoardPkg/Debugger_scripts/EBLoadSecSyms.inc b/SamsungPlatformPkg/ArndaleBoardPkg/Debugger_scripts/EBLoadSecSyms.inc
new file mode 100644
index 000000000..281c99b4a
--- /dev/null
+++ b/SamsungPlatformPkg/ArndaleBoardPkg/Debugger_scripts/EBLoadSecSyms.inc
@@ -0,0 +1,15 @@
+// returns the base address of the SEC FV in flash on the EB board
+// change this address for where your platform's SEC FV is located
+// (or make it more intelligent to search for it)
+define /r FindFv()
+{
+ return 0x40000000;
+}
+.
+
+include /s 'ZZZZZZ/EfiFuncs.inc'
+error=continue
+unload ,all
+error=abort
+LoadPeiSec()
+include C:\loadfiles.inc
diff --git a/SamsungPlatformPkg/ArndaleBoardPkg/Debugger_scripts/EfiFuncs.inc b/SamsungPlatformPkg/ArndaleBoardPkg/Debugger_scripts/EfiFuncs.inc
new file mode 100644
index 000000000..014d09440
--- /dev/null
+++ b/SamsungPlatformPkg/ArndaleBoardPkg/Debugger_scripts/EfiFuncs.inc
@@ -0,0 +1,463 @@
+error=abort
+
+// NOTE: THIS MAY NEED TO BE ADJUSTED
+// change to reflect the total amount of ram in your system
+define /r GetMaxMem()
+{
+ return 0x10000000; // 256 MB
+}
+.
+
+define /r GetWord(Addr)
+{
+ unsigned long data;
+
+ if( (Addr & 0x2) == 0 )
+ {
+ data = dword(Addr);
+ data = data & 0xffff;
+ //$printf "getword data is %x\n", data$;
+ return data;
+ }
+ else
+ {
+ data = dword(Addr & 0xfffffffc);
+ //data = data >> 16;
+ data = data / 0x10000;
+ //$printf "getword data is %x (1)\n", data$;
+ return data;
+ }
+}
+.
+
+define /r ProcessPE32(imgstart)
+unsigned long imgstart;
+{
+ unsigned long filehdrstart;
+ unsigned long debugdirentryrva;
+ unsigned long debugtype;
+ unsigned long debugrva;
+ unsigned long dwarfsig;
+ unsigned long baseofcode;
+ unsigned long baseofdata;
+ unsigned long elfbase;
+ char *elfpath;
+
+ $printf "PE32 image found at %x",imgstart$;
+
+ //$printf "PE file hdr offset %x",dword(imgstart+0x3C)$;
+
+ // offset from dos hdr to PE file hdr
+ filehdrstart = imgstart + dword(imgstart+0x3C);
+
+ // offset to debug dir in PE hdrs
+ //$printf "debug dir is at %x",(filehdrstart+0xA8)$;
+ debugdirentryrva = dword(filehdrstart + 0xA8);
+ if(debugdirentryrva == 0)
+ {
+ $printf "no debug dir for image at %x",imgstart$;
+ return;
+ }
+
+ //$printf "debug dir entry rva is %x",debugdirentryrva$;
+
+ debugtype = dword(imgstart + debugdirentryrva + 0xc);
+ if( (debugtype != 0xdf) && (debugtype != 0x2) )
+ {
+ $printf "debug type is not dwarf for image at %x",imgstart$;
+ $printf "debug type is %x",debugtype$;
+ return;
+ }
+
+ debugrva = dword(imgstart + debugdirentryrva + 0x14);
+ dwarfsig = dword(imgstart + debugrva);
+ if(dwarfsig != 0x66727764)
+ {
+ $printf "dwarf debug signature not found for image at %x",imgstart$;
+ return;
+ }
+
+ elfpath = (char *)(imgstart + debugrva + 0xc);
+
+ baseofcode = imgstart + dword(filehdrstart + 0x28);
+ baseofdata = imgstart + dword(filehdrstart + 0x2c);
+
+ if( (baseofcode < baseofdata) && (baseofcode != 0) )
+ {
+ elfbase = baseofcode;
+ }
+ else
+ {
+ elfbase = baseofdata;
+ }
+
+ $printf "found path %s",elfpath$;
+ $fprintf 50, "load /ni /np /a %s &0x%x\n",elfpath,elfbase$;
+}
+.
+
+define /r ProcessTE(imgstart)
+unsigned long imgstart;
+{
+ unsigned long strippedsize;
+ unsigned long debugdirentryrva;
+ unsigned long debugtype;
+ unsigned long debugrva;
+ unsigned long dwarfsig;
+ unsigned long elfbase;
+ char *elfpath;
+
+ $printf "TE image found at %x",imgstart$;
+
+ // determine pe header bytes removed to account for in rva references
+ //strippedsize = word(imgstart + 0x6);
+ //strippedsize = (dword(imgstart + 0x4) & 0xffff0000) >> 16;
+ strippedsize = (dword(imgstart + 0x4) & 0xffff0000) / 0x10000;
+ strippedsize = strippedsize - 0x28;
+
+ debugdirentryrva = dword(imgstart + 0x20);
+ if(debugdirentryrva == 0)
+ {
+ $printf "no debug dir for image at %x",imgstart$;
+ return;
+ }
+ debugdirentryrva = debugdirentryrva - strippedsize;
+
+ //$printf "debug dir entry rva is %x",debugdirentryrva$;
+
+ debugtype = dword(imgstart + debugdirentryrva + 0xc);
+ if( (debugtype != 0xdf) && (debugtype != 0x2) )
+ {
+ $printf "debug type is not dwarf for image at %x",imgstart$;
+ $printf "debug type is %x",debugtype$;
+ return;
+ }
+
+ debugrva = dword(imgstart + debugdirentryrva + 0x14);
+ debugrva = debugrva - strippedsize;
+ dwarfsig = dword(imgstart + debugrva);
+ if( (dwarfsig != 0x66727764) && (dwarfsig != 0x3031424e) )
+ {
+ $printf "dwarf debug signature not found for image at %x",imgstart$;
+ $printf "found %x", dwarfsig$;
+ return;
+ }
+
+ if( dwarfsig == 0x66727764 )
+ {
+ elfpath = (char *)(imgstart + debugrva + 0xc);
+ $printf "looking for elf path at 0x%x", elfpath$;
+ }
+ else
+ {
+ elfpath = (char *)(imgstart + debugrva + 0x10);
+ $printf "looking for elf path at 0x%x", elfpath$;
+ }
+
+ // elf base is baseofcode (we hope that for TE images it's not baseofdata)
+ elfbase = imgstart + dword(imgstart + 0xc) - strippedsize;
+
+ $printf "found path %s",elfpath$;
+ $fprintf 50, "load /ni /np /a %s &0x%x\n",elfpath,elfbase$;
+}
+.
+
+define /r ProcessFvSection(secstart)
+unsigned long secstart;
+{
+ unsigned long sectionsize;
+ unsigned char sectiontype;
+
+ sectionsize = dword(secstart);
+ //sectiontype = (sectionsize & 0xff000000) >> 24;
+ sectiontype = (sectionsize & 0xff000000) / 0x1000000;
+ sectionsize = sectionsize & 0x00ffffff;
+
+ $printf "fv section at %x size %x type %x",secstart,sectionsize,sectiontype$;
+
+ if(sectiontype == 0x10) // PE32
+ {
+ ProcessPE32(secstart+0x4);
+ }
+ else if(sectiontype == 0x12) // TE
+ {
+ ProcessTE(secstart+0x4);
+ }
+}
+.
+
+define /r ProcessFfsFile(ffsfilestart)
+unsigned long ffsfilestart;
+{
+ unsigned long ffsfilesize;
+ unsigned long ffsfiletype;
+ unsigned long secoffset;
+ unsigned long secsize;
+
+ //ffsfiletype = byte(ffsfilestart + 0x12);
+ ffsfilesize = dword(ffsfilestart + 0x14);
+ //ffsfiletype = (ffsfilesize & 0xff000000) >> 24;
+ ffsfiletype = (ffsfilesize & 0xff000000) / 0x1000000;
+ ffsfilesize = ffsfilesize & 0x00ffffff;
+
+ if(ffsfiletype == 0xff) return;
+
+ $printf "ffs file at %x size %x type %x",ffsfilestart,ffsfilesize,ffsfiletype$;
+
+ secoffset = ffsfilestart + 0x18;
+
+ // loop through sections in file
+ while(secoffset < (ffsfilestart + ffsfilesize))
+ {
+ // process fv section and increment section offset by size
+ secsize = dword(secoffset) & 0x00ffffff;
+ ProcessFvSection(secoffset);
+ secoffset = secoffset + secsize;
+
+ // align to next 4 byte boundary
+ if( (secoffset & 0x3) != 0 )
+ {
+ secoffset = secoffset + (0x4 - (secoffset & 0x3));
+ }
+ } // end section loop
+}
+.
+
+define /r LoadPeiSec()
+{
+ unsigned long fvbase;
+ unsigned long fvlen;
+ unsigned long fvsig;
+ unsigned long ffsoffset;
+ unsigned long ffsfilesize;
+
+ fvbase = FindFv();
+ $printf "fvbase %x",fvbase$;
+
+ // get fv signature field
+ fvsig = dword(fvbase + 0x28);
+ if(fvsig != 0x4856465F)
+ {
+ $printf "FV does not have proper signature, exiting"$;
+ return 0;
+ }
+
+ $printf "FV signature found"$;
+
+ $fopen 50, 'C:\loadfiles.inc'$;
+
+ fvlen = dword(fvbase + 0x20);
+
+ // first ffs file is after fv header, use headerlength field
+ //ffsoffset = (dword(fvbase + 0x30) & 0xffff0000) >> 16;
+ ffsoffset = (dword(fvbase + 0x30) & 0xffff0000) / 0x10000;
+ ffsoffset = fvbase + GetWord(fvbase + 0x30);
+
+ // loop through ffs files
+ while(ffsoffset < (fvbase+fvlen))
+ {
+ // process ffs file and increment by ffs file size field
+ ProcessFfsFile(ffsoffset);
+ ffsfilesize = (dword(ffsoffset + 0x14) & 0x00ffffff);
+ if(ffsfilesize == 0)
+ {
+ break;
+ }
+ ffsoffset = ffsoffset + ffsfilesize;
+
+
+ // align to next 8 byte boundary
+ if( (ffsoffset & 0x7) != 0 )
+ {
+ ffsoffset = ffsoffset + (0x8 - (ffsoffset & 0x7));
+ }
+
+ } // end fv ffs loop
+
+ $vclose 50$;
+
+}
+.
+
+define /r FindSystemTable(TopOfRam)
+unsigned long TopOfRam;
+{
+ unsigned long offset;
+
+ $printf "FindSystemTable"$;
+ $printf "top of mem is %x",TopOfRam$;
+
+ offset = TopOfRam;
+
+ // align to highest 4MB boundary
+ offset = offset & 0xFFC00000;
+
+ // start at top and look on 4MB boundaries for system table ptr structure
+ while(offset > 0)
+ {
+ //$printf "checking %x",offset$;
+ //$printf "value is %x",dword(offset)$;
+
+ // low signature match
+ if(dword(offset) == 0x20494249)
+ {
+ // high signature match
+ if(dword(offset+4) == 0x54535953)
+ {
+ // less than 4GB?
+ if(dword(offset+0x0c) == 0)
+ {
+ // less than top of ram?
+ if(dword(offset+8) < TopOfRam)
+ {
+ return(dword(offset+8));
+ }
+ }
+ }
+
+ }
+
+ if(offset < 0x400000) break;
+ offset = offset - 0x400000;
+ }
+
+ return 0;
+}
+.
+
+define /r ProcessImage(ImageBase)
+unsigned long ImageBase;
+{
+ $printf "ProcessImage %x", ImageBase$;
+}
+.
+
+define /r FindDebugInfo(SystemTable)
+unsigned long SystemTable;
+{
+ unsigned long CfgTableEntries;
+ unsigned long ConfigTable;
+ unsigned long i;
+ unsigned long offset;
+ unsigned long dbghdr;
+ unsigned long dbgentries;
+ unsigned long dbgptr;
+ unsigned long dbginfo;
+ unsigned long loadedimg;
+
+ $printf "FindDebugInfo"$;
+
+ dbgentries = 0;
+ CfgTableEntries = dword(SystemTable + 0x40);
+ ConfigTable = dword(SystemTable + 0x44);
+
+ $printf "config table is at %x (%d entries)", ConfigTable, CfgTableEntries$;
+
+ // now search for debug info entry with guid 49152E77-1ADA-4764-B7A2-7AFEFED95E8B
+ // 0x49152E77 0x47641ADA 0xFE7AA2B7 0x8B5ED9FE
+ for(i=0; i<CfgTableEntries; i++)
+ {
+ offset = ConfigTable + (i*0x14);
+ if(dword(offset) == 0x49152E77)
+ {
+ if(dword(offset+4) == 0x47641ADA)
+ {
+ if(dword(offset+8) == 0xFE7AA2B7)
+ {
+ if(dword(offset+0xc) == 0x8B5ED9FE)
+ {
+ dbghdr = dword(offset+0x10);
+ dbgentries = dword(dbghdr + 4);
+ dbgptr = dword(dbghdr + 8);
+ }
+ }
+ }
+ }
+ }
+
+ if(dbgentries == 0)
+ {
+ $printf "no debug entries found"$;
+ return;
+ }
+
+ $printf "debug table at %x (%d entries)", dbgptr, dbgentries$;
+
+ for(i=0; i<dbgentries; i++)
+ {
+ dbginfo = dword(dbgptr + (i*4));
+ if(dbginfo != 0)
+ {
+ if(dword(dbginfo) == 1) // normal debug info type
+ {
+ loadedimg = dword(dbginfo + 4);
+ ProcessPE32(dword(loadedimg + 0x20));
+ }
+ }
+ }
+}
+.
+
+define /r LoadDxe()
+{
+ unsigned long maxmem;
+ unsigned long systbl;
+
+ $printf "LoadDxe"$;
+
+ $fopen 50, 'C:\loadfiles.inc'$;
+
+ maxmem = GetMaxMem();
+ systbl = FindSystemTable(maxmem);
+ if(systbl != 0)
+ {
+ $printf "found system table at %x",systbl$;
+ FindDebugInfo(systbl);
+ }
+
+ $vclose 50$;
+}
+.
+
+define /r LoadRuntimeDxe()
+
+{
+ unsigned long maxmem;
+ unsigned long SystemTable;
+ unsigned long CfgTableEntries;
+ unsigned long ConfigTable;
+ unsigned long i;
+ unsigned long offset;
+ unsigned long numentries;
+ unsigned long RuntimeDebugInfo;
+ unsigned long DebugInfoOffset;
+ unsigned long imgbase;
+
+ $printf "LoadRuntimeDxe"$;
+
+ $fopen 50, 'C:\loadfiles.inc'$;
+
+ RuntimeDebugInfo = 0x80000010;
+
+ if(RuntimeDebugInfo != 0)
+ {
+ numentries = dword(RuntimeDebugInfo);
+
+ $printf "runtime debug info is at %x (%d entries)", RuntimeDebugInfo, numentries$;
+
+ DebugInfoOffset = RuntimeDebugInfo + 0x4;
+ for(i=0; i<numentries; i++)
+ {
+ imgbase = dword(DebugInfoOffset);
+ if(imgbase != 0)
+ {
+ $printf "found image at %x",imgbase$;
+ ProcessPE32(imgbase);
+ }
+ DebugInfoOffset = DebugInfoOffset + 0x4;
+ }
+ }
+
+ $vclose 50$;
+}
+.
diff --git a/SamsungPlatformPkg/ArndaleBoardPkg/Debugger_scripts/rvi_boot_from_ram.inc b/SamsungPlatformPkg/ArndaleBoardPkg/Debugger_scripts/rvi_boot_from_ram.inc
new file mode 100644
index 000000000..cd273a423
--- /dev/null
+++ b/SamsungPlatformPkg/ArndaleBoardPkg/Debugger_scripts/rvi_boot_from_ram.inc
@@ -0,0 +1,20 @@
+//
+// Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+//
+// This program and the accompanying materials
+// are licensed and made available under the terms and conditions of the BSD License
+// which accompanies this distribution. The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+//
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+error = continue
+unload
+error = abort
+
+setreg @CP15_CONTROL = 0x0005107E
+setreg @pc=0x80008208
+setreg @cpsr=0x000000D3
+dis/D
+readfile,raw,nowarn "ZZZZZZ/FV/BEAGLEBOARD_EFI.fd"=0x80008000
diff --git a/SamsungPlatformPkg/ArndaleBoardPkg/Debugger_scripts/rvi_convert_symbols.sh b/SamsungPlatformPkg/ArndaleBoardPkg/Debugger_scripts/rvi_convert_symbols.sh
new file mode 100644
index 000000000..46dd65cf3
--- /dev/null
+++ b/SamsungPlatformPkg/ArndaleBoardPkg/Debugger_scripts/rvi_convert_symbols.sh
@@ -0,0 +1,22 @@
+#!/bin/sh
+#
+# Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http:#opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+
+
+IN=`/usr/bin/cygpath -u $1`
+OUT=`/usr/bin/cygpath -u $2`
+
+/usr/bin/sed -e "s/\/cygdrive\/\(.\)/load\/a\/ni\/np \"\1:/g" \
+ -e 's:\\:/:g' \
+ -e "s/^/load\/a\/ni\/np \"/g" \
+ -e "s/dll /dll\" \&/g" \
+ $IN | /usr/bin/sort.exe --key=3 --output=$OUT
diff --git a/SamsungPlatformPkg/ArndaleBoardPkg/Debugger_scripts/rvi_hw_setup.inc b/SamsungPlatformPkg/ArndaleBoardPkg/Debugger_scripts/rvi_hw_setup.inc
new file mode 100644
index 000000000..c03a443e8
--- /dev/null
+++ b/SamsungPlatformPkg/ArndaleBoardPkg/Debugger_scripts/rvi_hw_setup.inc
@@ -0,0 +1,67 @@
+//
+// Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+//
+// This program and the accompanying materials
+// are licensed and made available under the terms and conditions of the BSD License
+// which accompanies this distribution. The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+//
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+
+error = continue
+unload
+error = abort
+
+setreg @CP15_CONTROL = 0x0005107E
+setreg @cpsr=0x000000D3
+
+; General clock settings.
+setmem /32 0x48307270=0x00000080
+setmem /32 0x48306D40=0x00000003
+setmem /32 0x48005140=0x03020A50
+
+;Clock configuration
+setmem /32 0x48004A40=0x0000030A
+setmem /32 0x48004C40=0x00000015
+
+;DPLL3 (Core) settings
+setmem /32 0x48004D00=0x00370037
+setmem /32 0x48004D30=0x00000000
+setmem /32 0x48004D40=0x094C0C00
+
+;DPLL4 (Peripheral) settings
+setmem /32 0x48004D00=0x00370037
+setmem /32 0x48004D30=0x00000000
+setmem /32 0x48004D44=0x0001B00C
+setmem /32 0x48004D48=0x00000009
+
+;DPLL1 (MPU) settings
+setmem /32 0x48004904=0x00000037
+setmem /32 0x48004934=0x00000000
+setmem /32 0x48004940=0x0011F40C
+setmem /32 0x48004944=0x00000001
+setmem /32 0x48004948=0x00000000
+
+;RAM setup.
+setmem /16 0x6D000010=0x0000
+setmem /16 0x6D000040=0x0001
+setmem /16 0x6D000044=0x0100
+setmem /16 0x6D000048=0x0000
+setmem /32 0x6D000060=0x0000000A
+setmem /32 0x6D000070=0x00000081
+setmem /16 0x6D000040=0x0003
+setmem /32 0x6D000080=0x02D04011
+setmem /16 0x6D000084=0x0032
+setmem /16 0x6D00008C=0x0000
+setmem /32 0x6D00009C=0xBA9DC4C6
+setmem /32 0x6D0000A0=0x00012522
+setmem /32 0x6D0000A4=0x0004E201
+setmem /16 0x6D000040=0x0003
+setmem /32 0x6D0000B0=0x02D04011
+setmem /16 0x6D0000B4=0x0032
+setmem /16 0x6D0000BC=0x0000
+setmem /32 0x6D0000C4=0xBA9DC4C6
+setmem /32 0x6D0000C8=0x00012522
+setmem /32 0x6D0000D4=0x0004E201 \ No newline at end of file
diff --git a/SamsungPlatformPkg/ArndaleBoardPkg/Debugger_scripts/rvi_load_symbols.inc b/SamsungPlatformPkg/ArndaleBoardPkg/Debugger_scripts/rvi_load_symbols.inc
new file mode 100644
index 000000000..a8f98433d
--- /dev/null
+++ b/SamsungPlatformPkg/ArndaleBoardPkg/Debugger_scripts/rvi_load_symbols.inc
@@ -0,0 +1,21 @@
+//
+// Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+//
+// This program and the accompanying materials
+// are licensed and made available under the terms and conditions of the BSD License
+// which accompanies this distribution. The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+//
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+
+include 'ZZZZZZ/rvi_symbols_macros.inc'
+
+macro write_symbols_file("ZZZZZZ/rvi_symbols.tmp", 0x00000000, 0x10000000)
+
+host "bash -o igncr ZZZZZZ/rvi_convert_symbols.sh ZZZZZZ/rvi_symbols.tmp ZZZZZZ/rvi_symbols.inc"
+include 'ZZZZZZ/rvi_symbols.inc'
+load /NI /NP 'ZZZZZZ/rvi_dummy.axf' ;.constdata
+unload rvi_dummy.axf
+delfile rvi_dummy.axf
diff --git a/SamsungPlatformPkg/ArndaleBoardPkg/Debugger_scripts/rvi_symbols_macros.inc b/SamsungPlatformPkg/ArndaleBoardPkg/Debugger_scripts/rvi_symbols_macros.inc
new file mode 100644
index 000000000..6f7377cbb
--- /dev/null
+++ b/SamsungPlatformPkg/ArndaleBoardPkg/Debugger_scripts/rvi_symbols_macros.inc
@@ -0,0 +1,193 @@
+//
+// Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+//
+// This program and the accompanying materials
+// are licensed and made available under the terms and conditions of the BSD License
+// which accompanies this distribution. The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+//
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+
+define /R int compare_guid(guid1, guid2)
+ unsigned char *guid1;
+ unsigned char *guid2;
+{
+ return strncmp(guid1, guid2, 16);
+}
+.
+
+define /R unsigned char * find_system_table(mem_start, mem_size)
+ unsigned char *mem_start;
+ unsigned long mem_size;
+{
+ unsigned char *mem_ptr;
+
+ mem_ptr = mem_start + mem_size;
+
+ do
+ {
+ mem_ptr -= 0x400000; // 4 MB
+
+ if (strncmp(mem_ptr, "IBI SYST", 8) == 0)
+ {
+ return *(unsigned long *)(mem_ptr + 8); // EfiSystemTableBase
+ }
+
+ } while (mem_ptr > mem_start);
+
+ return 0;
+}
+.
+
+define /R unsigned char * find_debug_info_table_header(system_table)
+ unsigned char *system_table;
+{
+ unsigned long configuration_table_entries;
+ unsigned char *configuration_table;
+ unsigned long index;
+ unsigned char debug_table_guid[16];
+
+ // Fill in the debug table's guid
+ debug_table_guid[ 0] = 0x77;
+ debug_table_guid[ 1] = 0x2E;
+ debug_table_guid[ 2] = 0x15;
+ debug_table_guid[ 3] = 0x49;
+ debug_table_guid[ 4] = 0xDA;
+ debug_table_guid[ 5] = 0x1A;
+ debug_table_guid[ 6] = 0x64;
+ debug_table_guid[ 7] = 0x47;
+ debug_table_guid[ 8] = 0xB7;
+ debug_table_guid[ 9] = 0xA2;
+ debug_table_guid[10] = 0x7A;
+ debug_table_guid[11] = 0xFE;
+ debug_table_guid[12] = 0xFE;
+ debug_table_guid[13] = 0xD9;
+ debug_table_guid[14] = 0x5E;
+ debug_table_guid[15] = 0x8B;
+
+ configuration_table_entries = *(unsigned long *)(system_table + 64);
+ configuration_table = *(unsigned long *)(system_table + 68);
+
+ for (index = 0; index < configuration_table_entries; index++)
+ {
+ if (compare_guid(configuration_table, debug_table_guid) == 0)
+ {
+ return *(unsigned long *)(configuration_table + 16);
+ }
+
+ configuration_table += 20;
+ }
+
+ return 0;
+}
+.
+
+define /R int valid_pe_header(header)
+ unsigned char *header;
+{
+ if ((header[0x00] == 'M') &&
+ (header[0x01] == 'Z') &&
+ (header[0x80] == 'P') &&
+ (header[0x81] == 'E'))
+ {
+ return 1;
+ }
+
+ return 0;
+}
+.
+
+define /R unsigned long pe_headersize(header)
+ unsigned char *header;
+{
+ unsigned long *size;
+
+ size = header + 0x00AC;
+
+ return *size;
+}
+.
+
+define /R unsigned char *pe_filename(header)
+ unsigned char *header;
+{
+ unsigned long *debugOffset;
+ unsigned char *stringOffset;
+
+ if (valid_pe_header(header))
+ {
+ debugOffset = header + 0x0128;
+ stringOffset = header + *debugOffset + 0x002C;
+
+ return stringOffset;
+ }
+
+ return 0;
+}
+.
+
+define /R int char_is_valid(c)
+ unsigned char c;
+{
+ if (c >= 32 && c < 127)
+ return 1;
+
+ return 0;
+}
+.
+
+define /R write_symbols_file(filename, mem_start, mem_size)
+ unsigned char *filename;
+ unsigned char *mem_start;
+ unsigned long mem_size;
+{
+ unsigned char *system_table;
+ unsigned char *debug_info_table_header;
+ unsigned char *debug_info_table;
+ unsigned long debug_info_table_size;
+ unsigned long index;
+ unsigned char *debug_image_info;
+ unsigned char *loaded_image_protocol;
+ unsigned char *image_base;
+ unsigned char *debug_filename;
+ unsigned long header_size;
+ int status;
+
+ system_table = find_system_table(mem_start, mem_size);
+ if (system_table == 0)
+ {
+ return;
+ }
+
+ status = fopen(88, filename, "w");
+
+ debug_info_table_header = find_debug_info_table_header(system_table);
+
+ debug_info_table = *(unsigned long *)(debug_info_table_header + 8);
+ debug_info_table_size = *(unsigned long *)(debug_info_table_header + 4);
+
+ for (index = 0; index < (debug_info_table_size * 4); index += 4)
+ {
+ debug_image_info = *(unsigned long *)(debug_info_table + index);
+
+ if (debug_image_info == 0)
+ {
+ break;
+ }
+
+ loaded_image_protocol = *(unsigned long *)(debug_image_info + 4);
+
+ image_base = *(unsigned long *)(loaded_image_protocol + 32);
+
+ debug_filename = pe_filename(image_base);
+ header_size = pe_headersize(image_base);
+
+ $fprintf 88, "%s 0x%08x\n", debug_filename, image_base + header_size$;
+ }
+
+
+ fclose(88);
+}
+.
diff --git a/SamsungPlatformPkg/ArndaleBoardPkg/Debugger_scripts/rvi_unload_symbols.inc b/SamsungPlatformPkg/ArndaleBoardPkg/Debugger_scripts/rvi_unload_symbols.inc
new file mode 100644
index 000000000..4a7e12b81
--- /dev/null
+++ b/SamsungPlatformPkg/ArndaleBoardPkg/Debugger_scripts/rvi_unload_symbols.inc
@@ -0,0 +1,118 @@
+//
+// Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+//
+// This program and the accompanying materials
+// are licensed and made available under the terms and conditions of the BSD License
+// which accompanies this distribution. The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+//
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+
+error = continue
+
+unload
+
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+delfile 1
+
+error = abort
diff --git a/SamsungPlatformPkg/ArndaleBoardPkg/FvbDxe/FvbDxe.c b/SamsungPlatformPkg/ArndaleBoardPkg/FvbDxe/FvbDxe.c
new file mode 100755
index 000000000..18d13d570
--- /dev/null
+++ b/SamsungPlatformPkg/ArndaleBoardPkg/FvbDxe/FvbDxe.c
@@ -0,0 +1,621 @@
+/*++
+ FVB DXE Driver
+
+Copyright (c) 2012, Samsung Inc. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the
+BSD License which accompanies this distribution. The full text of the
+license may be found at http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+
+--*/
+
+#include <PiDxe.h>
+
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiLib.h>
+#include <Library/PcdLib.h>
+#include <Protocol/FirmwareVolumeBlock.h>
+#include <Protocol/BlockIo.h>
+#include <Library/MemoryAllocationLib.h>
+
+
+//#undef EFI_D_INFO
+//#define EFI_D_INFO 1
+
+EFI_FVB_ATTRIBUTES_2 gAttribute = (EFI_FVB2_READ_STATUS|EFI_FVB2_WRITE_STATUS|EFI_FVB2_ALIGNMENT_32);
+EFI_BLOCK_IO_PROTOCOL *BlockIo;
+EFI_EVENT mBlockIORegistration = NULL;
+EFI_HANDLE mHandle = NULL;
+UINT32 TargetMediaId;
+
+#define EMMC_BLOCK_SIZE 512
+#define EMMC_BLOCK_NUMBER 512
+#define MSHC_BOOT_NV_OFFSET 0x1000
+#define NV_READ_BUFFER_SIZE 0x20000
+#define FVB_HEADER_LEN 0x64
+#define DMA_BUFFER_NV_OFFSET 0x60000
+
+VOID *BufPtr;
+VOID *ReadBufPtr;
+
+#define FVB_TEST 0
+//VOID *TestBufPtr;
+
+/**
+ The GetAttributes() function retrieves the attributes and
+ current settings of the block.
+
+ @param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance.
+
+ @param Attributes Pointer to EFI_FVB_ATTRIBUTES_2 in which the
+ attributes and current settings are
+ returned. Type EFI_FVB_ATTRIBUTES_2 is defined
+ in EFI_FIRMWARE_VOLUME_HEADER.
+
+ @retval EFI_SUCCESS The firmware volume attributes were
+ returned.
+
+**/
+
+EFI_STATUS
+EFIAPI
+FvbGetAttributes (
+ IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This,
+ OUT EFI_FVB_ATTRIBUTES_2 *Attributes
+ )
+{
+ *Attributes = gAttribute;
+ DEBUG ((EFI_D_INFO, "FVB:FvbGetAttributes 0x%x\n", gAttribute));
+ return EFI_SUCCESS;
+}
+
+
+/**
+ The SetAttributes() function sets configurable firmware volume
+ attributes and returns the new settings of the firmware volume.
+
+
+ @param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance.
+
+ @param Attributes On input, Attributes is a pointer to
+ EFI_FVB_ATTRIBUTES_2 that contains the
+ desired firmware volume settings. On
+ successful return, it contains the new
+ settings of the firmware volume. Type
+ EFI_FVB_ATTRIBUTES_2 is defined in
+ EFI_FIRMWARE_VOLUME_HEADER.
+
+ @retval EFI_SUCCESS The firmware volume attributes were returned.
+
+ @retval EFI_INVALID_PARAMETER The attributes requested are in
+ conflict with the capabilities
+ as declared in the firmware
+ volume header.
+
+**/
+EFI_STATUS
+EFIAPI
+FvbSetAttributes (
+ IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This,
+ IN OUT EFI_FVB_ATTRIBUTES_2 *Attributes
+ )
+{
+ gAttribute |= *Attributes;
+ *Attributes = gAttribute;
+ DEBUG ((EFI_D_INFO, "FVB:FvbSetAttributes 0x%x\n", gAttribute));
+ return EFI_SUCCESS;
+}
+
+
+/**
+ The GetPhysicalAddress() function retrieves the base address of
+ a memory-mapped firmware volume. This function should be called
+ only for memory-mapped firmware volumes.
+
+ @param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance.
+
+ @param Address Pointer to a caller-allocated
+ EFI_PHYSICAL_ADDRESS that, on successful
+ return from GetPhysicalAddress(), contains the
+ base address of the firmware volume.
+
+ @retval EFI_SUCCESS The firmware volume base address was returned.
+
+ @retval EFI_NOT_SUPPORTED The firmware volume is not memory mapped.
+
+**/
+EFI_STATUS
+EFIAPI
+FvbGetPhysicalAddress (
+ IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This,
+ OUT EFI_PHYSICAL_ADDRESS *Address
+ )
+{
+ EFI_PHYSICAL_ADDRESS NVBase = PcdGet32(PcdFlashNvStorageVariableBase);
+ //UINT32 NVSize = PcdGet32(PcdFlashNvStorageVariableSize);
+
+ *Address = NVBase;
+ //DEBUG ((EFI_D_INFO, "FVB:FvbGetPhysicalAddress Addr:0x%x\n", *Address));
+ return EFI_SUCCESS;
+}
+
+
+
+/**
+ The GetBlockSize() function retrieves the size of the requested
+ block. It also returns the number of additional blocks with
+ the identical size. The GetBlockSize() function is used to
+ retrieve the block map (see EFI_FIRMWARE_VOLUME_HEADER).
+
+
+ @param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance.
+
+ @param Lba Indicates the block for which to return the size.
+
+ @param BlockSize Pointer to a caller-allocated UINTN in which
+ the size of the block is returned.
+
+ @param NumberOfBlocks Pointer to a caller-allocated UINTN in
+ which the number of consecutive blocks,
+ starting with Lba, is returned. All
+ blocks in this range have a size of
+ BlockSize.
+
+
+ @retval EFI_SUCCESS The firmware volume base address was returned.
+
+ @retval EFI_INVALID_PARAMETER The requested LBA is out of range.
+
+**/
+EFI_STATUS
+EFIAPI
+FvbGetBlockSize (
+ IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This,
+ IN EFI_LBA Lba,
+ OUT UINTN *BlockSize,
+ OUT UINTN *NumberOfBlocks
+ )
+{
+ EFI_STATUS status = EFI_SUCCESS;
+ *BlockSize = EMMC_BLOCK_SIZE;
+ *NumberOfBlocks = EMMC_BLOCK_NUMBER;
+ DEBUG ((EFI_D_INFO, "FVB:FvbGetBlockSize numblocks:%d\n", *NumberOfBlocks));
+ return status;
+}
+
+
+
+/**
+ Reads the specified number of bytes into a buffer from the specified block.
+
+ The Read() function reads the requested number of bytes from the
+ requested block and stores them in the provided buffer.
+ Implementations should be mindful that the firmware volume
+ might be in the ReadDisabled state. If it is in this state,
+ the Read() function must return the status code
+ EFI_ACCESS_DENIED without modifying the contents of the
+ buffer. The Read() function must also prevent spanning block
+ boundaries. If a read is requested that would span a block
+ boundary, the read must read up to the boundary but not
+ beyond. The output parameter NumBytes must be set to correctly
+ indicate the number of bytes actually read. The caller must be
+ aware that a read may be partially completed.
+
+ @param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance.
+
+ @param Lba The starting logical block index
+ from which to read.
+
+ @param Offset Offset into the block at which to begin reading.
+
+ @param NumBytes Pointer to a UINTN. At entry, *NumBytes
+ contains the total size of the buffer. At
+ exit, *NumBytes contains the total number of
+ bytes read.
+
+ @param Buffer Pointer to a caller-allocated buffer that will
+ be used to hold the data that is read.
+
+ @retval EFI_SUCCESS The firmware volume was read successfully,
+ and contents are in Buffer.
+
+ @retval EFI_BAD_BUFFER_SIZE Read attempted across an LBA
+ boundary. On output, NumBytes
+ contains the total number of bytes
+ returned in Buffer.
+
+ @retval EFI_ACCESS_DENIED The firmware volume is in the
+ ReadDisabled state.
+
+ @retval EFI_DEVICE_ERROR The block device is not
+ functioning correctly and could
+ not be read.
+
+**/
+UINT8 FVB_Header[100]={0xff,};
+
+EFI_STATUS
+EFIAPI
+FvbRead (
+ IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This,
+ IN EFI_LBA Lba,
+ IN UINTN Offset,
+ IN OUT UINTN *NumBytes,
+ IN OUT UINT8 *Buffer
+ )
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ UINT32 NumBlock;
+ UINT32 AllocSize = 0;
+ EFI_LBA NV_Lba = Lba + MSHC_BOOT_NV_OFFSET;
+ UINT32 NVBase = PcdGet32(PcdFlashNvStorageVariableBase);
+
+ DEBUG ((EFI_D_INFO, "FVB:FvbRead O:%d ",Offset));
+ DEBUG ((EFI_D_INFO, "Lba:%d \n",Lba));
+ DEBUG ((EFI_D_INFO, "N:%d \n",*NumBytes));
+
+ // check invalid input parameter
+ if(*NumBytes<=0){
+ goto Exit;
+ }
+ if((*NumBytes-1)>=(MAX_ADDRESS-(UINTN)Buffer)){
+ goto Exit;
+ }
+
+ // 1. Copy FVB header
+ CopyMem(&FVB_Header[0], (UINT8 *)NVBase, 100);
+
+ // 2. calculate block number and allocate memory
+ // 3. ReadBlock
+ if (0 == ((Offset + *NumBytes)%EMMC_BLOCK_SIZE))
+ {
+ NumBlock = ((Offset + *NumBytes)/EMMC_BLOCK_SIZE);
+ }
+ else
+ {
+ NumBlock = ((Offset + *NumBytes)/EMMC_BLOCK_SIZE)+1;
+ }
+ AllocSize = NumBlock*EMMC_BLOCK_SIZE;
+ Status = BlockIo->ReadBlocks(BlockIo, BlockIo->Media->MediaId, NV_Lba, AllocSize, (UINT8 *)NVBase);
+
+ if (((EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)(NVBase))->Signature != EFI_FVH_SIGNATURE)
+ {
+ DEBUG ((EFI_D_ERROR, "FVB:FvbRead invalid header\n"));
+ CopyMem((UINT8 *)NVBase, &FVB_Header[0], 100);
+ goto Exit;
+ }
+ // 4. Copy read buffer to dest
+ CopyMem(Buffer, (UINT8 *)(NVBase +Offset), *NumBytes);
+
+ if(Status!=EFI_SUCCESS)
+ {
+ DEBUG ((EFI_D_ERROR, "FVB:FvbRead Failed %r\n", Status));
+ Status = EFI_ACCESS_DENIED;
+ }
+
+Exit:
+ return Status;
+}
+
+
+/**
+ Writes the specified number of bytes from the input buffer to the block.
+
+ The Write() function writes the specified number of bytes from
+ the provided buffer to the specified block and offset. If the
+ firmware volume is sticky write, the caller must ensure that
+ all the bits of the specified range to write are in the
+ EFI_FVB_ERASE_POLARITY state before calling the Write()
+ function, or else the result will be unpredictable. This
+ unpredictability arises because, for a sticky-write firmware
+ volume, a write may negate a bit in the EFI_FVB_ERASE_POLARITY
+ state but cannot flip it back again. Before calling the
+ Write() function, it is recommended for the caller to first call
+ the EraseBlocks() function to erase the specified block to
+ write. A block erase cycle will transition bits from the
+ (NOT)EFI_FVB_ERASE_POLARITY state back to the
+ EFI_FVB_ERASE_POLARITY state. Implementations should be
+ mindful that the firmware volume might be in the WriteDisabled
+ state. If it is in this state, the Write() function must
+ return the status code EFI_ACCESS_DENIED without modifying the
+ contents of the firmware volume. The Write() function must
+ also prevent spanning block boundaries. If a write is
+ requested that spans a block boundary, the write must store up
+ to the boundary but not beyond. The output parameter NumBytes
+ must be set to correctly indicate the number of bytes actually
+ written. The caller must be aware that a write may be
+ partially completed. All writes, partial or otherwise, must be
+ fully flushed to the hardware before the Write() service
+ returns.
+
+ @param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance.
+
+ @param Lba The starting logical block index to write to.
+
+ @param Offset Offset into the block at which to begin writing.
+
+ @param NumBytes The pointer to a UINTN. At entry, *NumBytes
+ contains the total size of the buffer. At
+ exit, *NumBytes contains the total number of
+ bytes actually written.
+
+ @param Buffer The pointer to a caller-allocated buffer that
+ contains the source for the write.
+
+ @retval EFI_SUCCESS The firmware volume was written successfully.
+
+ @retval EFI_BAD_BUFFER_SIZE The write was attempted across an
+ LBA boundary. On output, NumBytes
+ contains the total number of bytes
+ actually written.
+
+ @retval EFI_ACCESS_DENIED The firmware volume is in the
+ WriteDisabled state.
+
+ @retval EFI_DEVICE_ERROR The block device is malfunctioning
+ and could not be written.
+
+
+**/
+EFI_STATUS
+EFIAPI
+FvbWrite (
+ IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This,
+ IN EFI_LBA Lba,
+ IN UINTN Offset,
+ IN OUT UINTN *NumBytes,
+ IN UINT8 *Buffer
+ )
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ UINT32 NumBlock;
+ UINT32 AllocSize = 0;
+ EFI_LBA NV_Lba = Lba + MSHC_BOOT_NV_OFFSET;
+ UINT32 NVBase = PcdGet32(PcdFlashNvStorageVariableBase);
+
+ DEBUG ((EFI_D_INFO, "FvbWrite O:%d\n ", Offset));
+ DEBUG ((EFI_D_INFO, "FVB:FvbWrite O:%d ", Offset));
+ DEBUG ((EFI_D_INFO, "N:%d ", *NumBytes));
+
+ // 1. Calculate block count number
+ if (0 == ((Offset+*NumBytes)%EMMC_BLOCK_SIZE))
+ {
+ NumBlock = ((Offset+*NumBytes)/EMMC_BLOCK_SIZE);
+ }
+ else
+ {
+ NumBlock = ((Offset+*NumBytes)/EMMC_BLOCK_SIZE) + 1;
+ }
+ AllocSize = (NumBlock * EMMC_BLOCK_SIZE);
+
+ CopyMem((UINT8 *)(NVBase + Offset), Buffer, *NumBytes);
+
+ // 4. Apply the offset and WriteBlock
+ Status = BlockIo->WriteBlocks(BlockIo, TargetMediaId, NV_Lba, AllocSize, (VOID *)(NVBase));
+ if(Status!=EFI_SUCCESS)
+ {
+ DEBUG ((EFI_D_ERROR, "FVB:FvbWrite Failed %r\n", Status));
+ Status = EFI_ACCESS_DENIED;
+ }
+
+ return Status;
+}
+
+
+/**
+ Erases and initializes a firmware volume block.
+
+ The EraseBlocks() function erases one or more blocks as denoted
+ by the variable argument list. The entire parameter list of
+ blocks must be verified before erasing any blocks. If a block is
+ requested that does not exist within the associated firmware
+ volume (it has a larger index than the last block of the
+ firmware volume), the EraseBlocks() function must return the
+ status code EFI_INVALID_PARAMETER without modifying the contents
+ of the firmware volume. Implementations should be mindful that
+ the firmware volume might be in the WriteDisabled state. If it
+ is in this state, the EraseBlocks() function must return the
+ status code EFI_ACCESS_DENIED without modifying the contents of
+ the firmware volume. All calls to EraseBlocks() must be fully
+ flushed to the hardware before the EraseBlocks() service
+ returns.
+
+ @param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL
+ instance.
+
+ @param ... The variable argument list is a list of tuples.
+ Each tuple describes a range of LBAs to erase
+ and consists of the following:
+ - An EFI_LBA that indicates the starting LBA
+ - A UINTN that indicates the number of blocks to
+ erase.
+
+ The list is terminated with an
+ EFI_LBA_LIST_TERMINATOR. For example, the
+ following indicates that two ranges of blocks
+ (5-7 and 10-11) are to be erased: EraseBlocks
+ (This, 5, 3, 10, 2, EFI_LBA_LIST_TERMINATOR);
+
+ @retval EFI_SUCCESS The erase request successfully
+ completed.
+
+ @retval EFI_ACCESS_DENIED The firmware volume is in the
+ WriteDisabled state.
+ @retval EFI_DEVICE_ERROR The block device is not functioning
+ correctly and could not be written.
+ The firmware device may have been
+ partially erased.
+ @retval EFI_INVALID_PARAMETER One or more of the LBAs listed
+ in the variable argument list do
+ not exist in the firmware volume.
+
+**/
+EFI_STATUS
+EFIAPI
+FvbEraseBlocks (
+ IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This,
+ ...
+ )
+{
+ DEBUG ((EFI_D_INFO, "FvbEraseBlocks\n"));
+ return EFI_SUCCESS;
+}
+
+
+//
+// Making this global saves a few bytes in image size
+//
+EFI_HANDLE gFvbHandle = NULL;
+
+
+///
+/// The Firmware Volume Block Protocol is the low-level interface
+/// to a firmware volume. File-level access to a firmware volume
+/// should not be done using the Firmware Volume Block Protocol.
+/// Normal access to a firmware volume must use the Firmware
+/// Volume Protocol. Typically, only the file system driver that
+/// produces the Firmware Volume Protocol will bind to the
+/// Firmware Volume Block Protocol.
+///
+EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL gFvbProtocol = {
+ FvbGetAttributes,
+ FvbSetAttributes,
+ FvbGetPhysicalAddress,
+ FvbGetBlockSize,
+ FvbRead,
+ FvbWrite,
+ FvbEraseBlocks,
+ ///
+ /// The handle of the parent firmware volume.
+ ///
+ NULL
+};
+
+
+
+/**
+ Initialize the FVB to use block IO
+
+
+ @retval EFI_SUCCESS Protocol registered
+ @retval EFI_DEVICE_ERROR Hardware problems
+
+**/
+VOID
+EFIAPI
+BlockIONotificationEvent (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ EFI_HANDLE *HandleBuffer = NULL;
+ EFI_STATUS Status;
+ UINTN NumHandles;
+ UINT32 i;
+ DEBUG((EFI_D_INFO, "FVB:BlockIONotificationEvent Start \n"));
+
+ TargetMediaId = SIGNATURE_32('e','m','m','c');
+ //TargetMediaId ++;
+ DEBUG((EFI_D_INFO, "FVB:Target Device ID = 0x%x\n", TargetMediaId));
+
+ if(mHandle!=NULL)
+ return;
+
+ Status = gBS->LocateHandleBuffer(ByProtocol, &gEfiBlockIoProtocolGuid, NULL, &NumHandles, &HandleBuffer);
+
+ for(i=0;i<NumHandles;i++) {
+ Status = gBS->HandleProtocol(HandleBuffer[i], &gEfiBlockIoProtocolGuid, (VOID **)&BlockIo);
+
+ DEBUG((EFI_D_INFO, "FVB:Device %d Media ID=0x%x\n", i, BlockIo->Media->MediaId));
+
+ if((BlockIo->Media->MediaId == TargetMediaId)||(BlockIo->Media->MediaId == (TargetMediaId+1)))
+ {
+ DEBUG((EFI_D_INFO, "FVB:InstallFVBProtocol 0x%x \n", BlockIo));
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &mHandle,
+ &gEfiFirmwareVolumeBlockProtocolGuid, &gFvbProtocol,
+ NULL
+ );
+
+ if(Status!=EFI_SUCCESS)
+ {
+ DEBUG((EFI_D_ERROR, "FVB:BlockIO handle is not valid %r\n", Status));
+ }
+
+ break;
+ }
+
+ if(i == NumHandles) {
+ DEBUG((EFI_D_ERROR, "Cannot find Block IO protocol handle! \n"));
+ }
+ }
+
+}
+
+
+
+/**
+ Initialize the state information for the CPU Architectural Protocol
+
+ @param ImageHandle of the loaded driver
+ @param SystemTable Pointer to the System Table
+
+ @retval EFI_SUCCESS Protocol registered
+ @retval EFI_OUT_OF_RESOURCES Cannot allocate protocol data structure
+ @retval EFI_DEVICE_ERROR Hardware problems
+
+**/
+EFI_STATUS
+EFIAPI
+FvbDxeInitialize (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status=EFI_SUCCESS;
+
+ //
+ // Register FvbNotificationEvent () notify function.
+ //
+
+ BlockIo = AllocatePool(sizeof(EFI_BLOCK_IO_PROTOCOL)+sizeof(EFI_BLOCK_IO_MEDIA));
+ BufPtr = AllocatePool(EMMC_BLOCK_SIZE*2);
+ if(BufPtr==NULL)
+ {
+ DEBUG ((EFI_D_ERROR, "FVB:Temp buffer allocate failed!!!\n"));
+ }
+ ReadBufPtr = AllocatePool(NV_READ_BUFFER_SIZE);
+ if(ReadBufPtr==NULL)
+ {
+ DEBUG ((EFI_D_ERROR, "FVB:NV Read buffer allocate failed!!!\n"));
+ }
+#if FVB_TEST
+ TestBufPtr = AllocatePool(EMMC_BLOCK_SIZE*2);
+ DEBUG ((EFI_D_ERROR, "FVB:TestBufPtr:0x%x ", TestBufPtr));
+#endif
+ DEBUG ((EFI_D_ERROR, "BufPtr:0x%x\n", BufPtr));
+
+ EfiCreateProtocolNotifyEvent (
+ &gEfiBlockIoProtocolGuid,
+ TPL_CALLBACK,
+ BlockIONotificationEvent,
+ (VOID *)SystemTable,
+ &mBlockIORegistration
+ );
+
+ DEBUG ((EFI_D_INFO, "\nFVB:FvbDxeInitialize\n"));
+
+ // SetVertAddressEvent ()
+
+ // GCD Map NAND as RT
+
+ return Status;
+}
+
diff --git a/SamsungPlatformPkg/ArndaleBoardPkg/FvbDxe/FvbDxe.inf b/SamsungPlatformPkg/ArndaleBoardPkg/FvbDxe/FvbDxe.inf
new file mode 100755
index 000000000..450df3caf
--- /dev/null
+++ b/SamsungPlatformPkg/ArndaleBoardPkg/FvbDxe/FvbDxe.inf
@@ -0,0 +1,57 @@
+#/** @file
+#
+# Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD
+# License which accompanies this distribution. The full text of the license
+# may be found at http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#**/
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = FvbDxe
+ FILE_GUID = 43ECE281-D9E2-4DD0-B304-E6A5689256F4
+ MODULE_TYPE = DXE_RUNTIME_DRIVER
+ VERSION_STRING = 1.0
+
+ ENTRY_POINT = FvbDxeInitialize
+
+
+[Sources.common]
+ FvbDxe.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ EmbeddedPkg/EmbeddedPkg.dec
+ SamsungPlatformPkg/ArndaleBoardPkg/ArndaleBoardPkg.dec
+ SamsungPlatformPkg/ExynosPkg/Exynos5250/ExynosPkg.dec
+
+
+[LibraryClasses]
+ BaseLib
+ UefiLib
+ UefiBootServicesTableLib
+ DebugLib
+ PrintLib
+ UefiDriverEntryPoint
+
+[Guids]
+
+
+[Protocols]
+ gEfiBlockIoProtocolGuid
+ gEfiDiskIoProtocolGuid
+ gEfiFirmwareVolumeBlockProtocolGuid
+
+[FixedPcd.common]
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase
+ gExynosPkgTokenSpaceGuid.PcdEmmcDMABufferBase
+
+[depex]
+ TRUE
diff --git a/SamsungPlatformPkg/ArndaleBoardPkg/Library/ArndaleBoardLib/Exynos5250/Board.c b/SamsungPlatformPkg/ArndaleBoardPkg/Library/ArndaleBoardLib/Exynos5250/Board.c
new file mode 100644
index 000000000..364101071
--- /dev/null
+++ b/SamsungPlatformPkg/ArndaleBoardPkg/Library/ArndaleBoardLib/Exynos5250/Board.c
@@ -0,0 +1,226 @@
+/** @file
+*
+* Copyright (c) 2012, Samsung Electronics Co. All rights reserved.
+*
+* This program and the accompanying materials
+* are licensed and made available under the terms and conditions of the BSD License
+* which accompanies this distribution. The full text of the license may be found at
+* http://opensource.org/licenses/bsd-license.php
+*
+* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#include <Library/IoLib.h>
+#include <Library/ArmPlatformLib.h>
+#include <Library/DebugLib.h>
+#include <Library/PcdLib.h>
+
+#include <Ppi/ArmMpCoreInfo.h>
+#include <Drivers/PL341Dmc.h>
+#include <Platform/ArmPlatform.h>
+
+/**
+ Return if Trustzone is supported by your platform
+
+ A non-zero value must be returned if you want to support a Secure World on your platform.
+ ArmPlatformSecTrustzoneInit() will later set up the secure regions.
+ This function can return 0 even if Trustzone is supported by your processor. In this case,
+ the platform will continue to run in Secure World.
+
+ @return A non-zero value if Trustzone supported.
+
+**/
+UINTN ArmPlatformTrustzoneSupported(VOID) {
+ // There is no Trustzone controllers (TZPC & TZASC) and no Secure Memory on RTSM
+ return TRUE;
+}
+
+/**
+ Initialize the Secure peripherals and memory regions
+
+ If Trustzone is supported by your platform then this function makes the required initialization
+ of the secure peripherals and memory regions.
+
+**/
+VOID ArmPlatformSecTrustzoneInit(
+ IN UINTN MpId
+)
+{
+ UINT32 TZPCBase;
+ TZPCBase = PcdGet32(PcdTZPCBase) + TZPC0_OFFSET;
+ MmioWrite32((TZPCBase + 0x00),0x00);
+ MmioWrite32((TZPCBase +TZPC_DECPROT0SET_OFFSET),0xFF);
+ MmioWrite32((TZPCBase +TZPC_DECPROT1SET_OFFSET),0xFF);
+ MmioWrite32((TZPCBase +TZPC_DECPROT2SET_OFFSET),0xFF);
+ MmioWrite32((TZPCBase +TZPC_DECPROT3SET_OFFSET),0xFF);
+
+ TZPCBase = PcdGet32(PcdTZPCBase) + TZPC1_OFFSET;
+ MmioWrite32((TZPCBase +TZPC_DECPROT0SET_OFFSET),0xFF);
+ MmioWrite32((TZPCBase +TZPC_DECPROT1SET_OFFSET),0xFF);
+ MmioWrite32((TZPCBase +TZPC_DECPROT2SET_OFFSET),0xFF);
+ MmioWrite32((TZPCBase +TZPC_DECPROT3SET_OFFSET),0xFF);
+
+ TZPCBase = PcdGet32(PcdTZPCBase) + TZPC2_OFFSET;
+ MmioWrite32((TZPCBase +TZPC_DECPROT0SET_OFFSET),0xFF);
+ MmioWrite32((TZPCBase +TZPC_DECPROT1SET_OFFSET),0xFF);
+ MmioWrite32((TZPCBase +TZPC_DECPROT2SET_OFFSET),0xFF);
+ MmioWrite32((TZPCBase +TZPC_DECPROT3SET_OFFSET),0xFF);
+
+ TZPCBase = PcdGet32(PcdTZPCBase) + TZPC3_OFFSET;
+ MmioWrite32((TZPCBase +TZPC_DECPROT0SET_OFFSET),0xFF);
+ MmioWrite32((TZPCBase +TZPC_DECPROT1SET_OFFSET),0xFF);
+ MmioWrite32((TZPCBase +TZPC_DECPROT2SET_OFFSET),0xFF);
+ MmioWrite32((TZPCBase +TZPC_DECPROT3SET_OFFSET),0xFF);
+
+ TZPCBase = PcdGet32(PcdTZPCBase) + TZPC4_OFFSET;
+ MmioWrite32((TZPCBase +TZPC_DECPROT0SET_OFFSET),0xFF);
+ MmioWrite32((TZPCBase +TZPC_DECPROT1SET_OFFSET),0xFF);
+ MmioWrite32((TZPCBase +TZPC_DECPROT2SET_OFFSET),0xFF);
+ MmioWrite32((TZPCBase +TZPC_DECPROT3SET_OFFSET),0xFF);
+
+
+ TZPCBase = PcdGet32(PcdTZPCBase) + TZPC5_OFFSET;
+ MmioWrite32((TZPCBase +TZPC_DECPROT0SET_OFFSET),0xFF);
+ MmioWrite32((TZPCBase +TZPC_DECPROT1SET_OFFSET),0xFF);
+ MmioWrite32((TZPCBase +TZPC_DECPROT2SET_OFFSET),0xFF);
+ MmioWrite32((TZPCBase +TZPC_DECPROT3SET_OFFSET),0xFF);
+
+ TZPCBase = PcdGet32(PcdTZPCBase) + TZPC6_OFFSET;
+ MmioWrite32((TZPCBase +TZPC_DECPROT0SET_OFFSET),0xFF);
+ MmioWrite32((TZPCBase +TZPC_DECPROT1SET_OFFSET),0xFF);
+ MmioWrite32((TZPCBase +TZPC_DECPROT2SET_OFFSET),0xFF);
+ MmioWrite32((TZPCBase +TZPC_DECPROT3SET_OFFSET),0xFF);
+
+ TZPCBase = PcdGet32(PcdTZPCBase) + TZPC7_OFFSET;
+ MmioWrite32((TZPCBase +TZPC_DECPROT0SET_OFFSET),0xFF);
+ MmioWrite32((TZPCBase +TZPC_DECPROT1SET_OFFSET),0xFF);
+ MmioWrite32((TZPCBase +TZPC_DECPROT2SET_OFFSET),0xFF);
+ MmioWrite32((TZPCBase +TZPC_DECPROT3SET_OFFSET),0xFF);
+
+ TZPCBase = PcdGet32(PcdTZPCBase) + TZPC8_OFFSET;
+ MmioWrite32((TZPCBase +TZPC_DECPROT0SET_OFFSET),0xFF);
+ MmioWrite32((TZPCBase +TZPC_DECPROT1SET_OFFSET),0xFF);
+ MmioWrite32((TZPCBase +TZPC_DECPROT2SET_OFFSET),0xFF);
+ MmioWrite32((TZPCBase +TZPC_DECPROT3SET_OFFSET),0xFF);
+
+ TZPCBase = PcdGet32(PcdTZPCBase) + TZPC9_OFFSET;
+ MmioWrite32((TZPCBase +TZPC_DECPROT0SET_OFFSET),0xFF);
+ MmioWrite32((TZPCBase +TZPC_DECPROT1SET_OFFSET),0xFF);
+
+}
+
+/**
+ Remap the memory at 0x0
+
+ Some platform requires or gives the ability to remap the memory at the address 0x0.
+ This function can do nothing if this feature is not relevant to your platform.
+
+**/
+VOID ArmPlatformBootRemapping(VOID) {
+ // Disable memory remapping and return to normal mapping
+ MmioOr32 (ARM_EB_SYSCTRL, BIT8); //EB_SP810_CTRL_BASE
+}
+
+
+/**
+ Return the current Boot Mode
+
+ This function returns the boot reason on the platform
+
+ @return Return the current Boot Mode of the platform
+
+**/
+EFI_BOOT_MODE
+ArmPlatformGetBootMode (
+ VOID
+ )
+{
+ return BOOT_WITH_FULL_CONFIGURATION;
+}
+
+/**
+ Initialize controllers that must setup in the normal world
+
+ This function is called by the ArmPlatformPkg/Pei or ArmPlatformPkg/Pei/PlatformPeim
+ in the PEI phase.
+
+**/
+VOID
+ArmPlatformNormalInitialize (
+ VOID
+ )
+{
+ // Nothing to do here
+}
+
+/**
+ Initialize controllers that must setup in the normal world
+
+ This function is called by the ArmPlatformPkg/PrePi or ArmPlatformPkg/PlatformPei
+ in the PEI phase.
+
+ **/
+RETURN_STATUS
+ArmPlatformInitialize (
+ IN UINTN MpId
+ )
+{
+ return RETURN_SUCCESS;
+}
+
+
+/**
+ Initialize the system (or sometimes called permanent) memory
+
+ This memory is generally represented by the DRAM.
+
+**/
+VOID ArmPlatformInitializeSystemMemory(VOID) {
+ // We do not need to initialize the System Memory on RTSM
+}
+
+EFI_STATUS
+PrePeiCoreGetMpCoreInfo (
+ OUT UINTN *CoreCount,
+ OUT ARM_CORE_INFO **ArmCoreTable
+ )
+{
+#if 0
+ UINT32 ProcType;
+
+ ProcType = MmioRead32 (ARM_VE_SYS_PROCID0_REG) & ARM_VE_SYS_PROC_ID_MASK;
+ if ((ProcType == ARM_VE_SYS_PROC_ID_CORTEX_A9) || (ProcType == ARM_VE_SYS_PROC_ID_CORTEX_A15)) {
+ // Only support one cluster
+ *CoreCount = ArmGetCpuCountPerCluster ();
+ *ArmCoreTable = mVersatileExpressMpCoreInfoTable;
+ return EFI_SUCCESS;
+ } else {
+ return EFI_UNSUPPORTED;
+ }
+#endif
+ return EFI_UNSUPPORTED;
+}
+
+// Needs to be declared in the file. Otherwise gArmMpCoreInfoPpiGuid is undefined in the contect of PrePeiCore
+EFI_GUID mArmMpCoreInfoPpiGuid = ARM_MP_CORE_INFO_PPI_GUID;
+ARM_MP_CORE_INFO_PPI mMpCoreInfoPpi = { PrePeiCoreGetMpCoreInfo };
+
+EFI_PEI_PPI_DESCRIPTOR gPlatformPpiTable[] = {
+ {
+ EFI_PEI_PPI_DESCRIPTOR_PPI,
+ &mArmMpCoreInfoPpiGuid,
+ &mMpCoreInfoPpi
+ }
+};
+
+VOID
+ArmPlatformGetPlatformPpiList (
+ OUT UINTN *PpiListSize,
+ OUT EFI_PEI_PPI_DESCRIPTOR **PpiList
+ )
+{
+ *PpiListSize = sizeof(gPlatformPpiTable);
+ *PpiList = gPlatformPpiTable;
+}
diff --git a/SamsungPlatformPkg/ArndaleBoardPkg/Library/ArndaleBoardLib/Exynos5250/BoardBoot.S b/SamsungPlatformPkg/ArndaleBoardPkg/Library/ArndaleBoardLib/Exynos5250/BoardBoot.S
new file mode 100755
index 000000000..e47146e47
--- /dev/null
+++ b/SamsungPlatformPkg/ArndaleBoardPkg/Library/ArndaleBoardLib/Exynos5250/BoardBoot.S
@@ -0,0 +1,468 @@
+/*
+ * (C) Copyright 2012 Samsung Electronics Co. Ltd
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <Platform/ArmPlatform.h>
+#include <Platform/Arndale5250.h>
+#include <Platform/Exynos5250_Evt1.h>
+#include <Platform/Arndale5250_Val.h>
+#include <AutoGen.h>
+
+GCC_ASM_EXPORT(ArmPlatformClockInitialize)
+GCC_ASM_EXPORT(ArmPlatformTZPCInitialize)
+GCC_ASM_EXPORT(ArmPlatformSecBootAction)
+
+wait_pll_lock:
+ ldr r1, [r0, r2]
+ tst r1, #(1<<29)
+ beq wait_pll_lock
+ mov pc, lr
+
+wait_mux_state:
+ add r2, r2, #0x200
+
+check_mux_state:
+ ldr r1, [r0, r2]
+ orr r4, r1, r3
+ cmp r1, r4
+ bne check_mux_state
+ mov pc, lr
+
+wait_div_state:
+ add r2, r2, #0x100
+
+check_div_state:
+ ldr r1, [r0, r2]
+ cmp r1, r3
+ bne check_div_state
+ mov pc, lr
+
+ASM_PFX(ArmPlatformClockInitialize):
+
+ @push {lr}
+ mov r12, lr
+
+ ldr r0, =Exynos5250_CMU_BASE @0x1001_0000
+
+@ CMU_CPU MUX / DIV
+ ldr r2, =CLK_SRC_CPU_OFFSET
+ ldr r3, =0x00000001
+ ldr r1, [r0, r2]
+ bic r1, r1, r3
+ str r1, [r0, r2]
+ ldr r3, =0x00000001
+ bl wait_mux_state
+
+ ldr r2, =CLK_SRC_CORE1_OFFSET
+ ldr r3, =0x100
+ ldr r1, [r0, r2]
+ bic r1, r1, r3
+ str r1, [r0, r2]
+ ldr r3, =0x00000100
+ bl wait_mux_state
+
+ ldr r2, =CLK_SRC_TOP2_OFFSET
+ ldr r3, =0x10011100
+ ldr r1, [r0, r2]
+ bic r1, r1, r3
+ str r1, [r0, r2]
+ ldr r3, =0x10011100
+ bl wait_mux_state
+
+ ldr r2, =CLK_SRC_CDREX_OFFSET
+ ldr r3, =0x1
+ ldr r1, [r0, r2]
+ bic r1, r1, r3
+ str r1, [r0, r2]
+ ldr r3, =0x00000001
+ bl wait_mux_state
+
+@ Set PLL locktime
+ ldr r1, =APLL_LOCK_VAL
+ ldr r2, =APLL_LOCK_OFFSET
+ str r1, [r0, r2]
+
+ ldr r1, =MPLL_LOCK_VAL
+ ldr r2, =MPLL_LOCK_OFFSET
+ str r1, [r0, r2]
+
+ ldr r1, =BPLL_LOCK_VAL
+ ldr r2, =BPLL_LOCK_OFFSET
+ str r1, [r0, r2]
+
+ ldr r1, =CPLL_LOCK_VAL
+ ldr r2, =CPLL_LOCK_OFFSET
+ str r1, [r0, r2]
+
+ ldr r1, =GPLL_LOCK_VAL
+ ldr r2, =GPLL_LOCK_OFFSET
+ str r1, [r0, r2]
+
+ ldr r1, =EPLL_LOCK_VAL
+ ldr r2, =EPLL_LOCK_OFFSET
+ str r1, [r0, r2]
+
+ ldr r1, =VPLL_LOCK_VAL
+ ldr r2, =VPLL_LOCK_OFFSET
+ str r1, [r0, r2]
+
+@ Set BPLL, MPLL Fixed Divider 2
+ ldr r1, =0x00
+ ldr r2, =PLL_DIV2_SEL_OFFSET
+ str r1, [r0, r2]
+
+@ ARM_CLK
+ ldr r2, =CLK_SRC_CPU_OFFSET
+ ldr r3, =0x00100000
+ str r3, [r0, r2]
+ ldr r3, =0x00200000
+ bl wait_mux_state
+
+ ldr r1, =CLK_DIV_CPU0_VAL @0x01147720
+ ldr r2, =CLK_DIV_CPU0_OFFSET
+ str r1, [r0, r2]
+ ldr r3, =0x0
+ bl wait_div_state
+
+ ldr r1, =CLK_DIV_CPU1_VAL @0x20
+ ldr r2, =CLK_DIV_CPU1_OFFSET
+ str r1, [r0, r2]
+ ldr r3, =0x0
+ bl wait_div_state
+
+@ Set APLL
+ ldr r1, =APLL_CON1_VAL
+ ldr r2, =APLL_CON1_OFFSET
+ str r1, [r0, r2]
+ ldr r1, =APLL_CON0_VAL
+ ldr r2, =APLL_CON0_OFFSET
+ str r1, [r0, r2]
+ bl wait_pll_lock
+
+@ Set MPLL @800Mhz
+ ldr r1, =MPLL_CON1_VAL
+ ldr r2, =MPLL_CON1_OFFSET
+ str r1, [r0, r2]
+ ldr r1, =MPLL_CON0_VAL
+ ldr r2, =MPLL_CON0_OFFSET
+ str r1, [r0, r2]
+ bl wait_pll_lock
+
+@ Set BPLL @800Mhz
+ ldr r1, =BPLL_CON1_VAL
+ ldr r2, =BPLL_CON1_OFFSET
+ str r1, [r0, r2]
+ ldr r1, =BPLL_CON0_VAL
+ ldr r2, =BPLL_CON0_OFFSET
+ str r1, [r0, r2]
+ bl wait_pll_lock
+
+@ Set CPLL @333Mhz
+ ldr r1, =CPLL_CON1_VAL
+ ldr r2, =CPLL_CON1_OFFSET
+ str r1, [r0, r2]
+ ldr r1, =CPLL_CON0_VAL
+ ldr r2, =CPLL_CON0_OFFSET
+ str r1, [r0, r2]
+ bl wait_pll_lock
+
+@ Set GPLL @533Mhz
+ ldr r1, =GPLL_CON1_VAL
+ ldr r2, =GPLL_CON1_OFFSET
+ str r1, [r0, r2]
+ ldr r1, =GPLL_CON0_VAL
+ ldr r2, =GPLL_CON0_OFFSET
+ str r1, [r0, r2]
+ bl wait_pll_lock
+
+@ Set EPLL @96Mhz
+ ldr r1, =EPLL_CON2_VAL
+ ldr r2, =EPLL_CON2_OFFSET
+ str r1, [r0, r2]
+ ldr r1, =EPLL_CON1_VAL
+ ldr r2, =EPLL_CON1_OFFSET
+ str r1, [r0, r2]
+ ldr r1, =EPLL_CON0_VAL
+ ldr r2, =EPLL_CON0_OFFSET
+ str r1, [r0, r2]
+ bl wait_pll_lock
+
+@ Set VPLL @300Mhz
+ ldr r1, =VPLL_CON2_VAL
+ ldr r2, =VPLL_CON2_OFFSET
+ str r1, [r0, r2]
+ ldr r1, =VPLL_CON1_VAL
+ ldr r2, =VPLL_CON1_OFFSET
+ str r1, [r0, r2]
+ ldr r1, =VPLL_CON0_VAL
+ ldr r2, =VPLL_CON0_OFFSET
+ str r1, [r0, r2]
+ bl wait_pll_lock
+
+@ CMU_CORE MUX / DIV
+ ldr r2, =CLK_SRC_CORE0_OFFSET
+ ldr r3, =CLK_SRC_CORE0_VAL
+ str r3, [r0, r2]
+
+ ldr r1, =CLK_DIV_CORE0_VAL
+ ldr r2, =CLK_DIV_CORE0_OFFSET
+ str r1, [r0, r2]
+ ldr r3, =0x0
+ bl wait_div_state
+
+ ldr r1, =CLK_DIV_CORE1_VAL
+ ldr r2, =CLK_DIV_CORE1_OFFSET
+ str r1, [r0, r2]
+ ldr r3, =0x0
+ bl wait_div_state
+
+ ldr r1, =CLK_DIV_SYSRGT_VAL
+ ldr r2, =CLK_DIV_SYSRGT_OFFSET
+ str r1, [r0, r2]
+ ldr r3, =0x0
+ bl wait_div_state
+
+@ CMU_ACP DIV
+ ldr r1, =CLK_DIV_ACP_VAL
+ ldr r2, =CLK_DIV_ACP_OFFSET
+ str r1, [r0, r2]
+ ldr r3, =0x0
+ bl wait_div_state
+
+ ldr r1, =CLK_DIV_SYSLFT_VAL
+ ldr r2, =CLK_DIV_SYSLFT_OFFSET
+ str r1, [r0, r2]
+ ldr r3, =0x0
+ ldr r2, =CLK_DIV_STAT_SYSLFT_OFFSET
+check_div_syslft_state:
+ ldr r1, [r0, r2]
+ cmp r1, r3
+ bne check_div_syslft_state
+
+@ CMU_TOP SRC
+ ldr r2, =CLK_SRC_TOP0_OFFSET
+ ldr r3, =CLK_SRC_TOP0_VAL
+ str r3, [r0, r2]
+
+ ldr r2, =CLK_SRC_TOP1_OFFSET
+ ldr r3, =CLK_SRC_TOP1_VAL
+ str r3, [r0, r2]
+
+ ldr r2, =CLK_SRC_TOP2_OFFSET
+ ldr r3, =0x01100000
+ str r3, [r0, r2]
+
+ ldr r2, =CLK_SRC_TOP3_OFFSET
+ ldr r3, =CLK_SRC_TOP3_VAL
+ ldr r1, [r0, r2]
+ str r3, [r0, r2]
+
+@ CMU_TOP MUX / DIV
+ ldr r1, =CLK_DIV_TOP0_VAL
+ ldr r2, =CLK_DIV_TOP0_OFFSET
+ str r1, [r0, r2]
+ ldr r3, =0x0
+ bl wait_div_state
+
+ ldr r1, =CLK_DIV_TOP1_VAL
+ ldr r2, =CLK_DIV_TOP1_OFFSET
+ str r1, [r0, r2]
+ ldr r3, =0x0
+ bl wait_div_state
+
+@ CMU_LEX SRC / DIV
+ ldr r2, =CLK_SRC_LEX_OFFSET
+ ldr r3, =CLK_SRC_LEX_VAL
+ ldr r1, [r0, r2]
+ orr r1, r1, r3
+ str r1, [r0, r2]
+ ldr r3, =0x1
+ bl wait_mux_state
+
+ ldr r1, =CLK_DIV_LEX_VAL
+ ldr r2, =CLK_DIV_LEX_OFFSET
+ str r1, [r0, r2]
+ ldr r3, =0x0
+ bl wait_div_state
+
+@ CMU_R0X DIV
+ ldr r1, =CLK_DIV_R0X_VAL
+ ldr r2, =CLK_DIV_R0X_OFFSET
+ str r1, [r0, r2]
+ ldr r3, =0x0
+ bl wait_div_state
+
+@ CMU_R1X DIV
+ ldr r1, =CLK_DIV_R1X_VAL
+ ldr r2, =CLK_DIV_R1X_OFFSET
+ str r1, [r0, r2]
+ ldr r3, =0x0
+ bl wait_div_state
+
+@ CMU_CDREX MUX / DIV
+ ldr r2, =CLK_SRC_CDREX_OFFSET
+ ldr r3, =0x0
+ str r3, [r0, r2]
+
+ ldr r1, =0x71720071
+ ldr r2, =CLK_DIV_CDREX_OFFSET
+ str r1, [r0, r2]
+ ldr r3, =0x0
+ bl wait_div_state
+
+@CMU_CPU SRC
+ ldr r2, =CLK_SRC_CPU_OFFSET
+ ldr r3, =CLK_SRC_CPU_VAL
+ ldr r1, [r0, r2]
+ orr r1, r1, r3
+ str r1, [r0, r2]
+
+ ldr r2, =CLK_SRC_TOP2_OFFSET
+ ldr r3, =CLK_SRC_TOP2_VAL
+ ldr r1, [r0, r2]
+ orr r1, r1, r3
+ str r1, [r0, r2]
+
+ ldr r2, =CLK_SRC_CORE1_OFFSET
+ ldr r3, =CLK_SRC_CORE1_VAL
+ ldr r1, [r0, r2]
+ orr r1, r1, r3
+ str r1, [r0, r2]
+
+ ldr r1, =0x66666
+ ldr r2, =CLK_SRC_FSYS_OFFSET
+ str r1, [r0, r2]
+
+ ldr r1, =0x0BB00000
+ ldr r2, =CLK_DIV_FSYS0_OFFSET
+ str r1, [r0, r2]
+ ldr r3, =0x0
+ bl wait_div_state
+
+@disable CLKOUT_CMU
+ ldr r1, =0x0
+ ldr r2, =CLKOUT_CMU_CPU_OFFSET
+ str r1, [r0, r2]
+
+ ldr r2, =CLKOUT_CMU_CORE_OFFSET
+ str r1, [r0, r2]
+
+ ldr r2, =CLKOUT_CMU_ACP_OFFSET
+ str r1, [r0, r2]
+
+ ldr r2, =CLKOUT_CMU_TOP_OFFSET
+ str r1, [r0, r2]
+
+ ldr r2, =CLKOUT_CMU_LEX_OFFSET
+ str r1, [r0, r2]
+
+ ldr r2, =CLKOUT_CMU_R0X_OFFSET
+ str r1, [r0, r2]
+
+ ldr r2, =CLKOUT_CMU_R1X_OFFSET
+ str r1, [r0, r2]
+
+ ldr r2, =CLKOUT_CMU_CDREX_OFFSET
+ str r1, [r0, r2]
+
+ ldr r0, =ELFIN_POWER_BASE
+@power down FSYS_ARM
+ ldr r1, =0x0
+ ldr r2, =FSYS_ARM_CONFIGURATION_OFFSET
+ str r1, [r0, r2]
+
+@disable SATA_PHY_CONTROL
+ ldr r1, =0x0
+ ldr r2, =SATA_PHY_CONTROL_OFFSET
+ str r1, [r0, r2]
+
+ @pop {lr}
+ mov lr, r12
+
+ bx lr
+
+ASM_PFX(ArmPlatformTZPCInitialize):
+ ldr r0, =Exynos5250_TZPC0_BASE
+ mov r1, #0x0
+ str r1, [r0]
+ mov r1, #0xff
+ str r1, [r0, #TZPC_DECPROT0SET_OFFSET]
+ str r1, [r0, #TZPC_DECPROT1SET_OFFSET]
+ str r1, [r0, #TZPC_DECPROT2SET_OFFSET]
+ str r1, [r0, #TZPC_DECPROT3SET_OFFSET]
+
+ ldr r0, =Exynos5250_TZPC1_BASE
+ str r1, [r0, #TZPC_DECPROT0SET_OFFSET]
+ str r1, [r0, #TZPC_DECPROT1SET_OFFSET]
+ str r1, [r0, #TZPC_DECPROT2SET_OFFSET]
+ str r1, [r0, #TZPC_DECPROT3SET_OFFSET]
+
+ ldr r0, =Exynos5250_TZPC2_BASE
+ str r1, [r0, #TZPC_DECPROT0SET_OFFSET]
+ str r1, [r0, #TZPC_DECPROT1SET_OFFSET]
+ str r1, [r0, #TZPC_DECPROT2SET_OFFSET]
+ str r1, [r0, #TZPC_DECPROT3SET_OFFSET]
+
+ ldr r0, =Exynos5250_TZPC3_BASE
+ str r1, [r0, #TZPC_DECPROT0SET_OFFSET]
+ str r1, [r0, #TZPC_DECPROT1SET_OFFSET]
+ str r1, [r0, #TZPC_DECPROT2SET_OFFSET]
+ str r1, [r0, #TZPC_DECPROT3SET_OFFSET]
+
+ ldr r0, =Exynos5250_TZPC4_BASE
+ str r1, [r0, #TZPC_DECPROT0SET_OFFSET]
+ str r1, [r0, #TZPC_DECPROT1SET_OFFSET]
+ str r1, [r0, #TZPC_DECPROT2SET_OFFSET]
+ str r1, [r0, #TZPC_DECPROT3SET_OFFSET]
+
+ ldr r0, =Exynos5250_TZPC5_BASE
+ str r1, [r0, #TZPC_DECPROT0SET_OFFSET]
+ str r1, [r0, #TZPC_DECPROT1SET_OFFSET]
+ str r1, [r0, #TZPC_DECPROT2SET_OFFSET]
+ str r1, [r0, #TZPC_DECPROT3SET_OFFSET]
+
+ ldr r0, =Exynos5250_TZPC6_BASE
+ str r1, [r0, #TZPC_DECPROT0SET_OFFSET]
+ str r1, [r0, #TZPC_DECPROT1SET_OFFSET]
+ str r1, [r0, #TZPC_DECPROT2SET_OFFSET]
+ str r1, [r0, #TZPC_DECPROT3SET_OFFSET]
+
+ ldr r0, =Exynos5250_TZPC7_BASE
+ str r1, [r0, #TZPC_DECPROT0SET_OFFSET]
+ str r1, [r0, #TZPC_DECPROT1SET_OFFSET]
+ str r1, [r0, #TZPC_DECPROT2SET_OFFSET]
+ str r1, [r0, #TZPC_DECPROT3SET_OFFSET]
+
+ ldr r0, =Exynos5250_TZPC8_BASE
+ str r1, [r0, #TZPC_DECPROT0SET_OFFSET]
+ str r1, [r0, #TZPC_DECPROT1SET_OFFSET]
+ str r1, [r0, #TZPC_DECPROT2SET_OFFSET]
+ str r1, [r0, #TZPC_DECPROT3SET_OFFSET]
+
+ ldr r0, =Exynos5250_TZPC9_BASE
+ str r1, [r0, #TZPC_DECPROT0SET_OFFSET]
+ str r1, [r0, #TZPC_DECPROT1SET_OFFSET]
+
+ bx lr
+
+/**
+ Call at the beginning of the platform boot up
+
+ This function allows the firmware platform to do extra actions at the early
+ stage of the platform power up.
+
+ Note: This function must be implemented in assembler as there is no stack set up yet
+
+**/
+ASM_PFX(ArmPlatformSecBootAction):
+ bx lr
+
+
diff --git a/SamsungPlatformPkg/ArndaleBoardPkg/Library/ArndaleBoardLib/Exynos5250/BoardBoot.asm b/SamsungPlatformPkg/ArndaleBoardPkg/Library/ArndaleBoardLib/Exynos5250/BoardBoot.asm
new file mode 100644
index 000000000..056a3e7e9
--- /dev/null
+++ b/SamsungPlatformPkg/ArndaleBoardPkg/Library/ArndaleBoardLib/Exynos5250/BoardBoot.asm
@@ -0,0 +1,52 @@
+//
+// Copyright (c) 2011, ARM Limited. All rights reserved.
+//
+// This program and the accompanying materials
+// are licensed and made available under the terms and conditions of the BSD License
+// which accompanies this distribution. The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+//
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+//
+
+#include <AsmMacroIoLib.h>
+#include <Base.h>
+#include <Library/ArmPlatformLib.h>
+#include <AutoGen.h>
+#include <ArmPlatform.h>
+
+ INCLUDE AsmMacroIoLib.inc
+
+ EXPORT ArmPlatformSecBootAction
+ EXPORT ArmPlatformInitializeBootMemory
+
+ PRESERVE8
+ AREA RTSMVExpressBootMode, CODE, READONLY
+
+/**
+ Call at the beginning of the platform boot up
+
+ This function allows the firmware platform to do extra actions at the early
+ stage of the platform power up.
+
+ Note: This function must be implemented in assembler as there is no stack set up yet
+
+**/
+ArmPlatformSecBootAction
+ bx lr
+
+/**
+ Initialize the memory where the initial stacks will reside
+
+ This memory can contain the initial stacks (Secure and Secure Monitor stacks).
+ In some platform, this region is already initialized and the implementation of this function can
+ do nothing. This memory can also represent the Secure RAM.
+ This function is called before the satck has been set up. Its implementation must ensure the stack
+ pointer is not used (probably required to use assembly language)
+
+**/
+ArmPlatformInitializeBootMemory
+ // The SMC does not need to be initialized for RTSM
+ bx lr
diff --git a/SamsungPlatformPkg/ArndaleBoardPkg/Library/ArndaleBoardLib/Exynos5250/BoardHelper.S b/SamsungPlatformPkg/ArndaleBoardPkg/Library/ArndaleBoardLib/Exynos5250/BoardHelper.S
new file mode 100644
index 000000000..d5858630f
--- /dev/null
+++ b/SamsungPlatformPkg/ArndaleBoardPkg/Library/ArndaleBoardLib/Exynos5250/BoardHelper.S
@@ -0,0 +1,96 @@
+#
+# Copyright (c) 2012, Sasmsung Limited. All rights reserved.
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http:#opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#
+
+#include <AsmMacroIoLib.h>
+#include <Base.h>
+#include <Library/PcdLib.h>
+#include <Library/ArmLib.h>
+#include <AutoGen.h>
+#.include AsmMacroIoLib.inc
+
+#include <Chipset/ArmCortexA9.h>
+
+.text
+.align 2
+
+GCC_ASM_EXPORT(ArmGetCpuCountPerCluster)
+GCC_ASM_EXPORT(ArmPlatformGetCorePosition)
+GCC_ASM_EXPORT(ArmPlatformIsPrimaryCore)
+GCC_ASM_EXPORT(ArmPlatformPeiBootAction)
+
+# IN None
+# OUT r0 = SCU Base Address
+ASM_PFX(ArmGetScuBaseAddress):
+ # Read Configuration Base Address Register. ArmCBar cannot be called to get
+ # the Configuration BAR as a stack is not necessary setup. The SCU is at the
+ # offset 0x0000 from the Private Memory Region.
+ mrc p15, 4, r0, c15, c0, 0
+ bx lr
+
+# IN None
+# OUT r0 = number of cores present in the system
+ASM_PFX(ArmGetCpuCountPerCluster):
+ stmfd SP!, {r1-r2}
+
+ # Read CP15 MIDR
+ mrc p15, 0, r1, c0, c0, 0
+
+ # Check if the CPU is A15
+ mov r1, r1, LSR #4
+ LoadConstantToReg (ARM_CPU_TYPE_MASK, r0)
+ and r1, r1, r0
+
+ LoadConstantToReg (ARM_CPU_TYPE_A15, r0)
+ cmp r1, r0
+ beq _Read_cp15_reg
+
+_CPU_is_not_A15:
+ mov r2, lr @ Save link register
+ bl ArmGetScuBaseAddress @ Read SCU Base Address
+ mov lr, r2 @ Restore link register val
+ ldr r0, [r0, #A9_SCU_CONFIG_OFFSET] @ Read SCU Config reg to get CPU count
+ b _Return
+
+_Read_cp15_reg:
+ mrc p15, 1, r0, c9, c0, 2 @ Read C9 register of CP15 to get CPU count
+ lsr r0, #24
+
+_Return:
+ and r0, r0, #3
+ # Add '1' to the number of CPU on the Cluster
+ add r0, r0, #1
+ ldmfd SP!, {r1-r2}
+ bx lr
+
+ASM_PFX(ArmPlatformIsPrimaryCore):
+ #last 2 bit of mpid register in 5250 is CPU ID
+ ldr r1, =0x3
+ and r0, r0, r1
+ #id for core0 should be 0
+ ldr r1, =0x0
+ cmp r0, r1
+ moveq r0, #1
+ movne r0, #0
+ mov pc, lr
+
+ASM_PFX(ArmPlatformGetCorePosition):
+ and r1, r0, #0x03 //cpu core mask last 2 bits
+ and r0, r0, #(0x0f<<8) //cpu cluster mask bit 8-11
+ add r0, r1, r0, LSR #7
+ mov pc, lr
+
+
+ASM_PFX(ArmPlatformPeiBootAction):
+ mov pc, lr
+
+ASM_FUNCTION_REMOVE_IF_UNREFERENCED
diff --git a/SamsungPlatformPkg/ArndaleBoardPkg/Library/ArndaleBoardLib/Exynos5250/BoardHelper.asm b/SamsungPlatformPkg/ArndaleBoardPkg/Library/ArndaleBoardLib/Exynos5250/BoardHelper.asm
new file mode 100644
index 000000000..bf81f142a
--- /dev/null
+++ b/SamsungPlatformPkg/ArndaleBoardPkg/Library/ArndaleBoardLib/Exynos5250/BoardHelper.asm
@@ -0,0 +1,73 @@
+//
+// Copyright (c) 2011, ARM Limited. All rights reserved.
+//
+// This program and the accompanying materials
+// are licensed and made available under the terms and conditions of the BSD License
+// which accompanies this distribution. The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+//
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+//
+
+#include <AsmMacroIoLib.h>
+#include <Base.h>
+#include <Library/PcdLib.h>
+
+#include <Chipset/ArmCortexA9.h>
+
+#include <AutoGen.h>
+
+ INCLUDE AsmMacroIoLib.inc
+
+ EXPORT ArmGetCpuCountPerCluster
+
+ AREA RTSMHelper, CODE, READONLY
+
+// IN None
+// OUT r0 = SCU Base Address
+ArmGetScuBaseAddress
+ // Read Configuration Base Address Register. ArmCBar cannot be called to get
+ // the Configuration BAR as a stack is not necessary setup. The SCU is at the
+ // offset 0x0000 from the Private Memory Region.
+ mrc p15, 4, r0, c15, c0, 0
+ bx lr
+
+// IN None
+// OUT r0 = number of cores present in the system
+ArmGetCpuCountPerCluster
+ stmfd SP!, {r1-r2}
+
+ // Read CP15 MIDR
+ mrc p15, 0, r1, c0, c0, 0
+
+ // Check if the CPU is A15
+ mov r1, r1, LSR #4
+ mov r0, #ARM_CPU_TYPE_MASK
+ and r1, r1, r0
+
+ mov r0, #ARM_CPU_TYPE_A15
+ cmp r1, r0
+ beq _Read_cp15_reg
+
+_CPU_is_not_A15
+ mov r2, lr ; Save link register
+ bl ArmGetScuBaseAddress ; Read SCU Base Address
+ mov lr, r2 ; Restore link register val
+ ldr r0, [r0, #A9_SCU_CONFIG_OFFSET] ; Read SCU Config reg to get CPU count
+ b _Return
+
+_Read_cp15_reg
+ mrc p15, 1, r0, c9, c0, 2 ; Read C9 register of CP15 to get CPU count
+ lsr r0, #24
+
+
+_Return
+ and r0, r0, #3
+ // Add '1' to the number of CPU on the Cluster
+ add r0, r0, #1
+ ldmfd SP!, {r1-r2}
+ bx lr
+
+ END
diff --git a/SamsungPlatformPkg/ArndaleBoardPkg/Library/ArndaleBoardLib/Exynos5250/BoardLib.inf b/SamsungPlatformPkg/ArndaleBoardPkg/Library/ArndaleBoardLib/Exynos5250/BoardLib.inf
new file mode 100755
index 000000000..9ac255abc
--- /dev/null
+++ b/SamsungPlatformPkg/ArndaleBoardPkg/Library/ArndaleBoardLib/Exynos5250/BoardLib.inf
@@ -0,0 +1,69 @@
+#/* @file
+# Copyright (c) 2012, Samsung Electronics Co. All rights reserved.
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#*/
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = BoardLib
+ FILE_GUID = 736343a0-1d96-11e0-aaaa-0002a5d5c51b
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = ArmPlatformLib
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ EmbeddedPkg/EmbeddedPkg.dec
+ ArmPkg/ArmPkg.dec
+ ArmPlatformPkg/ArmPlatformPkg.dec
+ SamsungPlatformPkg/ExynosPkg/Exynos5250/ExynosPkg.dec
+
+[LibraryClasses]
+ IoLib
+ ArmLib
+ MemoryAllocationLib
+
+[Sources.common]
+ Board.c
+ BoardMem.c
+ BoardHelper.asm | RVCT
+ BoardHelper.S | GCC
+
+[Protocols]
+
+[FeaturePcd]
+ gEmbeddedTokenSpaceGuid.PcdCacheEnable
+ gArmPlatformTokenSpaceGuid.PcdStandalone
+
+[FixedPcd]
+ gArmTokenSpaceGuid.PcdSystemMemoryBase
+ gArmTokenSpaceGuid.PcdSystemMemorySize
+ gArmTokenSpaceGuid.PcdFvBaseAddress
+
+ gArmTokenSpaceGuid.PcdFdBaseAddress
+ gArmTokenSpaceGuid.PcdFdSize
+ gArmTokenSpaceGuid.PcdTrustzoneSupport
+
+ gExynosPkgTokenSpaceGuid.PcdTZPCBase
+ gExynosPkgTokenSpaceGuid.PcdFrameBufferBase
+ gExynosPkgTokenSpaceGuid.PcdFrameBufferSize
+
+ gExynosPkgTokenSpaceGuid.PcdMpSharedArgsBase
+ gExynosPkgTokenSpaceGuid.PcdMpSharedArgsSize
+
+ gExynosPkgTokenSpaceGuid.PcdSmemBaseAddress
+ gExynosPkgTokenSpaceGuid.PcdSmemSize
+
+ gExynosPkgTokenSpaceGuid.PcdiRamBootBase
+ gExynosPkgTokenSpaceGuid.PcdiRamBootSize
+ gExynosPkgTokenSpaceGuid.PcdEmmcDMABufferBase
+# gExynosPkgTokenSpaceGuid.PcdEmmcDMABufferSize
diff --git a/SamsungPlatformPkg/ArndaleBoardPkg/Library/ArndaleBoardLib/Exynos5250/BoardMem.c b/SamsungPlatformPkg/ArndaleBoardPkg/Library/ArndaleBoardLib/Exynos5250/BoardMem.c
new file mode 100755
index 000000000..051776d42
--- /dev/null
+++ b/SamsungPlatformPkg/ArndaleBoardPkg/Library/ArndaleBoardLib/Exynos5250/BoardMem.c
@@ -0,0 +1,221 @@
+/** @file
+*
+* Copyright (c) 2012, Samsung Electronics Co. All rights reserved.
+*
+* This program and the accompanying materials
+* are licensed and made available under the terms and conditions of the BSD License
+* which accompanies this distribution. The full text of the license may be found at
+* http://opensource.org/licenses/bsd-license.php
+*
+* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#include <Library/ArmPlatformLib.h>
+#include <Library/DebugLib.h>
+#include <Library/PcdLib.h>
+#include <Library/IoLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <ArmPlatform.h>
+
+// Number of Virtual Memory Map Descriptors without a Logic Tile
+#define MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS 9
+
+// DDR attributes
+#define DDR_ATTRIBUTES_CACHED ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_WRITE_BACK
+#define DDR_ATTRIBUTES_UNCACHED ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_UNCACHED_UNBUFFERED
+#define DDR_ATTRIBUTES_SECURE_CACHED ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK
+#define DDR_ATTRIBUTES_SECURE_UNCACHED ARM_MEMORY_REGION_ATTRIBUTE_UNCACHED_UNBUFFERED
+
+// Logical Region 1
+#define SOC_REGISTERS_IROM_PHYSICAL_BASE 0x00000000
+#define SOC_REGISTERS_IROM_PHYSICAL_LENGTH 0x02010000
+#define SOC_REGISTERS_IROM_ATTRIBUTES ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_DEVICE
+#define SOC_REGISTERS_IROM_SECURE_ATTRIBUTES ARM_MEMORY_REGION_ATTRIBUTE_DEVICE
+
+// Logical Region 2
+#define SOC_REGISTERS_SFR_PHYSICAL_BASE 0x10000000
+#define SOC_REGISTERS_SFR_PHYSICAL_LENGTH 0x08FFFFFF
+#define SOC_REGISTERS_SFR_ATTRIBUTES ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_DEVICE
+#define SOC_REGISTERS_SFR_SECURE_ATTRIBUTES ARM_MEMORY_REGION_ATTRIBUTE_DEVICE
+
+/**
+ Return the Virtual Memory Map of your platform
+
+ This Virtual Memory Map is used by MemoryInitPei Module to initialize the MMU on your platform.
+
+ @param[out] VirtualMemoryMap Array of ARM_MEMORY_REGION_DESCRIPTOR describing a Physical-to-
+ Virtual Memory mapping. This array must be ended by a zero-filled
+ entry
+
+**/
+VOID
+ArmPlatformGetVirtualMemoryMap (
+ IN ARM_MEMORY_REGION_DESCRIPTOR** VirtualMemoryMap
+ )
+{
+ ARM_MEMORY_REGION_ATTRIBUTES CacheAttributes;
+ UINTN Index = 0;
+ ARM_MEMORY_REGION_DESCRIPTOR *VirtualMemoryTable;
+
+ DEBUG ((EFI_D_ERROR, "++%a:%d\n", __FUNCTION__, __LINE__));
+
+ UINTN MemoryBase_Pcd = PcdGet32(PcdSystemMemoryBase);
+ UINTN MemorySize_Pcd = PcdGet32(PcdSystemMemorySize);
+ UINTN FrameBufferBase_Pcd = PcdGet32(PcdFrameBufferBase);
+ UINTN FrameBufferSize_Pcd = PcdGet32(PcdFrameBufferSize);
+ UINTN MpSharedArgsBase_Pcd = PcdGet32(PcdMpSharedArgsBase);
+ UINTN MpSharedArgsSize_Pcd = PcdGet32(PcdMpSharedArgsSize);
+ UINTN FdBaseAddress_Pcd = PcdGet32(PcdFdBaseAddress);
+ UINTN FdSize_Pcd = PcdGet32(PcdFdSize);
+ UINTN SmemBase_Pcd = PcdGet32(PcdSmemBaseAddress);
+ UINTN SmemSize_Pcd = PcdGet32(PcdSmemSize);
+ UINTN iRamBootBase_Pcd = PcdGet32(PcdiRamBootBase);
+ UINTN iRamBootSize_Pcd = PcdGet32(PcdiRamBootSize);
+ BOOLEAN TrustzoneSupport_Pcd = PcdGetBool (PcdTrustzoneSupport);
+ UINT32 Nsacr = ArmReadNsacr();
+ UINTN EmmcDMABufferBase_Pcd = PcdGet32(PcdEmmcDMABufferBase);
+
+ // Checking Secure mode
+ if(Nsacr == 0x0) // Secure mode
+ {
+ TrustzoneSupport_Pcd = FALSE;
+ }
+
+ // Check if SMC TZASC is enabled. If Trustzone not enabled then all the entries remain in Secure World.
+ // As this value can be changed in the Board Configuration file, the UEFI firmware needs to work for both case
+
+
+ ASSERT(VirtualMemoryMap != NULL);
+
+ VirtualMemoryTable = (ARM_MEMORY_REGION_DESCRIPTOR*)AllocatePages(EFI_SIZE_TO_PAGES (sizeof(ARM_MEMORY_REGION_DESCRIPTOR) * MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS));
+ if (VirtualMemoryTable == NULL) {
+ return;
+ }
+
+ if (FeaturePcdGet(PcdCacheEnable) == TRUE) {
+ CacheAttributes = (TrustzoneSupport_Pcd ? DDR_ATTRIBUTES_CACHED : DDR_ATTRIBUTES_SECURE_CACHED);
+ } else {
+ CacheAttributes = (TrustzoneSupport_Pcd ? DDR_ATTRIBUTES_UNCACHED : DDR_ATTRIBUTES_SECURE_UNCACHED);
+ }
+
+ // FD region : 0x40000000 - 0x40200000
+ // Map in the FD region (includes SEC), the stack, and the exception vector region
+ VirtualMemoryTable[Index].PhysicalBase = FdBaseAddress_Pcd;
+ VirtualMemoryTable[Index].VirtualBase = FdBaseAddress_Pcd;
+ VirtualMemoryTable[Index].Length = FdSize_Pcd; // need to check
+ VirtualMemoryTable[Index].Attributes = (ARM_MEMORY_REGION_ATTRIBUTES)CacheAttributes;
+ DEBUG ((EFI_D_ERROR, "FD region : 0x%8X - 0x%8X\n", (UINT32)(VirtualMemoryTable[Index].PhysicalBase),
+ (UINT32)(VirtualMemoryTable[Index].PhysicalBase + VirtualMemoryTable[Index].Length)));
+
+ // SMEM : 0x40200000 - 0x40300000
+ // Shared memory 1MB (0x4000_0000 -- 0x4010_0000)
+ VirtualMemoryTable[++Index].PhysicalBase = SmemBase_Pcd;
+ VirtualMemoryTable[Index].VirtualBase = SmemBase_Pcd;
+ VirtualMemoryTable[Index].Length = SmemSize_Pcd;
+ VirtualMemoryTable[Index].Attributes = (TrustzoneSupport_Pcd ? DDR_ATTRIBUTES_UNCACHED : DDR_ATTRIBUTES_SECURE_UNCACHED);
+ DEBUG ((EFI_D_ERROR, "SMEM : 0x%8X - 0x%8X\n", (UINT32)(VirtualMemoryTable[Index].PhysicalBase),
+ (UINT32)(VirtualMemoryTable[Index].PhysicalBase + VirtualMemoryTable[Index].Length)));
+
+ // EMMC : 0x40300000 - 0x40400000
+ // EMMC (0x4030_0000 - 0x404_0000) (1MB)
+ VirtualMemoryTable[++Index].PhysicalBase = EmmcDMABufferBase_Pcd;
+ VirtualMemoryTable[Index].VirtualBase = EmmcDMABufferBase_Pcd;
+ VirtualMemoryTable[Index].Length = 0x00100000;
+ VirtualMemoryTable[Index].Attributes = (TrustzoneSupport_Pcd ? DDR_ATTRIBUTES_UNCACHED : DDR_ATTRIBUTES_SECURE_UNCACHED);
+ DEBUG ((EFI_D_ERROR, "EMMC : 0x%8X - 0x%8X\n", (UINT32)(VirtualMemoryTable[Index].PhysicalBase),
+ (UINT32)(VirtualMemoryTable[Index].PhysicalBase + VirtualMemoryTable[Index].Length)));
+
+
+ // DDR : 0x40400000 - 0x4E000000
+ // DDR (0x4040_0000 - 0x4E00_0000) (511MB)
+ VirtualMemoryTable[++Index].PhysicalBase = 0x40400000;
+ VirtualMemoryTable[Index].VirtualBase = 0x40400000;
+ VirtualMemoryTable[Index].Length = 0x0DC00000;
+ VirtualMemoryTable[Index].Attributes = (ARM_MEMORY_REGION_ATTRIBUTES)CacheAttributes;
+ DEBUG ((EFI_D_ERROR, "DDR : 0x%8X - 0x%8X\n", (UINT32)(VirtualMemoryTable[Index].PhysicalBase),
+ (UINT32)(VirtualMemoryTable[Index].PhysicalBase + VirtualMemoryTable[Index].Length)));
+
+ // MpParkShared: 0x4D00_0000 - 0x4D10_0000
+ // MpParkSahred (0x4D00_0000 - 0x4D10_0000)
+ VirtualMemoryTable[++Index].PhysicalBase = MpSharedArgsBase_Pcd;
+ VirtualMemoryTable[Index].VirtualBase = MpSharedArgsBase_Pcd;
+ VirtualMemoryTable[Index].Length = MpSharedArgsSize_Pcd;
+ VirtualMemoryTable[Index].Attributes = (TrustzoneSupport_Pcd ? DDR_ATTRIBUTES_UNCACHED : DDR_ATTRIBUTES_SECURE_UNCACHED);
+ DEBUG ((EFI_D_ERROR, "FrameBuffer: 0x%8X - 0x%8X\n", VirtualMemoryTable[Index].PhysicalBase,
+ (UINT32)(VirtualMemoryTable[Index].PhysicalBase + VirtualMemoryTable[Index].Length)));
+
+ // FrameBuffer: 0x4E000000 - 0x50000000
+ // Framebuffer (0x4E00_0000 - 0x5000_0000)
+ VirtualMemoryTable[++Index].PhysicalBase = FrameBufferBase_Pcd;
+ VirtualMemoryTable[Index].VirtualBase = FrameBufferBase_Pcd;
+ VirtualMemoryTable[Index].Length = FrameBufferSize_Pcd;
+ VirtualMemoryTable[Index].Attributes = (TrustzoneSupport_Pcd ? DDR_ATTRIBUTES_UNCACHED : DDR_ATTRIBUTES_SECURE_UNCACHED);
+ DEBUG ((EFI_D_ERROR, "FrameBuffer: 0x%8X - 0x%8X\n", (UINT32)(VirtualMemoryTable[Index].PhysicalBase),
+ (UINT32)(VirtualMemoryTable[Index].PhysicalBase + VirtualMemoryTable[Index].Length)));
+
+ // DDR : 0x50000000 - 0xA0000000
+ // DDR (0x5000_0000 - 0x8000_0000) (512MB)
+ VirtualMemoryTable[++Index].PhysicalBase = MemoryBase_Pcd;
+ VirtualMemoryTable[Index].VirtualBase = MemoryBase_Pcd;
+ VirtualMemoryTable[Index].Length = MemorySize_Pcd;
+ VirtualMemoryTable[Index].Attributes = (ARM_MEMORY_REGION_ATTRIBUTES)CacheAttributes;
+ DEBUG ((EFI_D_ERROR, "DDR : 0x%8X - 0x%8X\n", (UINT32)(VirtualMemoryTable[Index].PhysicalBase),
+ (UINT32)(VirtualMemoryTable[Index].PhysicalBase + VirtualMemoryTable[Index].Length)));
+
+ // SFR : 0x10000000 - 0x14000000
+ // SFR
+ VirtualMemoryTable[++Index].PhysicalBase = SOC_REGISTERS_SFR_PHYSICAL_BASE;
+ VirtualMemoryTable[Index].VirtualBase = SOC_REGISTERS_SFR_PHYSICAL_BASE;
+ VirtualMemoryTable[Index].Length = SOC_REGISTERS_SFR_PHYSICAL_LENGTH;
+ VirtualMemoryTable[Index].Attributes = (TrustzoneSupport_Pcd ? SOC_REGISTERS_SFR_ATTRIBUTES : SOC_REGISTERS_SFR_SECURE_ATTRIBUTES);
+ DEBUG ((EFI_D_ERROR, "SFR : 0x%8X - 0x%8X\n", (UINT32)(VirtualMemoryTable[Index].PhysicalBase),
+ (UINT32)(VirtualMemoryTable[Index].PhysicalBase + VirtualMemoryTable[Index].Length)));
+
+ // iRAM : 0x02020000 - 0x02040000
+ // iRAM
+ VirtualMemoryTable[++Index].PhysicalBase = iRamBootBase_Pcd;
+ VirtualMemoryTable[Index].VirtualBase = iRamBootBase_Pcd;
+ VirtualMemoryTable[Index].Length = iRamBootSize_Pcd;
+ VirtualMemoryTable[Index].Attributes = (TrustzoneSupport_Pcd ? ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_DEVICE : ARM_MEMORY_REGION_ATTRIBUTE_DEVICE);
+ DEBUG ((EFI_D_ERROR, "iRAM : 0x%8X - 0x%8X\n", (UINT32)(VirtualMemoryTable[Index].PhysicalBase),
+ (UINT32)(VirtualMemoryTable[Index].PhysicalBase + VirtualMemoryTable[Index].Length)));
+
+ // iROM : 0x00000000 - 0x02010000
+ // iROM
+ VirtualMemoryTable[++Index].PhysicalBase = SOC_REGISTERS_IROM_PHYSICAL_BASE;
+ VirtualMemoryTable[Index].VirtualBase = SOC_REGISTERS_IROM_PHYSICAL_BASE;
+ VirtualMemoryTable[Index].Length = SOC_REGISTERS_IROM_PHYSICAL_LENGTH;
+ VirtualMemoryTable[Index].Attributes = (TrustzoneSupport_Pcd ? SOC_REGISTERS_IROM_ATTRIBUTES : SOC_REGISTERS_IROM_SECURE_ATTRIBUTES);
+ DEBUG ((EFI_D_ERROR, "iROM : 0x%8X - 0x%8X\n", (UINT32)(VirtualMemoryTable[Index].PhysicalBase),
+ (UINT32)(VirtualMemoryTable[Index].PhysicalBase + VirtualMemoryTable[Index].Length)));
+
+ // End of Table
+ VirtualMemoryTable[++Index].PhysicalBase = 0;
+ VirtualMemoryTable[Index].VirtualBase = 0;
+ VirtualMemoryTable[Index].Length = 0;
+ VirtualMemoryTable[Index].Attributes = (ARM_MEMORY_REGION_ATTRIBUTES)0;
+
+ *VirtualMemoryMap = VirtualMemoryTable;
+ DEBUG ((EFI_D_ERROR, "--%a:%d\n", __FUNCTION__, __LINE__));
+}
+
+/**
+ Return the EFI Memory Map provided by extension memory on your platform
+
+ This EFI Memory Map of the System Memory is used by MemoryInitPei module to create the Resource
+ Descriptor HOBs used by DXE core.
+ TODO: CompleteMe .... say this is the memory not covered by the System Memory PCDs
+
+ @param[out] EfiMemoryMap Array of ARM_SYSTEM_MEMORY_REGION_DESCRIPTOR describing an
+ EFI Memory region. This array must be ended by a zero-filled entry
+
+**/
+EFI_STATUS
+ArmPlatformGetAdditionalSystemMemory (
+ OUT ARM_SYSTEM_MEMORY_REGION_DESCRIPTOR** EfiMemoryMap
+ )
+{
+ return EFI_UNSUPPORTED;
+}
diff --git a/SamsungPlatformPkg/ArndaleBoardPkg/Library/ArndaleBoardLib/Exynos5250/BoardSec.c b/SamsungPlatformPkg/ArndaleBoardPkg/Library/ArndaleBoardLib/Exynos5250/BoardSec.c
new file mode 100644
index 000000000..374712722
--- /dev/null
+++ b/SamsungPlatformPkg/ArndaleBoardPkg/Library/ArndaleBoardLib/Exynos5250/BoardSec.c
@@ -0,0 +1,52 @@
+/** @file
+*
+* Copyright (c) 2012, Samsung Electronics Co. All rights reserved.
+*
+* This program and the accompanying materials
+* are licensed and made available under the terms and conditions of the BSD License
+* which accompanies this distribution. The full text of the license may be found at
+* http://opensource.org/licenses/bsd-license.php
+*
+* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#include <Library/IoLib.h>
+#include <Library/ArmPlatformLib.h>
+#include <Library/DebugLib.h>
+#include <Library/PcdLib.h>
+#include <Drivers/PL310L2Cache.h>
+#include <Drivers/PL341Dmc.h>
+
+
+/**
+ Initialize controllers that must setup at the early stage
+
+ Some peripherals must be initialized in Secure World.
+ For example, some L2x0 requires to be initialized in Secure World
+
+**/
+VOID
+ArmPlatformSecInitialize (
+ VOID
+ )
+{
+ return;
+}
+
+/**
+ Call before jumping to Normal World
+
+ This function allows the firmware platform to do extra actions before
+ jumping to the Normal World
+
+**/
+VOID
+ArmPlatformSecExtraAction (
+ IN UINTN MpId,
+ OUT UINTN* JumpAddress
+ )
+{
+ *JumpAddress = PcdGet32(PcdFvBaseAddress);
+}
diff --git a/SamsungPlatformPkg/ArndaleBoardPkg/Library/ArndaleBoardLib/Exynos5250/BoardSecLib.inf b/SamsungPlatformPkg/ArndaleBoardPkg/Library/ArndaleBoardLib/Exynos5250/BoardSecLib.inf
new file mode 100755
index 000000000..aeaba6eb2
--- /dev/null
+++ b/SamsungPlatformPkg/ArndaleBoardPkg/Library/ArndaleBoardLib/Exynos5250/BoardSecLib.inf
@@ -0,0 +1,60 @@
+#/* @file
+# Copyright (c) 2012, Samsung Electronics Co. All rights reserved.
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#*/
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = BoardSecLib
+ FILE_GUID = 6e02ebe0-1d96-11e0-b9cb-0002a5d5c51b
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = ArmPlatformLib
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ EmbeddedPkg/EmbeddedPkg.dec
+ ArmPkg/ArmPkg.dec
+ ArmPlatformPkg/ArmPlatformPkg.dec
+ SamsungPlatformPkg/ExynosPkg/Exynos5250/ExynosPkg.dec
+
+[LibraryClasses]
+ IoLib
+ ArmLib
+
+[Sources.common]
+ Board.c
+ BoardSec.c
+ mem_init_ddr3.S | GCC
+ BoardBoot.S | GCC
+ BoardBoot.asm | RVCT
+ BoardHelper.asm | RVCT
+ BoardHelper.S | GCC
+
+[Protocols]
+
+[FeaturePcd]
+ gEmbeddedTokenSpaceGuid.PcdCacheEnable
+ gArmPlatformTokenSpaceGuid.PcdStandalone
+
+[FixedPcd]
+ gEmbeddedTokenSpaceGuid.PcdEmbeddedFdBaseAddress
+ gEmbeddedTokenSpaceGuid.PcdEmbeddedFdSize
+ gArmTokenSpaceGuid.PcdFvBaseAddress
+
+ gExynosPkgTokenSpaceGuid.PcdiRamBootBase
+ gExynosPkgTokenSpaceGuid.PcdiRamBootSize
+ gExynosPkgTokenSpaceGuid.PcdTZPCBase
+
+ gArmTokenSpaceGuid.PcdFdSize
+ gArmTokenSpaceGuid.PcdFdBaseAddress
+ gArmTokenSpaceGuid.PcdL2x0ControllerBase
diff --git a/SamsungPlatformPkg/ArndaleBoardPkg/Library/ArndaleBoardLib/Exynos5250/dmc_init.c b/SamsungPlatformPkg/ArndaleBoardPkg/Library/ArndaleBoardLib/Exynos5250/dmc_init.c
new file mode 100644
index 000000000..297dd6edf
--- /dev/null
+++ b/SamsungPlatformPkg/ArndaleBoardPkg/Library/ArndaleBoardLib/Exynos5250/dmc_init.c
@@ -0,0 +1,787 @@
+/*
+ * (C) Copyright 2012 Samsung Electronics Co. Ltd
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+void dmc_delay(UINT32);
+void mem_ctrl_init_done();
+
+#define Outp32(addr, data) (*(volatile UINT32 *)(addr) = (data))
+#define Inp32(addr) ((*(volatile UINT32 *)(addr)))
+
+#define CONFIG_DMC_CALIBRATION
+#define CONFIG_ODTOFF_GATELEVELINGON
+#define POP_TYPE 1
+#define PRO_PKGINFO 0
+
+void DMC_Delay(UINT32 x)
+{
+ dmc_delay(x);
+}
+
+void CMU_SetMemClk(UINT32 nMEMCLK)
+{
+ volatile UINT32 uBits;
+
+ // MEM Clock = 800 MHz
+
+ // MCLK_DPHY(0:8), MCLK_CDREX(0:4), BPLL(0:0)
+ uBits = (0 << 8) | (0 << 4) | (1 << 0);
+ Outp32(0x10030200, uBits); // rCLK_SRC_CDREX
+
+ // MCLK_DPHY = 800 / 1 = 800
+ // MCLK_CDREX = 800 / 1 = 800
+ // ACLK_CDREX = MCLK_CDREX / 2 = 400
+ // PCLK_CDREX = 800 / 1 / 6 = 133
+
+ // MCLK_CDREX2(1/1:28), ACLK_SFRTZASCP(1/2:24), MCLK_DPHY(1/1:20), MCLK_CDREX(1/1:16), PCLK_CDREX(1/6:4), ACLK_CDREX(1/2:0)
+ uBits = (0 << 28) | (1 << 24) | (0 << 20) | (0 << 16) | (5 << 4) | (1 << 0);
+ Outp32(0x10030500, uBits); // rCLK_DIV_CDREX
+
+ // MPLL(0:8)
+ uBits = (1 << 8);
+ Outp32(0x10014204, Inp32(0x10014204) & ~uBits); // rCLK_SRC_CORE1
+
+ // Setting MPLL [P,M,S]
+ //
+ uBits = (1 << 21) | (3 << 12) | (8 << 8);
+ Outp32(0x10014104, uBits); // rMPLL_CON1
+
+ // ENABLE(1), MDIV(200), PDIV(3), SDIV(0)
+ uBits = (1 << 31) | (200 << 16) | (3 << 8) | (0 << 0); // MPLL=1600MHz(3:200:0)
+ Outp32(0x10014100, uBits); // rMPLL_CON0
+
+ while ((Inp32(0x10014100) & (1 << 29)) == 0);
+
+ // MPLL(1:8)
+ uBits = (1 << 8);
+ Outp32(0x10014204, Inp32(0x10014204) | uBits); // rCLK_SRC_CORE1
+
+}
+
+void DMC_CaTraining(int ch)
+{
+ unsigned char code;
+ int find_vmw;
+ unsigned int phyBase;
+ unsigned int ioRdOffset;
+ unsigned int temp, mr41, mr48, vwml, vwmr, vwmc;
+ unsigned int lock;
+ unsigned int resp_mr41, resp_mr48;
+ UINT32 pkg_type = PRO_PKGINFO;
+
+
+ phyBase = 0x10c00000+(0x10000 * ch);
+ ioRdOffset = 0x150 + (0x4 * ch);
+
+ temp = Inp32( phyBase + 0x0000 );
+ temp |= (1 << 16);
+ Outp32( phyBase + 0x0000, temp );
+
+ temp = Inp32( phyBase + 0x0008 );
+ temp |= (1 << 23);
+ Outp32( phyBase + 0x0008, temp );
+
+ code = 0x8;
+ find_vmw = 0;
+ vwml = vwmr = vwmc = 0;
+
+ if (pkg_type == POP_TYPE) {
+ resp_mr41 = 0x5555;
+ resp_mr48 = 0x0101;
+ } else {
+ if ( ch == 0 ) {
+ resp_mr41 = 0x69C5;
+ resp_mr48 = 0x4040;
+ } else {
+ resp_mr41 = 0xD14E;
+ resp_mr48 = 0x8008;
+ }
+ }
+
+ while (1) {
+
+ //- code update
+ temp = Inp32( phyBase + 0x0028 );
+ temp &= 0xFFFFFF00;
+ temp |= code;
+ Outp32( phyBase + 0x0028, temp );
+
+ //- resync
+ temp = Inp32( phyBase + 0x0028 );
+ temp &= 0xFEFFFFFF;
+ Outp32( phyBase + 0x0028, temp );
+ temp |= 0x01000000;
+ Outp32( phyBase + 0x0028, temp );
+ temp &= 0xFEFFFFFF;
+ Outp32( phyBase + 0x0028, temp );
+
+ if(ch == 0) {
+ Outp32( 0x10DD0000+0x0010, 0x50690 ); //- Send MRW: MA=0x29 OP=0xA4, 0x50690
+ //Outp32( 0x10DD0000+0x0010, 0x001050690 ); //- Send MRW: MA=0x29 OP=0xA4, 0x50690
+ } else {
+ Outp32( 0x10DD0000+0x0010, 0x10050690 ); //- Send MRW: MA=0x29 OP=0xA4, 0x10050690
+ //Outp32( 0x10DD0000+0x0010, 0x10150690 ); //- Send MRW: MA=0x29 OP=0xA4, 0x10050690
+ }
+
+ Outp32( 0x10DD0000+0x0160, 0x3FF011 ); //- Set DMC.CACAL_CONFIG0.deassert_cke=1
+ Outp32( 0x10DD0000+0x0164, 0x1 ); //- Set DMC.CACAL_CONFIG1.cacal_csn=1
+ DMC_Delay(0x100);
+
+ mr41 = Inp32( 0x10DD0000 + ioRdOffset );
+ mr41 &= 0xFFFF;
+
+ Outp32( 0x10DD0000+0x0160, 0x3FF010 ); //- Set DMC.CACAL_CONFIG0.deassert_cke=0
+ DMC_Delay(0x100);
+
+ if( ch == 0 ) {
+ Outp32( 0x10DD0000+0x0010, 0x60300 ); //- Send MRW: MA=0x30 OP=0xC0, 0x60300
+ //Outp32( 0x10DD0000+0x0010, 0x001060300 ); //- Send MRW: MA=0x30 OP=0xC0, 0x60300
+ } else {
+ Outp32( 0x10DD0000+0x0010, 0x10060300 ); //- Send MRW: MA=0x30 OP=0xC0, 0x10060300
+ //Outp32( 0x10DD0000+0x0010, 0x10160300 ); //- Send MRW: MA=0x30 OP=0xC0, 0x10060300
+ }
+
+ Outp32( 0x10DD0000+0x0160, 0x3FF011 ); //- Set DMC.CACAL_CONFIG0.deassert_cke=1
+ Outp32( 0x10DD0000+0x0164, 0x1 ); //- Set DMC.CACAL_CONFIG1.cacal_csn=1
+ DMC_Delay(0x100);
+
+ mr48 = Inp32( 0x10DD0000 + ioRdOffset );
+
+ if (pkg_type == POP_TYPE) {
+ mr48 &= 0x0303;
+ } else {
+ if ( ch == 0 ) {
+ mr48 &= 0xC060;
+ } else {
+ mr48 &= 0x8418;
+ }
+ }
+
+ Outp32( 0x10DD0000+0x0160, 0x3FF010 ); //- Set DMC.CACAL_CONFIG0.deassert_cke=0
+ DMC_Delay(0x100);
+
+ if( (find_vmw == 0) && (mr41 == resp_mr41 ) && ( mr48 == resp_mr48 ) ) {
+ find_vmw = 0x1;
+ vwml = code;
+ }
+
+ if( (find_vmw == 1) && ( (mr41 != resp_mr41 ) || ( mr48 != resp_mr48 ) ) ) {
+ find_vmw = 0x3;
+ vwmr = code - 1;
+
+ if( ch == 0 ) {
+ Outp32( 0x10DD0000+0x0010, 0x50AA0 ); //- Send MRW: MA=0x2A OP=0xA8, 0x50AA0
+ //Outp32( 0x10DD0000+0x0010, 0x001050AA0 ); //- Send MRW: MA=0x2A OP=0xA8, 0x50AA0
+ } else {
+ Outp32( 0x10DD0000+0x0010, 0x10050AA0 ); //- Send MRW: MA=0x2A OP=0xA8, 0x50AA0
+ //Outp32( 0x10DD0000+0x0010, 0x10150AA0 ); //- Send MRW: MA=0x2A OP=0xA8, 0x50AA0
+ }
+ //DMC_Delay(0x10000);
+ break;
+ }
+
+ code++;
+
+ if(code == 255) {
+ while(1);
+ }
+ }
+
+ vwmc = (vwml + vwmr) / 2;
+
+#if 1
+ {
+ UINT32 lock_force;
+ UINT32 temp = 0;
+
+ lock_force = (Inp32( phyBase + 0x30 ) >> 8) & 0x7F;
+
+ temp = ((vwml & 0xFF) << 16) |
+ ((vwmr & 0xFF) << 8) |
+ ((vwmc & 0xFF));
+
+ if(ch == 0) {
+ Outp32(0x10040818, temp);
+ }
+ else {
+ Outp32(0x1004081C, temp);
+ }
+ }
+#endif
+
+ //- code update
+ temp = Inp32( phyBase + 0x0028 );
+ temp &= 0xFFFFFF00;
+ temp |= vwmc;
+ Outp32( phyBase + 0x0028, temp );
+
+ //- resync
+ temp = Inp32( phyBase + 0x0028 );
+ temp &= 0xFEFFFFFF;
+ Outp32( phyBase + 0x0028, temp );
+ temp |= 0x01000000;
+ Outp32( phyBase + 0x0028, temp );
+ temp &= 0xFEFFFFFF;
+ Outp32( phyBase + 0x0028, temp );
+
+ temp = Inp32( phyBase+0x0000 );
+ temp &= 0xFFFEFFFF;
+ Outp32( phyBase + 0x0000, temp );
+
+#if 1
+
+ //- vmwc convert to offsetd value.
+
+ lock = Inp32( phyBase + 0x0034 );
+ lock &= 0x1FF00;
+ lock >>= 8;
+
+ if( (lock & 0x3) == 0x3 ) {
+ lock++;
+ }
+
+ code = vwmc - (lock >> 2);
+
+ temp = Inp32( phyBase + 0x0028 );
+ temp &= 0xFFFFFF00;
+ temp |= code;
+ Outp32( phyBase + 0x0028, temp );
+
+ temp = Inp32( phyBase + 0x0008 );
+ temp &= 0xFF7FFFFF;
+ Outp32( phyBase + 0x0008, temp );
+#endif
+}
+
+static void DMC_ZqInit(UINT8 dq, UINT8 ck, UINT8 cke, UINT8 cs, UINT8 ca)
+{
+ UINT32 temp;
+ UINT32 zqBase;
+ int ch;
+
+ for( ch = 0; ch < 2; ch++ ) {
+
+ zqBase = 0x10c00000 + ( 0x10000 * ch );
+
+ temp = Inp32( zqBase + 0x40 );
+ temp &= 0xF8FBFFF1;
+ temp |= ( ( dq & 0x7 ) << 24 );
+ temp |= ( ( 1 << 18 ) | ( 1 << 2 ) );
+
+ Outp32( zqBase + 0x40, temp );
+
+ temp |= (1 << 1);
+
+ Outp32( zqBase + 0x40, temp );
+
+ while( ( Inp32( zqBase + 0x48 ) & 0x5 ) != 0x1 );
+
+ temp = Inp32( zqBase + 0x40 );
+
+ temp &= ~( 1 << 18 );
+
+ Outp32( zqBase + 0x40, temp );
+
+ temp = ( ( ck & 0x7 ) << 9 ) | ( ( cke & 0x7 ) << 6 ) |
+ ( ( cs & 0x7 ) << 3 ) | ( ca & 0x7 );
+
+ Outp32( zqBase + 0xA0, temp );
+ }
+}
+
+void mem_ctrl_init_lpddr3(UINT32 nMEMCLK)
+{
+ UINT32 lock, temp;
+ UINT32 pkg_type = PRO_PKGINFO;
+
+ //-
+ //-PHASE 1 : PHY DLL Initialization
+ //-
+ //-2) Set the right value to PHY_CON0.ctrl_ddr_mode
+ Outp32( 0x10C00000+0x0000, 0x17021A40 ); //- PHY0.CON0[12:11].ctrl_ddr_mode=LPDDR3
+ Outp32( 0x10C10000+0x0000, 0x17021A40 ); //- PHY1.CON0[12:11].ctrl_ddr_mode=LPDDR3
+ //-3) Enable CA swap when POP is used
+ Outp32( 0x10C00000+0x0000, 0x17021A00 ); //- PHY0.CON0.ctrl_atgate=0x0
+ Outp32( 0x10C10000+0x0000, 0x17021A00 ); //- PHY1.CON0.ctrl_atgate=0x0
+
+ if (pkg_type == POP_TYPE) {
+ Outp32( 0x10030A20, 0x80000000 ); //- LPDDR3PHY_CON3[31]=1.
+ Outp32( 0x10C00000+0x0064, 0x1 ); //- PHY0.CON24[0]=1
+ Outp32( 0x10C10000+0x0064, 0x1 ); //- PHY0.CON24[0]=1
+ } else {
+ Outp32( 0x10030A20, 0x00000000 ); //- LPDDR3PHY_CON3[31]=0.
+ Outp32( 0x10C00000+0x0064, 0x0 ); //- PHY0.CON24[0]=0
+ Outp32( 0x10C10000+0x0064, 0x0 ); //- PHY0.CON24[0]=0
+ }
+ //-4) Set PHY for DQS pull-down mode
+ Outp32( 0x10C00000+0x0038, 0x0F ); //- PHY0.CON14.ctrl_pulld_dq=0x0, ctrl_pulld_dqs=0x0F
+ Outp32( 0x10C10000+0x0038, 0x0F ); //- PHY1.CON14.ctrl_pulld_dq=0x0, ctrl_pulld_dqs=0x0F
+ //-5) Set PHY_CON42.ctrl_bstlen and PHY_CON42.ctrl_rdlat
+ Outp32( 0x10C00000+0x00ac, 0x80C ); //- PHY0.CON42.ctrl_bstlen[12:8]=0x8, ctrl_rdlat[4:0]=0x0C
+ Outp32( 0x10C10000+0x00ac, 0x80C ); //- PHY1.CON42.ctrl_bstlen[12:8]=0x8, ctrl_rdlat[4:0]=0x0C
+ Outp32( 0x10C00000+0x006C, 0x7107F ); //- PHY0.CON26.T_wrdata_en[20:16]=0x7
+ Outp32( 0x10C10000+0x006C, 0x7107F ); //- PHY1.CON26.T_wrdata_en[20:16]=0x7
+ Outp32( 0x10C00000+0x0000, 0x17021A00 ); //- Set PHY0.PHY_CON0.ctrl_read_disable=0x0
+ Outp32( 0x10C00000+0x0040, 0x8080304 ); //- Set PHY0.PHY_CON16.zq_term.
+ Outp32( 0x10C10000+0x0000, 0x17021A00 ); //- Set PHY1.PHY_CON0.ctrl_read_disable=0x0
+ Outp32( 0x10C10000+0x0040, 0x8080304 ); //- Set PHY1.PHY_CON16.zq_term.
+ Outp32( 0x10030B00, 0x1 ); //- Set 0x1003_0B00[0]=0x1
+ //-6) ZQ calibration
+ if (pkg_type == POP_TYPE) {
+ Outp32( 0x10C00000+0x0040, 0xE0C0304 ); //- Set PHY0.CON16.zq_mode_dds=0x6000000
+ Outp32( 0x10C00000+0x0040, 0xE0C0304 ); //- Set PHY0.CON16.zq_manual_mode=1
+ Outp32( 0x10C00000+0x0040, 0xE0C0306 ); //- Set PHY0.CON16.zq_manual_str
+ while( ( Inp32( 0x10C00000+0x0048 ) & 0x1 ) != 0x1 ); //- Wait for PHY0.CON17.zq_done
+ Outp32( 0x10C00000+0x0040, 0xE080304 ); //- Set PHY0.CON16.zq_clk_en=0
+ Outp32( 0x10C10000+0x0040, 0xE0C0304 ); //- Set PHY1.CON16.zq_mode_dds=0x6000000
+ Outp32( 0x10C10000+0x0040, 0xE0C0304 ); //- Set PHY1.CON16.zq_manual_mode=1
+ Outp32( 0x10C10000+0x0040, 0xE0C0306 ); //- Set PHY1.CON16.zq_manual_str
+ while( ( Inp32( 0x10C10000+0x0048 ) & 0x1 ) != 0x1 ); //- Wait for PHY1.CON17.zq_done
+ Outp32( 0x10C10000+0x0040, 0xE080304 ); //- Set PHY1.CON16.zq_clk_en=0
+ Outp32( 0x10C00000+0x00A0, 0xDB6 ); //- PHY0.CON39[11:0]=0xDB6
+ Outp32( 0x10C10000+0x00A0, 0xDB6 ); //- PHY1.CON39[11:0]=0xDB6
+ } else {
+ DMC_ZqInit(0x4, 0x4, 0x4, 0x4, 0x4);
+ }
+
+ //-7) Set CONCONTROL. At this moment, assert the dfi_init_start field to high.
+ Outp32( 0x10DD0000+0x0000, 0xFFF2100 ); //- rdfetch=0x2
+ Outp32( 0x10DD0000+0x0000, 0x1FFF2100 ); //- assert dfi_init_start
+ DMC_Delay(0x10000); //- wait 100ms
+ Outp32( 0x10DD0000+0x0000, 0xFFF2100 ); //- deassert dfi_init_start
+ //-
+ //-PHASE 2 : Setting Controller Register
+ //-
+ //-8) Set MEMCONTROL. At this moment, switch OFF all low power feature.
+ Outp32( 0x10DD0000+0x0004, 0x312700 ); //- memcontrol
+ //-9) Set the MEMBASECONFIG0 register.
+ //- If there are two external memory chips set the MEMBASECONFIG1 register.
+ Outp32( 0x10DD0000+0x010C, 0x4007C0 ); //- chipbase0=0x40, mask=0x7C0
+ Outp32( 0x10DD0000+0x0110, 0x8007C0 ); //- chipbase1=0x80, mask=0x7C0
+ Outp32( 0x10DD0000+0x0008, 0x1323 ); //- memconfig0
+ Outp32( 0x10DD0000+0x000C, 0x1323 ); //- memconfig1
+ //-10) Set the PRECHCONFIG register
+ Outp32( 0x10DD0000+0x0014, 0xFF000000 ); //- DMC.PRECHCONFIG[15:0]=(0x0|0x0)
+ //-11) Set the TIMINGAREF, TIMINGROW, TIMINGDATA, and TIMINGPOWER registers
+ //- according to memory AC parameters.
+ Outp32( 0x10DD0000+0x00F0, 0x7 ); //- iv_size=0x7
+ Outp32( 0x10DD0000+0x0030, 0x5D ); //- tREFI=0x5D
+ Outp32( 0x10DD0000+0x0034, 0x34498692 ); //- DMC.TIMINGROW=0x34498692
+ Outp32( 0x10DD0000+0x0038, 0x3630560C ); //- DMC.TIMINGDATA=0x3630560C
+ Outp32( 0x10DD0000+0x003C, 0x50380336 ); //- DMC.TIMINGPOWER=0x50380336
+ Outp32( 0x10DD0000+0x0004, 0x312700 ); //-
+ //-12) Set the QOSCONTROL0~15 and BRBQOSCONFIG register if Qos Scheme is required.
+ Outp32( 0x10DD0000+0x60, 0xFFF ); //- QOS#0.=0xFFF
+ Outp32( 0x10DD0000+0x68, 0xFFF ); //- QOS#1.=0xFFF
+ Outp32( 0x10DD0000+0x70, 0xFFF ); //- QOS#2.=0xFFF
+ Outp32( 0x10DD0000+0x78, 0xFFF ); //- QOS#3.=0xFFF
+ Outp32( 0x10DD0000+0x80, 0xFFF ); //- QOS#4.=0xFFF
+ Outp32( 0x10DD0000+0x88, 0xFFF ); //- QOS#5.=0xFFF
+ Outp32( 0x10DD0000+0x90, 0xFFF ); //- QOS#6.=0xFFF
+ Outp32( 0x10DD0000+0x98, 0xFFF ); //- QOS#7.=0xFFF
+ Outp32( 0x10DD0000+0xA0, 0xFFF ); //- QOS#8.=0xFFF
+ Outp32( 0x10DD0000+0xA8, 0xFFF ); //- QOS#9.=0xFFF
+ Outp32( 0x10DD0000+0xB0, 0xFFF ); //- QOS#10.=0xFFF
+ Outp32( 0x10DD0000+0xB8, 0xFFF ); //- QOS#11.=0xFFF
+ Outp32( 0x10DD0000+0xC0, 0xFFF ); //- QOS#12.=0xFFF
+ Outp32( 0x10DD0000+0xC8, 0xFFF ); //- QOS#13.=0xFFF
+ Outp32( 0x10DD0000+0xD0, 0xFFF ); //- QOS#14.=0xFFF
+ Outp32( 0x10DD0000+0xD8, 0x0 ); //- QOS#15.=0xFFF
+ //-13) Set the PHY_CON4.ctrl_offsetr0~3 and PHY_CON6.ctrl_offsetw0~3 to 0x7F.
+ Outp32( 0x10C00000+0x0010, 0x7F7F7F7F ); //- offsetr=0:0x7F, 1:0x7F, 2:0x7F, 3:0x7F
+ Outp32( 0x10C10000+0x0010, 0x7F7F7F7F ); //- offsetr=0:0x7F, 1:0x7F, 2:0x7F, 3:0x7F
+ Outp32( 0x10C00000+0x0018, 0x7F7F7F7F ); //- offsetw=0:0x7F, 1:0x7F, 2:0x7F, 3:0x7F
+ Outp32( 0x10C10000+0x0018, 0x7F7F7F7F ); //- offsetw=0:0x7F, 1:0x7F, 2:0x7F, 3:0x7F
+ //-14) Set the PHY_CON4.ctrl_offsetd value to 0x7F.
+ Outp32( 0x10C00000+0x0028, 0x7F ); //- offsetd=0x7F
+ Outp32( 0x10C10000+0x0028, 0x7F ); //- offsetd=0x7F
+ //-15)
+ //-16)
+ Outp32( 0x10C00000+0x0030, 0x10107F70 ); //- lock forcing=0x7F
+ Outp32( 0x10C10000+0x0030, 0x10107F70 ); //- lock forcing=0x7F
+ Outp32( 0x10C00000+0x0030, 0x10107F50 ); //- disable ctrl_dll_on
+ Outp32( 0x10C10000+0x0030, 0x10107F50 ); //- disable ctrl_dll_on
+ DMC_Delay(0x100); //- wait 1ms
+ //-18) Update the DLL information.
+ Outp32( 0x10DD0000+0x0018, 0x8 ); //- fp_resync=1
+ Outp32( 0x10DD0000+0x0018, 0x0 ); //- fp_resync=0
+ //-
+ //-PHASE 3 : Memory Initialization
+ //-
+ //-18)~26)
+ Outp32( 0x10DD0000+0x0010, 0x7000000 ); //- port:0x0, cs:0x0 nop command
+ DMC_Delay(0x100); //- wait 1ms
+ Outp32( 0x10DD0000+0x0010, 0x71C00 ); //- port:0x0, cs:0x0 mr63 command
+ DMC_Delay(0x10000); //- wait 100ms
+ Outp32( 0x10DD0000+0x0010, 0x10BFC ); //- port:0x0, cs:0x0 mr10 command
+ DMC_Delay(0x100); //- wait 1ms
+ Outp32( 0x10DD0000+0x0010, 0x50C ); //- port:0x0, cs:0x0 mr1 command
+ DMC_Delay(0x100); //- wait 1ms
+ Outp32( 0x10DD0000+0x0010, 0x868 ); //- port:0x0, cs:0x0 mr2 command
+ DMC_Delay(0x100); //- wait 1ms
+ Outp32( 0x10DD0000+0x0010, 0xC04 ); //- port:0x0, cs:0x0 mr3 command
+ DMC_Delay(0x100); //- wait 1ms
+ Outp32( 0x10DD0000+0x0010, 0x7100000 ); //- port:0x0, cs:0x1 nop command
+ DMC_Delay(0x100); //- wait 1ms
+ Outp32( 0x10DD0000+0x0010, 0x171C00 ); //- port:0x0, cs:0x1 mr63 command
+ DMC_Delay(0x10000); //- wait 100ms
+ Outp32( 0x10DD0000+0x0010, 0x110BFC ); //- port:0x0, cs:0x1 mr10 command
+ DMC_Delay(0x100); //- wait 1ms
+ Outp32( 0x10DD0000+0x0010, 0x10050C ); //- port:0x0, cs:0x1 mr1 command
+ DMC_Delay(0x100); //- wait 1ms
+ Outp32( 0x10DD0000+0x0010, 0x100868 ); //- port:0x0, cs:0x1 mr2 command
+ DMC_Delay(0x100); //- wait 1ms
+ Outp32( 0x10DD0000+0x0010, 0x100C04 ); //- port:0x0, cs:0x1 mr3 command
+ DMC_Delay(0x100); //- wait 1ms
+ Outp32( 0x10DD0000+0x0010, 0x17000000 ); //- port:0x1, cs:0x0 nop command
+ DMC_Delay(0x100); //- wait 1ms
+ Outp32( 0x10DD0000+0x0010, 0x10071C00 ); //- port:0x1, cs:0x0 mr63 command
+ DMC_Delay(0x10000); //- wait 100ms
+ Outp32( 0x10DD0000+0x0010, 0x10010BFC ); //- port:0x1, cs:0x0 mr10 command
+ DMC_Delay(0x100); //- wait 1ms
+ Outp32( 0x10DD0000+0x0010, 0x1000050C ); //- port:0x1, cs:0x0 mr1 command
+ DMC_Delay(0x100); //- wait 1ms
+ Outp32( 0x10DD0000+0x0010, 0x10000868 ); //- port:0x1, cs:0x0 mr2 command
+ DMC_Delay(0x100); //- wait 1ms
+ Outp32( 0x10DD0000+0x0010, 0x10000C04 ); //- port:0x1, cs:0x0 mr3 command
+ DMC_Delay(0x100); //- wait 1ms
+ Outp32( 0x10DD0000+0x0010, 0x17100000 ); //- port:0x1, cs:0x1 nop command
+ DMC_Delay(0x100); //- wait 1ms
+ Outp32( 0x10DD0000+0x0010, 0x10171C00 ); //- port:0x1, cs:0x1 mr63 command
+ DMC_Delay(0x10000); //- wait 100ms
+ Outp32( 0x10DD0000+0x0010, 0x10110BFC ); //- port:0x1, cs:0x1 mr10 command
+ DMC_Delay(0x100); //- wait 1ms
+ Outp32( 0x10DD0000+0x0010, 0x1010050C ); //- port:0x1, cs:0x1 mr1 command
+ DMC_Delay(0x100); //- wait 1ms
+ Outp32( 0x10DD0000+0x0010, 0x10100868 ); //- port:0x1, cs:0x1 mr2 command
+ DMC_Delay(0x100); //- wait 1ms
+ Outp32( 0x10DD0000+0x0010, 0x10100C04 ); //- port:0x1, cs:0x1 mr3 command
+ DMC_Delay(0x100); //- wait 1ms
+ //-27) Return to the memory operating frequency.
+ CMU_SetMemClk(800);
+
+ //-28) Set the PHY_CON4.ctrl_offsetr0~3 and PHY_CON6.ctrl_offsetw0~3 to 0x8.
+ Outp32( 0x10C00000+0x0010, 0x8080808 ); //- offsetr=0:0x08, 1:0x08, 2:0x08, 3:0x08
+ Outp32( 0x10C10000+0x0010, 0x8080808 ); //- offsetr=0:0x08, 1:0x08, 2:0x08, 3:0x08
+ Outp32( 0x10C00000+0x0018, 0x8080808 ); //- offsetw=0:0x08, 1:0x08, 2:0x08, 3:0x08
+ Outp32( 0x10C10000+0x0018, 0x8080808 ); //- offsetw=0:0x08, 1:0x08, 2:0x08, 3:0x08
+ //-29) Set the PHY_CON4.ctrl_offsetd value to 0x8.
+ Outp32( 0x10C00000+0x0028, 0x8 ); //- offsetd=0x08
+ Outp32( 0x10C10000+0x0028, 0x8 ); //- offsetd=0x08
+ //-30)~34)
+ Outp32( 0x10C00000+0x0030, 0x10107F70 ); //- ctrl_dll_on[5] = 1
+ DMC_Delay(0x100); //- wait 1ms
+ Outp32( 0x10C00000+0x0030, 0x10107F30 ); //- ctrl_start[6] = 0
+ Outp32( 0x10C00000+0x0030, 0x10107F70 ); //- ctrl_start[6] = 1
+ DMC_Delay(0x100); //- wait 1ms
+ Outp32( 0x10C10000+0x0030, 0x10107F70 ); //- ctrl_dll_on[5] = 1
+ DMC_Delay(0x100); //- wait 1ms
+ Outp32( 0x10C10000+0x0030, 0x10107F30 ); //- ctrl_start[6] = 0
+ Outp32( 0x10C10000+0x0030, 0x10107F70 ); //- ctrl_start[6] = 1
+ DMC_Delay(0x100); //- wait 1ms
+ //-35)~36)
+ Outp32( 0x10DD0000+0x0000, 0x1FFF2100 ); //- assert dfi_init_start
+ while( ( Inp32( 0x10DD0000+0x0040 ) & 0xC ) != 0xC ); //- Wait for DMC.dfi_init_complete_ch0/1
+ Outp32( 0x10DD0000+0x0000, 0xFFF2100 ); //- deassert dfi_init_start
+ //-37) Update the DLL information.
+ Outp32( 0x10DD0000+0x0018, 0x8 ); //- fp_resync=1
+ Outp32( 0x10DD0000+0x0018, 0x0 ); //- fp_resync=0
+
+#if defined(CONFIG_DMC_CALIBRATION)
+ //-38) Do leveing and calibration
+ //-39) Perform these steps
+ //- - a. Update PHYCON12.ctrl_force with by using PHY_CON13.ctrl_lock_value[9:2]
+ lock = (Inp32(0x10c00034) >> 8) & 0xFF;
+ if((lock & 0x3) == 0x3) {
+ lock++;
+ }
+
+ temp = Inp32(0x10c00030) & 0xFFFF80FF;
+ temp |= ((lock >> 2) << 8);
+ Outp32( 0x10c00000 + 0x0030, temp);
+
+ lock = (Inp32(0x10c10034) >> 8) & 0xFF;
+ if((lock & 0x3) == 0x3) {
+ lock++;
+ }
+
+ temp = Inp32(0x10c10030) & 0xFFFF80FF;
+ temp |= ((lock >> 2) << 8);
+ Outp32( 0x10c10000 + 0x0030, temp);
+
+ //- - b. Enable PHY_CON0.ctrl_atgate
+ Outp32( 0x10C00000+0x0000, 0x17021A40 ); //- PHY0.CON0.ctrl_atgate=1.
+ Outp32( 0x10C10000+0x0000, 0x17021A40 ); //- PHY1.CON0.ctrl_atgate=1.
+ //- - d. Enable PHY_CON0.p0_cmd_en
+ Outp32( 0x10C00000+0x0000, 0x17025A40 ); //- PHY0.CON0.p0_cmd_en=1.
+ Outp32( 0x10C10000+0x0000, 0x17025A40 ); //- PHY1.CON0.p0_cmd_en=1.
+ //- - e. Enable PHY_CON2.InitDeskewEn
+ Outp32( 0x10C00000+0x0008, 0x10044 ); //- PHY0.CON2.InitDeskewEn=1.
+ Outp32( 0x10C10000+0x0008, 0x10044 ); //- PHY1.CON2.InitDeskewEn=1.
+ //- - f. Enable PHY_CON0.byte_rdlvl_en
+ Outp32( 0x10C00000+0x0000, 0x17027A40 ); //-
+ Outp32( 0x10C10000+0x0000, 0x17027A40 ); //-
+
+ //- - c. Disable PHY_CON12.ctrl_dll_on
+ temp = Inp32(0x10c00030) & 0xFFFFFFDF;
+ Outp32( 0x10c00030, temp );
+ temp = Inp32(0x10c10030) & 0xFFFFFFDF;
+ Outp32( 0x10c10030, temp );
+ DMC_Delay(0x100); //- wait 1ms
+
+ //-CA Training.
+ DMC_CaTraining(0);
+ DMC_CaTraining(1);
+
+ if (pkg_type == POP_TYPE) {
+ //-Read DQ Calibration.
+ Outp32( 0x10C00000+0x0004, 0x92F0001 ); //- Set PHY0.CON1.rdlvl_rddata_adj
+ Outp32( 0x10C10000+0x0004, 0x92F0001 ); //- Set PHY1.CON1.rdlvl_rddata_adj
+ Outp32( 0x10C00000+0x005C, 0x00000041 ); //- PHY0.CON22.lpddr2_addr=0x041
+ Outp32( 0x10C10000+0x005C, 0x00000041 ); //- PHY1.CON22.lpddr2_addr=0x041
+ Outp32( 0x10C00000+0x0008, 0x2010044 ); //- Set PHY0.CON2.rdlvl_en
+ Outp32( 0x10C10000+0x0008, 0x2010044 ); //- Set PHY1.CON2.rdlvl_en
+ Outp32( 0x10DD0000+0x00F8, 0x2 ); //- DMC.RDLVLCONFIG.ctrl_rdlvl_data_en=1
+ while( ( Inp32( 0x10DD0000+0x0040 ) & 0xC000 ) != 0xC000 ); //- Wait DMC.rdlvl_complete_ch0/1
+ Outp32( 0x10DD0000+0x00F8, 0x0 ); //- Set DMC.RDLVLCONFIG.ctrl_rdlvl_data_en=0
+
+ Outp32(0x10C00000 + 0x0014, 0xC);
+ while( Inp32(0x10C00000 + 0x0058) != 0);
+
+ Outp32(0x10C10000 + 0x0014, 0xC);
+ while( Inp32(0x10C00000 + 0x0058) != 0);
+
+ Outp32(0x10C00000 + 0x0014, 0x0);
+ Outp32(0x10C10000 + 0x0014, 0x0);
+
+ //-Write DQ Calibration.
+ while( ( Inp32( 0x10DD0000+0x0048 ) & 0x3 ) != 0x0 ); //- Wait for DMC.chip_busy_state CH0
+ while( ( Inp32( 0x10DD0000+0x004C ) & 0x3 ) != 0x0 ); //- Wait for DMC.chip_busy_state CH1
+ Outp32( 0x10DD0000+0x00F4, 0x1 ); //- DMC.WRTRACONFIG
+ Outp32( 0x10C00000+0x005C, 0x204 ); //-
+ Outp32( 0x10C10000+0x005C, 0x204 ); //-
+ Outp32( 0x10C00000+0x0004, 0x92F00FF ); //-Set "rdlvl_rddata_adj" to 0x0001 or 0x0100 in PHY_CON1[15:0]
+ Outp32( 0x10C10000+0x0004, 0x92F00FF ); //-Set "rdlvl_rddata_adj" to 0x0001 or 0x0100 in PHY_CON1[15:0]
+ Outp32( 0x10C00000+0x0008, 0x6010044 ); //-
+ Outp32( 0x10C10000+0x0008, 0x6010044 ); //-
+ Outp32( 0x10C00000+0x0008, 0xE010044 ); //-
+ Outp32( 0x10C10000+0x0008, 0xE010044 ); //-
+ while( ( Inp32( 0x10DD0000+0x0040 ) & 0xC000 ) != 0xC000 ); //- Wait DMC.rdlvl_complete_ch0/1
+ Outp32( 0x10C00000+0x0008, 0x6010044 ); //-
+ Outp32( 0x10C10000+0x0008, 0x6010044 ); //-
+
+ Outp32(0x10C00000 + 0x0014, 0xC);
+ while( Inp32(0x10C00000 + 0x0058) != 0);
+
+ Outp32(0x10C10000 + 0x0014, 0xC);
+ while( Inp32(0x10C10000 + 0x0058) != 0);
+
+ Outp32(0x10C00000 + 0x0014, 0x0);
+ Outp32(0x10C10000 + 0x0014, 0x0);
+ }
+
+ //-43) Enable PHY_CON12.ctrl_dll_on
+ temp = Inp32( 0x10c00030) | 0x20;
+ Outp32( 0x10c00030, temp );
+ //while( ( Inp32(0x10c00030) & 0x1 ) != 0x1 );
+
+ temp = Inp32( 0x10c10030) | 0x20;
+ Outp32( 0x10c10030, temp );
+ //while( ( Inp32(0x10c10030) & 0x1 ) != 0x1 );
+
+ //-44) Disable PHY_CON.ctrl_atgate when POP is used
+ if (pkg_type == POP_TYPE) {
+ Outp32( 0x10C00000+0x0000, 0x17027A00 ); //- PHY0.CON0.ctrl_atgate=0x0
+ Outp32( 0x10C10000+0x0000, 0x17027A00 ); //- PHY1.CON0.ctrl_atgate=0x0
+ }
+ Outp32( 0x10C00000+0x0000, 0x17127A00 ); //- Set PHY0.CON0.ctrl_upd_range=0x1
+ Outp32( 0x10C10000+0x0000, 0x17127A00 ); //- Set PHY1.CON0.ctrl_upd_range=0x1
+
+ //-45) Enable PHY_CON2.DLLDeSkewEn
+ if (pkg_type == POP_TYPE) {
+ Outp32( 0x10C00000+0x0008, 0x6011044 ); //- PHY0.CON2.DllDeskewEn=1.
+ Outp32( 0x10C10000+0x0008, 0x6011044 ); //- PHY1.CON2.DllDeskewEn=1.
+ } else {
+ Outp32( 0x10C00000+0x0008, 0x11044 ); //- PHY0.CON2.DllDeskewEn=1.
+ Outp32( 0x10C10000+0x0008, 0x11044 ); //- PHY1.CON2.DllDeskewEn=1.
+ }
+ //-46) Update the DLL information
+ Outp32( 0x10DD0000+0x0018, 0x8 ); //- fp_resync=1
+ Outp32( 0x10DD0000+0x0018, 0x0 ); //- fp_resync=0
+#endif
+
+ //-47) ODT is not supported in LPDDR2/LPDDR3
+ if (pkg_type == POP_TYPE) {
+ Outp32( 0x10C00000+0x0000, 0x17127A00 ); //- Set PHY0.PHY_CON0.ctrl_read_disable=0x0
+ Outp32( 0x10C00000+0x0040, 0xE080304 ); //- Set PHY0.PHY_CON16.zq_term.
+ Outp32( 0x10C10000+0x0000, 0x17127A00 ); //- Set PHY1.PHY_CON0.ctrl_read_disable=0x0
+ Outp32( 0x10C10000+0x0040, 0xE080304 ); //- Set PHY1.PHY_CON16.zq_term.
+ }
+
+ //-48) Issue the PALL command to memory
+ Outp32( 0x10DD0000+0x0010, 0x1000000 ); //- send PALL to port=0x0, cs=0x0
+ Outp32( 0x10DD0000+0x0010, 0x1100000 ); //- send PALL to port=0x0, cs=0x1
+ Outp32( 0x10DD0000+0x0010, 0x11000000 ); //- send PALL to port=0x1, cs=0x0
+ Outp32( 0x10DD0000+0x0010, 0x11100000 ); //- send PALL to port=0x1, cs=0x1
+ //-49) Set the MEMCONTROL if power-down modes are required.
+ Outp32( 0x10DD0000+0x0004, 0x312700 ); //- DMC.MEMCONTROL.tp_en=0x0.
+ Outp32( 0x10DD0000+0x0014, 0xFF000000 ); //- DMC.PRECHCONFIG.tp_cnt=0xFF
+ Outp32( 0x10DD0000+0x0028, 0xFFFF00FF ); //- DMC.PWRDNCONFIG.dsref_cyc=0xFFFF0000
+ Outp32( 0x10DD0000+0x0004, 0x312720 ); //- Set DMC.MEMCONTROL.dsref_en=0x20.
+ Outp32( 0x10DD0000+0x0028, 0xFFFF00FF ); //- Set DMC.PWRDNCONFIG.dpwrdn_cyc=0xFF
+ Outp32( 0x10DD0000+0x0004, 0x312722 ); //- Set DMC.MEMCONTROL.dpwrdn_en=0x2., dpwrdn_type=0x0
+ Outp32( 0x10DD0000+0x0004, 0x312723 ); //- DMC.MEMCONTROL.clk_stop_en=0x1.
+ Outp32( 0x10DD0000+0x0000, 0xFFF2108 ); //- Set DMC.PHYCONTROL.io_pd_con=0x1.
+ //-50) Set the CONCONTROL to turn on an auto refresh counter.
+ Outp32( 0x10DD0000+0x0000, 0xFFF2128 ); //- aref enabled
+
+ mem_ctrl_init_done();
+
+}
+
+void mem_ctrl_init_ddr3(UINT32 nMEMCLK)
+{
+ UINT32 ap_odt, dram_odt;
+
+#if defined(CONFIG_ODTOFF_GATELEVELINGON)
+ ap_odt = 0xE2C0000;
+ dram_odt = 0x2;
+#else // ODT On and Gate Leveling Off
+ ap_odt = 0xE240000;
+ dram_odt = 0x42;
+#endif
+
+ CMU_SetMemClk(nMEMCLK);
+
+ DMC_Delay(0x10000); // wait 300ms
+ Outp32( 0x10030A10, 0x00000000 ); //- PHY_RESET[0]=0
+ DMC_Delay(100);
+ Outp32( 0x10030A10, 0x00000001 ); //- PHY_RESET[0]=1
+ DMC_Delay(100);
+ Outp32( 0x10C00000+0x00a0, 0x000006db ); //- dds of CA = 0x3
+ Outp32( 0x10C10000+0x00a0, 0x000006db ); //- dds of CA = 0x3
+ Outp32( 0x10C00000+0x00ac, 0x0000080b ); //- ctrl_bstlen[12:8]=8, ctrl_rdlat[4:0]=11
+ Outp32( 0x10C10000+0x00ac, 0x0000080b ); //- ctrl_bstlen[12:8]=8, ctrl_rdlat[4:0]=11
+ Outp32( 0x10C00000+0x0040, ap_odt|0x0304 ); //- zq_mode_dds[26:24], zq_mode_term[23:21], zq_clk_div_en[18]=1
+ Outp32( 0x10C10000+0x0040, ap_odt|0x0304 ); //- zq_mode_dds[26:24], zq_mode_term[23:21], zq_clk_div_en[18]=1
+ Outp32( 0x10C00000+0x0040, ap_odt|0x0304 ); //- zq_mode_dds[26:24], zq_mode_term[23:21], zq_mode_noterm[19]=0
+ Outp32( 0x10C10000+0x0040, ap_odt|0x0304 ); //- zq_mode_dds[26:24], zq_mode_term[23:21], zq_mode_noterm[19]=0
+ Outp32( 0x10C00000+0x0040, ap_odt|0x0306 ); //- zq_mode_dds[26:24], zq_mode_term[23:21], zq_manual_start[1]=1
+ Outp32( 0x10C10000+0x0040, ap_odt|0x0306 ); //- zq_mode_dds[26:24], zq_mode_term[23:21], zq_manual_start[1]=1
+ while( ( Inp32( 0x10C00000+0x0048 ) & 0x1 ) != 0x1 ); //- PHY0: wait for zq_done
+ while( ( Inp32( 0x10C10000+0x0048 ) & 0x1 ) != 0x1 ); //- PHY1: wait for zq_done
+ Outp32( 0x10C00000+0x0040, ap_odt|0x0304 ); //- zq_mode_dds[26:24], zq_mode_term[23:21], zq_manual_start[1]=0
+ Outp32( 0x10C10000+0x0040, ap_odt|0x0304 ); //- zq_mode_dds[26:24], zq_mode_term[23:21], zq_manual_start[1]=0
+ Outp32( 0x10C00000+0x0038, 0x0000000f ); //- ctrl_pulld_dq[11:8]=0xf, ctrl_pulld_dqs[3:0]=0xf
+ Outp32( 0x10C10000+0x0038, 0x0000000f ); //- ctrl_pulld_dq[11:8]=0xf, ctrl_pulld_dqs[3:0]=0xf
+ Outp32( 0x10DD0000+0x0000, 0x1FFF0000|(0x3<<12) ); //- dfi_init_start[28]=1, rd_fetch[14:12]=3
+ Outp32( 0x10DD0000+0x0018, 0xe0000008 ); //- mem_term_en[31]=1, phy_term_en[30]=1, gate signal length[29]=1, fp_resync[3]=1
+ Outp32( 0x10DD0000+0x0018, 0xe0000000 ); //- mem_term_en[31]=1, phy_term_en[30]=1, gate signal length[29]=1, fp_resync[3]=0
+ Outp32( 0x10C00000+0x0010, 0x8080808 ); //- ctrl_offsetr
+ Outp32( 0x10C10000+0x0010, 0x8080808 ); //- ctrl_offsetr
+ Outp32( 0x10C00000+0x0018, 0x8080808 ); //- ctrl_offsetw
+ Outp32( 0x10C10000+0x0018, 0x8080808 ); //- ctrl_offsetw
+ Outp32( 0x10C00000+0x0028, 0x8 ); //- ctrl_offsetd[7:0]=0x8
+ Outp32( 0x10C10000+0x0028, 0x8 ); //- ctrl_offsetd[7:0]=0x8
+ Outp32( 0x10C00000+0x0030, 0x10100030 ); //- ctrl_force[14:8]=0x0, ctrl_start[6]=0, ctrl_dll_on[5]=1
+ Outp32( 0x10C10000+0x0030, 0x10100030 ); //- ctrl_force[14:8]=0x0, ctrl_start[6]=0, ctrl_dll_on[5]=1
+ DMC_Delay(100);
+ Outp32( 0x10C00000+0x0030, 0x10100070 ); //- ctrl_dll_start[6]=1
+ Outp32( 0x10C10000+0x0030, 0x10100070 ); //- ctrl_dll_start[6]=1
+ DMC_Delay(100);
+ while( ( Inp32( 0x10DD0000+0x0040 ) & 0xC ) != 0xC ); //- wait dfi_init_complete
+ Outp32( 0x10DD0000+0x0018, 0xe0000008 ); //- mem_term_en[31]=1, phy_term_en[30]=1, gate signal length[29]=1, fp_resync[3]=1
+ Outp32( 0x10DD0000+0x0018, 0xe0000000 ); //- mem_term_en[31]=1, phy_term_en[30]=1, gate signal length[29]=1, fp_resync[3]=0
+ Outp32( 0x10DD0000+0x0018, 0xe0000008 ); //- mem_term_en[31]=1, phy_term_en[30]=1, gate signal length[29]=1, fp_resync[3]=1
+ Outp32( 0x10DD0000+0x0018, 0xe0000000 ); //- mem_term_en[31]=1, phy_term_en[30]=1, gate signal length[29]=1, fp_resync[3]=0
+ Outp32( 0x10DD0000+0x0000, 0x0FFF0000|(0x3<<12) ); //- dfi_init_start[28]=0, rd_fetch[14:12]=3
+ Outp32( 0x10DD0000+0x00F0, 0x7 ); //- channel interleaving
+ Outp32( 0x10DD0000+0x0008, 0x00001333 ); //- bank interleaving
+ Outp32( 0x10DD0000+0x000C, 0x00001333 ); //- bank interleaving
+ Outp32( 0x10DD0000+0x010C, 0x00400780 ); //- chip_base[26:16]=40, chip_mask[10:0]=780
+ Outp32( 0x10DD0000+0x0110, 0x00800780 ); //- chip_base[26:16]=80, chip_mask[10:0]=780
+ Outp32( 0x10DD0000+0x0014, 0xFF000000 ); //- precharge policy counter
+ Outp32( 0x10DD0000+0x0028, 0xFFFF00FF ); //- low power counter
+ Outp32( 0x10DD0000+0x0030, 0x000000bb ); //- refresh counter
+ Outp32( 0x10DD0000+0x0034, 0x8C36650E ); //- timing row
+ Outp32( 0x10DD0000+0x0038, 0x3630580B ); //- timing data
+ Outp32( 0x10DD0000+0x003C, 0x41000A44 ); //- timing power
+ // Set the QOSCONTROL0~15 and BRBQOSCONFIG register if Qos Scheme is required.
+ Outp32( 0x10DD0000+0x60, 0xFFF ); //- QOS#0.=0xFFF
+ Outp32( 0x10DD0000+0x68, 0xFFF ); //- QOS#1.=0xFFF
+ Outp32( 0x10DD0000+0x70, 0xFFF ); //- QOS#2.=0xFFF
+ Outp32( 0x10DD0000+0x78, 0xFFF ); //- QOS#3.=0xFFF
+ Outp32( 0x10DD0000+0x80, 0xFFF ); //- QOS#4.=0xFFF
+ Outp32( 0x10DD0000+0x88, 0xFFF ); //- QOS#5.=0xFFF
+ Outp32( 0x10DD0000+0x90, 0xFFF ); //- QOS#6.=0xFFF
+ Outp32( 0x10DD0000+0x98, 0xFFF ); //- QOS#7.=0xFFF
+ Outp32( 0x10DD0000+0xA0, 0xFFF ); //- QOS#8.=0xFFF
+ Outp32( 0x10DD0000+0xA8, 0xFFF ); //- QOS#9.=0xFFF
+ Outp32( 0x10DD0000+0xB0, 0xFFF ); //- QOS#10.=0xFFF
+ Outp32( 0x10DD0000+0xB8, 0xFFF ); //- QOS#11.=0xFFF
+ Outp32( 0x10DD0000+0xC0, 0xFFF ); //- QOS#12.=0xFFF
+ Outp32( 0x10DD0000+0xC8, 0xFFF ); //- QOS#13.=0xFFF
+ Outp32( 0x10DD0000+0xD0, 0xFFF ); //- QOS#14.=0xFFF
+ Outp32( 0x10DD0000+0xD8, 0x0 ); //- QOS#15.=0xFFF
+ Outp32( 0x10DD0000+0x0010, 0x01000000 ); //- Issue PALL
+ Outp32( 0x10DD0000+0x0010, 0x01100000 ); //- Issue PALL
+ Outp32( 0x10DD0000+0x0010, 0x11000000 ); //- Issue PALL
+ Outp32( 0x10DD0000+0x0010, 0x11100000 ); //- Issue PALL
+ Outp32( 0x10DD0000+0x0010, 0x07000000 );
+ Outp32( 0x10DD0000+0x0010, 0x00020000|0x18 );
+ Outp32( 0x10DD0000+0x0010, 0x00030000 );
+ Outp32( 0x10DD0000+0x0010, 0x00010000|dram_odt );
+ Outp32( 0x10DD0000+0x0010, 0x00000000|0xD70 );
+ Outp32( 0x10DD0000+0x0010, 0x0a000000 ); //- ZQInit
+ Outp32( 0x10DD0000+0x0010, 0x17000000 );
+ Outp32( 0x10DD0000+0x0010, 0x10020000|0x18 );
+ Outp32( 0x10DD0000+0x0010, 0x10030000 );
+ Outp32( 0x10DD0000+0x0010, 0x10010000|dram_odt );
+ Outp32( 0x10DD0000+0x0010, 0x10000000|0xD70 );
+ Outp32( 0x10DD0000+0x0010, 0x1a000000 ); //- ZQInit
+
+#if defined(CONFIG_ODTOFF_GATELEVELINGON)
+ Outp32( 0x10C00000+0x0000, 386009664 ); // ctrl_atgate=1
+ Outp32( 0x10C10000+0x0000, 386009664 ); // ctrl_atgate=1
+ Outp32( 0x10C00000+0x0000, 386026048 ); // p0_cmd_en=1
+ Outp32( 0x10C10000+0x0000, 386026048 ); // p0_cmd_en=1
+ Outp32( 0x10C00000+0x0008, 65604 ); // InitDeskewEn=1
+ Outp32( 0x10C10000+0x0008, 65604 ); // InitDeskewEn=1
+ Outp32( 0x10C00000+0x0000, 386034240 ); // byte_rdlvl_en=1
+ Outp32( 0x10C10000+0x0000, 386034240 ); // byte_rdlvl_en=1
+ Outp32( 0x10C00000+0x0030, 0x10100050+0x1900 ); //- ctrl_force[14:8], ctrl_dll_on[5]=0
+ Outp32( 0x10C10000+0x0030, 0x10100050+0x1900 ); //- ctrl_force[14:8], ctrl_dll_on[5]=0
+ Outp32( 0x10C00000+0x0008, 16842820 ); // rdlvl_gate_en=1
+ Outp32( 0x10C10000+0x0008, 16842820 ); // rdlvl_gate_en=1
+ Outp32( 0x10C00000+0x0000, 386034496 ); // ctrl_shgate=1
+ Outp32( 0x10C10000+0x0000, 386034496 ); // ctrl_shgate=1
+ Outp32( 0x10C00000+0x0004, 0x9010100 ); // ctrl_gateduradj=0
+ Outp32( 0x10C10000+0x0004, 0x9010100 ); // ctrl_gateduradj=0
+ Outp32( 0x10DD0000+0x00f8, 0x00000001 ); //- ctrl_rdlvl_data_en[1]=1
+ while( ( Inp32( 0x10DD0000+0x0040 ) & 0xC000 ) != 0xC000 ); //- Rdlvl_complete_ch1[15]=1, Rdlvl_complete_ch0[14]=1
+ Outp32( 0x10DD0000+0x00f8, 0x00000000 ); //- ctrl_rdlvl_data_en[1]=0
+ Outp32( 0x10C00000+0x0038, 0x00000000 ); //- ctrl_pulld_dq[11:8]=0x0, ctrl_pulld_dqs[3:0]=0x0
+ Outp32( 0x10C10000+0x0038, 0x00000000 ); //- ctrl_pulld_dq[11:8]=0x0, ctrl_pulld_dqs[3:0]=0x0
+ Outp32( 0x10C00000+0x0030, 0x10100070+0x1900 ); //- ctrl_force[14:8], ctrl_start[6]=1, ctrl_dll_on[5]=1
+ Outp32( 0x10C10000+0x0030, 0x10100070+0x1900 ); //- ctrl_force[14:8], ctrl_start[6]=1, ctrl_dll_on[5]=1
+ DMC_Delay(100);
+ Outp32( 0x10DD0000+0x0018, 0xe0000008 ); //- ctrl_shgate[29]=1, fp_resync[3]=1
+ Outp32( 0x10DD0000+0x0018, 0xe0000000 ); //- ctrl_shgate[29]=1, fp_resync[3]=0
+ Outp32( 0x10DD0000+0x0010, 0x01000000 ); //- Issue PALL
+ Outp32( 0x10DD0000+0x0010, 0x01100000 ); //- Issue PALL
+ Outp32( 0x10DD0000+0x0010, 0x11000000 ); //- Issue PALL
+ Outp32( 0x10DD0000+0x0010, 0x11100000 ); //- Issue PALL
+#endif
+ Outp32( 0x10DD0000+0x0004, 0x00302620 ); //- bl[22:20]=8, mem_type[11:8]=7, dsref_en[5]=1, dpwrdn_en[1]=1, clk_stop_en[0]=1
+ Outp32( 0x10DD0000+0x0000, 0x0FFF0020|(0x3<<12) ); //- dfi_init_start[28]=1, rd_fetch[14:12]=3, aref_en[5]=1
+
+ mem_ctrl_init_done();
+}
diff --git a/SamsungPlatformPkg/ArndaleBoardPkg/Library/ArndaleBoardLib/Exynos5250/mem_init_ddr3.S b/SamsungPlatformPkg/ArndaleBoardPkg/Library/ArndaleBoardLib/Exynos5250/mem_init_ddr3.S
new file mode 100755
index 000000000..a86b192e3
--- /dev/null
+++ b/SamsungPlatformPkg/ArndaleBoardPkg/Library/ArndaleBoardLib/Exynos5250/mem_init_ddr3.S
@@ -0,0 +1,412 @@
+/*
+ * (C) Copyright 2012 Samsung Electronics Co. Ltd
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <Platform/ArmPlatform.h>
+#include <Platform/Arndale5250.h>
+#include <Platform/Exynos5250_Evt1.h>
+#include <Platform/Arndale5250_Val.h>
+#include <AutoGen.h>
+
+GCC_ASM_EXPORT(ArmPlatformSecBootMemoryInit)
+GCC_ASM_EXPORT(ArmPlatformClockInitialize)
+GCC_ASM_EXPORT(ArmPlatformTZPCInitialize)
+GCC_ASM_EXPORT(ArmPlatformSecBootAction)
+
+#define MCLK_CDREX_800 1
+#define CONFIG_LOW_POWER_CTRL 1
+@#define CONFIG_DMC_BRB
+#define LPDDR3PHY_CTRL_CON3 0x20A20
+
+ASM_PFX(ArmPlatformSecBootMemoryInit):
+ @push {lr}
+ mov r12, lr
+
+ @Outp32( 0x10030200, 0. ); //- rCLK_SRC_CDREX
+ ldr r0, =0x10030200
+ ldr r1, =0
+ str r1, [r0]
+ @Outp32( 0x10030500, 16777297. ); //- rCLK_DIV_CDREX
+ ldr r0, =0x10030500
+ ldr r1, =16777297
+ str r1, [r0]
+ @Outp32( 0x10014104, 2111488. ); // rMPLL_CON1
+ ldr r0, =0x10014104
+ ldr r1, =2111488
+ str r1, [r0]
+ @Outp32( 0x10014100, 2160591616. ); // rMPLL_CON0
+ ldr r0, =0x10014100
+ ldr r1, =2182417408
+ str r1, [r0]
+@DMC_Delay(0x10000); // wait 300ms
+ bl delay100
+ bl delay100
+ bl delay100
+ @Outp32( 0x10014204, 256. ); //
+ ldr r0, =0x10014204
+ ldr r1, =256
+ str r1, [r0]
+@DMC_Delay(0x10000); // wait 300ms
+ bl delay100
+ bl delay100
+ bl delay100
+ @Outp32( 0x10030A10, 0x00000000 ); //- PHY_RESET[0]=0
+ ldr r0, =0x10030A10
+ ldr r1, =0x00000000
+ str r1, [r0]
+@DMC_Delay(1ms);
+ bl delay
+ @Outp32( 0x10030A10, 0x00000001 ); //- PHY_RESET[0]=1
+ ldr r0, =0x10030A10
+ ldr r1, =0x00000001
+ str r1, [r0]
+@DMC_Delay(1ms);
+ bl delay
+ @Outp32( 0x10C00000+0x00a0, 0x000006db ); //- dds of CA = 0x3
+ ldr r0, =(0x10C00000+0x00a0)
+ ldr r1, =0x000006db
+ str r1, [r0]
+ @Outp32( 0x10C10000+0x00a0, 0x000006db ); //- dds of CA = 0x3
+ ldr r0, =(0x10C10000+0x00a0)
+ ldr r1, =0x000006db
+ str r1, [r0]
+ @Outp32( 0x10C00000+0x00ac, 0x0000080b ); //- ctrl_bstlen[12:8]=8, ctrl_rdlat[4:0]=11
+ ldr r0, =(0x10C00000+0x00ac)
+ ldr r1, =0x0000080b
+ str r1, [r0]
+ @Outp32( 0x10C10000+0x00ac, 0x0000080b ); //- ctrl_bstlen[12:8]=8, ctrl_rdlat[4:0]=11
+ ldr r0, =(0x10C10000+0x00ac)
+ ldr r1, =0x0000080b
+ str r1, [r0]
+ @Outp32( 0x10C00000+0x0040, 0xE240000|0x0304 ); //- zq_mode_dds[26:24], zq_mode_term[23:21], zq_clk_div_en[18]=1
+ ldr r0, =(0x10C00000+0x0040)
+ ldr r1, =(0xE240000|0x0304)
+ str r1, [r0]
+ @Outp32( 0x10C10000+0x0040, 0xE240000|0x0304 ); //- zq_mode_dds[26:24], zq_mode_term[23:21], zq_clk_div_en[18]=1
+ ldr r0, =(0x10C10000+0x0040)
+ ldr r1, =(0xE240000|0x0304)
+ str r1, [r0]
+ @Outp32( 0x10C00000+0x0040, 0xE240000|0x0304 ); //- zq_mode_dds[26:24], zq_mode_term[23:21], zq_mode_noterm[19]=0
+ ldr r0, =(0x10C00000+0x0040)
+ ldr r1, =(0xE240000|0x0304)
+ str r1, [r0]
+ @Outp32( 0x10C10000+0x0040, 0xE240000|0x0304 ); //- zq_mode_dds[26:24], zq_mode_term[23:21], zq_mode_noterm[19]=0
+ ldr r0, =(0x10C10000+0x0040)
+ ldr r1, =(0xE240000|0x0304)
+ str r1, [r0]
+ @Outp32( 0x10C00000+0x0040, 0xE240000|0x0306 ); //- zq_mode_dds[26:24], zq_mode_term[23:21], zq_manual_start[1]=1
+ ldr r0, =(0x10C00000+0x0040)
+ ldr r1, =(0xE240000|0x0306)
+ str r1, [r0]
+ @Outp32( 0x10C10000+0x0040, 0xE240000|0x0306 ); //- zq_mode_dds[26:24], zq_mode_term[23:21], zq_manual_start[1]=1
+ ldr r0, =(0x10C10000+0x0040)
+ ldr r1, =(0xE240000|0x0306)
+ str r1, [r0]
+@DMC_Delay(1ms);
+ bl delay
+ @Outp32( 0x10C00000+0x0040, 0xE240000|0x0304 ); //- zq_mode_dds[26:24], zq_mode_term[23:21], zq_manual_start[1]=0
+ ldr r0, =(0x10C00000+0x0040)
+ ldr r1, =(0xE240000|0x0304)
+ str r1, [r0]
+ @Outp32( 0x10C10000+0x0040, 0xE240000|0x0304 ); //- zq_mode_dds[26:24], zq_mode_term[23:21], zq_manual_start[1]=0
+ ldr r0, =(0x10C10000+0x0040)
+ ldr r1, =(0xE240000|0x0304)
+ str r1, [r0]
+ @Outp32( 0x10C00000+0x0038, 0x0000000f ); //- ctrl_pulld_dq[11:8]=0xf, ctrl_pulld_dqs[3:0]=0xf
+ ldr r0, =(0x10C00000+0x0038)
+ ldr r1, =(0x0000000f)
+ str r1, [r0]
+ @Outp32( 0x10C10000+0x0038, 0x0000000f ); //- ctrl_pulld_dq[11:8]=0xf, ctrl_pulld_dqs[3:0]=0xf
+ ldr r0, =(0x10C10000+0x0038)
+ ldr r1, =(0x0000000f)
+ str r1, [r0]
+ @Outp32( 0x10DD0000+0x0000, 0x1FFF0000|(0x3<<12.) ); //- dfi_init_start[28]=1, rd_fetch[14:12]=3
+ ldr r0, =(0x10DD0000+0x0000)
+ ldr r1, =(0x1FFF0000|(0x3<<12))
+ str r1, [r0]
+ @Outp32( 0x10DD0000+0x0018, 0xe0000008 ); //- mem_term_en[31]=1, phy_term_en[30]=1, gate signal length[29]=1, fp_resync[3]=1
+ ldr r0, =(0x10DD0000+0x0018)
+ ldr r1, =(0xe0000008)
+ str r1, [r0]
+ @Outp32( 0x10DD0000+0x0018, 0xe0000000 ); //- mem_term_en[31]=1, phy_term_en[30]=1, gate signal length[29]=1, fp_resync[3]=0
+ ldr r0, =(0x10DD0000+0x0018)
+ ldr r1, =(0xe0000000)
+ str r1, [r0]
+ @Outp32( 0x10C00000+0x0010, 0x8080808 ); //- ctrl_offsetr
+ ldr r0, =(0x10C00000+0x0010)
+ ldr r1, =(0x8080808)
+ str r1, [r0]
+ @Outp32( 0x10C10000+0x0010, 0x8080808 ); //- ctrl_offsetr
+ ldr r0, =(0x10C10000+0x0010)
+ ldr r1, =(0x8080808)
+ str r1, [r0]
+ @Outp32( 0x10C00000+0x0018, 0x8080808 ); //- ctrl_offsetw
+ ldr r0, =(0x10C00000+0x0018)
+ ldr r1, =(0x8080808)
+ str r1, [r0]
+ @Outp32( 0x10C10000+0x0018, 0x8080808 ); //- ctrl_offsetw
+ ldr r0, =(0x10C10000+0x0018)
+ ldr r1, =(0x8080808)
+ str r1, [r0]
+ @Outp32( 0x10C00000+0x0028, 0x8 ); //- ctrl_offsetd[7:0]=0x8
+ ldr r0, =(0x10C00000+0x0028)
+ ldr r1, =(0x8)
+ str r1, [r0]
+ @Outp32( 0x10C10000+0x0028, 0x8 ); //- ctrl_offsetd[7:0]=0x8
+ ldr r0, =(0x10C10000+0x0028)
+ ldr r1, =(0x8)
+ str r1, [r0]
+ @Outp32( 0x10C00000+0x0030, 0x10100030 ); //- ctrl_force[14:8]=0x0, ctrl_start[6]=0, ctrl_dll_on[5]=1
+ ldr r0, =(0x10C00000+0x0030)
+ ldr r1, =(0x10100030)
+ str r1, [r0]
+ @Outp32( 0x10C10000+0x0030, 0x10100030 ); //- ctrl_force[14:8]=0x0, ctrl_start[6]=0, ctrl_dll_on[5]=1
+ ldr r0, =(0x10C10000+0x0030)
+ ldr r1, =(0x10100030)
+ str r1, [r0]
+@DMC_Delay(1ms);
+bl delay
+ @Outp32( 0x10C00000+0x0030, 0x10100070 ); //- ctrl_dll_start[6]=1
+ ldr r0, =(0x10C00000+0x0030)
+ ldr r1, =(0x10100070)
+ str r1, [r0]
+ @Outp32( 0x10C10000+0x0030, 0x10100070 ); //- ctrl_dll_start[6]=1
+ ldr r0, =(0x10C10000+0x0030)
+ ldr r1, =(0x10100070)
+ str r1, [r0]
+@DMC_Delay(1ms);
+bl delay
+@DMC_Delay(1ms);
+bl delay
+ @Outp32( 0x10DD0000+0x0018, 0xe0000008 ); //- mem_term_en[31]=1, phy_term_en[30]=1, gate signal length[29]=1, fp_resync[3]=1
+ ldr r0, =(0x10DD0000+0x0018)
+ ldr r1, =(0xe0000008)
+ str r1, [r0]
+ @Outp32( 0x10DD0000+0x0018, 0xe0000000 ); //- mem_term_en[31]=1, phy_term_en[30]=1, gate signal length[29]=1, fp_resync[3]=0
+ ldr r0, =(0x10DD0000+0x0018)
+ ldr r1, =(0xe0000000)
+ str r1, [r0]
+ @Outp32( 0x10DD0000+0x0018, 0xe0000008 ); //- mem_term_en[31]=1, phy_term_en[30]=1, gate signal length[29]=1, fp_resync[3]=1
+ ldr r0, =(0x10DD0000+0x0018)
+ ldr r1, =(0xe0000008)
+ str r1, [r0]
+ @Outp32( 0x10DD0000+0x0018, 0xe0000000 ); //- mem_term_en[31]=1, phy_term_en[30]=1, gate signal length[29]=1, fp_resync[3]=0
+ ldr r0, =(0x10DD0000+0x0018)
+ ldr r1, =(0xe0000000)
+ str r1, [r0]
+ @Outp32( 0x10DD0000+0x0000, 0x0FFF0000|(0x3<<12.) ); //- dfi_init_start[28]=0, rd_fetch[14:12]=3
+ ldr r0, =(0x10DD0000+0x0000)
+ ldr r1, =(0x0FFF0000|(0x3<<12))
+ str r1, [r0]
+ @Outp32( 0x10DD0000+0x00F0, 0x3 ); //- channel interleaving
+ ldr r0, =(0x10DD0000+0x00F0)
+ ldr r1, =(0x3)
+ str r1, [r0]
+ @Outp32( 0x10DD0000+0x0008, 0x00001333 ); //- bank interleaving
+ ldr r0, =(0x10DD0000+0x0008)
+ ldr r1, =(0x00001333)
+ str r1, [r0]
+ @Outp32( 0x10DD0000+0x000C, 0x00001333 ); //- bank interleaving
+ ldr r0, =(0x10DD0000+0x000C)
+ ldr r1, =(0x00001333)
+ str r1, [r0]
+ @Outp32( 0x10DD0000+0x010C, 0x00400780 ); //- chip_base[26:16]=40, chip_mask[10:0]=780
+ ldr r0, =(0x10DD0000+0x010C)
+ ldr r1, =(0x00400780)
+ str r1, [r0]
+ @Outp32( 0x10DD0000+0x0110, 0x00800780 ); //- chip_base[26:16]=80, chip_mask[10:0]=780
+ ldr r0, =(0x10DD0000+0x0110)
+ ldr r1, =(0x00800780)
+ str r1, [r0]
+ @Outp32( 0x10DD0000+0x0014, 0xFF000000 ); //- precharge policy counter
+ ldr r0, =(0x10DD0000+0x0014)
+ ldr r1, =(0xFF000000)
+ str r1, [r0]
+ @Outp32( 0x10DD0000+0x0028, 0xFFFF00FF ); //- low power counter
+ ldr r0, =(0x10DD0000+0x0028)
+ ldr r1, =(0xFFFF00FF)
+ str r1, [r0]
+ @Outp32( 0x10DD0000+0x0030, 0x000000bb ); //- refresh counter
+ ldr r0, =(0x10DD0000+0x0030)
+ ldr r1, =(0x000000bb)
+ str r1, [r0]
+ @Outp32( 0x10DD0000+0x0034, 0x8C36650E ); //- timing row
+ ldr r0, =(0x10DD0000+0x0034)
+ ldr r1, =(0x8C36650E)
+ str r1, [r0]
+ @Outp32( 0x10DD0000+0x0038, 0x3630580B ); //- timing data
+ ldr r0, =(0x10DD0000+0x0038)
+ ldr r1, =(0x3630580B)
+ str r1, [r0]
+ @Outp32( 0x10DD0000+0x003C, 0x41000A44 ); //- timing power
+ ldr r0, =(0x10DD0000+0x003C)
+ ldr r1, =(0x41000A44)
+ str r1, [r0]
+ @Outp32( 0x10DD0000+0x0010, 0x01000000 ); //- Issue PALL
+ ldr r0, =(0x10DD0000+0x0010)
+ ldr r1, =(0x01000000)
+ str r1, [r0]
+@DMC_Delay(100ms);
+bl delay100
+ @Outp32( 0x10DD0000+0x0010, 0x01100000 ); //- Issue PALL
+ ldr r0, =(0x10DD0000+0x0010)
+ ldr r1, =(0x01100000)
+ str r1, [r0]
+@DMC_Delay(100ms);
+bl delay100
+ @Outp32( 0x10DD0000+0x0010, 0x11000000 ); //- Issue PALL
+ ldr r0, =(0x10DD0000+0x0010)
+ ldr r1, =(0x11000000)
+ str r1, [r0]
+@DMC_Delay(100ms);
+bl delay100
+ @Outp32( 0x10DD0000+0x0010, 0x11100000 ); //- Issue PALL
+ ldr r0, =(0x10DD0000+0x0010)
+ ldr r1, =(0x11100000)
+ str r1, [r0]
+@DMC_Delay(100ms);
+bl delay100
+ @Outp32( 0x10DD0000+0x0010, 0x07000000 );
+ ldr r0, =(0x10DD0000+0x0010)
+ ldr r1, =(0x07000000)
+ str r1, [r0]
+@DMC_Delay(100ms);
+bl delay100
+ @Outp32( 0x10DD0000+0x0010, 0x00020000|0x18 );
+ ldr r0, =(0x10DD0000+0x0010)
+ ldr r1, =(0x00020000|0x18)
+ str r1, [r0]
+@DMC_Delay(100ms);
+bl delay100
+ @Outp32( 0x10DD0000+0x0010, 0x00030000 );
+ ldr r0, =(0x10DD0000+0x0010)
+ ldr r1, =(0x00030000)
+ str r1, [r0]
+@DMC_Delay(100ms);
+bl delay100
+ @Outp32( 0x10DD0000+0x0010, 0x00010000|0x42 );
+ ldr r0, =(0x10DD0000+0x0010)
+ ldr r1, =(0x00010000|0x42)
+ str r1, [r0]
+@DMC_Delay(100ms);
+bl delay100
+ @Outp32( 0x10DD0000+0x0010, 0x00000000|0xD70 );
+ ldr r0, =(0x10DD0000+0x0010)
+ ldr r1, =(0x00000000|0xD70)
+ str r1, [r0]
+@DMC_Delay(100ms);
+bl delay100
+ @Outp32( 0x10DD0000+0x0010, 0x0a000000 );
+ ldr r0, =(0x10DD0000+0x0010)
+ ldr r1, =(0x0a000000)
+ str r1, [r0]
+@DMC_Delay(100ms);
+bl delay100
+ @Outp32( 0x10DD0000+0x0010, 0x17000000 );
+ ldr r0, =(0x10DD0000+0x0010)
+ ldr r1, =(0x17000000)
+ str r1, [r0]
+@DMC_Delay(100ms);
+bl delay100
+ @Outp32( 0x10DD0000+0x0010, 0x10020000|0x18 );
+ ldr r0, =(0x10DD0000+0x0010)
+ ldr r1, =(0x10020000|0x18)
+ str r1, [r0]
+@DMC_Delay(100ms);
+bl delay100
+ @Outp32( 0x10DD0000+0x0010, 0x10030000 );
+ ldr r0, =(0x10DD0000+0x0010)
+ ldr r1, =(0x10030000)
+ str r1, [r0]
+@DMC_Delay(100ms);
+bl delay100
+ @Outp32( 0x10DD0000+0x0010, 0x10010000|0x42 );
+ ldr r0, =(0x10DD0000+0x0010)
+ ldr r1, =(0x10010000|0x42)
+ str r1, [r0]
+@DMC_Delay(100ms);
+bl delay100
+ @Outp32( 0x10DD0000+0x0010, 0x10000000|0xD70 );
+ ldr r0, =(0x10DD0000+0x0010)
+ ldr r1, =(0x10000000|0xD70)
+ str r1, [r0]
+@DMC_Delay(100ms);
+bl delay100
+ @Outp32( 0x10DD0000+0x0010, 0x1a000000 ); //- ZQInit
+ ldr r0, =(0x10DD0000+0x0010)
+ ldr r1, =(0x1a000000)
+ str r1, [r0]
+@DMC_Delay(100ms);
+bl delay100
+ @Outp32( 0x10DD0000+0x0004, 0x00302620 ); //- bl[22:20]=8, mem_type[11:8]=7, dsref_en[5]=1, dpwrdn_en[1]=1, clk_stop_en[0]=1
+ ldr r0, =(0x10DD0000+0x0004)
+ ldr r1, =(0x00302620)
+ str r1, [r0]
+ @Outp32( 0x10DD0000+0x0000, 0x0FFF0020|(0x3<<12.) ); //- dfi_init_start[28]=1, rd_fetch[14:12]=3, aref_en[5]=1
+ ldr r0, =(0x10DD0000+0x0000)
+ ldr r1, =(0x0FFF0020|(0x3<<12))
+ str r1, [r0]
+
+#if defined(CONFIG_DMC_BRB)
+ /* DMC BRB QoS */
+ ldr r0, =DMC_CTRL_BASE
+ ldr r1, =0x66668666
+ str r1, [r0, #DMC_BRBRSVCONFIG]
+ ldr r1, =0xFF
+ str r1, [r0, #DMC_BRBRSVCONTROL]
+ ldr r1, =0x1
+ str r1, [r0, #DMC_BRBQOSCONFIG]
+#endif
+ @pop {lr}
+ mov lr, r12
+ mov pc, lr
+
+ .globl dmc_delay
+dmc_delay:
+ subs r0, r0, #1
+ bne dmc_delay
+ mov pc, lr
+
+delay100:
+ mov r2, #0x10000
+delayloop100:
+ subs r2, r2, #1
+ bne delayloop100
+ mov pc, lr
+
+delay:
+ mov r2, #0x100
+delayloop:
+ subs r2, r2, #1
+ bne delayloop
+ mov pc, lr
+
+wait_pll_lock:
+ ldr r1, [r0, r2]
+ tst r1, #(1<<29)
+ beq wait_pll_lock
+ mov pc, lr
+
+wait_mux_state:
+ add r2, r2, #0x200
+check_mux_state:
+ ldr r1, [r0, r2]
+ cmp r1, r3
+ bne check_mux_state
+ mov pc, lr
+
+wait_div_state:
+ add r2, r2, #0x100
+check_div_state:
+ ldr r1, [r0, r2]
+ cmp r1, r3
+ bne check_div_state
+ mov pc, lr
diff --git a/SamsungPlatformPkg/ArndaleBoardPkg/Library/DebugAgentTimerLib/DebugAgentTimerLib.c b/SamsungPlatformPkg/ArndaleBoardPkg/Library/DebugAgentTimerLib/DebugAgentTimerLib.c
new file mode 100644
index 000000000..2fd2b8353
--- /dev/null
+++ b/SamsungPlatformPkg/ArndaleBoardPkg/Library/DebugAgentTimerLib/DebugAgentTimerLib.c
@@ -0,0 +1,78 @@
+/** @file
+ Template for ArmEb DebugAgentLib.
+
+ For ARM we reserve FIQ for the Debug Agent Timer. We don't care about
+ laytency as we only really need the timer to run a few times a second
+ (how fast can some one type a ctrl-c?), but it works much better if
+ the interrupt we are using to break into the debugger is not being
+ used, and masked, by the system.
+
+ Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <Base.h>
+
+#include <Library/DebugAgentTimerLib.h>
+
+#include <ArmEb/ArmEb.h>
+
+
+/**
+ Setup all the hardware needed for the debug agents timer.
+
+ This function is used to set up debug enviroment.
+
+**/
+VOID
+EFIAPI
+DebugAgentTimerIntialize (
+ VOID
+ )
+{
+ // Map Timer to FIQ
+}
+
+
+/**
+ Set the period for the debug agent timer. Zero means disable the timer.
+
+ @param[in] TimerPeriodMilliseconds Frequency of the debug agent timer.
+
+**/
+VOID
+EFIAPI
+DebugAgentTimerSetPeriod (
+ IN UINT32 TimerPeriodMilliseconds
+ )
+{
+ if (TimerPeriodMilliseconds == 0) {
+ // Disable timer and Disable FIQ
+ return;
+ }
+
+ // Set timer period and unmask FIQ
+}
+
+
+/**
+ Perform End Of Interrupt for the debug agent timer. This is called in the
+ interrupt handler after the interrupt has been processed.
+
+**/
+VOID
+EFIAPI
+DebugAgentTimerEndOfInterrupt (
+ VOID
+ )
+{
+ // EOI Timer interrupt for FIQ
+}
diff --git a/SamsungPlatformPkg/ArndaleBoardPkg/Library/DebugAgentTimerLib/DebugAgentTimerLib.inf b/SamsungPlatformPkg/ArndaleBoardPkg/Library/DebugAgentTimerLib/DebugAgentTimerLib.inf
new file mode 100644
index 000000000..c4ed68600
--- /dev/null
+++ b/SamsungPlatformPkg/ArndaleBoardPkg/Library/DebugAgentTimerLib/DebugAgentTimerLib.inf
@@ -0,0 +1,37 @@
+#/** @file
+# Component description file for Base PCI Cf8 Library.
+#
+# PCI CF8 Library that uses I/O ports 0xCF8 and 0xCFC to perform PCI Configuration cycles.
+# Layers on top of an I/O Library instance.
+# Copyright (c) 2007, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#
+#**/
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = ArmEbDebugAgentTimerLib
+ FILE_GUID = 80949BBB-68EE-4a4c-B434-D5DB5A232F0C
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = DebugAgentTimerLib|SEC BASE DXE_CORE
+
+
+[Sources.common]
+ DebugAgentTimerLib.c
+
+
+[Packages]
+ MdePkg/MdePkg.dec
+ EmbeddedPkg/EmbeddedPkg.dec
+ SamsungPlatformPkg/ArndaleBoardPkg/ArndaleBoardPkg.dec
+
+[LibraryClasses]
+ IoLib
diff --git a/SamsungPlatformPkg/ArndaleBoardPkg/arndale-Exynos5250.dsc b/SamsungPlatformPkg/ArndaleBoardPkg/arndale-Exynos5250.dsc
new file mode 100755
index 000000000..054c90d92
--- /dev/null
+++ b/SamsungPlatformPkg/ArndaleBoardPkg/arndale-Exynos5250.dsc
@@ -0,0 +1,363 @@
+#
+# Copyright (c) 2012, Samsung Electronics Co. All rights reserved.
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#
+
+################################################################################
+#
+# Defines Section - statements that will be processed to create a Makefile.
+#
+################################################################################
+[Defines]
+ PLATFORM_NAME = Arndale-Exynos-A15_MPCore
+ PLATFORM_GUID = 66a5a01d-be0a-4398-9b74-5af4a261381f
+ PLATFORM_VERSION = 0.1
+ DSC_SPECIFICATION = 0x00010005
+ OUTPUT_DIRECTORY = Build/Arndale-Exynos
+ SUPPORTED_ARCHITECTURES = ARM
+ BUILD_TARGETS = DEBUG|RELEASE
+ SKUID_IDENTIFIER = DEFAULT
+ FLASH_DEFINITION = SamsungPlatformPkg/ArndaleBoardPkg/arndale-Exynos5250.fdf
+
+!include SamsungPlatformPkg/ArndaleBoardPkg/ArndaleBoardPkg.dsc.inc
+
+[LibraryClasses.common]
+ ArmLib|ArmPkg/Library/ArmLib/ArmV7/ArmV7Lib.inf
+ ArmCpuLib|ArmPkg/Drivers/ArmCpuLib/ArmCortexA15Lib/ArmCortexA15Lib.inf
+ ArmPlatformLib|SamsungPlatformPkg/ArndaleBoardPkg/Library/ArndaleBoardLib/Exynos5250/BoardLib.inf
+
+ # Exynos5250 ArndaleBoard Specific Libraries
+ SerialPortLib|SamsungPlatformPkg/ExynosPkg/Exynos5250/Library/SerialPortLib/SerialPortLib_Evt1.inf
+ TimerLib|SamsungPlatformPkg/ExynosPkg/Exynos5250/Library/TimerLib/TimerLib.inf
+ RealTimeClockLib|SamsungPlatformPkg/ExynosPkg/Exynos5250/Library/RealTimeClockLib/RealTimeClockLib.inf
+ ExynosLib|SamsungPlatformPkg/ExynosPkg/Exynos5250/Library/ExynosLib/ExynosLib.inf
+ EfiResetSystemLib|SamsungPlatformPkg/ExynosPkg/Exynos5250/Library/ResetSystemLib/ResetSystemLib.inf
+ GdbSerialLib|SamsungPlatformPkg/ExynosPkg/Exynos5250/Library/GdbSerialLib/GdbSerialLib.inf
+ FdtLib|EmbeddedPkg/Library/FdtLib/FdtLib.inf
+
+ # ARM PL390 General Interrupt Driver in Secure and Non-secure
+ ArmGicSecLib|SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/Gic400Dxe/PL390GicSecLib.inf
+ ArmGicLib|SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/Gic400Dxe/PL390GicLib.inf
+ ArmSmcLib|ArmPkg/Library/ArmSmcLibNull/ArmSmcLibNull.inf
+
+[LibraryClasses.common.SEC]
+ ArmLib|ArmPkg/Library/ArmLib/ArmV7/ArmV7LibSec.inf
+
+ ArmPlatformSecLib|SamsungPlatformPkg/ArndaleBoardPkg/Library/ArndaleBoardLib/Exynos5250/BoardSecLib.inf
+
+[BuildOptions]
+ RVCT:*_*_ARM_PLATFORM_FLAGS == --cpu Cortex-A8 --fpu=softvfp -I$(WORKSPACE)/SamsungPlatformPkg/ExynosPkg/Exynos5250/Include/Platform
+
+ GCC:*_*_ARM_PLATFORM_FLAGS == -march=armv7-a -I$(WORKSPACE)/SamsungPlatformPkg/ExynosPkg/Exynos5250/Include/Platform
+
+ XCODE:*_*_ARM_PLATFORM_FLAGS == -arch armv7 -I$(WORKSPACE)/SamsungPlatformPkg/ExynosPkg/Exynos5250/Include/Platform
+
+
+################################################################################
+#
+# Pcd Section - list of all EDK II PCD Entries defined by this Platform
+#
+################################################################################
+
+[PcdsFeatureFlag.common]
+ gEfiMdePkgTokenSpaceGuid.PcdComponentNameDisable|FALSE
+ gEfiMdePkgTokenSpaceGuid.PcdDriverDiagnosticsDisable|TRUE
+ gEfiMdePkgTokenSpaceGuid.PcdComponentName2Disable|FALSE
+ gEfiMdePkgTokenSpaceGuid.PcdDriverDiagnostics2Disable|TRUE
+
+!ifdef $(EDK2_SKIP_PEICORE)
+ gArmPlatformTokenSpaceGuid.PcdSystemMemoryInitializeInSec|TRUE
+ gArmPlatformTokenSpaceGuid.PcdSendSgiToBringUpSecondaryCores|TRUE
+!endif
+
+ ## If TRUE, Graphics Output Protocol will be installed on virtual handle created by ConsplitterDxe.
+ # It could be set FALSE to save size.
+ gEfiMdeModulePkgTokenSpaceGuid.PcdConOutGopSupport|TRUE
+
+ # Install Debugger Exception Handlers.
+ gArmTokenSpaceGuid.PcdDebuggerExceptionSupport|TRUE
+
+ gEfiMdeModulePkgTokenSpaceGuid.PcdVariableCollectStatistics|TRUE
+
+[PcdsFixedAtBuild.common]
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVendor|L"Exynos5250 Arndale"
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVersionString|L"0.90"
+ gEmbeddedTokenSpaceGuid.PcdEmbeddedPrompt|"ARNDALE%"
+ gArmTokenSpaceGuid.PcdTrustzoneSupport|FALSE
+
+ gArmTokenSpaceGuid.PcdArmScr|0x31
+
+ # Stack for CPU Cores in Secure Mode
+ gArmPlatformTokenSpaceGuid.PcdCPUCoresSecStackBase|0x4B000000
+ gArmPlatformTokenSpaceGuid.PcdCPUCoresSecMonStackBase|0x4A000000
+ gArmPlatformTokenSpaceGuid.PcdCPUCoresStackBase|0x48000000
+
+ # Stacks for MPCores in Monitor Mode
+ gArmPlatformTokenSpaceGuid.PcdCPUCoresSecMonStackBase|0x4A000000 # Top of SEC Stack for Monitor World
+ gArmPlatformTokenSpaceGuid.PcdCPUCoreSecMonStackSize|0x2000 # Stack for each of the 4 CPU cores
+
+ # Non Sec UEFI Firmware: These two PCDs must match PcdFlashFvMainBase/PcdFlashFvMainSize
+ gArmTokenSpaceGuid.PcdFdBaseAddress |0x40000000 # Must be equal to gEmbeddedTokenSpaceGuid.PcdFlashFvMainBase
+ gArmTokenSpaceGuid.PcdFdSize|0x00200000 # Must be equal to gEmbeddedTokenSpaceGuid.PcdFlashFvMainSize
+
+ # System Memory (256MB)
+ gArmTokenSpaceGuid.PcdSystemMemoryBase|0x40000000
+ gArmTokenSpaceGuid.PcdSystemMemorySize|0x50000000
+
+ #FDT offset
+ gArmTokenSpaceGuid.PcdArmLinuxFdtMaxOffset|0x9000000
+
+ # Size of the region used by UEFI in permanent memory (Reserved 64MB)
+ gArmPlatformTokenSpaceGuid.PcdSystemMemoryUefiRegionSize|0x04000000
+
+ # Framebuffer Base Address and size
+ gExynosPkgTokenSpaceGuid.PcdFrameBufferBase|0x4E000000
+ gExynosPkgTokenSpaceGuid.PcdFrameBufferSize|0x02000000
+
+ gExynosPkgTokenSpaceGuid.PcdMpSharedArgsBase|0x4D000000
+ gExynosPkgTokenSpaceGuid.PcdMpSharedArgsSize|0x100000
+
+ # Memory Partition : Shared memory 1MB (0x4000_0000 -- 0x4010_0000)
+ gExynosPkgTokenSpaceGuid.PcdSmemBaseAddress|0x40200000
+ gExynosPkgTokenSpaceGuid.PcdSmemSize|0x00100000
+
+ # Memory Partition : EMMC DMA buffer Address and Size 1MB (0x4030_0000 -- 0x4040_0000)
+ gExynosPkgTokenSpaceGuid.PcdEmmcDMABufferBase|0x40300000
+ #gExynosPkgTokenSpaceGuid.PcdEmmcDMABufferSize|0x00100000
+
+ ## iRam Base Address and size.
+ gExynosPkgTokenSpaceGuid.PcdiRamBootBase|0x02020000
+ gExynosPkgTokenSpaceGuid.PcdiRamBootSize|0x00040000
+
+ ## iRam Stack Base Address and size.
+ gExynosPkgTokenSpaceGuid.PcdiRamStackBase|0x02050100
+ gExynosPkgTokenSpaceGuid.PcdiRamStackSize|0x00000100
+
+ gEmbeddedTokenSpaceGuid.PcdTimerPeriod|100000 # expressed in 100ns units, 100,000 x 100 ns = 10,000,000 ns = 10 ms
+
+ gEmbeddedTokenSpaceGuid.PcdPrePiStackBase|0x40200000
+ gEmbeddedTokenSpaceGuid.PcdPrePiStackSize|0x00020000 # 128K stack
+
+ #
+ # ARM Pcds
+ #
+ gArmTokenSpaceGuid.PcdArmUncachedMemoryMask|0x0000000040000000
+
+ ## PL011 - Serial Terminal
+ gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterBase|0x12C10000
+ gEfiMdePkgTokenSpaceGuid.PcdUartDefaultBaudRate|115200
+
+ #
+ # ARM Exynos PCDS
+ #
+ gExynosPkgTokenSpaceGuid.PcdConsoleUartBase|0x12C20000
+ gExynosPkgTokenSpaceGuid.PcdExynos5250Evt1|TRUE
+ gExynosPkgTokenSpaceGuid.PcdWinDebugUartBase|0x12C30000
+ gExynosPkgTokenSpaceGuid.PcdCmuBase|0x10010000
+ gExynosPkgTokenSpaceGuid.PcdPWMTimerBase|0x12DD0000
+ gExynosPkgTokenSpaceGuid.PcdPmuBase|0x10040000
+
+ gExynosPkgTokenSpaceGuid.PcdGpioPart1Base|0x11400000
+ gExynosPkgTokenSpaceGuid.PcdGpioPart2Base|0x13400000
+ gExynosPkgTokenSpaceGuid.PcdGpioPart3Base|0x10D10000
+ gExynosPkgTokenSpaceGuid.PcdGpioPart4Base|0x03860000
+
+ gExynosPkgTokenSpaceGuid.PcdSdMmcCH0Base|0x12200000
+ gExynosPkgTokenSpaceGuid.PcdSdMmcBase|0x12220000
+ gExynosPkgTokenSpaceGuid.PcdSysBase|0x10050000
+ gExynosPkgTokenSpaceGuid.PcdFIMD1Base|0x14400000
+ gExynosPkgTokenSpaceGuid.PcdDSIM1Base|0x14500000
+ gExynosPkgTokenSpaceGuid.PcdGICBase|0x10500000
+ gExynosPkgTokenSpaceGuid.PcdTZPCBase|0x10100000
+ gExynosPkgTokenSpaceGuid.PcdRtcBase|0x101E0000
+ gExynosPkgTokenSpaceGuid.PcdCryptoBase|0x10830000
+
+ #
+ # ARM PL390 General Interrupt Controller
+ #
+ gArmTokenSpaceGuid.PcdGicDistributorBase|0x10481000
+ gArmTokenSpaceGuid.PcdGicInterruptInterfaceBase|0x10482000
+ #gArmTokenSpaceGuid.PcdGicNumInterrupts|160
+
+ #
+ # ARM Architectual Timer Frequency
+ #
+ gArmTokenSpaceGuid.PcdArmArchTimerFreqInHz|60000000
+
+
+[PcdsPatchableInModule]
+ ## This PCD defines the Console output column and the default value is 25 according to UEFI spec
+ gEfiMdeModulePkgTokenSpaceGuid.PcdConOutRow|53
+
+ ## This PCD defines the Console output row and the default value is 80 according to UEFI spec
+ gEfiMdeModulePkgTokenSpaceGuid.PcdConOutColumn|75
+
+
+################################################################################
+#
+# Components Section - list of all EDK II Modules needed by this Platform
+#
+################################################################################
+[Components.common]
+
+ #
+ # SEC
+ #
+ #ArmPlatformPkg/Sec/Sec.inf
+ SamsungPlatformPkg/ExynosPkg/Exynos5250/Sec/Sec.inf {
+ <LibraryClasses>
+ ArmGicLib|SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/Gic400Dxe/PL390GicSecLib.inf
+ }
+
+ #
+ # PEI Phase modules
+ #
+!ifdef $(EDK2_SKIP_PEICORE)
+ ArmPlatformPkg/PrePi/PeiMPCore.inf {
+ <LibraryClasses>
+ ArmLib|ArmPkg/Library/ArmLib/ArmV7/ArmV7Lib.inf
+ ArmPlatformLib|SamsungPlatformPkg/ArndaleBoardPkg/Library/ArndaleBoardLib/Exynos5250/BoardLib.inf
+ ArmPlatformGlobalVariableLib|ArmPlatformPkg/Library/ArmPlatformGlobalVariableLib/PrePi/PrePiArmPlatformGlobalVariableLib.inf
+ }
+!else
+ ArmPlatformPkg/PrePeiCore/PrePeiCoreMPCore.inf {
+ <LibraryClasses>
+ ArmPlatformGlobalVariableLib|ArmPlatformPkg/Library/ArmPlatformGlobalVariableLib/Pei/PeiArmPlatformGlobalVariableLib.inf
+ }
+ MdeModulePkg/Core/Pei/PeiMain.inf
+ MdeModulePkg/Universal/PCD/Pei/Pcd.inf {
+ <LibraryClasses>
+ PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+ }
+ SamsungPlatformPkg/ExynosPkg/Exynos5250/PlatformPei/PlatformPeim.inf
+ SamsungPlatformPkg/ExynosPkg/Exynos5250/MemoryInitPei/MemoryInitPeim.inf
+ ArmPkg/Drivers/CpuPei/CpuPei.inf
+ IntelFrameworkModulePkg/Universal/StatusCode/Pei/StatusCodePei.inf
+ MdeModulePkg/Universal/Variable/Pei/VariablePei.inf
+ MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf {
+ <LibraryClasses>
+ NULL|IntelFrameworkModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf
+ }
+!endif
+
+ #
+ # DXE
+ #
+ MdeModulePkg/Core/Dxe/DxeMain.inf {
+ <LibraryClasses>
+ PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+ NULL|MdeModulePkg/Library/DxeCrc32GuidedSectionExtractLib/DxeCrc32GuidedSectionExtractLib.inf
+ }
+
+ #
+ # Architectural Protocols
+ #
+ ArmPkg/Drivers/CpuDxe/CpuDxe.inf
+ MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf
+ MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf
+ MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf
+ MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf
+ MdeModulePkg/Universal/Variable/EmuRuntimeDxe/EmuVariableRuntimeDxe.inf
+ MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf
+ EmbeddedPkg/ResetRuntimeDxe/ResetRuntimeDxe.inf
+ EmbeddedPkg/RealTimeClockRuntimeDxe/RealTimeClockRuntimeDxe.inf
+ EmbeddedPkg/MetronomeDxe/MetronomeDxe.inf
+
+ MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf
+ MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsoleDxe.inf
+ MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf
+ EmbeddedPkg/SimpleTextInOutSerial/SimpleTextInOutSerial.inf
+
+ MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf
+
+ SamsungPlatformPkg/ArndaleBoardPkg/FvbDxe/FvbDxe.inf
+ SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/TimerDxe/TimerDxe.inf
+ #
+ # ACPI Support
+ #
+ MdeModulePkg/Universal/Acpi/AcpiPlatformDxe/AcpiPlatformDxe.inf
+ MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf
+
+ #
+ # Samsung specific Driver
+ #
+ SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/Gic400Dxe/PL390GicDxe.inf
+ SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/Gpio/Gpio.inf{
+ <LibraryClasses>
+ ExynosLib|SamsungPlatformPkg/ExynosPkg/Exynos5250/Library/ExynosLib/ExynosLib.inf
+ }
+
+ #
+ # Multimedia Card Interface
+ #
+ SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/eMMCDxe/eMMCDxe.inf
+ SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/SDHCDxe_EVT1/SDHCDxe.inf
+ #
+ # FAT filesystem + GPT/MBR partitioning
+ #
+ MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf
+ MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf
+ MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf
+
+ #
+ # Application
+ #
+ #
+ # Bds
+ #
+ MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf
+ ArmPlatformPkg/Bds/Bds.inf
+
+ #
+ # VariableServicesTestNonSec
+ #
+ SamsungPlatformPkg/Apps/TestApps/VariableServicesTestNonSec/VariableServicesTestNonSec.inf
+
+ #
+ # TimeServicesTest
+ #
+ SamsungPlatformPkg/Apps/TestApps/TimeServicesTest/TimeServicesTest.inf
+
+ #
+ # MiscellaneousServicesTest
+ #
+ SamsungPlatformPkg/Apps/TestApps/MiscellaneousServicesTest/MiscellaneousServicesTest.inf
+
+ #
+ # usb host : ehci + bus + pci_emul + mass_storage
+ #
+ SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/PciEmulation/PciEmulation.inf
+ MdeModulePkg/Bus/Pci/EhciDxe/EhciDxe.inf
+ MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBusDxe.inf
+ MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassStorageDxe.inf
+
+ #
+ # Graphics for Exynos
+ #
+ MdeModulePkg/Universal/ReportStatusCodeRouter/Pei/ReportStatusCodeRouterPei.inf
+ MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportStatusCodeRouterRuntimeDxe.inf
+ SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/DisplayDxe/DisplayDxe.inf
+
+ MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTablePei/FirmwarePerformancePei.inf {
+ <LibraryClasses>
+ LockBoxLib|MdeModulePkg/Library/LockBoxNullLib/LockBoxNullLib.inf
+ }
+
+ MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.inf
+ SamsungPlatformPkg/Apps/Tools/fwupdate/fwupdate_5250.inf
+
+ #
+ # Crypto for Exynos
+ #
+
+ #
+ # Rng for Exynos
+ #
diff --git a/SamsungPlatformPkg/ArndaleBoardPkg/arndale-Exynos5250.fdf b/SamsungPlatformPkg/ArndaleBoardPkg/arndale-Exynos5250.fdf
new file mode 100755
index 000000000..29e4aa36f
--- /dev/null
+++ b/SamsungPlatformPkg/ArndaleBoardPkg/arndale-Exynos5250.fdf
@@ -0,0 +1,397 @@
+# FLASH layout file for ARM VE.
+#
+# Copyright (c) 2012, Samsung Electronics Co. All rights reserved.
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+
+################################################################################
+#
+# FD Section
+# The [FD] Section is made up of the definition statements and a
+# description of what goes into the Flash Device Image. Each FD section
+# defines one flash "device" image. A flash device image may be one of
+# the following: Removable media bootable image (like a boot floppy
+# image,) an Option ROM image (that would be "flashed" into an add-in
+# card,) a System "Flash" image (that would be burned into a system's
+# flash) or an Update ("Capsule") image that will be used to update and
+# existing system flash.
+#
+################################################################################
+
+
+[FD.Arndale_EFI]
+BaseAddress = 0x40000000|gArmTokenSpaceGuid.PcdFdBaseAddress
+Size = 0x00294000|gArmTokenSpaceGuid.PcdFdSize
+ErasePolarity = 1
+BlockSize = 0x00014000
+NumBlocks = 0x21
+
+################################################################################
+#
+# Following are lists of FD Region layout which correspond to the locations of different
+# images within the flash device.
+#
+# Regions must be defined in ascending order and may not overlap.
+#
+# A Layout Region start with a eight digit hex offset (leading "0x" required) followed by
+# the pipe "|" character, followed by the size of the region, also in hex with the leading
+# "0x" characters. Like:
+# Offset|Size
+# PcdOffsetCName|PcdSizeCName
+# RegionType <FV, DATA, or FILE>
+#
+################################################################################
+
+0x0000000|0x00014000
+gArmTokenSpaceGuid.PcdSecureFvBaseAddress|gArmTokenSpaceGuid.PcdSecureFvSize
+FV = FVMAIN_SEC
+
+0x00014000|0x0026C000
+gArmTokenSpaceGuid.PcdFvBaseAddress|gArmTokenSpaceGuid.PcdFvSize
+FV = FVMAIN_COMPACT
+
+0x00284000|0x00010000
+gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase|gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize
+#NV_VARIABLE_STORE
+DATA = {
+ ## This is the EFI_FIRMWARE_VOLUME_HEADER
+ # ZeroVector []
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ # FileSystemGuid: gEfiSystemNvDataFvGuid =
+ # { 0xFFF12B8D, 0x7696, 0x4C8B, { 0xA9, 0x85, 0x27, 0x47, 0x07, 0x5B, 0x4F, 0x50 }}
+ 0x8D, 0x2B, 0xF1, 0xFF, 0x96, 0x76, 0x8B, 0x4C,
+ 0xA9, 0x85, 0x27, 0x47, 0x07, 0x5B, 0x4F, 0x50,
+ # FvLength: 0x20000
+ 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
+ #Signature "_FVH" #Attributes
+ 0x5f, 0x46, 0x56, 0x48, 0xff, 0xfe, 0x04, 0x00,
+ #HeaderLength #CheckSum #ExtHeaderOffset #Reserved #Revision
+ 0x48, 0x00, 0x36, 0x09, 0x00, 0x00, 0x00, 0x02,
+ #Blockmap[0]: 2 Blocks * 0x10000 Bytes / Block
+ 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
+ #Blockmap[1]: End
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ ## This is the VARIABLE_STORE_HEADER
+ #Signature: gEfiVariableGuid =
+ # { 0xddcf3616, 0x3275, 0x4164, { 0x98, 0xb6, 0xfe, 0x85, 0x70, 0x7f, 0xfe, 0x7d }}
+ 0x16, 0x36, 0xcf, 0xdd, 0x75, 0x32, 0x64, 0x41,
+ 0x98, 0xb6, 0xfe, 0x85, 0x70, 0x7f, 0xfe, 0x7d,
+ #Size: 0x10000 (gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize) - 0x48 (size of EFI_FIRMWARE_VOLUME_HEADER) = 0xFFB8
+ # This can speed up the Variable Dispatch a bit.
+ 0xB8, 0xFF, 0x00, 0x00,
+ #FORMATTED: 0x5A #HEALTHY: 0xFE #Reserved: UINT16 #Reserved1: UINT32
+ 0x5A, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+}
+
+################################################################################
+#
+# FV Section
+#
+# [FV] section is used to define what components or modules are placed within a flash
+# device file. This section also defines order the components and modules are positioned
+# within the image. The [FV] section consists of define statements, set statements and
+# module statements.
+#
+################################################################################
+
+[FV.FVMAIN_SEC]
+FvAlignment = 8
+ERASE_POLARITY = 1
+MEMORY_MAPPED = TRUE
+STICKY_WRITE = TRUE
+LOCK_CAP = TRUE
+LOCK_STATUS = TRUE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP = TRUE
+WRITE_STATUS = TRUE
+WRITE_LOCK_CAP = TRUE
+WRITE_LOCK_STATUS = TRUE
+READ_DISABLED_CAP = TRUE
+READ_ENABLED_CAP = TRUE
+READ_STATUS = TRUE
+READ_LOCK_CAP = TRUE
+READ_LOCK_STATUS = TRUE
+
+ INF SamsungPlatformPkg/ExynosPkg/Exynos5250/Sec/Sec.inf
+
+
+[FV.FVMAIN]
+BlockSize = 0x40
+NumBlocks = 0 # This FV gets compressed so make it just big enough
+FvAlignment = 8 # FV alignment and FV attributes setting.
+ERASE_POLARITY = 1
+MEMORY_MAPPED = TRUE
+STICKY_WRITE = TRUE
+LOCK_CAP = TRUE
+LOCK_STATUS = TRUE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP = TRUE
+WRITE_STATUS = TRUE
+WRITE_LOCK_CAP = TRUE
+WRITE_LOCK_STATUS = TRUE
+READ_DISABLED_CAP = TRUE
+READ_ENABLED_CAP = TRUE
+READ_STATUS = TRUE
+READ_LOCK_CAP = TRUE
+READ_LOCK_STATUS = TRUE
+
+ INF MdeModulePkg/Core/Dxe/DxeMain.inf
+
+ #
+ # PI DXE Drivers producing Architectural Protocols (EFI Services)
+ #
+ INF ArmPkg/Drivers/CpuDxe/CpuDxe.inf
+ INF MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf
+ INF MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf
+ INF MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf
+ INF MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf
+ INF MdeModulePkg/Universal/Variable/EmuRuntimeDxe/EmuVariableRuntimeDxe.inf
+ INF MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf
+ INF EmbeddedPkg/ResetRuntimeDxe/ResetRuntimeDxe.inf
+ INF EmbeddedPkg/RealTimeClockRuntimeDxe/RealTimeClockRuntimeDxe.inf
+ INF EmbeddedPkg/MetronomeDxe/MetronomeDxe.inf
+
+ #
+ # Multiple Console IO support
+ #
+ INF MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf
+ INF MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsoleDxe.inf
+ INF MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf
+ INF EmbeddedPkg/SimpleTextInOutSerial/SimpleTextInOutSerial.inf
+ INF MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf
+
+!ifdef $(EXYNOS5250_EVT1)
+ INF SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/Gic400Dxe/PL390GicDxe.inf
+!else
+ INF ArmPkg/Drivers/PL390Gic/PL390GicDxe.inf
+!endif
+ INF SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/TimerDxe/TimerDxe.inf
+
+ #
+ # ACPI Support
+ #
+ INF MdeModulePkg/Universal/Acpi/AcpiPlatformDxe/AcpiPlatformDxe.inf
+ INF MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf
+
+ #
+ # Samsung specific Driver
+ #
+ INF SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/Gpio/Gpio.inf
+ INF SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/eMMCDxe/eMMCDxe.inf
+ INF SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/SDHCDxe_EVT1/SDHCDxe.inf
+
+ #
+ # FAT filesystem + GPT/MBR partitioning
+ #
+ INF MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf
+ INF MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf
+ INF FatBinPkg/EnhancedFatDxe/Fat.inf
+ INF MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf
+
+ #
+ # USB HOST STACK
+ #
+ INF SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/PciEmulation/PciEmulation.inf
+ INF MdeModulePkg/Bus/Pci/EhciDxe/EhciDxe.inf
+ INF MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBusDxe.inf
+ INF MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassStorageDxe.inf
+
+ #
+ # Graphics for Exynos
+ #
+ INF SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/DisplayDxe/DisplayDxe.inf
+
+ INF MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.inf
+
+ INF MdeModulePkg/Universal/ReportStatusCodeRouter/Pei/ReportStatusCodeRouterPei.inf
+ INF MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportStatusCodeRouterRuntimeDxe.inf
+ INF MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTablePei/FirmwarePerformancePei.inf
+
+ # Crypto for Exynos
+ #
+
+ #
+ # UEFI application (Shell Embedded Boot Loader)
+ #
+ INF ShellBinPkg/UefiShell/UefiShell.inf
+
+ #
+ # Bds
+ #
+ INF MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf
+ INF ArmPlatformPkg/Bds/Bds.inf
+
+ #
+ # Firmware Updater
+ #
+ INF SamsungPlatformPkg/Apps/Tools/fwupdate/fwupdate_5250.inf
+
+
+ #
+ # Boot Logo
+ #
+ FILE FREEFORM = PCD(gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdLogoFile) {
+ SECTION RAW = SamsungPlatformPkg/Logo/Logo.bmp
+ }
+
+ #
+ # FVB
+ #
+ INF SamsungPlatformPkg/ArndaleBoardPkg/FvbDxe/FvbDxe.inf
+
+[FV.FVMAIN_COMPACT]
+FvAlignment = 8
+ERASE_POLARITY = 1
+MEMORY_MAPPED = TRUE
+STICKY_WRITE = TRUE
+LOCK_CAP = TRUE
+LOCK_STATUS = TRUE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP = TRUE
+WRITE_STATUS = TRUE
+WRITE_LOCK_CAP = TRUE
+WRITE_LOCK_STATUS = TRUE
+READ_DISABLED_CAP = TRUE
+READ_ENABLED_CAP = TRUE
+READ_STATUS = TRUE
+READ_LOCK_CAP = TRUE
+READ_LOCK_STATUS = TRUE
+
+!if $(EDK2_SKIP_PEICORE) == 1
+ INF ArmPlatformPkg/PrePi/PeiMPCore.inf
+!else
+ INF MdeModulePkg/Core/Pei/PeiMain.inf
+ INF ArmPlatformPkg/PrePeiCore/PrePeiCoreMPCore.inf
+ INF SamsungPlatformPkg/ExynosPkg/Exynos5250/PlatformPei/PlatformPeim.inf
+ INF SamsungPlatformPkg/ExynosPkg/Exynos5250/MemoryInitPei/MemoryInitPeim.inf
+ INF ArmPkg/Drivers/CpuPei/CpuPei.inf
+ INF MdeModulePkg/Universal/PCD/Pei/Pcd.inf
+ INF IntelFrameworkModulePkg/Universal/StatusCode/Pei/StatusCodePei.inf
+ INF MdeModulePkg/Universal/Variable/Pei/VariablePei.inf
+ INF MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf
+!endif
+
+ FILE FV_IMAGE = 9E21FD93-9C72-4c15-8C4B-E77F1DB2D792 {
+ SECTION GUIDED EE4E5898-3914-4259-9D6E-DC7BD79403CF PROCESSING_REQUIRED = TRUE {
+ SECTION FV_IMAGE = FVMAIN
+ }
+ }
+
+
+################################################################################
+#
+# Rules are use with the [FV] section's module INF type to define
+# how an FFS file is created for a given INF file. The following Rule are the default
+# rules for the different module type. User can add the customized rules to define the
+# content of the FFS file.
+#
+################################################################################
+
+
+############################################################################
+# Example of a DXE_DRIVER FFS file with a Checksum encapsulation section #
+############################################################################
+#
+#[Rule.Common.DXE_DRIVER]
+# FILE DRIVER = $(NAMED_GUID) {
+# DXE_DEPEX DXE_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex
+# COMPRESS PI_STD {
+# GUIDED {
+# PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi
+# UI STRING="$(MODULE_NAME)" Optional
+# VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+# }
+# }
+# }
+#
+############################################################################
+
+[Rule.Common.SEC]
+ FILE SEC = $(NAMED_GUID) RELOCS_STRIPPED {
+ TE TE Align = 32 $(INF_OUTPUT)/$(MODULE_NAME).efi
+ }
+
+[Rule.Common.PEI_CORE]
+ FILE PEI_CORE = $(NAMED_GUID) {
+ TE TE $(INF_OUTPUT)/$(MODULE_NAME).efi
+ UI STRING ="$(MODULE_NAME)" Optional
+ }
+
+[Rule.Common.PEIM]
+ FILE PEIM = $(NAMED_GUID) {
+ PEI_DEPEX PEI_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex
+ TE TE $(INF_OUTPUT)/$(MODULE_NAME).efi
+ UI STRING="$(MODULE_NAME)" Optional
+ }
+
+[Rule.Common.PEIM.TIANOCOMPRESSED]
+ FILE PEIM = $(NAMED_GUID) DEBUG_MYTOOLS_IA32 {
+ PEI_DEPEX PEI_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex
+ GUIDED A31280AD-481E-41B6-95E8-127F4C984779 PROCESSING_REQUIRED = TRUE {
+ PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi
+ UI STRING="$(MODULE_NAME)" Optional
+ }
+ }
+
+[Rule.Common.DXE_CORE]
+ FILE DXE_CORE = $(NAMED_GUID) {
+ PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi
+ UI STRING="$(MODULE_NAME)" Optional
+ }
+
+[Rule.Common.UEFI_DRIVER]
+ FILE DRIVER = $(NAMED_GUID) {
+ DXE_DEPEX DXE_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex
+ PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi
+ UI STRING="$(MODULE_NAME)" Optional
+ }
+
+[Rule.Common.UEFI_DRIVER.BINARY]
+ FILE DRIVER = $(NAMED_GUID) {
+ DXE_DEPEX DXE_DEPEX Optional |.depex
+ PE32 PE32 |.efi
+ UI STRING="$(MODULE_NAME)" Optional
+ VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+ }
+
+[Rule.Common.DXE_DRIVER]
+ FILE DRIVER = $(NAMED_GUID) {
+ DXE_DEPEX DXE_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex
+ PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi
+ UI STRING="$(MODULE_NAME)" Optional
+ }
+
+[Rule.Common.DXE_RUNTIME_DRIVER]
+ FILE DRIVER = $(NAMED_GUID) {
+ DXE_DEPEX DXE_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex
+ PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi
+ UI STRING="$(MODULE_NAME)" Optional
+ }
+
+[Rule.Common.USER_DEFINED.ACPITABLE]
+ FILE FREEFORM = $(NAMED_GUID) {
+ RAW ACPI |.acpi
+ RAW ASL |.aml
+ UI STRING="$(MODULE_NAME)" Optional
+ }
+
+[Rule.Common.UEFI_APPLICATION]
+ FILE APPLICATION = $(NAMED_GUID) {
+ UI STRING ="$(MODULE_NAME)" Optional
+ PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi
+ }
+
+[Rule.Common.UEFI_APPLICATION.BINARY]
+ FILE APPLICATION = $(NAMED_GUID) {
+ PE32 PE32 |.efi
+ UI STRING="$(MODULE_NAME)" Optional
+ VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+ }
diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/DisplayDxe/DisplayDxe.c b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/DisplayDxe/DisplayDxe.c
new file mode 100644
index 000000000..d1b5a3be6
--- /dev/null
+++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/DisplayDxe/DisplayDxe.c
@@ -0,0 +1,692 @@
+/** @file
+ Template for Timer Architecture Protocol driver of the ARM flavor
+
+ Copyright (c) 2012, Samsung Electronics Co. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+
+#include <PiDxe.h>
+
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiLib.h>
+#include <Library/PcdLib.h>
+#include <Library/IoLib.h>
+#include <Library/TimerLib.h>
+#include <Protocol/GraphicsOutput.h>
+#include <Protocol/DevicePath.h>
+#include <Protocol/ExynosGpio.h>
+#include <Platform/ArmPlatform.h>
+#include <Platform/Exynos5250.h>
+#include "DisplayDxe.h"
+
+
+typedef struct {
+ VENDOR_DEVICE_PATH DisplayDevicePath;
+ EFI_DEVICE_PATH EndDevicePath;
+} DISPLAY_DEVICE_PATH;
+
+DISPLAY_DEVICE_PATH gDisplayDevicePath =
+{
+ {
+ HARDWARE_DEVICE_PATH,
+ HW_VENDOR_DP,
+ (UINT8)(sizeof(VENDOR_DEVICE_PATH)),
+ (UINT8)((sizeof(VENDOR_DEVICE_PATH)) >> 8),
+ EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID
+ },
+ {
+ END_DEVICE_PATH_TYPE,
+ END_ENTIRE_DEVICE_PATH_SUBTYPE,
+ sizeof (EFI_DEVICE_PATH_PROTOCOL),
+ 0
+ }
+};
+
+#define LCD_WIDTH 1280
+#define LCD_HEIGHT 800
+
+#define VCLK 62946240
+
+#define SRC_CLK 800000000
+
+/**
+ This function configures the MIPI-DSIM channel
+**/
+INT32 s5p_mipi_dsi_wr_data(UINT32 data_id, UINT32 data0, UINT32 data1)
+{
+ UINT32 DSIM1BaseAddr = PcdGet32(PcdDSIM1Base);
+ UINT32 data_cnt = 0;
+ UINT32 payload = 0;
+ UINT32 timeout_count = 100000;
+
+ MicroSecondDelay(20000);
+
+ /* in case that data count is more then 4 */
+ for (data_cnt=0; data_cnt<data1; data_cnt+=4) {
+ /*
+ * after sending 4bytes per one time,
+ * send remainder data less then 4.
+ */
+ if ((data1 - data_cnt) < 4) {
+ if ((data1 - data_cnt) == 3) {
+ payload = *(UINT8 *)(data0 + data_cnt) | (*(UINT8 *)(data0 + (data_cnt + 1))) << 8 | (*(UINT8 *)(data0 + (data_cnt + 2))) << 16;
+ } else if ((data1 - data_cnt) == 2) {
+ payload = *(UINT8 *)(data0 + data_cnt) | (*(UINT8 *)(data0 + (data_cnt + 1))) << 8;
+ } else if ((data1 - data_cnt) == 1) {
+ payload = *(UINT8 *)(data0 + data_cnt);
+ }
+
+ MmioWrite32(DSIM1BaseAddr + DSIM_PAYLOAD, payload);
+ /* send 4bytes per one time. */
+ } else {
+ payload = *(UINT8 *)(data0 + data_cnt) | (*(UINT8 *)(data0 + (data_cnt + 1))) << 8 | \
+ (*(UINT8 *)(data0 + (data_cnt + 2))) << 16 | (*(UINT8 *)(data0 + (data_cnt + 3))) << 24;
+
+ MmioWrite32(DSIM1BaseAddr + DSIM_PAYLOAD, payload);
+ }
+ }
+
+ MmioWrite32(DSIM1BaseAddr + DSIM_PKTHDR, ((((data1 & 0xFF00) >> 8)<<16) | ((data1 & 0xFF)<<8) | ((data_id & 0x3F)<<0)));
+
+ while(1) {
+ if(timeout_count == 0)
+ return -1;
+
+ if(MmioRead32(DSIM1BaseAddr + DSIM_INTSRC) & (0x1<<29)) {
+ MmioWrite32(DSIM1BaseAddr + DSIM_INTSRC, (0x1<<29));
+ return 1;
+ }
+ else if((MmioRead32(DSIM1BaseAddr + DSIM_FIFOCTRL) & 0xF00000) == 0)
+ return -1;
+ timeout_count--;
+ }
+}
+
+INT32 lcd_display_on(VOID)
+{
+ UINT8 initcode_013c[6] = {0x3c, 0x01, 0x03, 0x00, 0x02, 0x00};
+ UINT8 initcode_0114[6] = {0x14, 0x01, 0x02, 0x00, 0x00, 0x00};
+ UINT8 initcode_0164[6] = {0x64, 0x01, 0x05, 0x00, 0x00, 0x00};
+ UINT8 initcode_0168[6] = {0x68, 0x01, 0x05, 0x00, 0x00, 0x00};
+ UINT8 initcode_016c[6] = {0x6c, 0x01, 0x05, 0x00, 0x00, 0x00};
+ UINT8 initcode_0170[6] = {0x70, 0x01, 0x05, 0x00, 0x00, 0x00};
+ UINT8 initcode_0134[6] = {0x34, 0x01, 0x1f, 0x00, 0x00, 0x00};
+ UINT8 initcode_0210[6] = {0x10, 0x02, 0x1f, 0x00, 0x00, 0x00};
+ UINT8 initcode_0104[6] = {0x04, 0x01, 0x01, 0x00, 0x00, 0x00};
+ UINT8 initcode_0204[6] = {0x04, 0x02, 0x01, 0x00, 0x00, 0x00};
+ UINT8 initcode_0450[6] = {0x50, 0x04, 0x20, 0x01, 0xfa, 0x00};
+ UINT8 initcode_0454[6] = {0x54, 0x04, 0x20, 0x00, 0x50, 0x00};
+ UINT8 initcode_0458[6] = {0x58, 0x04, 0x00, 0x05, 0x30, 0x00};
+ UINT8 initcode_045c[6] = {0x5c, 0x04, 0x05, 0x00, 0x0a, 0x00};
+ UINT8 initcode_0460[6] = {0x60, 0x04, 0x20, 0x03, 0x0a, 0x00};
+ UINT8 initcode_0464[6] = {0x64, 0x04, 0x01, 0x00, 0x00, 0x00};
+ UINT8 initcode_04a0_1[6] = {0xa0, 0x04, 0x06, 0x80, 0x44, 0x00};
+ UINT8 initcode_04a0_2[6] = {0xa0, 0x04, 0x06, 0x80, 0x04, 0x00};
+ UINT8 initcode_0504[6] = {0x04, 0x05, 0x04, 0x00, 0x00, 0x00};
+ UINT8 initcode_049c[6] = {0x9c, 0x04, 0x0d, 0x00, 0x00, 0x00};
+
+ /* Initialize MIPI LCD */
+ if(s5p_mipi_dsi_wr_data(0x29, (UINT32)initcode_013c, sizeof(initcode_013c)) == -1)
+ return 0;
+ MicroSecondDelay(6000);
+ if(s5p_mipi_dsi_wr_data(0x29, (UINT32)initcode_0114, sizeof(initcode_0114)) == -1)
+ return 0;
+ MicroSecondDelay(6000);
+ if(s5p_mipi_dsi_wr_data(0x29, (UINT32)initcode_0164, sizeof(initcode_0164)) == -1)
+ return 0;
+ MicroSecondDelay(6000);
+ if(s5p_mipi_dsi_wr_data(0x29, (UINT32)initcode_0168, sizeof(initcode_0168)) == -1)
+ return 0;
+ MicroSecondDelay(6000);
+ if(s5p_mipi_dsi_wr_data(0x29, (UINT32)initcode_016c, sizeof(initcode_016c)) == -1)
+ return 0;
+ MicroSecondDelay(6000);
+ if(s5p_mipi_dsi_wr_data(0x29, (UINT32)initcode_0170, sizeof(initcode_0170)) == -1)
+ return 0;
+ MicroSecondDelay(6000);
+ if(s5p_mipi_dsi_wr_data(0x29, (UINT32)initcode_0134, sizeof(initcode_0134)) == -1)
+ return 0;
+ MicroSecondDelay(6000);
+ if(s5p_mipi_dsi_wr_data(0x29, (UINT32)initcode_0210, sizeof(initcode_0210)) == -1)
+ return 0;
+ MicroSecondDelay(6000);
+ if(s5p_mipi_dsi_wr_data(0x29, (UINT32)initcode_0104, sizeof(initcode_0104)) == -1)
+ return 0;
+ MicroSecondDelay(6000);
+ if(s5p_mipi_dsi_wr_data(0x29, (UINT32)initcode_0204, sizeof(initcode_0204)) == -1)
+ return 0;
+ MicroSecondDelay(6000);
+ if(s5p_mipi_dsi_wr_data(0x29, (UINT32)initcode_0450, sizeof(initcode_0450)) == -1)
+ return 0;
+ MicroSecondDelay(6000);
+ if(s5p_mipi_dsi_wr_data(0x29, (UINT32)initcode_0454, sizeof(initcode_0454)) == -1)
+ return 0;
+ MicroSecondDelay(6000);
+ if(s5p_mipi_dsi_wr_data(0x29, (UINT32)initcode_0458, sizeof(initcode_0458)) == -1)
+ return 0;
+ MicroSecondDelay(6000);
+ if(s5p_mipi_dsi_wr_data(0x29, (UINT32)initcode_045c, sizeof(initcode_045c)) == -1)
+ return 0;
+ MicroSecondDelay(6000);
+ if(s5p_mipi_dsi_wr_data(0x29, (UINT32)initcode_0460, sizeof(initcode_0460)) == -1)
+ return 0;
+ MicroSecondDelay(6000);
+ if(s5p_mipi_dsi_wr_data(0x29, (UINT32)initcode_0464, sizeof(initcode_0464)) == -1)
+ return 0;
+ MicroSecondDelay(6000);
+ if(s5p_mipi_dsi_wr_data(0x29, (UINT32)initcode_04a0_1, sizeof(initcode_04a0_1)) == -1)
+ return 0;
+ MicroSecondDelay(6000);
+ if(s5p_mipi_dsi_wr_data(0x29, (UINT32)initcode_04a0_2, sizeof(initcode_04a0_2)) == -1)
+ return 0;
+ MicroSecondDelay(6000);
+ if(s5p_mipi_dsi_wr_data(0x29, (UINT32)initcode_0504, sizeof(initcode_0504)) == -1)
+ return 0;
+ MicroSecondDelay(6000);
+ if(s5p_mipi_dsi_wr_data(0x29, (UINT32)initcode_049c, sizeof(initcode_049c)) == -1)
+ return 0;
+ MicroSecondDelay(800000);
+
+ return 1;
+}
+
+VOID ConfigureMIPI(VOID)
+{
+ UINT32 DSIM1BaseAddr = PcdGet32(PcdDSIM1Base);
+ UINT32 DSIM_status;
+ BOOLEAN config_done = FALSE;
+
+ /* Enable MIPI-DSIM clock */
+ MmioAndThenOr32((PcdGet32(PcdCmuBase) + CLK_GATE_IP_DISP1_OFFSET), ~CLK_GATE_DSIM1_MASK,CLK_GATE_DSIM1_MASK);
+
+ while(!config_done) {
+ /* Enable MIPI PHY1 */
+ MmioAndThenOr32((PcdGet32(PcdPmuBase) +PMU_MIPI_PHY1_CONTROL_OFFSET), ~(1<<0), (1<<0));
+ /* Reset DSIM part of MIPI PHY1 */
+ MmioAndThenOr32((PcdGet32(PcdPmuBase) +PMU_MIPI_PHY1_CONTROL_OFFSET), ~(1<<2), (1<<2));
+
+ /* DSIM SW Reset */
+ MmioOr32(DSIM1BaseAddr + DSIM_SWRST, (1<<0));
+
+ /* Disable swap of Dp/Dn channel of data and clock lanes */
+ MmioAndThenOr32(DSIM1BaseAddr + DSIM_PHYACCHR1, ~(0x3<<0), ((0 & 0x3)<<0));
+
+ /* DSIM SW Reset */
+ MmioOr32(DSIM1BaseAddr + DSIM_SWRST, (1<<0));
+
+ /* Initialize FIFO pointer */
+ MmioAnd32(DSIM1BaseAddr + DSIM_FIFOCTRL, ~(0x1F<<0));
+ MicroSecondDelay(10000);
+ MmioOr32(DSIM1BaseAddr + DSIM_FIFOCTRL, (0x1F<<0));
+
+ /* DSI configuration */
+ MmioAndThenOr32(DSIM1BaseAddr + DSIM_CONFIG, ~((0x1<<28) | (0x1F<<20) | (0x3<<5)), (0x3<<5));
+ MmioOr32(DSIM1BaseAddr + DSIM_CONFIG, ((0x1<<0)|(0x1<<1)|(0x1<<2)|(0x1<<3)|(0x1<<4)));
+
+ /* clock configuration */
+ MmioAndThenOr32(DSIM1BaseAddr + DSIM_CLKCTRL, ~(0x3<<25), (0x0<<25));
+ MmioAndThenOr32(DSIM1BaseAddr + DSIM_PHYACCHR, ~(0x7<<5), ((0x1<<14)|(0x3<<5)));
+ MmioAndThenOr32(DSIM1BaseAddr + DSIM_PLLCTRL, ~(0x7FFFF<<1), ((3<<13)|(115<<4)|(1<<1)));
+ MmioAndThenOr32(DSIM1BaseAddr + DSIM_PLLCTRL, ~(0xF<<28), (0x0<<28));
+ MmioAndThenOr32(DSIM1BaseAddr + DSIM_PLLCTRL, ~(0x7<<20), (0x0<<20));
+ MmioAndThenOr32(DSIM1BaseAddr + DSIM_PLLCTRL, ~(0xF<<24), (0x8<<24));
+ MmioWrite32(DSIM1BaseAddr + DSIM_PLLTMR, 500);
+ MmioAndThenOr32(DSIM1BaseAddr + DSIM_CLKCTRL, ~(0x1<<27), (0x0<<27));
+
+ /* Enable PLL */
+ MmioWrite32(DSIM1BaseAddr + DSIM_INTSRC, (0x1<<31));
+ MmioAndThenOr32(DSIM1BaseAddr + DSIM_PLLCTRL, ~(0x1<<23), (0x1<<23));
+ while(1) {
+ if(MmioRead32(DSIM1BaseAddr + DSIM_STATUS) & (0x1<<31))
+ break;
+ }
+
+ /* Enable byte clock */
+ MmioAndThenOr32(DSIM1BaseAddr + DSIM_CLKCTRL, ~(0x1<<24), (0x1<<24));
+ /* Enable escape clock */
+ MmioAndThenOr32(DSIM1BaseAddr + DSIM_CLKCTRL, ~((0x1<<28) | (0xFFFF<<0)), ((0x1<<28) | (144<<0)));
+ /* Enable escape clock data and clock lanes */
+ MmioOr32(DSIM1BaseAddr + DSIM_CLKCTRL, (0x1F<<19));
+
+ MicroSecondDelay(100000);
+
+ while(1) {
+ DSIM_status = MmioRead32(DSIM1BaseAddr + DSIM_STATUS);
+ if((DSIM_status & (0xF<<0)) && ((DSIM_status & (0x1<<8)) || (DSIM_status & (0x1<<10))))
+ break;
+ }
+
+ /* BTA sequence counters */
+ MmioAndThenOr32(DSIM1BaseAddr + DSIM_ESCMODE, ~(0x7FF<<21), ((0xF &0x7FF) << 21));
+ MmioAndThenOr32(DSIM1BaseAddr + DSIM_TIMEOUT, ~(0xFF<<16), (0xFF<<16));
+ MmioAndThenOr32(DSIM1BaseAddr + DSIM_TIMEOUT, ~(0xFFFF<<0), (0xFFFF<<0));
+
+ /* Enable HS clock */
+ MmioAndThenOr32(DSIM1BaseAddr + DSIM_CLKCTRL, ~(0x1<<31), (0x1<<31));
+
+ /* Set CPU transfer mode */
+ MmioAndThenOr32(DSIM1BaseAddr + DSIM_ESCMODE, ~(0x1<<7), (0x1<<7));
+
+ /* Set display mode */
+ MmioAndThenOr32(DSIM1BaseAddr + DSIM_MVPORCH, ~((0xF<<28)|(0x7FF<<16)|(0x7FF<<0)), ((0xF<<28)|(0x4<<16)|(0x4<<0)));
+ MmioAndThenOr32(DSIM1BaseAddr + DSIM_MHPORCH, ~((0xFFFF<<16)|(0xFFFF<<0)), ((0x4<<16)|(0x4<<0)));
+ MmioAndThenOr32(DSIM1BaseAddr + DSIM_MSYNC, ~((0x3FF<<22)|(0xFFFF<<0)), ((0x4<<22)|(0x4<<0)));
+
+ MmioAnd32(DSIM1BaseAddr + DSIM_MDRESOL, ~(0x1<<31));
+ MmioAndThenOr32(DSIM1BaseAddr + DSIM_MDRESOL, ~((0x7FF<<16)|(0x7FF<<0)), ((0x1<<31)|(LCD_HEIGHT<<16)|(LCD_WIDTH<<0)));
+ MmioAndThenOr32(DSIM1BaseAddr + DSIM_CONFIG, ~((0x3<<26)|(0x1<<25)|(0x3<<18)|(0x7<<12)|(0x3<<16)|(0x7<<8)), \
+ ((0x1<<26)|(0x1<<25)|(0x7<<12)));
+
+ /* Clear interrupt status */
+ MmioWrite32(DSIM1BaseAddr + DSIM_INTSRC, (0x1<<29));
+
+ if(lcd_display_on() == 1)
+ config_done = TRUE;
+
+ /* Reset CPU transfer mode */
+ MmioAndThenOr32(DSIM1BaseAddr + DSIM_ESCMODE, ~(0x1<<7), (0x0<<7));
+
+ if(!config_done)
+ MmioOr32(DSIM1BaseAddr + DSIM_SWRST, (1<<0)); /* DSIM SW Reset */
+ }
+}
+
+VOID s5p_mipi_dsi_func_reset(VOID)
+{
+ UINT32 DSIM1BaseAddr = PcdGet32(PcdDSIM1Base);
+
+ MmioOr32(DSIM1BaseAddr + DSIM_SWRST, (1<<16));
+}
+
+/**
+ This function configures the Power Domain of the LCD 0 Module to Normal Mode.
+**/
+VOID ConfigurePower(VOID)
+{
+ UINT32 PrevGateState;
+
+ /* Enable FIMD1 power domain */
+ PrevGateState = MmioRead32((PcdGet32(PcdCmuBase) + CLK_GATE_IP_DISP1_OFFSET));
+ MmioWrite32((PcdGet32(PcdCmuBase) + CLK_GATE_IP_DISP1_OFFSET), 0xFFFFFFFF);
+
+ MmioWrite32((PcdGet32(PcdPmuBase) + PMU_DISP1_CONFIGURATION_OFFSET), LOCAL_PWR_ENABLE);
+ while( (MmioRead32((PcdGet32(PcdPmuBase) + PMU_DISP1_STATUS_OFFSET)) & LOCAL_PWR_ENABLE) != \
+ LOCAL_PWR_ENABLE);
+
+ MmioWrite32((PcdGet32(PcdCmuBase) + CLK_GATE_IP_DISP1_OFFSET), PrevGateState);
+}
+
+/**
+ This function configures Clock Source,Clock gating,Clock Divider and Mask values for the
+ FIMD0 in the LCD0 Module
+
+**/
+VOID ConfigureClk(VOID)
+{
+ MmioAndThenOr32((PcdGet32(PcdCmuBase) + CLK_GATE_IP_DISP1_OFFSET), \
+ ~CLK_GATE_FIMD1_MASK,CLK_GATE_FIMD1_MASK);
+
+ /* MPLL is the clock source of FIMD1 IP */
+ MmioAndThenOr32((PcdGet32(PcdCmuBase) + CLK_SRC_DISP1_0_OFFSET), \
+ ~CLK_SRC_FIMD1_MASK, CLK_SRC_FIMD1_SEL(FIMD1_SCLKMPLL));
+
+ /* Considering MPLL=800000000(800 MHz), SCLK_FIMD0=800000000(800 MHz) => DIV => (800/800) => 1
+ The DIV value to be programmed should be (1 -1) = 0 */
+ MmioAndThenOr32((PcdGet32(PcdCmuBase) + CLK_DIV_DISP1_0_OFFSET), \
+ ~CLK_DIV_FIMD1_MASK, CLK_DIV_FIMD1_SEL(FIMD1_CLK_DIV));
+
+ MmioOr32((PcdGet32(PcdCmuBase) + CLK_SRC_MASK_DISP1_0_OFFSET), CLK_SRC_DISP1_0_UNMASK);
+}
+
+VOID lcd_power_on(VOID)
+{
+ EFI_STATUS Status;
+ EXYNOS_GPIO *Gpio;
+
+ Status = gBS->LocateProtocol(&gSamsungPlatformGpioProtocolGuid, NULL, (VOID **)&Gpio);
+ ASSERT_EFI_ERROR(Status);
+
+ /* reset */
+ Gpio->Set(Gpio,LCD_RESET,GPIO_MODE_OUTPUT_1);
+ MicroSecondDelay(20000);
+ Gpio->Set(Gpio,LCD_RESET,GPIO_MODE_OUTPUT_0);
+ MicroSecondDelay(20000);
+ Gpio->Set(Gpio,LCD_RESET,GPIO_MODE_OUTPUT_1);
+ MicroSecondDelay(20000);
+
+ /* power */
+ Gpio->Set(Gpio,LCD_POWER,GPIO_MODE_OUTPUT_0);
+ MicroSecondDelay(20000);
+ Gpio->Set(Gpio,LCD_POWER,GPIO_MODE_OUTPUT_1);
+ MicroSecondDelay(20000);
+
+ /*backlight */
+ Gpio->Set(Gpio,LCD_BACKLIGHT,GPIO_MODE_OUTPUT_0);
+ MicroSecondDelay(20000);
+ Gpio->Set(Gpio,LCD_BACKLIGHT,GPIO_MODE_OUTPUT_1);
+ MicroSecondDelay(20000);
+}
+
+
+VOID LCD_Initialize(VOID)
+{
+ UINTN div;
+ UINT32 Fimd1BaseAddr = PcdGet32(PcdFIMD1Base);
+ UINT32 FBAddr = PcdGet32(PcdFrameBufferBase);
+
+ gBS->SetMem((VOID *)FBAddr, (LCD_WIDTH*LCD_HEIGHT*4), 0x0);
+
+ ConfigurePower();
+
+ /* Power up the LCD */
+ lcd_power_on();
+
+ /* Initialize MIPI-DSIM */
+ ConfigureMIPI();
+
+ ConfigureClk();
+
+ /* Set FIMD1 bypass */
+ MmioOr32((PcdGet32(PcdSysBase) + SYS_DISP1BLK_CFG_OFFSET), FIMDBYPASS_DISP1);
+
+ /* Configure FIMD */
+ MmioAndThenOr32(Fimd1BaseAddr + VIDCON1_OFFSET, ~S5P_VIDCON1_FIXVCLK_MASK, (S5P_VIDCON1_IVCLK_RISING_EDGE | \
+ S5P_VIDCON1_FIXVCLK_RUN));
+
+ MmioOr32(Fimd1BaseAddr + SHADOWCON_OFFSET, S5P_SHADOWCON_PROTECT(0));
+
+ div = SRC_CLK / VCLK;
+
+ MmioAndThenOr32(Fimd1BaseAddr + VIDCON0_OFFSET, ~S5P_VIDCON0_CLKVAL_F_MASK, (S5P_VIDCON0_CLKDIR_DIVIDED | \
+ S5P_VIDCON0_CLKVAL_F(div - 1) | S5P_VIDCON0_ENVID_ENABLE | S5P_VIDCON0_ENVID_F_ENABLE));
+ MmioOr32(Fimd1BaseAddr + VIDTCON0_OFFSET, (S5P_VIDTCON0_VBPD(3) | S5P_VIDTCON0_VFPD(3) | S5P_VIDTCON0_VSPW(3)));
+ MmioOr32(Fimd1BaseAddr + VIDTCON1_OFFSET, (S5P_VIDTCON1_HBPD(3) | S5P_VIDTCON1_HFPD(3) | S5P_VIDTCON1_HSPW(3)));
+
+ MmioOr32(Fimd1BaseAddr + VIDTCON2_OFFSET, (S5P_VIDTCON2_HOZVAL(LCD_WIDTH - 1) | S5P_VIDTCON2_LINEVAL(LCD_HEIGHT - 1)));
+
+ MmioWrite32(Fimd1BaseAddr + VIDADDR_START0_OFFSET(0), FBAddr);
+ MmioWrite32(Fimd1BaseAddr + VIDADDR_END0_OFFSET(0), (FBAddr + (LCD_WIDTH * LCD_HEIGHT * 4)));
+ MmioWrite32(Fimd1BaseAddr + VIDADDR_SIZE_OFFSET(0), (S5P_VIDADDR_PAGEWIDTH(LCD_WIDTH * 4) | S5P_VIDADDR_OFFSIZE(0)));
+
+ MmioWrite32(Fimd1BaseAddr + VIDOSD_A_OFFSET(0), (S5P_VIDOSD_LEFT_X(0) | S5P_VIDOSD_TOP_Y(0)));
+ MmioWrite32(Fimd1BaseAddr + VIDOSD_B_OFFSET(0), (S5P_VIDOSD_RIGHT_X(LCD_WIDTH - 1) | S5P_VIDOSD_BOTTOM_Y(LCD_HEIGHT - 1)));
+ MmioWrite32(Fimd1BaseAddr + VIDOSD_C_OFFSET(0), S5P_VIDOSD_SIZE(LCD_WIDTH * LCD_HEIGHT));
+
+ MmioOr32(Fimd1BaseAddr + SHADOWCON_OFFSET, S5P_SHADOWCON_CH_ENABLE(0));
+
+ MmioAndThenOr32(Fimd1BaseAddr + WINCON_OFFSET(0), ~(S5P_WINCON_BURSTLEN_MASK | S5P_WINCON_BPPMODE_MASK), \
+ (S5P_WINCON_WSWP_ENABLE | S5P_WINCON_BURSTLEN_16WORD | S5P_WINCON_BPPMODE_24BPP_888 | S5P_WINCON_ENWIN_ENABLE));
+
+ MmioAnd32(Fimd1BaseAddr + SHADOWCON_OFFSET, ~(S5P_SHADOWCON_PROTECT(0)));
+
+#if defined(LCD_MIPI_TC358764)
+ s5p_mipi_dsi_func_reset();
+#endif
+}
+
+EFI_STATUS
+EFIAPI
+DisplayQueryMode(
+ IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This,
+ IN UINT32 ModeNumber,
+ OUT UINTN *SizeOfInfo,
+ OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION **Info
+ );
+
+EFI_STATUS
+EFIAPI
+DisplaySetMode(
+ IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This,
+ IN UINT32 ModeNumber
+ );
+
+EFI_STATUS
+EFIAPI
+DisplayBlt(
+ IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This,
+ IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer, OPTIONAL
+ IN EFI_GRAPHICS_OUTPUT_BLT_OPERATION BltOperation,
+ IN UINTN SourceX,
+ IN UINTN SourceY,
+ IN UINTN DestinationX,
+ IN UINTN DestinationY,
+ IN UINTN Width,
+ IN UINTN Height,
+ IN UINTN Delta OPTIONAL
+ );
+
+EFI_GRAPHICS_OUTPUT_PROTOCOL gDisplay = {
+ DisplayQueryMode,
+ DisplaySetMode,
+ DisplayBlt,
+ NULL
+};
+
+
+EFI_STATUS
+EFIAPI
+DisplayQueryMode(
+ IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This,
+ IN UINT32 ModeNumber,
+ OUT UINTN *SizeOfInfo,
+ OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION **Info
+ )
+{
+ EFI_STATUS Status;
+
+ Status = gBS->AllocatePool(
+ EfiBootServicesData,
+ sizeof(EFI_GRAPHICS_OUTPUT_MODE_INFORMATION),
+ (VOID **)Info
+ );
+ ASSERT_EFI_ERROR(Status);
+
+ *SizeOfInfo = sizeof(EFI_GRAPHICS_OUTPUT_MODE_INFORMATION);
+
+ (*Info)->Version = This->Mode->Info->Version;
+ (*Info)->HorizontalResolution = This->Mode->Info->HorizontalResolution;
+ (*Info)->VerticalResolution = This->Mode->Info->VerticalResolution;
+ (*Info)->PixelFormat = This->Mode->Info->PixelFormat;
+ (*Info)->PixelsPerScanLine = This->Mode->Info->PixelsPerScanLine;
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+DisplaySetMode(
+ IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This,
+ IN UINT32 ModeNumber
+ )
+{
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+DisplayBlt(
+ IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This,
+ IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer, OPTIONAL
+ IN EFI_GRAPHICS_OUTPUT_BLT_OPERATION BltOperation,
+ IN UINTN SourceX,
+ IN UINTN SourceY,
+ IN UINTN DestinationX,
+ IN UINTN DestinationY,
+ IN UINTN Width,
+ IN UINTN Height,
+ IN UINTN Delta OPTIONAL
+ )
+{
+ UINT8 *VidBuf, *BltBuf, *VidBuf1;
+ UINTN i, j;
+
+ switch(BltOperation) {
+ case EfiBltVideoFill:
+ BltBuf = (UINT8 *)BltBuffer;
+
+ for(i=0;i<Height;i++) {
+ VidBuf = (UINT8 *)((UINT32)This->Mode->FrameBufferBase + \
+ (DestinationY + i)*This->Mode->Info->PixelsPerScanLine*sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL) + \
+ DestinationX*sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
+
+ for(j=0;j<Width;j++) {
+ gBS->CopyMem((VOID *)VidBuf, (VOID *)BltBuf, sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
+ VidBuf += sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL);
+ }
+ }
+ break;
+
+ case EfiBltVideoToBltBuffer:
+ if(Delta == 0)
+ Delta = Width * sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL);
+
+ for(i=0;i<Height;i++) {
+ VidBuf = (UINT8 *)((UINT32)This->Mode->FrameBufferBase + \
+ (SourceY + i)*This->Mode->Info->PixelsPerScanLine*sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL) + \
+ SourceX*sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
+ BltBuf = (UINT8 *)((UINT32)BltBuffer + (DestinationY + i)*Delta + DestinationX*sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
+
+ for(j=0;j<Width;j++) {
+ gBS->CopyMem((VOID *)BltBuf, (VOID *)VidBuf, sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
+ VidBuf += sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL);
+ BltBuf += sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL);
+ }
+ }
+ break;
+
+ case EfiBltBufferToVideo:
+ if(Delta == 0)
+ Delta = Width * sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL);
+
+ for(i=0;i<Height;i++) {
+ VidBuf = (UINT8 *)((UINT32)This->Mode->FrameBufferBase + \
+ (DestinationY + i)*This->Mode->Info->PixelsPerScanLine*sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL) + \
+ DestinationX*sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
+ BltBuf = (UINT8 *)((UINT32)BltBuffer + (SourceY + i)*Delta + SourceX*sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
+
+ for(j=0;j<Width;j++) {
+ gBS->CopyMem((VOID *)VidBuf, (VOID *)BltBuf, sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
+ VidBuf += sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL);
+ BltBuf += sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL);
+ }
+ }
+ break;
+
+ case EfiBltVideoToVideo:
+ for(i=0;i<Height;i++) {
+ VidBuf = (UINT8 *)((UINT32)This->Mode->FrameBufferBase + \
+ (SourceY + i)*This->Mode->Info->PixelsPerScanLine*sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL) + \
+ SourceX*sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
+
+ VidBuf1 = (UINT8 *)((UINT32)This->Mode->FrameBufferBase + \
+ (DestinationY + i)*This->Mode->Info->PixelsPerScanLine*sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL) + \
+ DestinationX*sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
+
+ for(j=0;j<Width;j++) {
+ gBS->CopyMem((VOID *)VidBuf1, (VOID *)VidBuf, sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
+ VidBuf += sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL);
+ VidBuf1 += sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL);
+ }
+ }
+ break;
+
+ default:
+ ASSERT_EFI_ERROR(EFI_SUCCESS);
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+
+/**
+ Initialize the state information for the Display Dxe
+
+ @param ImageHandle of the loaded driver
+ @param SystemTable Pointer to the System Table
+
+ @retval EFI_SUCCESS Protocol registered
+ @retval EFI_OUT_OF_RESOURCES Cannot allocate protocol data structure
+ @retval EFI_DEVICE_ERROR Hardware problems
+
+**/
+EFI_STATUS
+EFIAPI
+DisplayDxeInitialize (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ EFI_GUID GraphicsOutputProtocolGuid = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID;
+ EFI_GUID DevicePathProtocolGuid = EFI_DEVICE_PATH_PROTOCOL_GUID;
+ UINT32 FBAddr = PcdGet32(PcdFrameBufferBase);
+
+ /* Initialize Display */
+ LCD_Initialize();
+ if(gDisplay.Mode == NULL){
+ Status = gBS->AllocatePool(
+ EfiBootServicesData,
+ sizeof(EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE),
+ (VOID **)&gDisplay.Mode
+ );
+ ASSERT_EFI_ERROR(Status);
+ ZeroMem(gDisplay.Mode,sizeof(EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE));
+ }
+ if(gDisplay.Mode->Info==NULL){
+ Status = gBS->AllocatePool(
+ EfiBootServicesData,
+ sizeof(EFI_GRAPHICS_OUTPUT_MODE_INFORMATION),
+ (VOID **)&gDisplay.Mode->Info
+ );
+ ASSERT_EFI_ERROR(Status);
+ ZeroMem(gDisplay.Mode->Info,sizeof(EFI_GRAPHICS_OUTPUT_MODE_INFORMATION));
+ }
+ /* Fill out mode information */
+ gDisplay.Mode->MaxMode = 1;
+ gDisplay.Mode->Mode = 0;
+ gDisplay.Mode->Info->Version = 0;
+ gDisplay.Mode->Info->HorizontalResolution = LCD_WIDTH;
+ gDisplay.Mode->Info->VerticalResolution = LCD_HEIGHT;
+ gDisplay.Mode->Info->PixelFormat = PixelBlueGreenRedReserved8BitPerColor;
+ gDisplay.Mode->Info->PixelsPerScanLine = LCD_WIDTH;
+ gDisplay.Mode->SizeOfInfo = sizeof(EFI_GRAPHICS_OUTPUT_MODE_INFORMATION);
+ gDisplay.Mode->FrameBufferBase = FBAddr;
+ gDisplay.Mode->FrameBufferSize = (LCD_WIDTH * LCD_HEIGHT * 4);
+
+#if 0
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &ImageHandle,
+ &DevicePathProtocolGuid,
+ &gDisplayDevicePath,
+ &GraphicsOutputProtocolGuid,
+ &gDisplay,
+ NULL);
+#else
+ {
+ EFI_HANDLE gUEFIDisplayHandle = NULL;
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &gUEFIDisplayHandle,
+ &DevicePathProtocolGuid,
+ &gDisplayDevicePath,
+ &GraphicsOutputProtocolGuid,
+ &gDisplay,
+ NULL);
+
+ }
+#endif
+
+ return Status;
+}
diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/DisplayDxe/DisplayDxe.h b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/DisplayDxe/DisplayDxe.h
new file mode 100644
index 000000000..5b784f384
--- /dev/null
+++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/DisplayDxe/DisplayDxe.h
@@ -0,0 +1,277 @@
+/** @file
+*
+* Copyright (c) 2012, Samsung Electronics Co. All rights reserved.
+*
+* This program and the accompanying materials
+* are licensed and made available under the terms and conditions of the BSD License
+* which accompanies this distribution. The full text of the license may be found at
+* http://opensource.org/licenses/bsd-license.php
+*
+* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+
+#ifndef _DisplayDxe_H__
+#define _DisplayDxe_H__
+
+/*
+ * Bit Definitions
+*/
+
+/* VIDCON0 */
+#define S5P_VIDCON0_DSI_DISABLE (0 << 30)
+#define S5P_VIDCON0_DSI_ENABLE (1 << 30)
+#define S5P_VIDCON0_SCAN_PROGRESSIVE (0 << 29)
+#define S5P_VIDCON0_SCAN_INTERLACE (1 << 29)
+#define S5P_VIDCON0_SCAN_MASK (1 << 29)
+#define S5P_VIDCON0_VIDOUT_RGB (0 << 26)
+#define S5P_VIDCON0_VIDOUT_ITU (1 << 26)
+#define S5P_VIDCON0_VIDOUT_I80LDI0 (2 << 26)
+#define S5P_VIDCON0_VIDOUT_I80LDI1 (3 << 26)
+#define S5P_VIDCON0_VIDOUT_WB_RGB (4 << 26)
+#define S5P_VIDCON0_VIDOUT_WB_I80LDI0 (6 << 26)
+#define S5P_VIDCON0_VIDOUT_WB_I80LDI1 (7 << 26)
+#define S5P_VIDCON0_VIDOUT_MASK (7 << 26)
+#define S5P_VIDCON0_PNRMODE_RGB_P (0 << 17)
+#define S5P_VIDCON0_PNRMODE_BGR_P (1 << 17)
+#define S5P_VIDCON0_PNRMODE_RGB_S (2 << 17)
+#define S5P_VIDCON0_PNRMODE_BGR_S (3 << 17)
+#define S5P_VIDCON0_PNRMODE_MASK (3 << 17)
+#define S5P_VIDCON0_PNRMODE_SHIFT (17)
+#define S5P_VIDCON0_CLKVALUP_ALWAYS (0 << 16)
+#define S5P_VIDCON0_CLKVALUP_START_FRAME (1 << 16)
+#define S5P_VIDCON0_CLKVALUP_MASK (1 << 16)
+#define S5P_VIDCON0_CLKVAL_F(x) (((x) & 0xff) << 6)
+#define S5P_VIDCON0_CLKVAL_F_MASK (0xff << 6)
+#define S5P_VIDCON0_VCLKEN_NORMAL (0 << 5)
+#define S5P_VIDCON0_VCLKEN_FREERUN (1 << 5)
+#define S5P_VIDCON0_VCLKEN_MASK (1 << 5)
+#define S5P_VIDCON0_CLKDIR_DIRECTED (0 << 4)
+#define S5P_VIDCON0_CLKDIR_DIVIDED (1 << 4)
+#define S5P_VIDCON0_CLKDIR_MASK (1 << 4)
+#define S5P_VIDCON0_CLKSEL_HCLK (0 << 2)
+#define S5P_VIDCON0_CLKSEL_SCLK (1 << 2)
+#define S5P_VIDCON0_CLKSEL_MASK (1 << 2)
+#define S5P_VIDCON0_ENVID_ENABLE (1 << 1)
+#define S5P_VIDCON0_ENVID_DISABLE (0 << 1)
+#define S5P_VIDCON0_ENVID_F_ENABLE (1 << 0)
+#define S5P_VIDCON0_ENVID_F_DISABLE (0 << 0)
+
+/* VIDCON1 */
+#define S5P_VIDCON1_FIXVCLK_MASK (3 << 9)
+#define S5P_VIDCON1_FIXVCLK_HOLD (0 << 9)
+#define S5P_VIDCON1_FIXVCLK_RUN (1 << 9)
+#define S5P_VIDCON1_IVCLK_FALLING_EDGE (0 << 7)
+#define S5P_VIDCON1_IVCLK_RISING_EDGE (1 << 7)
+#define S5P_VIDCON1_IHSYNC_NORMAL (0 << 6)
+#define S5P_VIDCON1_IHSYNC_INVERT (1 << 6)
+#define S5P_VIDCON1_IVSYNC_NORMAL (0 << 5)
+#define S5P_VIDCON1_IVSYNC_INVERT (1 << 5)
+#define S5P_VIDCON1_IVDEN_NORMAL (0 << 4)
+#define S5P_VIDCON1_IVDEN_INVERT (1 << 4)
+
+/* VIDCON2 */
+#define S5P_VIDCON2_EN601_DISABLE (0 << 23)
+#define S5P_VIDCON2_EN601_ENABLE (1 << 23)
+#define S5P_VIDCON2_EN601_MASK (1 << 23)
+#define S5P_VIDCON2_WB_DISABLE (0 << 15)
+#define S5P_VIDCON2_WB_ENABLE (1 << 15)
+#define S5P_VIDCON2_WB_MASK (1 << 15)
+#define S5P_VIDCON2_TVFORMATSEL_HW (0 << 14)
+#define S5P_VIDCON2_TVFORMATSEL_SW (1 << 14)
+#define S5P_VIDCON2_TVFORMATSEL_MASK (1 << 14)
+#define S5P_VIDCON2_TVFORMATSEL_YUV422 (1 << 12)
+#define S5P_VIDCON2_TVFORMATSEL_YUV444 (2 << 12)
+#define S5P_VIDCON2_TVFORMATSEL_YUV_MASK (3 << 12)
+#define S5P_VIDCON2_ORGYUV_YCBCR (0 << 8)
+#define S5P_VIDCON2_ORGYUV_CBCRY (1 << 8)
+#define S5P_VIDCON2_ORGYUV_MASK (1 << 8)
+#define S5P_VIDCON2_YUVORD_CBCR (0 << 7)
+#define S5P_VIDCON2_YUVORD_CRCB (1 << 7)
+#define S5P_VIDCON2_YUVORD_MASK (1 << 7)
+
+/* PRTCON */
+#define S5P_PRTCON_UPDATABLE (0 << 11)
+#define S5P_PRTCON_PROTECT (1 << 11)
+
+/* VIDTCON0 */
+#define S5P_VIDTCON0_VBPDE(x) (((x) & 0xff) << 24)
+#define S5P_VIDTCON0_VBPD(x) (((x) & 0xff) << 16)
+#define S5P_VIDTCON0_VFPD(x) (((x) & 0xff) << 8)
+#define S5P_VIDTCON0_VSPW(x) (((x) & 0xff) << 0)
+
+/* VIDTCON1 */
+#define S5P_VIDTCON1_VFPDE(x) (((x) & 0xff) << 24)
+#define S5P_VIDTCON1_HBPD(x) (((x) & 0xff) << 16)
+#define S5P_VIDTCON1_HFPD(x) (((x) & 0xff) << 8)
+#define S5P_VIDTCON1_HSPW(x) (((x) & 0xff) << 0)
+
+/* VIDTCON2 */
+#define S5P_VIDTCON2_LINEVAL(x) (((x) & 0x7ff) << 11)
+#define S5P_VIDTCON2_HOZVAL(x) (((x) & 0x7ff) << 0)
+
+/* Window 0~4 Control - WINCONx */
+#define S5P_WINCON_DATAPATH_DMA (0 << 22)
+#define S5P_WINCON_DATAPATH_LOCAL (1 << 22)
+#define S5P_WINCON_DATAPATH_MASK (1 << 22)
+#define S5P_WINCON_BUFSEL_0 (0 << 20)
+#define S5P_WINCON_BUFSEL_1 (1 << 20)
+#define S5P_WINCON_BUFSEL_MASK (1 << 20)
+#define S5P_WINCON_BUFSEL_SHIFT (20)
+#define S5P_WINCON_BUFAUTO_DISABLE (0 << 19)
+#define S5P_WINCON_BUFAUTO_ENABLE (1 << 19)
+#define S5P_WINCON_BUFAUTO_MASK (1 << 19)
+#define S5P_WINCON_BITSWP_DISABLE (0 << 18)
+#define S5P_WINCON_BITSWP_ENABLE (1 << 18)
+#define S5P_WINCON_BITSWP_SHIFT (18)
+#define S5P_WINCON_BYTESWP_DISABLE (0 << 17)
+#define S5P_WINCON_BYTESWP_ENABLE (1 << 17)
+#define S5P_WINCON_BYTESWP_SHIFT (17)
+#define S5P_WINCON_HAWSWP_DISABLE (0 << 16)
+#define S5P_WINCON_HAWSWP_ENABLE (1 << 16)
+#define S5P_WINCON_HAWSWP_SHIFT (16)
+#define S5P_WINCON_WSWP_DISABLE (0 << 15)
+#define S5P_WINCON_WSWP_ENABLE (1 << 15)
+#define S5P_WINCON_WSWP_SHIFT (15)
+#define S5P_WINCON_INRGB_RGB (0 << 13)
+#define S5P_WINCON_INRGB_YUV (1 << 13)
+#define S5P_WINCON_INRGB_MASK (1 << 13)
+#define S5P_WINCON_BURSTLEN_16WORD (0 << 9)
+#define S5P_WINCON_BURSTLEN_8WORD (1 << 9)
+#define S5P_WINCON_BURSTLEN_4WORD (2 << 9)
+#define S5P_WINCON_BURSTLEN_MASK (3 << 9)
+#define S5P_WINCON_ALPHA_MULTI_DISABLE (0 << 7)
+#define S5P_WINCON_ALPHA_MULTI_ENABLE (1 << 7)
+#define S5P_WINCON_BLD_PLANE (0 << 6)
+#define S5P_WINCON_BLD_PIXEL (1 << 6)
+#define S5P_WINCON_BLD_MASK (1 << 6)
+#define S5P_WINCON_BPPMODE_1BPP (0 << 2)
+#define S5P_WINCON_BPPMODE_2BPP (1 << 2)
+#define S5P_WINCON_BPPMODE_4BPP (2 << 2)
+#define S5P_WINCON_BPPMODE_8BPP_PAL (3 << 2)
+#define S5P_WINCON_BPPMODE_8BPP (4 << 2)
+#define S5P_WINCON_BPPMODE_16BPP_565 (5 << 2)
+#define S5P_WINCON_BPPMODE_16BPP_A555 (6 << 2)
+#define S5P_WINCON_BPPMODE_18BPP_666 (8 << 2)
+#define S5P_WINCON_BPPMODE_18BPP_A665 (9 << 2)
+#define S5P_WINCON_BPPMODE_24BPP_888 (0xb << 2)
+#define S5P_WINCON_BPPMODE_24BPP_A887 (0xc << 2)
+#define S5P_WINCON_BPPMODE_32BPP (0xd << 2)
+#define S5P_WINCON_BPPMODE_16BPP_A444 (0xe << 2)
+#define S5P_WINCON_BPPMODE_15BPP_555 (0xf << 2)
+#define S5P_WINCON_BPPMODE_MASK (0xf << 2)
+#define S5P_WINCON_BPPMODE_SHIFT (2)
+#define S5P_WINCON_ALPHA0_SEL (0 << 1)
+#define S5P_WINCON_ALPHA1_SEL (1 << 1)
+#define S5P_WINCON_ALPHA_SEL_MASK (1 << 1)
+#define S5P_WINCON_ENWIN_DISABLE (0 << 0)
+#define S5P_WINCON_ENWIN_ENABLE (1 << 0)
+
+/* WINCON1 special */
+#define S5P_WINCON1_VP_DISABLE (0 << 24)
+#define S5P_WINCON1_VP_ENABLE (1 << 24)
+#define S5P_WINCON1_LOCALSEL_FIMC1 (0 << 23)
+#define S5P_WINCON1_LOCALSEL_VP (1 << 23)
+#define S5P_WINCON1_LOCALSEL_MASK (1 << 23)
+
+/* WINSHMAP */
+#define S5P_SHADOWCON_PROTECT(x) (1 << (10 + x))
+#define S5P_SHADOWCON_CH_ENABLE(x) (1 << (x))
+#define S5P_SHADOWCON_CH_DISABLE(x) (1 << (x))
+
+
+/* VIDOSDxA, VIDOSDxB */
+#define S5P_VIDOSD_LEFT_X(x) (((x) & 0x7ff) << 11)
+#define S5P_VIDOSD_TOP_Y(x) (((x) & 0x7ff) << 0)
+#define S5P_VIDOSD_RIGHT_X(x) (((x) & 0x7ff) << 11)
+#define S5P_VIDOSD_BOTTOM_Y(x) (((x) & 0x7ff) << 0)
+
+/* VIDOSD0C, VIDOSDxD */
+#define S5P_VIDOSD_SIZE(x) (((x) & 0xffffff) << 0)
+
+/* VIDOSDxC (1~4) */
+#define S5P_VIDOSD_ALPHA0_R(x) (((x) & 0xf) << 20)
+#define S5P_VIDOSD_ALPHA0_G(x) (((x) & 0xf) << 16)
+#define S5P_VIDOSD_ALPHA0_B(x) (((x) & 0xf) << 12)
+#define S5P_VIDOSD_ALPHA1_R(x) (((x) & 0xf) << 8)
+#define S5P_VIDOSD_ALPHA1_G(x) (((x) & 0xf) << 4)
+#define S5P_VIDOSD_ALPHA1_B(x) (((x) & 0xf) << 0)
+#define S5P_VIDOSD_ALPHA0_SHIFT (12)
+#define S5P_VIDOSD_ALPHA1_SHIFT (0)
+
+/* Start Address */
+#define S5P_VIDADDR_START_VBANK(x) (((x) & 0xff) << 24)
+#define S5P_VIDADDR_START_VBASEU(x) (((x) & 0xffffff) << 0)
+
+/* End Address */
+#define S5P_VIDADDR_END_VBASEL(x) (((x) & 0xffffff) << 0)
+
+/* Buffer Size */
+#define S5P_VIDADDR_OFFSIZE(x) (((x) & 0x1fff) << 13)
+#define S5P_VIDADDR_PAGEWIDTH(x) (((x) & 0x1fff) << 0)
+
+/* WIN Color Map */
+#define S5P_WINMAP_COLOR(x) ((x) & 0xffffff)
+
+/* VIDINTCON0 */
+#define S5P_VIDINTCON0_SYSMAINCON_DISABLE (0 << 19)
+#define S5P_VIDINTCON0_SYSMAINCON_ENABLE (1 << 19)
+#define S5P_VIDINTCON0_SYSSUBCON_DISABLE (0 << 18)
+#define S5P_VIDINTCON0_SYSSUBCON_ENABLE (1 << 18)
+#define S5P_VIDINTCON0_SYSIFDONE_DISABLE (0 << 17)
+#define S5P_VIDINTCON0_SYSIFDONE_ENABLE (1 << 17)
+#define S5P_VIDINTCON0_FRAMESEL0_BACK (0 << 15)
+#define S5P_VIDINTCON0_FRAMESEL0_VSYNC (1 << 15)
+#define S5P_VIDINTCON0_FRAMESEL0_ACTIVE (2 << 15)
+#define S5P_VIDINTCON0_FRAMESEL0_FRONT (3 << 15)
+#define S5P_VIDINTCON0_FRAMESEL0_MASK (3 << 15)
+#define S5P_VIDINTCON0_FRAMESEL1_NONE (0 << 13)
+#define S5P_VIDINTCON0_FRAMESEL1_BACK (1 << 13)
+#define S5P_VIDINTCON0_FRAMESEL1_VSYNC (2 << 13)
+#define S5P_VIDINTCON0_FRAMESEL1_FRONT (3 << 13)
+#define S5P_VIDINTCON0_INTFRMEN_DISABLE (0 << 12)
+#define S5P_VIDINTCON0_INTFRMEN_ENABLE (1 << 12)
+#define S5P_VIDINTCON0_FIFOSEL_WIN4 (1 << 11)
+#define S5P_VIDINTCON0_FIFOSEL_WIN3 (1 << 10)
+#define S5P_VIDINTCON0_FIFOSEL_WIN2 (1 << 9)
+#define S5P_VIDINTCON0_FIFOSEL_WIN1 (1 << 6)
+#define S5P_VIDINTCON0_FIFOSEL_WIN0 (1 << 5)
+#define S5P_VIDINTCON0_FIFOSEL_ALL (0x73 << 5)
+#define S5P_VIDINTCON0_FIFOSEL_MASK (0x73 << 5)
+#define S5P_VIDINTCON0_FIFOLEVEL_25 (0 << 2)
+#define S5P_VIDINTCON0_FIFOLEVEL_50 (1 << 2)
+#define S5P_VIDINTCON0_FIFOLEVEL_75 (2 << 2)
+#define S5P_VIDINTCON0_FIFOLEVEL_EMPTY (3 << 2)
+#define S5P_VIDINTCON0_FIFOLEVEL_FULL (4 << 2)
+#define S5P_VIDINTCON0_FIFOLEVEL_MASK (7 << 2)
+#define S5P_VIDINTCON0_INTFIFO_DISABLE (0 << 1)
+#define S5P_VIDINTCON0_INTFIFO_ENABLE (1 << 1)
+#define S5P_VIDINTCON0_INT_DISABLE (0 << 0)
+#define S5P_VIDINTCON0_INT_ENABLE (1 << 0)
+#define S5P_VIDINTCON0_INT_MASK (1 << 0)
+
+/* VIDINTCON1 */
+#define S5P_VIDINTCON1_INTVPPEND (1 << 5)
+#define S5P_VIDINTCON1_INTI80PEND (1 << 2)
+#define S5P_VIDINTCON1_INTFRMPEND (1 << 1)
+#define S5P_VIDINTCON1_INTFIFOPEND (1 << 0)
+
+/* WINMAP */
+#define S5P_WINMAP_ENABLE (1 << 24)
+
+/* WxKEYCON0 (1~4) */
+#define S5P_KEYCON0_KEYBLEN_DISABLE (0 << 26)
+#define S5P_KEYCON0_KEYBLEN_ENABLE (1 << 26)
+#define S5P_KEYCON0_KEY_DISABLE (0 << 25)
+#define S5P_KEYCON0_KEY_ENABLE (1 << 25)
+#define S5P_KEYCON0_DIRCON_MATCH_FG (0 << 24)
+#define S5P_KEYCON0_DIRCON_MATCH_BG (1 << 24)
+#define S5P_KEYCON0_COMPKEY(x) (((x) & 0xffffff) << 0)
+
+/* WxKEYCON1 (1~4) */
+#define S5P_KEYCON1_COLVAL(x) (((x) & 0xffffff) << 0)
+
+
+#endif // _Display_Dxe_H__
diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/DisplayDxe/DisplayDxe.inf b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/DisplayDxe/DisplayDxe.inf
new file mode 100644
index 000000000..3667e00a2
--- /dev/null
+++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/DisplayDxe/DisplayDxe.inf
@@ -0,0 +1,65 @@
+## @file
+#
+# Component description file for GraphicsConsole module
+#
+# This is the main routine for initializing the Graphics Console support routines.
+#
+# Copyright (c) 2012, Samsung Electronics Co. All rights reserved.<BR>
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = DisplayDxe
+ FILE_GUID = c5deae31-fad2-4030-841b-cfc9644d2c5b
+ MODULE_TYPE = UEFI_DRIVER
+ VERSION_STRING = 1.0
+ ENTRY_POINT = DisplayDxeInitialize
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF EBC
+#
+# DRIVER_BINDING = gGraphicsConsoleDriverBinding
+# COMPONENT_NAME = gGraphicsConsoleComponentName
+# COMPONENT_NAME2 = gGraphicsConsoleComponentName2
+#
+
+[Sources]
+ DisplayDxe.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ SamsungPlatformPkg/ExynosPkg/Exynos5250/ExynosPkg.dec
+ SamsungPlatformPkg/SamsungPlatformPkg.dec
+
+[LibraryClasses]
+ BaseLib
+ UefiLib
+ MemoryAllocationLib
+ UefiDriverEntryPoint
+ IoLib
+ TimerLib
+
+[Protocols]
+ gEfiGraphicsOutputProtocolGuid ## TO_START
+ gSamsungPlatformGpioProtocolGuid ## GPIO Protocol
+
+[Guids]
+
+[Pcd]
+ gExynosPkgTokenSpaceGuid.PcdCmuBase
+ gExynosPkgTokenSpaceGuid.PcdPmuBase
+ gExynosPkgTokenSpaceGuid.PcdSysBase
+ gExynosPkgTokenSpaceGuid.PcdFIMD1Base
+ gExynosPkgTokenSpaceGuid.PcdFrameBufferBase
+ gExynosPkgTokenSpaceGuid.PcdDSIM1Base
diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/EthDxe/EthDxe.c b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/EthDxe/EthDxe.c
new file mode 100644
index 000000000..51a8c1617
--- /dev/null
+++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/EthDxe/EthDxe.c
@@ -0,0 +1,788 @@
+/** @file
+ Template for Timer Architecture Protocol driver of the ARM flavor
+
+ Copyright (c) 2012, Samsung Electronics Co. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+
+#include <PiDxe.h>
+
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiLib.h>
+#include <Library/PcdLib.h>
+#include <Library/IoLib.h>
+#include <Library/NetLib.h>
+#include <Library/TimerLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Protocol/SimpleNetwork.h>
+#include <Protocol/DevicePath.h>
+#include <Protocol/ExynosGpio.h>
+#include <Platform/ArmPlatform.h>
+#include "EthDxe.h"
+
+
+ETH_DXE_PRIVATE_DATA gEthDxePrivateTemplate = {
+ ETH_DXE_PRIVATE_DATA_SIGNATURE,
+ {
+ EFI_SIMPLE_NETWORK_PROTOCOL_REVISION,
+ EthStart,
+ EthStop,
+ EthInitialize,
+ EthReset,
+ EthShutdown,
+ EthReceiveFilters,
+ EthStationAddress,
+ EthStatistics,
+ EthMCastIpToMac,
+ EthNvData,
+ EthGetStatus,
+ EthTransmit,
+ EthReceive,
+ NULL,
+ NULL
+ },
+ {
+ EfiSimpleNetworkStopped, // State
+ NET_ETHER_ADDR_LEN, // HwAddressSize
+ NET_ETHER_HEADER_SIZE, // MediaHeaderSize
+ 1500, // MaxPacketSize
+ 0, // NvRamSize
+ 0, // NvRamAccessSize
+ 0, // ReceiveFilterMask
+ 0, // ReceiveFilterSetting
+ MAX_MCAST_FILTER_CNT, // MaxMCastFilterCount
+ 0, // MCastFilterCount
+ {
+ 0
+ }, // MCastFilter
+ {
+ 0
+ }, // CurrentAddress
+ {
+ 0
+ }, // BroadcastAddress
+ {
+ 0
+ }, // PermanentAddress
+ NET_IFTYPE_ETHERNET, // IfType
+ FALSE, // MacAddressChangeable
+ FALSE, // MultipleTxSupported
+ FALSE, // MediaPresentSupported
+ TRUE // MediaPresent
+ },
+ {
+ {
+ HARDWARE_DEVICE_PATH,
+ HW_VENDOR_DP,
+ (UINT8)(sizeof(VENDOR_DEVICE_PATH)),
+ (UINT8)((sizeof(VENDOR_DEVICE_PATH)) >> 8),
+ EFI_SIMPLE_NETWORK_PROTOCOL_GUID
+ },
+ {
+ END_DEVICE_PATH_TYPE,
+ END_ENTIRE_DEVICE_PATH_SUBTYPE,
+ sizeof (EFI_DEVICE_PATH_PROTOCOL),
+ 0
+ }
+ }
+};
+
+
+UINT32 smc911x_reg_read(UINT32 offset)
+{
+ UINT32 regBase = PcdGet32(PcdSMC911XBase);
+ UINT32 val;
+
+ val = (MmioRead16(regBase + offset) & 0xFFFF) | ((MmioRead16(regBase + offset + 2) & 0xFFFF) << 16);
+
+ return val;
+}
+
+VOID smc911x_reg_write(UINT32 offset, UINT32 val)
+{
+ UINT32 regBase = PcdGet32(PcdSMC911XBase);
+
+ MmioWrite16(regBase + offset, ((UINT16)(val & 0xFFFF)));
+ MmioWrite16(regBase + offset + 2, ((UINT16)((val & 0xFFFF0000)>>16)));
+}
+
+UINT32 smc911x_get_mac_csr(UINT8 reg)
+{
+ while (smc911x_reg_read(MAC_CSR_CMD) & MAC_CSR_CMD_CSR_BUSY)
+ ;
+ smc911x_reg_write(MAC_CSR_CMD, (MAC_CSR_CMD_CSR_BUSY | MAC_CSR_CMD_R_NOT_W | reg));
+ while (smc911x_reg_read(MAC_CSR_CMD) & MAC_CSR_CMD_CSR_BUSY)
+ ;
+ return smc911x_reg_read(MAC_CSR_DATA);
+}
+
+VOID smc911x_set_mac_csr(UINT8 reg, UINT32 data)
+{
+ while (smc911x_reg_read(MAC_CSR_CMD) & MAC_CSR_CMD_CSR_BUSY)
+ ;
+ smc911x_reg_write(MAC_CSR_DATA, data);
+ smc911x_reg_write(MAC_CSR_CMD, (MAC_CSR_CMD_CSR_BUSY | reg));
+ while (smc911x_reg_read(MAC_CSR_CMD) & MAC_CSR_CMD_CSR_BUSY)
+ ;
+}
+
+VOID smc911x_reset(VOID)
+{
+ INT32 timeout;
+
+ /* Take out of PM setting first */
+ if (smc911x_reg_read(PMT_CTRL) & PMT_CTRL_READY) {
+ /* Write to the bytetest will take out of powerdown */
+ smc911x_reg_write(BYTE_TEST, 0x0);
+
+ timeout = 10;
+
+ while (timeout-- && !(smc911x_reg_read(PMT_CTRL) & PMT_CTRL_READY))
+ MicroSecondDelay(10);
+ if (!timeout) {
+ DEBUG((EFI_D_ERROR, "smc911x_reset: timeout waiting for PM restore\n"));
+ return;
+ }
+ }
+
+ /* Disable interrupts */
+ smc911x_reg_write(INT_EN, 0);
+
+ smc911x_reg_write(HW_CFG, HW_CFG_SRST);
+
+ timeout = 1000;
+ while (timeout-- && (smc911x_reg_read(E2P_CMD) & E2P_CMD_EPC_BUSY))
+ MicroSecondDelay(10);
+
+ if (!timeout) {
+ DEBUG((EFI_D_ERROR, "smc911x_reset: reset timeout\n"));
+ return;
+ }
+
+ /* Reset the FIFO level and flow control settings */
+ smc911x_set_mac_csr(FLOW, FLOW_FCPT | FLOW_FCEN);
+ smc911x_reg_write(AFC_CFG, 0x0050287F);
+
+ /* Set to LED outputs */
+ smc911x_reg_write(GPIO_CFG, 0x70070000);
+}
+
+VOID smc911x_phy_reset(VOID)
+{
+ UINT32 reg;
+
+ reg = smc911x_reg_read(PMT_CTRL);
+ reg &= ~0xfffff030;
+ reg |= PMT_CTRL_PHY_RST;
+ smc911x_reg_write(PMT_CTRL, reg);
+
+ MicroSecondDelay(100000);
+}
+
+VOID smc911x_miiphy_read(UINT8 phy, UINT8 reg, UINT16 *val)
+{
+ while (smc911x_get_mac_csr(MII_ACC) & MII_ACC_MII_BUSY)
+ ;
+
+ smc911x_set_mac_csr(MII_ACC, (phy << 11 | reg << 6 | MII_ACC_MII_BUSY));
+
+ while (smc911x_get_mac_csr(MII_ACC) & MII_ACC_MII_BUSY)
+ ;
+
+ *val = smc911x_get_mac_csr(MII_DATA);
+}
+
+VOID smc911x_miiphy_write(UINT8 phy, UINT8 reg, UINT16 val)
+{
+ while (smc911x_get_mac_csr(MII_ACC) & MII_ACC_MII_BUSY)
+ ;
+
+ smc911x_set_mac_csr(MII_DATA, val);
+ smc911x_set_mac_csr(MII_ACC, (phy << 11 | reg << 6 | MII_ACC_MII_BUSY | MII_ACC_MII_WRITE));
+
+ while (smc911x_get_mac_csr(MII_ACC) & MII_ACC_MII_BUSY)
+ ;
+}
+
+VOID smc911x_phy_configure(VOID)
+{
+ INT32 timeout;
+ UINT16 status;
+
+ smc911x_phy_reset();
+
+ smc911x_miiphy_write(1, PHY_BMCR, PHY_BMCR_RESET);
+ MicroSecondDelay(1000);
+ smc911x_miiphy_write(1, PHY_ANAR, 0x01e1);
+ smc911x_miiphy_write(1, PHY_BMCR, (PHY_BMCR_AUTON | PHY_BMCR_RST_NEG));
+
+ timeout = 5000;
+ do {
+ MicroSecondDelay(1000);
+ if ((timeout--) == 0)
+ goto err_out;
+
+ smc911x_miiphy_read(1, PHY_BMSR, &status);
+ } while (!(status & PHY_BMSR_LS));
+
+ DEBUG((EFI_D_ERROR, "smc911x_phy_configure: PHY initialized\n"));
+
+ return;
+
+err_out:
+ DEBUG((EFI_D_ERROR, "smc911x_phy_configure: autonegotiation timed out\n"));
+}
+
+VOID smc911x_handle_mac_address(ETH_DXE_PRIVATE_DATA *Private)
+{
+ UINT32 addrh, addrl;
+
+ addrl = Private->Mode.CurrentAddress.Addr[0] | \
+ (Private->Mode.CurrentAddress.Addr[1] << 8) | \
+ (Private->Mode.CurrentAddress.Addr[2] << 16) | \
+ (Private->Mode.CurrentAddress.Addr[3] << 24);
+ addrh = Private->Mode.CurrentAddress.Addr[4] | \
+ (Private->Mode.CurrentAddress.Addr[5] << 8);
+
+ smc911x_set_mac_csr(ADDRL, addrl);
+ smc911x_set_mac_csr(ADDRH, addrh);
+}
+
+VOID smc911x_enable(VOID)
+{
+ /* Enable TX */
+ smc911x_reg_write(HW_CFG, (8 << 16 | HW_CFG_SF));
+
+ smc911x_reg_write(GPT_CFG, (GPT_CFG_TIMER_EN | 10000));
+
+ smc911x_reg_write(TX_CFG, TX_CFG_TX_ON);
+
+ /* no padding to start of packets */
+ smc911x_reg_write(RX_CFG, 0);
+
+ smc911x_set_mac_csr(MAC_CR, (MAC_CR_TXEN | MAC_CR_RXEN | MAC_CR_HBDIS /*| MAC_CR_PADSTR*/));
+}
+
+EFI_STATUS
+EFIAPI
+EthStart(
+ EFI_SIMPLE_NETWORK_PROTOCOL *This
+)
+{
+ ETH_DXE_PRIVATE_DATA *Private;
+
+ Private = ETH_DXE_PRIVATE_DATA_FROM_SNP_THIS(This);
+
+ switch ( Private->Snp.Mode->State )
+ {
+ case EfiSimpleNetworkStopped:
+ break;
+
+ case EfiSimpleNetworkStarted:
+ case EfiSimpleNetworkInitialized:
+ return( EFI_ALREADY_STARTED );
+ break;
+
+ default:
+ return( EFI_DEVICE_ERROR );
+ break;
+ }
+
+ /* gpio configuration */
+ MmioAndThenOr32(0x11000000 + 0x120, ~((0xFF<<16)|(0xFF<<4)), ((0x22<<16)|(0x52<<4)));
+
+ /* 16 Bit bus width */
+ MmioWrite32(0x11000000 + 0x1C0, 0x22222222);
+ MmioWrite32(0x11000000 + 0x1E0, 0x22222222);
+
+ /* SROM BANK1 */
+ MmioAndThenOr32(0x12570000, ~(0xF<<4), (((1<<0)|(0<<2)|(1<<3))<<4));
+
+ /* set timing for nCS1 suitable for ethernet chip */
+ MmioWrite32(0x12570008, ((0x1 << 0) | (0x9 << 4) | (0xC << 8) | (0x1 << 12) | \
+ (0x6 << 16) | (0x1 << 24) | (0x1 << 28)));
+
+ Private->Snp.Mode->State = EfiSimpleNetworkStarted;
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+EthStop(
+ EFI_SIMPLE_NETWORK_PROTOCOL *This
+)
+{
+ ETH_DXE_PRIVATE_DATA *Private;
+
+ Private = ETH_DXE_PRIVATE_DATA_FROM_SNP_THIS(This);
+
+ switch ( Private->Snp.Mode->State )
+ {
+ case EfiSimpleNetworkStarted:
+ break;
+
+ case EfiSimpleNetworkStopped:
+ return( EFI_NOT_STARTED );
+ break;
+
+ default:
+ return( EFI_DEVICE_ERROR );
+ break;
+ }
+
+ Private->Snp.Mode->State = EfiSimpleNetworkStopped;
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+EthInitialize(
+ EFI_SIMPLE_NETWORK_PROTOCOL *This,
+ UINTN ExtraRxBufferSize,
+ UINTN ExtraTxBufferSize
+)
+{
+ UINT32 val, i, addrh, addrl;
+ ETH_DXE_PRIVATE_DATA *Private;
+
+ Private = ETH_DXE_PRIVATE_DATA_FROM_SNP_THIS(This);
+
+ switch ( Private->Snp.Mode->State )
+ {
+ case EfiSimpleNetworkStarted:
+ break;
+
+ case EfiSimpleNetworkStopped:
+ return( EFI_NOT_STARTED );
+ break;
+
+ default:
+ return( EFI_DEVICE_ERROR );
+ break;
+ }
+
+ val = smc911x_reg_read(BYTE_TEST);
+
+ if(val == 0xFFFFFFFF) {
+ return EFI_NO_MEDIA;
+ }
+ else if(val != 0x87654321) {
+ DEBUG((EFI_D_ERROR,"EthInitialize: Invalid chip endian 0x%x\n", val));
+ return EFI_NO_MEDIA;
+ }
+
+ val = smc911x_reg_read(ID_REV) >> 16;
+ for(i=0;chip_ids[i].id != 0;i++) {
+ if(chip_ids[i].id == val)
+ break;
+ }
+
+ if(!chip_ids[i].id) {
+ DEBUG((EFI_D_ERROR,"EthInitialize: Unknown chip id 0x%x\n", val));
+ return EFI_NO_MEDIA;
+ }
+ else {
+ DEBUG((EFI_D_ERROR,"EthInitialize: Chip id 0x%x\n", val));
+ }
+
+ addrh = smc911x_get_mac_csr(ADDRH);
+ addrl = smc911x_get_mac_csr(ADDRL);
+
+ if (addrl == 0xffffffff && addrh == 0x0000ffff) {
+ addrh = 0x00000040;
+ addrl = 0x5c260a5b;
+ }
+
+ Private->Mode.CurrentAddress.Addr[0] = (addrl & 0xFF);
+ Private->Mode.CurrentAddress.Addr[1] = (addrl & 0xFF00)>>8;
+ Private->Mode.CurrentAddress.Addr[2] = (addrl & 0xFF0000)>>16;
+ Private->Mode.CurrentAddress.Addr[3] = (addrl & 0xFF000000)>>24;
+ Private->Mode.CurrentAddress.Addr[4] = (addrh & 0xFF);
+ Private->Mode.CurrentAddress.Addr[5] = (addrh & 0xFF00)>>8;
+ gBS->CopyMem((VOID *)&Private->Mode.PermanentAddress, \
+ (VOID *)&Private->Mode.CurrentAddress, \
+ sizeof(EFI_MAC_ADDRESS));
+
+ DEBUG((EFI_D_ERROR,"EthInitialize: MAC address is "));
+
+ for(i=6;i>0;i--) {
+ DEBUG((EFI_D_ERROR,"%02x", Private->Mode.CurrentAddress.Addr[i - 1]));
+ if(i > 1)
+ DEBUG((EFI_D_ERROR,":"));
+ else
+ DEBUG((EFI_D_ERROR,"\n"));
+ }
+
+ smc911x_reset();
+
+ /* Configure the PHY, initialize the link state */
+ smc911x_phy_configure();
+
+ smc911x_handle_mac_address(Private);
+
+ /* Turn on Tx + Rx */
+ smc911x_enable();
+
+ Private->Snp.Mode->State = EfiSimpleNetworkInitialized;
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+EthReset(
+ EFI_SIMPLE_NETWORK_PROTOCOL *This,
+ BOOLEAN ExtendedVerification
+)
+{
+ ETH_DXE_PRIVATE_DATA *Private;
+
+ Private = ETH_DXE_PRIVATE_DATA_FROM_SNP_THIS(This);
+
+ switch ( Private->Snp.Mode->State )
+ {
+ case EfiSimpleNetworkInitialized:
+ break;
+
+ case EfiSimpleNetworkStopped:
+ return( EFI_NOT_STARTED );
+ break;
+
+ default:
+ return( EFI_DEVICE_ERROR );
+ break;
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+EthShutdown(
+ EFI_SIMPLE_NETWORK_PROTOCOL *This
+)
+{
+ ETH_DXE_PRIVATE_DATA *Private;
+
+ Private = ETH_DXE_PRIVATE_DATA_FROM_SNP_THIS(This);
+
+ switch ( Private->Snp.Mode->State )
+ {
+ case EfiSimpleNetworkInitialized:
+ break;
+
+ case EfiSimpleNetworkStopped:
+ return( EFI_NOT_STARTED );
+ break;
+
+ default:
+ return( EFI_DEVICE_ERROR );
+ break;
+ }
+
+ Private->Snp.Mode->State = EfiSimpleNetworkStarted;
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+EthReceiveFilters(
+ EFI_SIMPLE_NETWORK_PROTOCOL *This,
+ UINT32 Enable,
+ UINT32 Disable,
+ BOOLEAN ResetMCastFilter,
+ UINTN MCastFilterCnt,
+ EFI_MAC_ADDRESS *MCastFilter
+)
+{
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+EthStationAddress(
+ EFI_SIMPLE_NETWORK_PROTOCOL *This,
+ BOOLEAN Reset,
+ EFI_MAC_ADDRESS *New
+)
+{
+ return EFI_UNSUPPORTED;
+}
+
+EFI_STATUS
+EFIAPI
+EthStatistics(
+ EFI_SIMPLE_NETWORK_PROTOCOL *This,
+ BOOLEAN Reset,
+ UINTN *StatisticsSize,
+ EFI_NETWORK_STATISTICS *StatisticsTable
+)
+{
+ return EFI_UNSUPPORTED;
+}
+
+EFI_STATUS
+EFIAPI
+EthMCastIpToMac(
+ EFI_SIMPLE_NETWORK_PROTOCOL *This,
+ BOOLEAN IPv6,
+ EFI_IP_ADDRESS *IP,
+ EFI_MAC_ADDRESS *MAC
+)
+{
+ return EFI_UNSUPPORTED;
+}
+
+EFI_STATUS
+EFIAPI
+EthNvData(
+ EFI_SIMPLE_NETWORK_PROTOCOL *This,
+ BOOLEAN ReadWrite,
+ UINTN Offset,
+ UINTN BufferSize,
+ VOID *Buffer
+)
+{
+ return EFI_UNSUPPORTED;
+}
+
+EFI_STATUS
+EFIAPI
+EthGetStatus(
+ EFI_SIMPLE_NETWORK_PROTOCOL *This,
+ UINT32 *InterruptStatus,
+ VOID **TxBuf
+)
+{
+ if ( TxBuf != NULL ) {
+ *( ( UINT8 ** ) TxBuf ) = ( UINT8 * ) 1;
+ }
+
+ if ( InterruptStatus != NULL ) {
+ *InterruptStatus = EFI_SIMPLE_NETWORK_TRANSMIT_INTERRUPT;
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+EthTransmit(
+ EFI_SIMPLE_NETWORK_PROTOCOL *This,
+ UINTN HeaderSize,
+ UINTN BufferSize,
+ VOID *Buffer,
+ EFI_MAC_ADDRESS *SrcAddr,
+ EFI_MAC_ADDRESS *DestAddr,
+ UINT16 *Protocol
+)
+{
+ UINT32 *data = (UINT32 *)Buffer;
+ UINT32 tmpSize;
+ UINT32 status;
+ EthernetHeader *EnetHeader;
+
+ if ( This->Mode->State < EfiSimpleNetworkStarted ) {
+ return( EFI_NOT_STARTED );
+ }
+
+ if ( HeaderSize != 0 ) {
+ if ( ( DestAddr == NULL ) || ( Protocol == NULL ) || \
+ ( HeaderSize != This->Mode->MediaHeaderSize ) ) {
+ return( EFI_INVALID_PARAMETER );
+ }
+
+ if ( SrcAddr == NULL ) {
+ SrcAddr = &This->Mode->CurrentAddress;
+ }
+
+ EnetHeader = (EthernetHeader *)Buffer;
+
+ CopyMem( EnetHeader->DstAddr, DestAddr, NET_ETHER_ADDR_LEN );
+ CopyMem( EnetHeader->SrcAddr, SrcAddr, NET_ETHER_ADDR_LEN );
+
+ EnetHeader->Type = HTONS( *Protocol );
+ }
+
+ smc911x_reg_write(TX_DATA_FIFO, TX_CMD_A_INT_FIRST_SEG | TX_CMD_A_INT_LAST_SEG | BufferSize);
+ smc911x_reg_write(TX_DATA_FIFO, BufferSize);
+
+ tmpSize = (BufferSize + 3) / 4;
+
+ while (tmpSize--)
+ smc911x_reg_write(TX_DATA_FIFO, *data++);
+
+ /* wait for transmission */
+ while (!((smc911x_reg_read(TX_FIFO_INF) & TX_FIFO_INF_TSUSED) >> 16))
+ ;
+
+ /* get status. Ignore 'no carrier' error, it has no meaning for
+ * full duplex operation
+ */
+ status = smc911x_reg_read(TX_STATUS_FIFO) & \
+ (TX_STS_LOC | TX_STS_LATE_COLL | \
+ TX_STS_MANY_COLL | TX_STS_MANY_DEFER | \
+ TX_STS_UNDERRUN);
+
+ if (!status)
+ return EFI_SUCCESS;
+
+ DEBUG((EFI_D_ERROR, "EthTransmit: Failed to send packet: %s%s%s%s%s\n",
+ status & TX_STS_LOC ? "TX_STS_LOC " : "",
+ status & TX_STS_LATE_COLL ? "TX_STS_LATE_COLL " : "",
+ status & TX_STS_MANY_COLL ? "TX_STS_MANY_COLL " : "",
+ status & TX_STS_MANY_DEFER ? "TX_STS_MANY_DEFER " : "",
+ status & TX_STS_UNDERRUN ? "TX_STS_UNDERRUN" : ""));
+
+ return EFI_DEVICE_ERROR;
+}
+
+EFI_STATUS
+EFIAPI
+EthReceive(
+ EFI_SIMPLE_NETWORK_PROTOCOL *This,
+ UINTN *HeaderSize,
+ UINTN *BufferSize,
+ VOID *Buffer,
+ EFI_MAC_ADDRESS *SrcAddr,
+ EFI_MAC_ADDRESS *DestAddr,
+ UINT16 *Protocol
+)
+{
+ UINT32 *data = (UINT32 *)Buffer;
+ UINT32 pktSize, tmpSize;
+ UINT32 status, i;
+ EthernetHeader *EnetHeader;
+
+ /* workaround: delay for rx packet should be added here.
+ * because NetLoop does not guarantee the RX packet delay.
+ */
+ for (i=0; i<0x100000; i++) {
+ if ((smc911x_reg_read(RX_FIFO_INF) & RX_FIFO_INF_RXSUSED) >> 16)
+ break;
+ }
+
+ if (i == 0x100000) {
+ DEBUG((EFI_D_ERROR, "EthReceive: timeout in RX\n"));
+ return EFI_TIMEOUT;
+ }
+
+ if ((smc911x_reg_read(RX_FIFO_INF) & RX_FIFO_INF_RXSUSED) >> 16) {
+ status = smc911x_reg_read(RX_STATUS_FIFO);
+ pktSize = (status & RX_STS_PKT_LEN) >> 16;
+
+ smc911x_reg_write(RX_CFG, 0);
+
+ tmpSize = (pktSize + 3) / 4;
+ i = 0;
+ while (tmpSize--)
+ *data++ = smc911x_reg_read(RX_DATA_FIFO);
+
+ if (status & RX_STS_ES) {
+ DEBUG((EFI_D_ERROR, "EthReceive: dropped bad packet. Status: 0x%x\n", status));
+ }
+
+ *BufferSize = pktSize -4; //discard 4 bytes of FCS
+
+ }
+
+#if 0
+ {
+ UINT8 *tmpBuffer = (UINT8 *)Buffer;
+
+ for(i=0;i<*BufferSize;i++) {
+ DEBUG((EFI_D_ERROR, "%02x", *tmpBuffer++));
+ if((i%16) < 15)
+ DEBUG((EFI_D_ERROR, " "));
+ else
+ DEBUG((EFI_D_ERROR, "\n"));
+ }
+
+ DEBUG((EFI_D_ERROR, "\n"));
+ }
+#endif
+
+ if(HeaderSize != NULL) {
+ *HeaderSize = sizeof(EthernetHeader);
+ }
+
+ EnetHeader = (EthernetHeader *)Buffer;
+
+ if(SrcAddr != NULL) {
+ ZeroMem(SrcAddr, sizeof(EFI_MAC_ADDRESS));
+ CopyMem(SrcAddr, EnetHeader->SrcAddr, NET_ETHER_ADDR_LEN);
+ }
+
+ if(DestAddr != NULL) {
+ ZeroMem(DestAddr, sizeof(EFI_MAC_ADDRESS));
+ CopyMem(DestAddr, EnetHeader->DstAddr, NET_ETHER_ADDR_LEN);
+ }
+
+ if (Protocol != NULL) {
+ *Protocol = NTOHS(EnetHeader->Type);
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Initialize the state information for the Display Dxe
+
+ @param ImageHandle of the loaded driver
+ @param SystemTable Pointer to the System Table
+
+ @retval EFI_SUCCESS Protocol registered
+ @retval EFI_OUT_OF_RESOURCES Cannot allocate protocol data structure
+ @retval EFI_DEVICE_ERROR Hardware problems
+
+**/
+EFI_STATUS
+EFIAPI
+EthDxeInitialize (
+ EFI_HANDLE ImageHandle,
+ EFI_SYSTEM_TABLE *SystemTable
+)
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ EFI_GUID SimpleNetworkProtocolGuid = EFI_SIMPLE_NETWORK_PROTOCOL_GUID;
+ EFI_GUID DevicePathProtocolGuid = EFI_DEVICE_PATH_PROTOCOL_GUID;
+ ETH_DXE_PRIVATE_DATA *Private;
+
+ /* Allocate the private data */
+ Private = (ETH_DXE_PRIVATE_DATA *)AllocateCopyPool(sizeof(ETH_DXE_PRIVATE_DATA), &gEthDxePrivateTemplate );
+ if ( Private == NULL ) {
+ Status = EFI_OUT_OF_RESOURCES;
+ ASSERT_EFI_ERROR(Status);
+ }
+
+ Private->Snp.Mode = &Private->Mode;
+
+ /* Set the broadcast address */
+ SetMem( &Private->Mode.BroadcastAddress, sizeof( EFI_MAC_ADDRESS ), 0xFF );
+
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &ImageHandle,
+ &DevicePathProtocolGuid,
+ &Private->DevicePath,
+ &SimpleNetworkProtocolGuid,
+ &Private->Snp,
+ NULL);
+
+ return Status;
+}
diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/EthDxe/EthDxe.h b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/EthDxe/EthDxe.h
new file mode 100644
index 000000000..3b9a790eb
--- /dev/null
+++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/EthDxe/EthDxe.h
@@ -0,0 +1,612 @@
+/** @file
+*
+* Copyright (c) 2012, Samsung Electronics Co. All rights reserved.
+*
+* This program and the accompanying materials
+* are licensed and made available under the terms and conditions of the BSD License
+* which accompanies this distribution. The full text of the license may be found at
+* http://opensource.org/licenses/bsd-license.php
+*
+* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+
+#ifndef _EthDxe_H__
+#define _EthDxe_H__
+
+#define NET_ETHER_HEADER_SIZE 14
+
+typedef struct
+{
+ UINT8 DstAddr[ NET_ETHER_ADDR_LEN ];
+ UINT8 SrcAddr[ NET_ETHER_ADDR_LEN ];
+ UINT16 Type;
+} EthernetHeader;
+
+/* Chip ID values */
+#define CHIP_9115 0x115
+#define CHIP_9116 0x116
+#define CHIP_9117 0x117
+#define CHIP_9118 0x118
+#define CHIP_9211 0x9211
+#define CHIP_9215 0x115a
+#define CHIP_9216 0x116a
+#define CHIP_9217 0x117a
+#define CHIP_9218 0x118a
+#define CHIP_9220 0x9220
+#define CHIP_9221 0x9221
+
+struct chip_id {
+ UINT16 id;
+ CHAR8 *name;
+};
+
+static const struct chip_id chip_ids[] = {
+ { CHIP_9115, "LAN9115" },
+ { CHIP_9116, "LAN9116" },
+ { CHIP_9117, "LAN9117" },
+ { CHIP_9118, "LAN9118" },
+ { CHIP_9211, "LAN9211" },
+ { CHIP_9215, "LAN9215" },
+ { CHIP_9216, "LAN9216" },
+ { CHIP_9217, "LAN9217" },
+ { CHIP_9218, "LAN9218" },
+ { CHIP_9220, "LAN9220" },
+ { CHIP_9221, "LAN9221" },
+ { 0, NULL },
+};
+
+
+/* Below are the register offsets and bit definitions
+ * of the Lan911x memory space
+ */
+#define RX_DATA_FIFO 0x00
+
+#define TX_DATA_FIFO 0x20
+#define TX_CMD_A_INT_ON_COMP 0x80000000
+#define TX_CMD_A_INT_BUF_END_ALGN 0x03000000
+#define TX_CMD_A_INT_4_BYTE_ALGN 0x00000000
+#define TX_CMD_A_INT_16_BYTE_ALGN 0x01000000
+#define TX_CMD_A_INT_32_BYTE_ALGN 0x02000000
+#define TX_CMD_A_INT_DATA_OFFSET 0x001F0000
+#define TX_CMD_A_INT_FIRST_SEG 0x00002000
+#define TX_CMD_A_INT_LAST_SEG 0x00001000
+#define TX_CMD_A_BUF_SIZE 0x000007FF
+#define TX_CMD_B_PKT_TAG 0xFFFF0000
+#define TX_CMD_B_ADD_CRC_DISABLE 0x00002000
+#define TX_CMD_B_DISABLE_PADDING 0x00001000
+#define TX_CMD_B_PKT_BYTE_LENGTH 0x000007FF
+
+#define RX_STATUS_FIFO 0x40
+#define RX_STS_PKT_LEN 0x3FFF0000
+#define RX_STS_ES 0x00008000
+#define RX_STS_BCST 0x00002000
+#define RX_STS_LEN_ERR 0x00001000
+#define RX_STS_RUNT_ERR 0x00000800
+#define RX_STS_MCAST 0x00000400
+#define RX_STS_TOO_LONG 0x00000080
+#define RX_STS_COLL 0x00000040
+#define RX_STS_ETH_TYPE 0x00000020
+#define RX_STS_WDOG_TMT 0x00000010
+#define RX_STS_MII_ERR 0x00000008
+#define RX_STS_DRIBBLING 0x00000004
+#define RX_STS_CRC_ERR 0x00000002
+#define RX_STATUS_FIFO_PEEK 0x44
+#define TX_STATUS_FIFO 0x48
+#define TX_STS_TAG 0xFFFF0000
+#define TX_STS_ES 0x00008000
+#define TX_STS_LOC 0x00000800
+#define TX_STS_NO_CARR 0x00000400
+#define TX_STS_LATE_COLL 0x00000200
+#define TX_STS_MANY_COLL 0x00000100
+#define TX_STS_COLL_CNT 0x00000078
+#define TX_STS_MANY_DEFER 0x00000004
+#define TX_STS_UNDERRUN 0x00000002
+#define TX_STS_DEFERRED 0x00000001
+#define TX_STATUS_FIFO_PEEK 0x4C
+#define ID_REV 0x50
+#define ID_REV_CHIP_ID 0xFFFF0000 /* RO */
+#define ID_REV_REV_ID 0x0000FFFF /* RO */
+
+#define INT_CFG 0x54
+#define INT_CFG_INT_DEAS 0xFF000000 /* R/W */
+#define INT_CFG_INT_DEAS_CLR 0x00004000
+#define INT_CFG_INT_DEAS_STS 0x00002000
+#define INT_CFG_IRQ_INT 0x00001000 /* RO */
+#define INT_CFG_IRQ_EN 0x00000100 /* R/W */
+ /* R/W Not Affected by SW Reset */
+#define INT_CFG_IRQ_POL 0x00000010
+ /* R/W Not Affected by SW Reset */
+#define INT_CFG_IRQ_TYPE 0x00000001
+
+#define INT_STS 0x58
+#define INT_STS_SW_INT 0x80000000 /* R/WC */
+#define INT_STS_TXSTOP_INT 0x02000000 /* R/WC */
+#define INT_STS_RXSTOP_INT 0x01000000 /* R/WC */
+#define INT_STS_RXDFH_INT 0x00800000 /* R/WC */
+#define INT_STS_RXDF_INT 0x00400000 /* R/WC */
+#define INT_STS_TX_IOC 0x00200000 /* R/WC */
+#define INT_STS_RXD_INT 0x00100000 /* R/WC */
+#define INT_STS_GPT_INT 0x00080000 /* R/WC */
+#define INT_STS_PHY_INT 0x00040000 /* RO */
+#define INT_STS_PME_INT 0x00020000 /* R/WC */
+#define INT_STS_TXSO 0x00010000 /* R/WC */
+#define INT_STS_RWT 0x00008000 /* R/WC */
+#define INT_STS_RXE 0x00004000 /* R/WC */
+#define INT_STS_TXE 0x00002000 /* R/WC */
+/*#define INT_STS_ERX 0x00001000*/ /* R/WC */
+#define INT_STS_TDFU 0x00000800 /* R/WC */
+#define INT_STS_TDFO 0x00000400 /* R/WC */
+#define INT_STS_TDFA 0x00000200 /* R/WC */
+#define INT_STS_TSFF 0x00000100 /* R/WC */
+#define INT_STS_TSFL 0x00000080 /* R/WC */
+/*#define INT_STS_RXDF 0x00000040*/ /* R/WC */
+#define INT_STS_RDFO 0x00000040 /* R/WC */
+#define INT_STS_RDFL 0x00000020 /* R/WC */
+#define INT_STS_RSFF 0x00000010 /* R/WC */
+#define INT_STS_RSFL 0x00000008 /* R/WC */
+#define INT_STS_GPIO2_INT 0x00000004 /* R/WC */
+#define INT_STS_GPIO1_INT 0x00000002 /* R/WC */
+#define INT_STS_GPIO0_INT 0x00000001 /* R/WC */
+#define INT_EN 0x5C
+#define INT_EN_SW_INT_EN 0x80000000 /* R/W */
+#define INT_EN_TXSTOP_INT_EN 0x02000000 /* R/W */
+#define INT_EN_RXSTOP_INT_EN 0x01000000 /* R/W */
+#define INT_EN_RXDFH_INT_EN 0x00800000 /* R/W */
+/*#define INT_EN_RXDF_INT_EN 0x00400000*/ /* R/W */
+#define INT_EN_TIOC_INT_EN 0x00200000 /* R/W */
+#define INT_EN_RXD_INT_EN 0x00100000 /* R/W */
+#define INT_EN_GPT_INT_EN 0x00080000 /* R/W */
+#define INT_EN_PHY_INT_EN 0x00040000 /* R/W */
+#define INT_EN_PME_INT_EN 0x00020000 /* R/W */
+#define INT_EN_TXSO_EN 0x00010000 /* R/W */
+#define INT_EN_RWT_EN 0x00008000 /* R/W */
+#define INT_EN_RXE_EN 0x00004000 /* R/W */
+#define INT_EN_TXE_EN 0x00002000 /* R/W */
+/*#define INT_EN_ERX_EN 0x00001000*/ /* R/W */
+#define INT_EN_TDFU_EN 0x00000800 /* R/W */
+#define INT_EN_TDFO_EN 0x00000400 /* R/W */
+#define INT_EN_TDFA_EN 0x00000200 /* R/W */
+#define INT_EN_TSFF_EN 0x00000100 /* R/W */
+#define INT_EN_TSFL_EN 0x00000080 /* R/W */
+/*#define INT_EN_RXDF_EN 0x00000040*/ /* R/W */
+#define INT_EN_RDFO_EN 0x00000040 /* R/W */
+#define INT_EN_RDFL_EN 0x00000020 /* R/W */
+#define INT_EN_RSFF_EN 0x00000010 /* R/W */
+#define INT_EN_RSFL_EN 0x00000008 /* R/W */
+#define INT_EN_GPIO2_INT 0x00000004 /* R/W */
+#define INT_EN_GPIO1_INT 0x00000002 /* R/W */
+#define INT_EN_GPIO0_INT 0x00000001 /* R/W */
+
+#define BYTE_TEST 0x64
+#define FIFO_INT 0x68
+#define FIFO_INT_TX_AVAIL_LEVEL 0xFF000000 /* R/W */
+#define FIFO_INT_TX_STS_LEVEL 0x00FF0000 /* R/W */
+#define FIFO_INT_RX_AVAIL_LEVEL 0x0000FF00 /* R/W */
+#define FIFO_INT_RX_STS_LEVEL 0x000000FF /* R/W */
+
+#define RX_CFG 0x6C
+#define RX_CFG_RX_END_ALGN 0xC0000000 /* R/W */
+#define RX_CFG_RX_END_ALGN4 0x00000000 /* R/W */
+#define RX_CFG_RX_END_ALGN16 0x40000000 /* R/W */
+#define RX_CFG_RX_END_ALGN32 0x80000000 /* R/W */
+#define RX_CFG_RX_DMA_CNT 0x0FFF0000 /* R/W */
+#define RX_CFG_RX_DUMP 0x00008000 /* R/W */
+#define RX_CFG_RXDOFF 0x00001F00 /* R/W */
+/*#define RX_CFG_RXBAD 0x00000001*/ /* R/W */
+
+#define TX_CFG 0x70
+/*#define TX_CFG_TX_DMA_LVL 0xE0000000*/ /* R/W */
+ /* R/W Self Clearing */
+/*#define TX_CFG_TX_DMA_CNT 0x0FFF0000*/
+#define TX_CFG_TXS_DUMP 0x00008000 /* Self Clearing */
+#define TX_CFG_TXD_DUMP 0x00004000 /* Self Clearing */
+#define TX_CFG_TXSAO 0x00000004 /* R/W */
+#define TX_CFG_TX_ON 0x00000002 /* R/W */
+#define TX_CFG_STOP_TX 0x00000001 /* Self Clearing */
+
+#define HW_CFG 0x74
+#define HW_CFG_TTM 0x00200000 /* R/W */
+#define HW_CFG_SF 0x00100000 /* R/W */
+#define HW_CFG_TX_FIF_SZ 0x000F0000 /* R/W */
+#define HW_CFG_TR 0x00003000 /* R/W */
+#define HW_CFG_PHY_CLK_SEL 0x00000060 /* R/W */
+#define HW_CFG_PHY_CLK_SEL_INT_PHY 0x00000000 /* R/W */
+#define HW_CFG_PHY_CLK_SEL_EXT_PHY 0x00000020 /* R/W */
+#define HW_CFG_PHY_CLK_SEL_CLK_DIS 0x00000040 /* R/W */
+#define HW_CFG_SMI_SEL 0x00000010 /* R/W */
+#define HW_CFG_EXT_PHY_DET 0x00000008 /* RO */
+#define HW_CFG_EXT_PHY_EN 0x00000004 /* R/W */
+#define HW_CFG_32_16_BIT_MODE 0x00000004 /* RO */
+#define HW_CFG_SRST_TO 0x00000002 /* RO */
+#define HW_CFG_SRST 0x00000001 /* Self Clearing */
+
+#define RX_DP_CTRL 0x78
+#define RX_DP_CTRL_RX_FFWD 0x80000000 /* R/W */
+#define RX_DP_CTRL_FFWD_BUSY 0x80000000 /* RO */
+
+#define RX_FIFO_INF 0x7C
+#define RX_FIFO_INF_RXSUSED 0x00FF0000 /* RO */
+#define RX_FIFO_INF_RXDUSED 0x0000FFFF /* RO */
+
+#define TX_FIFO_INF 0x80
+#define TX_FIFO_INF_TSUSED 0x00FF0000 /* RO */
+#define TX_FIFO_INF_TDFREE 0x0000FFFF /* RO */
+
+#define PMT_CTRL 0x84
+#define PMT_CTRL_PM_MODE 0x00003000 /* Self Clearing */
+#define PMT_CTRL_PHY_RST 0x00000400 /* Self Clearing */
+#define PMT_CTRL_WOL_EN 0x00000200 /* R/W */
+#define PMT_CTRL_ED_EN 0x00000100 /* R/W */
+ /* R/W Not Affected by SW Reset */
+#define PMT_CTRL_PME_TYPE 0x00000040
+#define PMT_CTRL_WUPS 0x00000030 /* R/WC */
+#define PMT_CTRL_WUPS_NOWAKE 0x00000000 /* R/WC */
+#define PMT_CTRL_WUPS_ED 0x00000010 /* R/WC */
+#define PMT_CTRL_WUPS_WOL 0x00000020 /* R/WC */
+#define PMT_CTRL_WUPS_MULTI 0x00000030 /* R/WC */
+#define PMT_CTRL_PME_IND 0x00000008 /* R/W */
+#define PMT_CTRL_PME_POL 0x00000004 /* R/W */
+ /* R/W Not Affected by SW Reset */
+#define PMT_CTRL_PME_EN 0x00000002
+#define PMT_CTRL_READY 0x00000001 /* RO */
+
+#define GPIO_CFG 0x88
+#define GPIO_CFG_LED3_EN 0x40000000 /* R/W */
+#define GPIO_CFG_LED2_EN 0x20000000 /* R/W */
+#define GPIO_CFG_LED1_EN 0x10000000 /* R/W */
+#define GPIO_CFG_GPIO2_INT_POL 0x04000000 /* R/W */
+#define GPIO_CFG_GPIO1_INT_POL 0x02000000 /* R/W */
+#define GPIO_CFG_GPIO0_INT_POL 0x01000000 /* R/W */
+#define GPIO_CFG_EEPR_EN 0x00700000 /* R/W */
+#define GPIO_CFG_GPIOBUF2 0x00040000 /* R/W */
+#define GPIO_CFG_GPIOBUF1 0x00020000 /* R/W */
+#define GPIO_CFG_GPIOBUF0 0x00010000 /* R/W */
+#define GPIO_CFG_GPIODIR2 0x00000400 /* R/W */
+#define GPIO_CFG_GPIODIR1 0x00000200 /* R/W */
+#define GPIO_CFG_GPIODIR0 0x00000100 /* R/W */
+#define GPIO_CFG_GPIOD4 0x00000010 /* R/W */
+#define GPIO_CFG_GPIOD3 0x00000008 /* R/W */
+#define GPIO_CFG_GPIOD2 0x00000004 /* R/W */
+#define GPIO_CFG_GPIOD1 0x00000002 /* R/W */
+#define GPIO_CFG_GPIOD0 0x00000001 /* R/W */
+
+#define GPT_CFG 0x8C
+#define GPT_CFG_TIMER_EN 0x20000000 /* R/W */
+#define GPT_CFG_GPT_LOAD 0x0000FFFF /* R/W */
+
+#define GPT_CNT 0x90
+#define GPT_CNT_GPT_CNT 0x0000FFFF /* RO */
+
+#define ENDIAN 0x98
+#define FREE_RUN 0x9C
+#define RX_DROP 0xA0
+#define MAC_CSR_CMD 0xA4
+#define MAC_CSR_CMD_CSR_BUSY 0x80000000 /* Self Clearing */
+#define MAC_CSR_CMD_R_NOT_W 0x40000000 /* R/W */
+#define MAC_CSR_CMD_CSR_ADDR 0x000000FF /* R/W */
+
+#define MAC_CSR_DATA 0xA8
+#define AFC_CFG 0xAC
+#define AFC_CFG_AFC_HI 0x00FF0000 /* R/W */
+#define AFC_CFG_AFC_LO 0x0000FF00 /* R/W */
+#define AFC_CFG_BACK_DUR 0x000000F0 /* R/W */
+#define AFC_CFG_FCMULT 0x00000008 /* R/W */
+#define AFC_CFG_FCBRD 0x00000004 /* R/W */
+#define AFC_CFG_FCADD 0x00000002 /* R/W */
+#define AFC_CFG_FCANY 0x00000001 /* R/W */
+
+#define E2P_CMD 0xB0
+#define E2P_CMD_EPC_BUSY 0x80000000 /* Self Clearing */
+#define E2P_CMD_EPC_CMD 0x70000000 /* R/W */
+#define E2P_CMD_EPC_CMD_READ 0x00000000 /* R/W */
+#define E2P_CMD_EPC_CMD_EWDS 0x10000000 /* R/W */
+#define E2P_CMD_EPC_CMD_EWEN 0x20000000 /* R/W */
+#define E2P_CMD_EPC_CMD_WRITE 0x30000000 /* R/W */
+#define E2P_CMD_EPC_CMD_WRAL 0x40000000 /* R/W */
+#define E2P_CMD_EPC_CMD_ERASE 0x50000000 /* R/W */
+#define E2P_CMD_EPC_CMD_ERAL 0x60000000 /* R/W */
+#define E2P_CMD_EPC_CMD_RELOAD 0x70000000 /* R/W */
+#define E2P_CMD_EPC_TIMEOUT 0x00000200 /* RO */
+#define E2P_CMD_MAC_ADDR_LOADED 0x00000100 /* RO */
+#define E2P_CMD_EPC_ADDR 0x000000FF /* R/W */
+
+#define E2P_DATA 0xB4
+#define E2P_DATA_EEPROM_DATA 0x000000FF /* R/W */
+/* end of LAN register offsets and bit definitions */
+
+/* MAC Control and Status registers */
+#define MAC_CR 0x01 /* R/W */
+
+/* MAC_CR - MAC Control Register */
+#define MAC_CR_RXALL 0x80000000
+/* TODO: delete this bit? It is not described in the data sheet. */
+#define MAC_CR_HBDIS 0x10000000
+#define MAC_CR_RCVOWN 0x00800000
+#define MAC_CR_LOOPBK 0x00200000
+#define MAC_CR_FDPX 0x00100000
+#define MAC_CR_MCPAS 0x00080000
+#define MAC_CR_PRMS 0x00040000
+#define MAC_CR_INVFILT 0x00020000
+#define MAC_CR_PASSBAD 0x00010000
+#define MAC_CR_HFILT 0x00008000
+#define MAC_CR_HPFILT 0x00002000
+#define MAC_CR_LCOLL 0x00001000
+#define MAC_CR_BCAST 0x00000800
+#define MAC_CR_DISRTY 0x00000400
+#define MAC_CR_PADSTR 0x00000100
+#define MAC_CR_BOLMT_MASK 0x000000C0
+#define MAC_CR_DFCHK 0x00000020
+#define MAC_CR_TXEN 0x00000008
+#define MAC_CR_RXEN 0x00000004
+
+#define ADDRH 0x02 /* R/W mask 0x0000FFFFUL */
+#define ADDRL 0x03 /* R/W mask 0xFFFFFFFFUL */
+#define HASHH 0x04 /* R/W */
+#define HASHL 0x05 /* R/W */
+
+#define MII_ACC 0x06 /* R/W */
+#define MII_ACC_PHY_ADDR 0x0000F800
+#define MII_ACC_MIIRINDA 0x000007C0
+#define MII_ACC_MII_WRITE 0x00000002
+#define MII_ACC_MII_BUSY 0x00000001
+
+#define MII_DATA 0x07 /* R/W mask 0x0000FFFFUL */
+
+#define FLOW 0x08 /* R/W */
+#define FLOW_FCPT 0xFFFF0000
+#define FLOW_FCPASS 0x00000004
+#define FLOW_FCEN 0x00000002
+#define FLOW_FCBSY 0x00000001
+
+#define VLAN1 0x09 /* R/W mask 0x0000FFFFUL */
+#define VLAN1_VTI1 0x0000ffff
+
+#define VLAN2 0x0A /* R/W mask 0x0000FFFFUL */
+#define VLAN2_VTI2 0x0000ffff
+
+#define WUFF 0x0B /* WO */
+
+#define WUCSR 0x0C /* R/W */
+#define WUCSR_GUE 0x00000200
+#define WUCSR_WUFR 0x00000040
+#define WUCSR_MPR 0x00000020
+#define WUCSR_WAKE_EN 0x00000004
+#define WUCSR_MPEN 0x00000002
+
+/* phy register offsets */
+#define PHY_BMCR 0x00
+#define PHY_BMSR 0x01
+#define PHY_PHYIDR1 0x02
+#define PHY_PHYIDR2 0x03
+#define PHY_ANAR 0x04
+#define PHY_ANLPAR 0x05
+#define PHY_ANER 0x06
+#define PHY_ANNPTR 0x07
+#define PHY_ANLPNP 0x08
+#define PHY_1000BTCR 0x09
+#define PHY_1000BTSR 0x0A
+#define PHY_EXSR 0x0F
+#define PHY_PHYSTS 0x10
+#define PHY_MIPSCR 0x11
+#define PHY_MIPGSR 0x12
+#define PHY_DCR 0x13
+#define PHY_FCSCR 0x14
+#define PHY_RECR 0x15
+#define PHY_PCSR 0x16
+#define PHY_LBR 0x17
+#define PHY_10BTSCR 0x18
+#define PHY_PHYCTRL 0x19
+
+/* PHY BMCR */
+#define PHY_BMCR_RESET 0x8000
+#define PHY_BMCR_LOOP 0x4000
+#define PHY_BMCR_100MB 0x2000
+#define PHY_BMCR_AUTON 0x1000
+#define PHY_BMCR_POWD 0x0800
+#define PHY_BMCR_ISO 0x0400
+#define PHY_BMCR_RST_NEG 0x0200
+#define PHY_BMCR_DPLX 0x0100
+#define PHY_BMCR_COL_TST 0x0080
+
+#define PHY_BMCR_SPEED_MASK 0x2040
+#define PHY_BMCR_1000_MBPS 0x0040
+#define PHY_BMCR_100_MBPS 0x2000
+#define PHY_BMCR_10_MBPS 0x0000
+
+/* phy BMSR */
+#define PHY_BMSR_100T4 0x8000
+#define PHY_BMSR_100TXF 0x4000
+#define PHY_BMSR_100TXH 0x2000
+#define PHY_BMSR_10TF 0x1000
+#define PHY_BMSR_10TH 0x0800
+#define PHY_BMSR_EXT_STAT 0x0100
+#define PHY_BMSR_PRE_SUP 0x0040
+#define PHY_BMSR_AUTN_COMP 0x0020
+#define PHY_BMSR_RF 0x0010
+#define PHY_BMSR_AUTN_ABLE 0x0008
+#define PHY_BMSR_LS 0x0004
+#define PHY_BMSR_JD 0x0002
+#define PHY_BMSR_EXT 0x0001
+
+/*phy ANLPAR */
+#define PHY_ANLPAR_NP 0x8000
+#define PHY_ANLPAR_ACK 0x4000
+#define PHY_ANLPAR_RF 0x2000
+#define PHY_ANLPAR_ASYMP 0x0800
+#define PHY_ANLPAR_PAUSE 0x0400
+#define PHY_ANLPAR_T4 0x0200
+#define PHY_ANLPAR_TXFD 0x0100
+#define PHY_ANLPAR_TX 0x0080
+#define PHY_ANLPAR_10FD 0x0040
+#define PHY_ANLPAR_10 0x0020
+#define PHY_ANLPAR_100 0x0380 /* we can run at 100 */
+/* phy ANLPAR 1000BASE-X */
+#define PHY_X_ANLPAR_NP 0x8000
+#define PHY_X_ANLPAR_ACK 0x4000
+#define PHY_X_ANLPAR_RF_MASK 0x3000
+#define PHY_X_ANLPAR_PAUSE_MASK 0x0180
+#define PHY_X_ANLPAR_HD 0x0040
+#define PHY_X_ANLPAR_FD 0x0020
+
+#define PHY_ANLPAR_PSB_MASK 0x001f
+#define PHY_ANLPAR_PSB_802_3 0x0001
+#define PHY_ANLPAR_PSB_802_9 0x0002
+
+/* phy 1000BTCR */
+#define PHY_1000BTCR_1000FD 0x0200
+#define PHY_1000BTCR_1000HD 0x0100
+
+/* phy 1000BTSR */
+#define PHY_1000BTSR_MSCF 0x8000
+#define PHY_1000BTSR_MSCR 0x4000
+#define PHY_1000BTSR_LRS 0x2000
+#define PHY_1000BTSR_RRS 0x1000
+#define PHY_1000BTSR_1000FD 0x0800
+#define PHY_1000BTSR_1000HD 0x0400
+
+/* phy EXSR */
+#define PHY_EXSR_1000XF 0x8000
+#define PHY_EXSR_1000XH 0x4000
+#define PHY_EXSR_1000TF 0x2000
+#define PHY_EXSR_1000TH 0x1000
+
+
+
+typedef struct {
+ VENDOR_DEVICE_PATH EthDevicePath;
+ EFI_DEVICE_PATH EndDevicePath;
+} ETH_DEVICE_PATH;
+
+//
+// Private data for driver.
+//
+#define ETH_DXE_PRIVATE_DATA_SIGNATURE SIGNATURE_32( 'E', 'T', 'H', 'D' )
+
+typedef struct
+{
+ UINT32 Signature;
+ EFI_SIMPLE_NETWORK_PROTOCOL Snp;
+ EFI_SIMPLE_NETWORK_MODE Mode;
+ ETH_DEVICE_PATH DevicePath;
+} ETH_DXE_PRIVATE_DATA;
+
+#define ETH_DXE_PRIVATE_DATA_FROM_SNP_THIS(a) \
+ CR( a, ETH_DXE_PRIVATE_DATA, Snp, ETH_DXE_PRIVATE_DATA_SIGNATURE )
+
+
+EFI_STATUS
+EFIAPI
+EthStart(
+ EFI_SIMPLE_NETWORK_PROTOCOL *This
+);
+
+EFI_STATUS
+EFIAPI
+EthStop(
+ EFI_SIMPLE_NETWORK_PROTOCOL *This
+);
+
+EFI_STATUS
+EFIAPI
+EthInitialize(
+ EFI_SIMPLE_NETWORK_PROTOCOL *This,
+ UINTN ExtraRxBufferSize,
+ UINTN ExtraTxBufferSize
+);
+
+EFI_STATUS
+EFIAPI
+EthReset(
+ EFI_SIMPLE_NETWORK_PROTOCOL *This,
+ BOOLEAN ExtendedVerification
+);
+
+EFI_STATUS
+EFIAPI
+EthShutdown(
+ EFI_SIMPLE_NETWORK_PROTOCOL *This
+);
+
+EFI_STATUS
+EFIAPI
+EthReceiveFilters(
+ EFI_SIMPLE_NETWORK_PROTOCOL *This,
+ UINT32 Enable,
+ UINT32 Disable,
+ BOOLEAN ResetMCastFilter,
+ UINTN MCastFilterCnt,
+ EFI_MAC_ADDRESS *MCastFilter
+);
+
+EFI_STATUS
+EFIAPI
+EthStationAddress(
+ EFI_SIMPLE_NETWORK_PROTOCOL *This,
+ BOOLEAN Reset,
+ EFI_MAC_ADDRESS *New
+);
+
+EFI_STATUS
+EFIAPI
+EthStatistics(
+ EFI_SIMPLE_NETWORK_PROTOCOL *This,
+ BOOLEAN Reset,
+ UINTN *StatisticsSize,
+ EFI_NETWORK_STATISTICS *StatisticsTable
+);
+
+EFI_STATUS
+EFIAPI
+EthMCastIpToMac(
+ EFI_SIMPLE_NETWORK_PROTOCOL *This,
+ BOOLEAN IPv6,
+ EFI_IP_ADDRESS *IP,
+ EFI_MAC_ADDRESS *MAC
+);
+
+EFI_STATUS
+EFIAPI
+EthNvData(
+ EFI_SIMPLE_NETWORK_PROTOCOL *This,
+ BOOLEAN ReadWrite,
+ UINTN Offset,
+ UINTN BufferSize,
+ VOID *Buffer
+);
+
+EFI_STATUS
+EFIAPI
+EthGetStatus(
+ EFI_SIMPLE_NETWORK_PROTOCOL *This,
+ UINT32 *InterruptStatus,
+ VOID **TxBuf
+);
+
+EFI_STATUS
+EFIAPI
+EthTransmit(
+ EFI_SIMPLE_NETWORK_PROTOCOL *This,
+ UINTN HeaderSize,
+ UINTN BufferSize,
+ VOID *Buffer,
+ EFI_MAC_ADDRESS *SrcAddr,
+ EFI_MAC_ADDRESS *DestAddr,
+ UINT16 *Protocol
+);
+
+EFI_STATUS
+EFIAPI
+EthReceive(
+ EFI_SIMPLE_NETWORK_PROTOCOL *This,
+ UINTN *HeaderSize,
+ UINTN *BufferSize,
+ VOID *Buffer,
+ EFI_MAC_ADDRESS *SrcAddr,
+ EFI_MAC_ADDRESS *DestAddr,
+ UINT16 *Protocol
+);
+
+#endif // _Eth_Dxe_H__
diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/EthDxe/EthDxe.inf b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/EthDxe/EthDxe.inf
new file mode 100644
index 000000000..e9f649e15
--- /dev/null
+++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/EthDxe/EthDxe.inf
@@ -0,0 +1,59 @@
+## @file
+#
+# Component description file for GraphicsConsole module
+#
+# This is the main routine for initializing the Graphics Console support routines.
+#
+# Copyright (c) 2012, Samsung Electronics Co. All rights reserved.<BR>
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = EthDxe
+ FILE_GUID = 25ac458a-cf60-476e-861a-211c757657a6
+ MODULE_TYPE = UEFI_DRIVER
+ VERSION_STRING = 1.0
+ ENTRY_POINT = EthDxeInitialize
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF EBC
+#
+# DRIVER_BINDING =
+# COMPONENT_NAME =
+# COMPONENT_NAME2 =
+#
+
+[Sources]
+ EthDxe.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ SamsungPlatformPkg/ExynosPkg/Exynos4210/ExynosPkg.dec
+ SamsungPlatformPkg/SamsungPlatformPkg.dec
+
+[LibraryClasses]
+ BaseLib
+ UefiLib
+ MemoryAllocationLib
+ UefiDriverEntryPoint
+ IoLib
+ TimerLib
+
+[Protocols]
+ gEfiSimpleNetworkProtocolGuid ## TO_START
+
+[Guids]
+
+[Pcd]
+ gExynosPkgTokenSpaceGuid.PcdSMC911XBase
diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/Gic400Dxe/PL390Gic.c b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/Gic400Dxe/PL390Gic.c
new file mode 100644
index 000000000..3224cbef9
--- /dev/null
+++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/Gic400Dxe/PL390Gic.c
@@ -0,0 +1,70 @@
+/** @file
+*
+* Copyright (c) 2011-2012, ARM Limited. All rights reserved.
+*
+* This program and the accompanying materials
+* are licensed and made available under the terms and conditions of the BSD License
+* which accompanies this distribution. The full text of the license may be found at
+* http://opensource.org/licenses/bsd-license.php
+*
+* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#include <Uefi.h>
+#include <Library/IoLib.h>
+#include <Library/ArmGicLib.h>
+#include <Library/PcdLib.h>
+
+UINTN
+EFIAPI
+ArmGicGetMaxNumInterrupts (
+ IN INTN GicDistributorBase
+ )
+{
+ return 32 * ((MmioRead32 (GicDistributorBase + ARM_GIC_ICDICTR) & 0x1F) + 1);
+}
+
+VOID
+EFIAPI
+ArmGicSendSgiTo (
+ IN INTN GicDistributorBase,
+ IN INTN TargetListFilter,
+ IN INTN CPUTargetList,
+ IN INTN SgiId
+ )
+{
+ MmioWrite32 (GicDistributorBase + ARM_GIC_ICDSGIR, ((TargetListFilter & 0x3) << 24) | ((CPUTargetList & 0xFF) << 16) | SgiId);
+}
+
+RETURN_STATUS
+EFIAPI
+ArmGicAcknowledgeInterrupt (
+ IN UINTN GicDistributorBase,
+ IN UINTN GicInterruptInterfaceBase,
+ OUT UINTN *CoreId,
+ OUT UINTN *InterruptId
+ )
+{
+ UINT32 Interrupt;
+
+ // Read the Interrupt Acknowledge Register
+ Interrupt = MmioRead32 (GicInterruptInterfaceBase + ARM_GIC_ICCIAR);
+
+ // Check if it is a valid interrupt ID
+ if ((Interrupt & 0x3FF) < ArmGicGetMaxNumInterrupts (GicDistributorBase)) {
+ // Got a valid SGI number hence signal End of Interrupt by writing to ICCEOIR
+ MmioWrite32 (GicInterruptInterfaceBase + ARM_GIC_ICCEIOR, Interrupt);
+
+ if (CoreId) {
+ *CoreId = (Interrupt >> 10) & 0x7;
+ }
+ if (InterruptId) {
+ *InterruptId = Interrupt & 0x3FF;
+ }
+ return RETURN_SUCCESS;
+ } else {
+ return RETURN_INVALID_PARAMETER;
+ }
+}
diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/Gic400Dxe/PL390GicDxe.c b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/Gic400Dxe/PL390GicDxe.c
new file mode 100644
index 000000000..4e2fc883d
--- /dev/null
+++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/Gic400Dxe/PL390GicDxe.c
@@ -0,0 +1,415 @@
+/*++
+
+Copyright (c) 2009, Hewlett-Packard Company. All rights reserved.<BR>
+Portions copyright (c) 2010, Apple Inc. All rights reserved.<BR>
+Portions copyright (c) 2011-2012, ARM Ltd. All rights reserved.<BR>
+
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ Gic.c
+
+Abstract:
+
+ Driver implementing the GIC interrupt controller protocol
+
+--*/
+
+#include <PiDxe.h>
+
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiLib.h>
+#include <Library/PcdLib.h>
+#include <Library/IoLib.h>
+#include <Library/ArmGicLib.h>
+
+#include <Protocol/Cpu.h>
+#include <Protocol/HardwareInterrupt.h>
+
+#define ARM_GIC_DEFAULT_PRIORITY 0x80
+
+extern EFI_HARDWARE_INTERRUPT_PROTOCOL gHardwareInterruptProtocol;
+
+//
+// Notifications
+//
+EFI_EVENT EfiExitBootServicesEvent = (EFI_EVENT)NULL;
+
+// Maximum Number of Interrupts
+UINTN mGicNumInterrupts = 0;
+
+HARDWARE_INTERRUPT_HANDLER *gRegisteredInterruptHandlers = NULL;
+
+/**
+ Register Handler for the specified interrupt source.
+
+ @param This Instance pointer for this protocol
+ @param Source Hardware source of the interrupt
+ @param Handler Callback for interrupt. NULL to unregister
+
+ @retval EFI_SUCCESS Source was updated to support Handler.
+ @retval EFI_DEVICE_ERROR Hardware could not be programmed.
+
+**/
+EFI_STATUS
+EFIAPI
+RegisterInterruptSource (
+ IN EFI_HARDWARE_INTERRUPT_PROTOCOL *This,
+ IN HARDWARE_INTERRUPT_SOURCE Source,
+ IN HARDWARE_INTERRUPT_HANDLER Handler
+ )
+{
+ if (Source > mGicNumInterrupts) {
+ ASSERT(FALSE);
+ return EFI_UNSUPPORTED;
+ }
+
+ if ((Handler == NULL) && (gRegisteredInterruptHandlers[Source] == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if ((Handler != NULL) && (gRegisteredInterruptHandlers[Source] != NULL)) {
+ return EFI_ALREADY_STARTED;
+ }
+
+ gRegisteredInterruptHandlers[Source] = Handler;
+
+ // If the interrupt handler is unregistered then disable the interrupt
+ if (NULL == Handler){
+ return This->DisableInterruptSource (This, Source);
+ } else {
+ return This->EnableInterruptSource (This, Source);
+ }
+}
+
+/**
+ Enable interrupt source Source.
+
+ @param This Instance pointer for this protocol
+ @param Source Hardware source of the interrupt
+
+ @retval EFI_SUCCESS Source interrupt enabled.
+ @retval EFI_DEVICE_ERROR Hardware could not be programmed.
+
+**/
+EFI_STATUS
+EFIAPI
+EnableInterruptSource (
+ IN EFI_HARDWARE_INTERRUPT_PROTOCOL *This,
+ IN HARDWARE_INTERRUPT_SOURCE Source
+ )
+{
+ UINT32 RegOffset;
+ UINTN RegShift;
+
+ if (Source > mGicNumInterrupts) {
+ ASSERT(FALSE);
+ return EFI_UNSUPPORTED;
+ }
+
+ // calculate enable register offset and bit position
+ RegOffset = Source / 32;
+ RegShift = Source % 32;
+
+ // write set-enable register
+ MmioWrite32 (PcdGet32(PcdGicDistributorBase) + ARM_GIC_ICDISER + (4*RegOffset), 1 << RegShift);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Disable interrupt source Source.
+
+ @param This Instance pointer for this protocol
+ @param Source Hardware source of the interrupt
+
+ @retval EFI_SUCCESS Source interrupt disabled.
+ @retval EFI_DEVICE_ERROR Hardware could not be programmed.
+
+**/
+EFI_STATUS
+EFIAPI
+DisableInterruptSource (
+ IN EFI_HARDWARE_INTERRUPT_PROTOCOL *This,
+ IN HARDWARE_INTERRUPT_SOURCE Source
+ )
+{
+ UINT32 RegOffset;
+ UINTN RegShift;
+
+ if (Source > mGicNumInterrupts) {
+ ASSERT(FALSE);
+ return EFI_UNSUPPORTED;
+ }
+
+ // Calculate enable register offset and bit position
+ RegOffset = Source / 32;
+ RegShift = Source % 32;
+
+ // Write set-enable register
+ MmioWrite32 (PcdGet32(PcdGicDistributorBase) + ARM_GIC_ICDICER + (4*RegOffset), 1 << RegShift);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Return current state of interrupt source Source.
+
+ @param This Instance pointer for this protocol
+ @param Source Hardware source of the interrupt
+ @param InterruptState TRUE: source enabled, FALSE: source disabled.
+
+ @retval EFI_SUCCESS InterruptState is valid
+ @retval EFI_DEVICE_ERROR InterruptState is not valid
+
+**/
+EFI_STATUS
+EFIAPI
+GetInterruptSourceState (
+ IN EFI_HARDWARE_INTERRUPT_PROTOCOL *This,
+ IN HARDWARE_INTERRUPT_SOURCE Source,
+ IN BOOLEAN *InterruptState
+ )
+{
+ UINT32 RegOffset;
+ UINTN RegShift;
+
+ if (Source > mGicNumInterrupts) {
+ ASSERT(FALSE);
+ return EFI_UNSUPPORTED;
+ }
+
+ // calculate enable register offset and bit position
+ RegOffset = Source / 32;
+ RegShift = Source % 32;
+
+ if ((MmioRead32 (PcdGet32(PcdGicDistributorBase) + ARM_GIC_ICDISER + (4*RegOffset)) & (1<<RegShift)) == 0) {
+ *InterruptState = FALSE;
+ } else {
+ *InterruptState = TRUE;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Signal to the hardware that the End Of Intrrupt state
+ has been reached.
+
+ @param This Instance pointer for this protocol
+ @param Source Hardware source of the interrupt
+
+ @retval EFI_SUCCESS Source interrupt EOI'ed.
+ @retval EFI_DEVICE_ERROR Hardware could not be programmed.
+
+**/
+EFI_STATUS
+EFIAPI
+EndOfInterrupt (
+ IN EFI_HARDWARE_INTERRUPT_PROTOCOL *This,
+ IN HARDWARE_INTERRUPT_SOURCE Source
+ )
+{
+ if (Source > mGicNumInterrupts) {
+ ASSERT(FALSE);
+ return EFI_UNSUPPORTED;
+ }
+
+ MmioWrite32 (PcdGet32(PcdGicInterruptInterfaceBase) + ARM_GIC_ICCEIOR, Source);
+ return EFI_SUCCESS;
+}
+
+/**
+ EFI_CPU_INTERRUPT_HANDLER that is called when a processor interrupt occurs.
+
+ @param InterruptType Defines the type of interrupt or exception that
+ occurred on the processor.This parameter is processor architecture specific.
+ @param SystemContext A pointer to the processor context when
+ the interrupt occurred on the processor.
+
+ @return None
+
+**/
+VOID
+EFIAPI
+IrqInterruptHandler (
+ IN EFI_EXCEPTION_TYPE InterruptType,
+ IN EFI_SYSTEM_CONTEXT SystemContext
+ )
+{
+ UINT32 GicInterrupt;
+ HARDWARE_INTERRUPT_HANDLER InterruptHandler;
+
+ GicInterrupt = MmioRead32 (PcdGet32(PcdGicInterruptInterfaceBase) + ARM_GIC_ICCIAR);
+
+ // Special Interrupts (ID1020-ID1023) have an Interrupt ID greater than the number of interrupt (ie: Spurious interrupt).
+ if (GicInterrupt >= mGicNumInterrupts) {
+ // The special interrupt do not need to be acknowledge
+ return;
+ }
+
+ InterruptHandler = gRegisteredInterruptHandlers[GicInterrupt];
+ if (InterruptHandler != NULL) {
+ // Call the registered interrupt handler.
+ InterruptHandler (GicInterrupt, SystemContext);
+ } else {
+ DEBUG ((EFI_D_ERROR, "Spurious GIC interrupt: 0x%x\n", GicInterrupt));
+ }
+
+ EndOfInterrupt (&gHardwareInterruptProtocol, GicInterrupt);
+}
+
+//
+// Making this global saves a few bytes in image size
+//
+EFI_HANDLE gHardwareInterruptHandle = NULL;
+
+//
+// The protocol instance produced by this driver
+//
+EFI_HARDWARE_INTERRUPT_PROTOCOL gHardwareInterruptProtocol = {
+ RegisterInterruptSource,
+ EnableInterruptSource,
+ DisableInterruptSource,
+ GetInterruptSourceState,
+ EndOfInterrupt
+};
+
+/**
+ Shutdown our hardware
+
+ DXE Core will disable interrupts and turn off the timer and disable interrupts
+ after all the event handlers have run.
+
+ @param[in] Event The Event that is being processed
+ @param[in] Context Event Context
+**/
+VOID
+EFIAPI
+ExitBootServicesEvent (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ UINTN Index;
+
+ // Acknowledge all pending interrupts
+ for (Index = 0; Index < mGicNumInterrupts; Index++) {
+ DisableInterruptSource (&gHardwareInterruptProtocol, Index);
+ }
+
+ for (Index = 0; Index < mGicNumInterrupts; Index++) {
+ EndOfInterrupt (&gHardwareInterruptProtocol, Index);
+ }
+
+ // Disable Gic Interface
+ MmioWrite32 (PcdGet32(PcdGicInterruptInterfaceBase) + ARM_GIC_ICCICR, 0x0);
+ MmioWrite32 (PcdGet32(PcdGicInterruptInterfaceBase) + ARM_GIC_ICCPMR, 0x0);
+
+ // Disable Gic Distributor
+ MmioWrite32 (PcdGet32(PcdGicDistributorBase) + ARM_GIC_ICDDCR, 0x0);
+}
+
+/**
+ Initialize the state information for the CPU Architectural Protocol
+
+ @param ImageHandle of the loaded driver
+ @param SystemTable Pointer to the System Table
+
+ @retval EFI_SUCCESS Protocol registered
+ @retval EFI_OUT_OF_RESOURCES Cannot allocate protocol data structure
+ @retval EFI_DEVICE_ERROR Hardware problems
+
+**/
+EFI_STATUS
+InterruptDxeInitialize (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ UINTN Index;
+ UINT32 RegOffset;
+ UINTN RegShift;
+ EFI_CPU_ARCH_PROTOCOL *Cpu;
+
+ // Make sure the Interrupt Controller Protocol is not already installed in the system.
+ ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gHardwareInterruptProtocolGuid);
+
+ mGicNumInterrupts = ArmGicGetMaxNumInterrupts (PcdGet32(PcdGicDistributorBase));
+
+ for (Index = 0; Index < mGicNumInterrupts; Index++) {
+ DisableInterruptSource (&gHardwareInterruptProtocol, Index);
+
+ // Set Priority
+ RegOffset = Index / 4;
+ RegShift = (Index % 4) * 8;
+ MmioAndThenOr32 (
+ PcdGet32(PcdGicDistributorBase) + ARM_GIC_ICDIPR + (4*RegOffset),
+ ~(0xff << RegShift),
+ ARM_GIC_DEFAULT_PRIORITY << RegShift
+ );
+ }
+
+ // Configure interrupts for cpu 0
+ for (Index = 0; Index < (mGicNumInterrupts / 4); Index++) {
+ MmioWrite32 (PcdGet32(PcdGicDistributorBase) + ARM_GIC_ICDIPTR + (Index*4), 0x01010101);
+ }
+
+ // Set binary point reg to 0x7 (no preemption)
+ MmioWrite32 (PcdGet32(PcdGicInterruptInterfaceBase) + ARM_GIC_ICCBPR, 0x7);
+
+ // Set priority mask reg to 0xff to allow all priorities through
+ MmioWrite32 (PcdGet32(PcdGicInterruptInterfaceBase) + ARM_GIC_ICCPMR, 0xF0);
+
+ // Enable gic cpu interface
+ MmioWrite32 (PcdGet32(PcdGicInterruptInterfaceBase) + ARM_GIC_ICCICR, 0x1);
+
+ // Enable gic distributor
+ MmioWrite32 (PcdGet32(PcdGicDistributorBase) + ARM_GIC_ICDDCR, 0x3);
+
+ // Initialize the array for the Interrupt Handlers
+ gRegisteredInterruptHandlers = (HARDWARE_INTERRUPT_HANDLER*)AllocateZeroPool (sizeof(HARDWARE_INTERRUPT_HANDLER) * mGicNumInterrupts);
+
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &gHardwareInterruptHandle,
+ &gHardwareInterruptProtocolGuid, &gHardwareInterruptProtocol,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Get the CPU protocol that this driver requires.
+ //
+ Status = gBS->LocateProtocol(&gEfiCpuArchProtocolGuid, NULL, (VOID **)&Cpu);
+ ASSERT_EFI_ERROR(Status);
+
+ //
+ // Unregister the default exception handler.
+ //
+ Status = Cpu->RegisterInterruptHandler(Cpu, EXCEPT_ARM_IRQ, NULL);
+ ASSERT_EFI_ERROR(Status);
+
+ //
+ // Register to receive interrupts
+ //
+ Status = Cpu->RegisterInterruptHandler(Cpu, EXCEPT_ARM_IRQ, IrqInterruptHandler);
+ ASSERT_EFI_ERROR(Status);
+
+ // Register for an ExitBootServicesEvent
+ Status = gBS->CreateEvent (EVT_SIGNAL_EXIT_BOOT_SERVICES, TPL_NOTIFY, ExitBootServicesEvent, NULL, &EfiExitBootServicesEvent);
+ ASSERT_EFI_ERROR (Status);
+
+ return Status;
+}
diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/Gic400Dxe/PL390GicDxe.inf b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/Gic400Dxe/PL390GicDxe.inf
new file mode 100644
index 000000000..723931522
--- /dev/null
+++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/Gic400Dxe/PL390GicDxe.inf
@@ -0,0 +1,54 @@
+#/** @file
+#
+# Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>
+# Copyright (c) 2012, ARM Ltd. All rights reserved.<BR>
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#**/
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = PL390GicDxe
+ FILE_GUID = DE371F7C-DEC4-4D21-ADF1-593ABCC15882
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+
+ ENTRY_POINT = InterruptDxeInitialize
+
+
+[Sources.common]
+ PL390Gic.c
+ PL390GicDxe.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ EmbeddedPkg/EmbeddedPkg.dec
+ ArmPkg/ArmPkg.dec
+
+[LibraryClasses]
+ BaseLib
+ UefiLib
+ UefiBootServicesTableLib
+ DebugLib
+ PrintLib
+ MemoryAllocationLib
+ UefiDriverEntryPoint
+ IoLib
+
+[Protocols]
+ gHardwareInterruptProtocolGuid
+ gEfiCpuArchProtocolGuid
+
+[FixedPcd.common]
+ gArmTokenSpaceGuid.PcdGicDistributorBase
+ gArmTokenSpaceGuid.PcdGicInterruptInterfaceBase
+
+[Depex]
+ gEfiCpuArchProtocolGuid
diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/Gic400Dxe/PL390GicLib.inf b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/Gic400Dxe/PL390GicLib.inf
new file mode 100644
index 000000000..615b41039
--- /dev/null
+++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/Gic400Dxe/PL390GicLib.inf
@@ -0,0 +1,28 @@
+#/* @file
+# Copyright (c) 2011-2012, ARM Limited. All rights reserved.
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#*/
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = PL390GicLib
+ FILE_GUID = 03d05ee4-cdeb-458c-9dfc-993f09bdf405
+ MODULE_TYPE = SEC
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = ArmGicLib
+
+[Sources]
+ PL390Gic.c
+ PL390GicNonSec.c
+
+[Packages]
+ ArmPkg/ArmPkg.dec
+ MdePkg/MdePkg.dec
diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/Gic400Dxe/PL390GicNonSec.c b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/Gic400Dxe/PL390GicNonSec.c
new file mode 100644
index 000000000..10fcb4e5e
--- /dev/null
+++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/Gic400Dxe/PL390GicNonSec.c
@@ -0,0 +1,44 @@
+/** @file
+*
+* Copyright (c) 2011, ARM Limited. All rights reserved.
+*
+* This program and the accompanying materials
+* are licensed and made available under the terms and conditions of the BSD License
+* which accompanies this distribution. The full text of the license may be found at
+* http://opensource.org/licenses/bsd-license.php
+*
+* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#include <Uefi.h>
+#include <Library/IoLib.h>
+#include <Library/ArmGicLib.h>
+
+
+VOID
+EFIAPI
+ArmGicEnableInterruptInterface (
+ IN INTN GicInterruptInterfaceBase
+ )
+{
+ /*
+ * Enable the CPU interface in Non-Secure world
+ * Note: The ICCICR register is banked when Security extensions are implemented
+ */
+ MmioWrite32 (GicInterruptInterfaceBase + ARM_GIC_ICCICR, 0x1);
+}
+
+VOID
+EFIAPI
+ArmGicEnableDistributor (
+ IN INTN GicDistributorBase
+ )
+{
+ /*
+ * Enable GIC distributor in Non-Secure world.
+ * Note: The ICDDCR register is banked when Security extensions are implemented
+ */
+ MmioWrite32 (GicDistributorBase + ARM_GIC_ICDDCR, 0x1);
+}
diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/Gic400Dxe/PL390GicSec.c b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/Gic400Dxe/PL390GicSec.c
new file mode 100644
index 000000000..82ecfde6e
--- /dev/null
+++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/Gic400Dxe/PL390GicSec.c
@@ -0,0 +1,119 @@
+/** @file
+*
+* Copyright (c) 2011-2012, ARM Limited. All rights reserved.
+*
+* This program and the accompanying materials
+* are licensed and made available under the terms and conditions of the BSD License
+* which accompanies this distribution. The full text of the license may be found at
+* http://opensource.org/licenses/bsd-license.php
+*
+* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#include <Base.h>
+#include <Library/ArmLib.h>
+#include <Library/DebugLib.h>
+#include <Library/ArmPlatformLib.h>
+#include <Library/IoLib.h>
+#include <Library/ArmGicLib.h>
+
+/*
+ * This function configures the all interrupts to be Non-secure.
+ *
+ */
+VOID
+EFIAPI
+ArmGicSetupNonSecure (
+ IN UINTN MpId,
+ IN INTN GicDistributorBase,
+ IN INTN GicInterruptInterfaceBase
+ )
+{
+ UINTN InterruptId;
+ UINTN CachedPriorityMask;
+ UINTN Index;
+
+ CachedPriorityMask = MmioRead32 (GicInterruptInterfaceBase + ARM_GIC_ICCPMR);
+
+ // Set priority Mask so that no interrupts get through to CPU
+ MmioWrite32 (GicInterruptInterfaceBase + ARM_GIC_ICCPMR, 0);
+
+ // Check if there are any pending interrupts
+ //TODO: could be extended to take Peripheral interrupts into consideration, but at the moment only SGI's are taken into consideration.
+ while(0 != (MmioRead32 (GicDistributorBase + ARM_GIC_ICDICPR) & 0xF)) {
+ // Some of the SGI's are still pending, read Ack register and send End of Interrupt Signal
+ InterruptId = MmioRead32 (GicInterruptInterfaceBase + ARM_GIC_ICCIAR);
+
+ // Write to End of interrupt signal
+ MmioWrite32 (GicInterruptInterfaceBase + ARM_GIC_ICCEIOR, InterruptId);
+ }
+
+ // Only the primary core should set the Non Secure bit to the SPIs (Shared Peripheral Interrupt).
+ if (ArmPlatformIsPrimaryCore (MpId)) {
+ // Ensure all GIC interrupts are Non-Secure
+ for (Index = 0; Index < (ArmGicGetMaxNumInterrupts (GicDistributorBase) / 32); Index++) {
+ MmioWrite32 (GicDistributorBase + ARM_GIC_ICDISR + (Index * 4), 0xffffffff);
+ }
+ } else {
+ // The secondary cores only set the Non Secure bit to their banked PPIs
+ MmioWrite32 (GicDistributorBase + ARM_GIC_ICDISR, 0xffffffff);
+ }
+
+ // Ensure all interrupts can get through the priority mask
+ MmioWrite32 (GicInterruptInterfaceBase + ARM_GIC_ICCPMR, CachedPriorityMask);
+}
+
+/*
+ * This function configures the interrupts set by the mask to be secure.
+ *
+ */
+VOID
+EFIAPI
+ArmGicSetSecureInterrupts (
+ IN UINTN GicDistributorBase,
+ IN UINTN* GicSecureInterruptMask,
+ IN UINTN GicSecureInterruptMaskSize
+ )
+{
+ UINTN Index;
+ UINT32 InterruptStatus;
+
+ // We must not have more interrupts defined by the mask than the number of available interrupts
+ ASSERT(GicSecureInterruptMaskSize <= (ArmGicGetMaxNumInterrupts (GicDistributorBase) / 32));
+
+ // Set all the interrupts defined by the mask as Secure
+ for (Index = 0; Index < GicSecureInterruptMaskSize; Index++) {
+ InterruptStatus = MmioRead32 (GicDistributorBase + ARM_GIC_ICDISR + (Index * 4));
+ MmioWrite32 (GicDistributorBase + ARM_GIC_ICDISR + (Index * 4), InterruptStatus & (~GicSecureInterruptMask[Index]));
+ }
+}
+
+VOID
+EFIAPI
+ArmGicEnableInterruptInterface (
+ IN INTN GicInterruptInterfaceBase
+ )
+{
+ // Set Priority Mask to allow interrupts
+ MmioWrite32 (GicInterruptInterfaceBase + ARM_GIC_ICCPMR, 0x000000F0);
+
+ // Enable CPU interface in Secure world
+ // Enable CPU inteface in Non-secure World
+ // Signal Secure Interrupts to CPU using FIQ line *
+ MmioWrite32 (GicInterruptInterfaceBase + ARM_GIC_ICCICR,
+ ARM_GIC_ICCICR_ENABLE_SECURE |
+ ARM_GIC_ICCICR_ENABLE_NS |
+ ARM_GIC_ICCICR_SIGNAL_SECURE_TO_FIQ);
+}
+
+VOID
+EFIAPI
+ArmGicEnableDistributor (
+ IN INTN GicDistributorBase
+ )
+{
+ // Turn on the GIC distributor
+ MmioWrite32 (GicDistributorBase + ARM_GIC_ICDDCR, 1);
+}
diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/Gic400Dxe/PL390GicSecLib.inf b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/Gic400Dxe/PL390GicSecLib.inf
new file mode 100644
index 000000000..ab399b4fb
--- /dev/null
+++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/Gic400Dxe/PL390GicSecLib.inf
@@ -0,0 +1,37 @@
+#/* @file
+# Copyright (c) 2011-2012, ARM Limited. All rights reserved.
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#*/
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = PL390GicSecLib
+ FILE_GUID = 85f3cf80-b5f4-11df-9855-0002a5d5c51b
+ MODULE_TYPE = SEC
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = ArmGicLib
+
+[Sources]
+ PL390Gic.c
+ PL390GicSec.c
+
+[Packages]
+ ArmPkg/ArmPkg.dec
+ ArmPlatformPkg/ArmPlatformPkg.dec
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+
+[LibraryClasses]
+ ArmLib
+ DebugLib
+ IoLib
+ PcdLib
+
diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/Gpio/Gpio.c b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/Gpio/Gpio.c
new file mode 100644
index 000000000..cdd4102e5
--- /dev/null
+++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/Gpio/Gpio.c
@@ -0,0 +1,177 @@
+/** @file
+
+ Copyright (c) 2012, Samsung Electronics Co. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <Uefi.h>
+
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Protocol/ExynosGpio.h>
+#include <Platform/ArmPlatform.h>
+#include <Library/ExynosLib.h>
+
+
+
+EFI_STATUS
+Get (
+ IN EXYNOS_GPIO *This,
+ IN EXYNOS_GPIO_PIN Gpio,
+ OUT UINTN *Value
+ )
+{
+ UINTN Port;
+ UINTN Pin;
+ UINT32 DataInRegister;
+
+ if (Value == NULL)
+ {
+ return EFI_UNSUPPORTED;
+ }
+
+ Port = GPIO_PORT(Gpio);
+ Pin = GPIO_PIN(Gpio);
+
+ DataInRegister = GpioBase(Port) + GPIO_DATAIN;
+
+ if (MmioRead32 (DataInRegister) & GPIO_DATAIN_MASK(Pin)) {
+ *Value = 1;
+ } else {
+ *Value = 0;
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+Set (
+ IN EXYNOS_GPIO *This,
+ IN EXYNOS_GPIO_PIN Gpio,
+ IN EXYNOS_GPIO_MODE Mode
+ )
+{
+ UINTN Port;
+ UINTN Pin;
+ UINT32 OutputRegister;
+
+ Port = GPIO_PORT(Gpio);
+ Pin = GPIO_PIN(Gpio);
+ OutputRegister = GpioBase(Port) + GPIO_CON;
+ DEBUG ((EFI_D_INFO, "Gpio->Set: Gpio(0x%x), Port (0x%x), Pin (0x%x), Register (0x%x).\n", Gpio, Port, Pin, OutputRegister));
+ switch (Mode)
+ {
+ case GPIO_MODE_INPUT:
+ break;
+ case GPIO_MODE_OUTPUT_0:
+ MmioAndThenOr32(OutputRegister, ~GPIO_SFN_MASK(Pin), GPIO_OP_EN(Pin));
+ MmioAndThenOr32((GpioBase(Port) + GPIO_DATAIN), ~GPIO_DATAIN_MASK(Pin), GPIO_DATA_LOW(Pin));
+ break;
+ case GPIO_MODE_OUTPUT_1:
+ MmioAndThenOr32(OutputRegister, ~GPIO_SFN_MASK(Pin), GPIO_OP_EN(Pin));
+ MmioAndThenOr32((GpioBase(Port) + GPIO_DATAIN), ~GPIO_DATAIN_MASK(Pin), GPIO_DATA_HIGH(Pin));
+ break;
+ case GPIO_MODE_SPECIAL_FUNCTION_2:
+ MmioAndThenOr32(OutputRegister, ~GPIO_SFN_MASK(Pin), GPIO_SFN_EN(Pin));
+ break;
+ default:
+ return EFI_UNSUPPORTED;
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+GetMode (
+ IN EXYNOS_GPIO *This,
+ IN EXYNOS_GPIO_PIN Gpio,
+ OUT EXYNOS_GPIO_MODE *Mode
+ )
+{
+ return EFI_UNSUPPORTED;
+}
+
+EFI_STATUS
+SetPull (
+ IN EXYNOS_GPIO *This,
+ IN EXYNOS_GPIO_PIN Gpio,
+ IN EXYNOS_GPIO_PULL Direction
+ )
+{
+ UINTN Port;
+ UINTN Pin;
+ UINT32 OutputRegister;
+
+ Port = GPIO_PORT(Gpio);
+ Pin = GPIO_PIN(Gpio);
+ OutputRegister = GpioBase(Port) + GPIO_PUD;
+ DEBUG ((EFI_D_INFO, "Gpio->SetPull: Gpio(0x%x), Port (0x%x), Pin (0x%x), Register (0x%x).\n", Gpio, Port, Pin, OutputRegister));
+ switch (Direction)
+ {
+ case GPIO_PULL_NONE:
+ MmioAndThenOr32(OutputRegister, ~GPIO_PUD_MASK(Pin), GPIO_PUD_DIS(Pin));
+ break;
+ case GPIO_PULL_UP:
+ MmioAndThenOr32(OutputRegister, ~GPIO_PUD_MASK(Pin), GPIO_PUP_EN(Pin));
+ break;
+ case GPIO_PULL_DOWN:
+ MmioAndThenOr32(OutputRegister, ~GPIO_PUD_MASK(Pin), GPIO_PDN_EN(Pin));
+ break;
+ default:
+ return EFI_UNSUPPORTED;
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+
+EFI_STATUS
+SetStrength (
+ IN EXYNOS_GPIO *This,
+ IN EXYNOS_GPIO_PIN Gpio,
+ IN EXYNOS_GPIO_STRN Strength
+ )
+{
+ UINTN Port;
+ UINTN Pin;
+ UINT32 OutputRegister;
+
+ Port = GPIO_PORT(Gpio);
+ Pin = GPIO_PIN(Gpio);
+ OutputRegister = GpioBase(Port) + GPIO_DRV;
+ MmioAndThenOr32(OutputRegister, ~GPIO_DRV_MASK(Pin), GPIO_DRV_SET(Strength,Pin));
+
+ return EFI_SUCCESS;
+}
+
+
+
+EXYNOS_GPIO Gpio = {
+ Get,
+ Set,
+ GetMode,
+ SetPull,
+ SetStrength
+};
+
+EFI_STATUS
+GpioInitialize (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+
+ Status = gBS->InstallMultipleProtocolInterfaces(&ImageHandle, &gSamsungPlatformGpioProtocolGuid, &Gpio, NULL);
+ return Status;
+}
diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/Gpio/Gpio.inf b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/Gpio/Gpio.inf
new file mode 100644
index 000000000..605b80576
--- /dev/null
+++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/Gpio/Gpio.inf
@@ -0,0 +1,46 @@
+#/** @file
+#
+# Copyright (c) 2012, Samsung Electronics Co. All rights reserved.<BR>
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#**/
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = Gpio
+ FILE_GUID = E7D9CAE1-6930-46E3-BDF9-0027446E7DF2
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+
+ ENTRY_POINT = GpioInitialize
+
+
+[Sources.common]
+ Gpio.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ SamsungPlatformPkg/ExynosPkg/Exynos5250/ExynosPkg.dec
+ SamsungPlatformPkg/SamsungPlatformPkg.dec
+
+[LibraryClasses]
+ IoLib
+ UefiDriverEntryPoint
+ ExynosLib
+ DebugLib
+
+[Guids]
+
+[Protocols]
+ gSamsungPlatformGpioProtocolGuid
+
+[Pcd]
+
+[depex]
+ TRUE
diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/HashDxe/HashDxe.c b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/HashDxe/HashDxe.c
new file mode 100644
index 000000000..75ffc2668
--- /dev/null
+++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/HashDxe/HashDxe.c
@@ -0,0 +1,241 @@
+#include <Library/PcdLib.h>
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/ArmGicLib.h>
+#include <Library/UncachedMemoryAllocationLib.h>
+
+#include <Protocol/Hash.h>
+
+#include <Platform/ArmPlatform.h>
+#include <Platform/Exynos5250.h>
+
+#include "HashDxe.h"
+
+#define CLOCK_ON 1
+#define CLOCK_OFF 0
+
+EFI_STATUS
+EFIAPI
+CryptoClockGating (
+ IN UINT32 clock_status
+ )
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ UINT32 CmuBase;
+ UINT32 value;
+
+ CmuBase = PcdGet32(PcdCmuBase);
+ value = MmioRead32(CmuBase + SSS_CMU_OFFSET);
+
+ if (clock_status == CLOCK_ON)
+ MmioWrite32(CmuBase + SSS_CMU_OFFSET, value | CLK_SSS);
+ else if (clock_status == CLOCK_OFF)
+ MmioWrite32(CmuBase + SSS_CMU_OFFSET, value & ~CLK_SSS);
+ else {
+ DEBUG((EFI_D_ERROR, "[HashDxe] : Unsupported SSS clock status\n"));
+ Status = EFI_INVALID_PARAMETER;
+ }
+
+ return Status;
+}
+
+/**
+ Returns the size of the hash which results from a specific algorithm.
+
+ @param[in] This Points to this instance of EFI_HASH_PROTOCOL.
+ @param[in] HashAlgorithm Points to the EFI_GUID which identifies the algorithm to use.
+ @param[out] HashSize Holds the returned size of the algorithm's hash.
+
+ @retval EFI_SUCCESS Hash size returned successfully.
+ @retval EFI_UNSUPPORTED The algorithm specified by HashAlgorithm is not supported
+ by this driver.
+
+**/
+EFI_STATUS
+EFIAPI
+HashDxeGetHashSize (
+ IN CONST EFI_HASH_PROTOCOL *This,
+ IN CONST EFI_GUID *HashAlgorithm,
+ OUT UINTN *HashSize
+ )
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+
+ if (CompareGuid(HashAlgorithm, &gEfiHashAlgorithmSha1Guid))
+ *HashSize = sizeof(EFI_SHA1_HASH);
+ else if (CompareGuid(HashAlgorithm, &gEfiHashAlgorithmSha256Guid))
+ *HashSize = sizeof(EFI_SHA256_HASH);
+ else {
+ DEBUG((EFI_D_ERROR, "[HashDxe] : Unsupported Hash Algorithm\n"));
+ Status = EFI_UNSUPPORTED;
+ }
+
+ return Status;
+}
+
+/**
+ Returns the size of the hash which results from a specific algorithm.
+
+ @param[in] This Points to this instance of EFI_HASH_PROTOCOL.
+ @param[in] HashAlgorithm Points to the EFI_GUID which identifies the algorithm to use.
+ @param[in] Extend Specifies whether to create a new hash (FALSE) or extend the specified
+ existing hash (TRUE).
+ @param[in] Message Points to the start of the message.
+ @param[in] MessageSize The size of Message, in bytes.
+ @param[in,out] Hash On input, if Extend is TRUE, then this holds the hash to extend. On
+ output, holds the resulting hash computed from the message.
+
+ @retval EFI_SUCCESS Hash returned successfully.
+ @retval EFI_UNSUPPORTED The algorithm specified by HashAlgorithm is not supported by this
+ driver. Or, Extend is TRUE, and the algorithm doesn't support extending the hash.
+
+**/
+EFI_STATUS
+EFIAPI
+HashDxeRunHash (
+ IN CONST EFI_HASH_PROTOCOL *This,
+ IN CONST EFI_GUID *HashAlgorithm,
+ IN BOOLEAN Extend,
+ IN CONST UINT8 *Message,
+ IN UINT64 MessageSize,
+ IN OUT EFI_HASH_OUTPUT *Hash
+ )
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ UINT32 value;
+ UINT32 CryptoBase;
+ UINT32 TotalMessageSize;
+ UINT32 HashResult[8];
+ UINT8 *TempMessage;
+
+ CryptoBase = PcdGet32(PcdCryptoBase);
+
+ CryptoClockGating(CLOCK_ON);
+
+ /* Flush HRDMA */
+ MmioWrite32(CryptoBase + SSS_FC_HRDMAC, SSS_FC_HRDMACFLUSH_ON);
+ MmioWrite32(CryptoBase + SSS_FC_HRDMAC, SSS_FC_HRDMACFLUSH_OFF);
+
+ /* Set byte swap of in/out data and iv */
+ MmioWrite32(CryptoBase + SSS_HASH_BYTESWAP,
+ SSS_HASH_SWAPDI_ON | SSS_HASH_SWAPDO_ON | SSS_HASH_SWAPIV_ON);
+
+ /* Select HASH input mux as external source */
+ value = MmioRead32(CryptoBase + SSS_FC_FIFOCTRL);
+ value = (value & ~SSS_FC_SELHASH_MASK) | SSS_FC_SELHASH_EXOUT;
+ MmioWrite32(CryptoBase + SSS_FC_FIFOCTRL, value);
+
+ /* Set HASH algorithm and start hash engine */
+ if (CompareGuid(HashAlgorithm, &gEfiHashAlgorithmSha1Guid))
+ value = SSS_HASH_ENGSEL_SHA1HASH | SSS_HASH_STARTBIT_ON;
+ else if (CompareGuid(HashAlgorithm, &gEfiHashAlgorithmSha256Guid))
+ value = SSS_HASH_ENGSEL_SHA256HASH | SSS_HASH_STARTBIT_ON;
+ else {
+ DEBUG((EFI_D_ERROR, "[HashDxe] : Unsupported Hash Algorithm\n"));
+ Status = EFI_UNSUPPORTED;
+ return Status;
+ }
+ MmioWrite32(CryptoBase + SSS_HASH_CONTROL, value);
+
+ /* Enable FIFO mode */
+ MmioWrite32(CryptoBase + SSS_HASH_FIFO_MODE, SSS_HASH_FIFO_ON);
+
+ if (Extend == 0)
+ TotalMessageSize = MessageSize;
+ else if (Extend == 1) {
+ if (CompareGuid(HashAlgorithm, &gEfiHashAlgorithmSha1Guid)) {
+ TempMessage = (UINT8 *)UncachedAllocatePool(sizeof(EFI_SHA1_HASH) + MessageSize);
+ CopyMem(TempMessage, Hash, sizeof(EFI_SHA1_HASH));
+ CopyMem(TempMessage + sizeof(EFI_SHA1_HASH), Message, MessageSize);
+ TotalMessageSize = sizeof(EFI_SHA1_HASH) + MessageSize;
+ } else if (CompareGuid(HashAlgorithm, &gEfiHashAlgorithmSha256Guid)) {
+ TempMessage = (UINT8 *)UncachedAllocatePool(sizeof(EFI_SHA256_HASH) + MessageSize);
+ CopyMem(TempMessage, Hash, sizeof(EFI_SHA256_HASH));
+ CopyMem(TempMessage + sizeof(EFI_SHA256_HASH), Message, MessageSize);
+ TotalMessageSize = sizeof(EFI_SHA256_HASH) + MessageSize;
+ }
+ }
+
+ MmioWrite32(CryptoBase + SSS_HASH_MSGSIZE_LOW, TotalMessageSize);
+ MmioWrite32(CryptoBase + SSS_HASH_MSGSIZE_HIGH, 0);
+
+ /* Set HRDMA */
+ /*
+ * Message must be a physical address. Check it.
+ */
+ if (Extend == 0)
+ MmioWrite32(CryptoBase + SSS_FC_HRDMAS, (UINT32)Message);
+ else if (Extend == 1)
+ MmioWrite32(CryptoBase + SSS_FC_HRDMAS, (UINT32)TempMessage);
+
+ MmioWrite32(CryptoBase + SSS_FC_HRDMAL, TotalMessageSize);
+
+ /* Check the HASH status */
+ while ((MmioRead32(CryptoBase + SSS_HASH_STATUS) & SSS_HASH_MSGDONE_MASK)
+ == SSS_HASH_MSGDONE_OFF);
+
+ /* Clear MSG_DONE bit */
+ MmioWrite32(CryptoBase + SSS_HASH_STATUS, SSS_HASH_MSGDONE_ON);
+
+ /* Read hash result */
+ HashResult[0] = MmioRead32(CryptoBase + SSS_HASH_RESULT1);
+ HashResult[1] = MmioRead32(CryptoBase + SSS_HASH_RESULT2);
+ HashResult[2] = MmioRead32(CryptoBase + SSS_HASH_RESULT3);
+ HashResult[3] = MmioRead32(CryptoBase + SSS_HASH_RESULT4);
+ HashResult[4] = MmioRead32(CryptoBase + SSS_HASH_RESULT5);
+
+ if (CompareGuid(HashAlgorithm, &gEfiHashAlgorithmSha256Guid)) {
+ HashResult[5] = MmioRead32(CryptoBase + SSS_HASH_RESULT6);
+ HashResult[6] = MmioRead32(CryptoBase + SSS_HASH_RESULT7);
+ HashResult[7] = MmioRead32(CryptoBase + SSS_HASH_RESULT8);
+ }
+
+ if (CompareGuid(HashAlgorithm, &gEfiHashAlgorithmSha1Guid))
+ CopyMem(Hash, HashResult, sizeof(EFI_SHA1_HASH));
+ else if (CompareGuid(HashAlgorithm, &gEfiHashAlgorithmSha256Guid))
+ CopyMem(Hash, HashResult, sizeof(EFI_SHA256_HASH));
+ else {
+ DEBUG((EFI_D_ERROR, "[HashDxe] : Unsupported Hash Algorithm\n"));
+ Status = EFI_UNSUPPORTED;
+ return Status;
+ }
+
+ MmioWrite32(CryptoBase + SSS_FC_INTPEND, SSS_FC_HRDMA);
+
+ return Status;
+}
+
+EFI_HASH_PROTOCOL gHash = {
+ HashDxeGetHashSize,
+ HashDxeRunHash
+};
+
+/**
+ Initialize the state information for the HashDxe
+
+ @param ImageHandle of the loaded driver
+ @param SystemTable Pointer to the System Table
+
+ @retval EFI_SUCCESS Protocol registered
+ @retval EFI_OUT_OF_RESOURCES Cannot allocate protocol data structure
+ @retval EFI_DEVICE_ERROR Hardware problems
+
+**/
+EFI_STATUS
+EFIAPI
+HashDxeInitialize (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+
+ Status = gBS->InstallMultipleProtocolInterfaces(
+ &ImageHandle,
+ &gEfiHashProtocolGuid,
+ &gHash,
+ NULL
+ );
+
+ return Status;
+}
diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/HashDxe/HashDxe.h b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/HashDxe/HashDxe.h
new file mode 100644
index 000000000..6a2562916
--- /dev/null
+++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/HashDxe/HashDxe.h
@@ -0,0 +1,417 @@
+/** @file
+
+ Copyright (c) 2012, Samsung Electronics Co. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _CRYPTODXE_H_
+#define _CRYPTODXE_H_
+
+#include <Uefi.h>
+
+#include <Library/BaseLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/PcdLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Protocol/BlockIo.h>
+#include <Protocol/DevicePath.h>
+
+#define SSS_CMU_OFFSET (0x8800)
+#define CLK_SSS (1 << 2)
+
+#define SSS_FC_OFFSET (0x0)
+#define SSS_AES_OFFSET (0x200)
+#define SSS_HASH_OFFSET (0x400)
+
+/* Feed control registers */
+#define SSS_FC_INTSTAT (SSS_FC_OFFSET + 0x00)
+#define SSS_FC_INTENSET (SSS_FC_OFFSET + 0x04)
+#define SSS_FC_INTENCLR (SSS_FC_OFFSET + 0x08)
+#define SSS_FC_INTPEND (SSS_FC_OFFSET + 0x0C)
+#define SSS_FC_FIFOSTAT (SSS_FC_OFFSET + 0x10)
+#define SSS_FC_FIFOCTRL (SSS_FC_OFFSET + 0x14)
+#define SSS_FC_GLOBAL (SSS_FC_OFFSET + 0x18)
+#define SSS_FC_BRDMAS (SSS_FC_OFFSET + 0x20)
+#define SSS_FC_BRDMAL (SSS_FC_OFFSET + 0x24)
+#define SSS_FC_BRDMAC (SSS_FC_OFFSET + 0x28)
+#define SSS_FC_BTDMAS (SSS_FC_OFFSET + 0x30)
+#define SSS_FC_BTDMAL (SSS_FC_OFFSET + 0x34)
+#define SSS_FC_BTDMAC (SSS_FC_OFFSET + 0x38)
+#define SSS_FC_HRDMAS (SSS_FC_OFFSET + 0x40)
+#define SSS_FC_HRDMAL (SSS_FC_OFFSET + 0x44)
+#define SSS_FC_HRDMAC (SSS_FC_OFFSET + 0x48)
+#define SSS_FC_PKDMAS (SSS_FC_OFFSET + 0x50)
+#define SSS_FC_PKDMAL (SSS_FC_OFFSET + 0x54)
+#define SSS_FC_PKDMAC (SSS_FC_OFFSET + 0x58)
+#define SSS_FC_PKDMAO (SSS_FC_OFFSET + 0x5C)
+
+/* AES control registers */
+#define SSS_AES_CONTROL (SSS_AES_OFFSET + 0x00)
+#define SSS_AES_STATUS (SSS_AES_OFFSET + 0x04)
+
+#define SSS_AES_IN1 (SSS_AES_OFFSET + 0x10)
+#define SSS_AES_IN2 (SSS_AES_OFFSET + 0x14)
+#define SSS_AES_IN3 (SSS_AES_OFFSET + 0x18)
+#define SSS_AES_IN4 (SSS_AES_OFFSET + 0x1C)
+
+#define SSS_AES_OUT1 (SSS_AES_OFFSET + 0x20)
+#define SSS_AES_OUT2 (SSS_AES_OFFSET + 0x24)
+#define SSS_AES_OUT3 (SSS_AES_OFFSET + 0x28)
+#define SSS_AES_OUT4 (SSS_AES_OFFSET + 0x2C)
+
+#define SSS_AES_IV1 (SSS_AES_OFFSET + 0x30)
+#define SSS_AES_IV2 (SSS_AES_OFFSET + 0x34)
+#define SSS_AES_IV3 (SSS_AES_OFFSET + 0x38)
+#define SSS_AES_IV4 (SSS_AES_OFFSET + 0x3C)
+
+#define SSS_AES_CNT1 (SSS_AES_OFFSET + 0x40)
+#define SSS_AES_CNT2 (SSS_AES_OFFSET + 0x44)
+#define SSS_AES_CNT3 (SSS_AES_OFFSET + 0x48)
+#define SSS_AES_CNT4 (SSS_AES_OFFSET + 0x4C)
+
+#define SSS_AES_KEY1 (SSS_AES_OFFSET + 0x80)
+#define SSS_AES_KEY2 (SSS_AES_OFFSET + 0x84)
+#define SSS_AES_KEY3 (SSS_AES_OFFSET + 0x88)
+#define SSS_AES_KEY4 (SSS_AES_OFFSET + 0x8C)
+#define SSS_AES_KEY5 (SSS_AES_OFFSET + 0x90)
+#define SSS_AES_KEY6 (SSS_AES_OFFSET + 0x94)
+#define SSS_AES_KEY7 (SSS_AES_OFFSET + 0x98)
+#define SSS_AES_KEY8 (SSS_AES_OFFSET + 0x9C)
+
+/* TDES control registers */
+#define SSS_TDES_CONTROL (SSS_TDES_OFFSET + 0x00)
+#define SSS_TDES_STATUS (SSS_TDES_OFFSET + 0x04)
+
+#define SSS_TDES_KEY11 (SSS_TDES_OFFSET + 0x10)
+#define SSS_TDES_KEY12 (SSS_TDES_OFFSET + 0x14)
+#define SSS_TDES_KEY21 (SSS_TDES_OFFSET + 0x18)
+#define SSS_TDES_KEY22 (SSS_TDES_OFFSET + 0x1C)
+#define SSS_TDES_KEY31 (SSS_TDES_OFFSET + 0x20)
+#define SSS_TDES_KEY32 (SSS_TDES_OFFSET + 0x24)
+
+#define SSS_TDES_IV1 (SSS_TDES_OFFSET + 0x28)
+#define SSS_TDES_IV2 (SSS_TDES_OFFSET + 0x2C)
+
+#define SSS_TDES_IN1 (SSS_TDES_OFFSET + 0x30)
+#define SSS_TDES_IN2 (SSS_TDES_OFFSET + 0x34)
+
+#define SSS_TDES_OUT1 (SSS_TDES_OFFSET + 0x38)
+#define SSS_TDES_OUT2 (SSS_TDES_OFFSET + 0x3C)
+
+/* HASH control registers */
+#define SSS_HASH_CONTROL (SSS_HASH_OFFSET + 0x00)
+#define SSS_HASH_CONTROL2 (SSS_HASH_OFFSET + 0x04)
+#define SSS_HASH_FIFO_MODE (SSS_HASH_OFFSET + 0x08)
+#define SSS_HASH_BYTESWAP (SSS_HASH_OFFSET + 0x0C)
+#define SSS_HASH_STATUS (SSS_HASH_OFFSET + 0x10)
+#define SSS_HASH_MSGSIZE_LOW (SSS_HASH_OFFSET + 0x20)
+#define SSS_HASH_MSGSIZE_HIGH (SSS_HASH_OFFSET + 0x24)
+#define SSS_HASH_PRELEN_LOW (SSS_HASH_OFFSET + 0x28)
+#define SSS_HASH_PRELEN_HIGH (SSS_HASH_OFFSET + 0x2C)
+
+#define SSS_HASH_IN1 (SSS_HASH_OFFSET + 0x30)
+#define SSS_HASH_IN2 (SSS_HASH_OFFSET + 0x34)
+#define SSS_HASH_IN3 (SSS_HASH_OFFSET + 0x38)
+#define SSS_HASH_IN4 (SSS_HASH_OFFSET + 0x3C)
+#define SSS_HASH_IN5 (SSS_HASH_OFFSET + 0x40)
+#define SSS_HASH_IN6 (SSS_HASH_OFFSET + 0x44)
+#define SSS_HASH_IN7 (SSS_HASH_OFFSET + 0x48)
+#define SSS_HASH_IN8 (SSS_HASH_OFFSET + 0x4C)
+#define SSS_HASH_IN9 (SSS_HASH_OFFSET + 0x50)
+#define SSS_HASH_IN10 (SSS_HASH_OFFSET + 0x54)
+#define SSS_HASH_IN11 (SSS_HASH_OFFSET + 0x58)
+#define SSS_HASH_IN12 (SSS_HASH_OFFSET + 0x5C)
+#define SSS_HASH_IN13 (SSS_HASH_OFFSET + 0x60)
+#define SSS_HASH_IN14 (SSS_HASH_OFFSET + 0x64)
+#define SSS_HASH_IN15 (SSS_HASH_OFFSET + 0x68)
+#define SSS_HASH_IN16 (SSS_HASH_OFFSET + 0x6C)
+
+#define SSS_HASH_HMAC_KEY_IN1 (SSS_HASH_OFFSET + 0x70)
+#define SSS_HASH_HMAC_KEY_IN2 (SSS_HASH_OFFSET + 0x74)
+#define SSS_HASH_HMAC_KEY_IN3 (SSS_HASH_OFFSET + 0x78)
+#define SSS_HASH_HMAC_KEY_IN4 (SSS_HASH_OFFSET + 0x7C)
+#define SSS_HASH_HMAC_KEY_IN5 (SSS_HASH_OFFSET + 0x80)
+#define SSS_HASH_HMAC_KEY_IN6 (SSS_HASH_OFFSET + 0x84)
+#define SSS_HASH_HMAC_KEY_IN7 (SSS_HASH_OFFSET + 0x88)
+#define SSS_HASH_HMAC_KEY_IN8 (SSS_HASH_OFFSET + 0x8C)
+#define SSS_HASH_HMAC_KEY_IN9 (SSS_HASH_OFFSET + 0x90)
+#define SSS_HASH_HMAC_KEY_IN10 (SSS_HASH_OFFSET + 0x94)
+#define SSS_HASH_HMAC_KEY_IN11 (SSS_HASH_OFFSET + 0x98)
+#define SSS_HASH_HMAC_KEY_IN12 (SSS_HASH_OFFSET + 0x9C)
+#define SSS_HASH_HMAC_KEY_IN13 (SSS_HASH_OFFSET + 0xA0)
+#define SSS_HASH_HMAC_KEY_IN14 (SSS_HASH_OFFSET + 0xA4)
+#define SSS_HASH_HMAC_KEY_IN15 (SSS_HASH_OFFSET + 0xA8)
+#define SSS_HASH_HMAC_KEY_IN16 (SSS_HASH_OFFSET + 0xAC)
+
+#define SSS_HASH_IV1 (SSS_HASH_OFFSET + 0xB0)
+#define SSS_HASH_IV2 (SSS_HASH_OFFSET + 0xB4)
+#define SSS_HASH_IV3 (SSS_HASH_OFFSET + 0xB8)
+#define SSS_HASH_IV4 (SSS_HASH_OFFSET + 0xBC)
+#define SSS_HASH_IV5 (SSS_HASH_OFFSET + 0xC0)
+#define SSS_HASH_IV6 (SSS_HASH_OFFSET + 0xC4)
+#define SSS_HASH_IV7 (SSS_HASH_OFFSET + 0xC8)
+#define SSS_HASH_IV8 (SSS_HASH_OFFSET + 0xCC)
+
+#define SSS_HASH_RESULT1 (SSS_HASH_OFFSET + 0x100)
+#define SSS_HASH_RESULT2 (SSS_HASH_OFFSET + 0x104)
+#define SSS_HASH_RESULT3 (SSS_HASH_OFFSET + 0x108)
+#define SSS_HASH_RESULT4 (SSS_HASH_OFFSET + 0x10C)
+#define SSS_HASH_RESULT5 (SSS_HASH_OFFSET + 0x110)
+#define SSS_HASH_RESULT6 (SSS_HASH_OFFSET + 0x114)
+#define SSS_HASH_RESULT7 (SSS_HASH_OFFSET + 0x118)
+#define SSS_HASH_RESULT8 (SSS_HASH_OFFSET + 0x11C)
+
+#define SSS_HASH_SEED1 (SSS_HASH_OFFSET + 0x140)
+#define SSS_HASH_SEED2 (SSS_HASH_OFFSET + 0x144)
+#define SSS_HASH_SEED3 (SSS_HASH_OFFSET + 0x148)
+#define SSS_HASH_SEED4 (SSS_HASH_OFFSET + 0x14C)
+#define SSS_HASH_SEED5 (SSS_HASH_OFFSET + 0x150)
+
+#define SSS_HASH_PRNG1 (SSS_HASH_OFFSET + 0x160)
+#define SSS_HASH_PRNG2 (SSS_HASH_OFFSET + 0x164)
+#define SSS_HASH_PRNG3 (SSS_HASH_OFFSET + 0x168)
+#define SSS_HASH_PRNG4 (SSS_HASH_OFFSET + 0x16C)
+#define SSS_HASH_PRNG5 (SSS_HASH_OFFSET + 0x170)
+
+/* PKA control registers */
+#define SSS_PKA_SFR0 (SSS_PKA_OFFSET + 0x00)
+#define SSS_PKA_SFR1 (SSS_PKA_OFFSET + 0x04)
+#define SSS_PKA_SFR2 (SSS_PKA_OFFSET + 0x08)
+#define SSS_PKA_SFR3 (SSS_PKA_OFFSET + 0x0C)
+#define SSS_PKA_SFR4 (SSS_PKA_OFFSET + 0x10)
+
+
+/*****************************************************************
+ OFFSET
+*****************************************************************/
+
+/* SSS_FC_INT */
+#define SSS_FC_PKDMA (1 << 0)
+#define SSS_FC_HRDMA (1 << 1)
+#define SSS_FC_BTDMA (1 << 2)
+#define SSS_FC_BRDMA (1 << 3)
+#define SSS_FC_PRNG_ERROR (1 << 4)
+#define SSS_FC_MSG_DONE (1 << 5)
+#define SSS_FC_PRNG_DONE (1 << 6)
+#define SSS_FC_PARTIAL_DONE (1 << 7)
+
+/* SSS_FC_FIFOSTAT */
+#define SSS_FC_PKFIFO_EMPTY (1 << 0)
+#define SSS_FC_PKFIFO_FULL (1 << 1)
+#define SSS_FC_HRFIFO_EMPTY (1 << 2)
+#define SSS_FC_HRFIFO_FULL (1 << 3)
+#define SSS_FC_BTFIFO_EMPTY (1 << 4)
+#define SSS_FC_BTFIFO_FULL (1 << 5)
+#define SSS_FC_BRFIFO_EMPTY (1 << 6)
+#define SSS_FC_BRFIFO_FULL (1 << 7)
+
+/* SSS_FC_FIFOCTRL */
+#define SSS_FC_SELHASH_MASK (3 << 0)
+#define SSS_FC_SELHASH_EXOUT (0 << 0)
+#define SSS_FC_SELHASH_BCIN (1 << 0)
+#define SSS_FC_SELHASH_BCOUT (2 << 0)
+#define SSS_FC_SELBC_MASK (1 << 2)
+#define SSS_FC_SELBC_AES (0 << 2)
+#define SSS_FC_SELBC_DES (1 << 2)
+
+/* SSS_FC_GLOBAL */
+#define SSS_FC_SSS_RESET (1 << 0)
+#define SSS_FC_DMA_RESET (1 << 1)
+#define SSS_FC_AES_RESET (1 << 2)
+#define SSS_FC_DES_RESET (1 << 3)
+#define SSS_FC_HASH_RESET (1 << 4)
+#define SSS_FC_AXI_ENDIAN_MASK (3 << 6)
+#define SSS_FC_AXI_ENDIAN_LE (0 << 6)
+#define SSS_FC_AXI_ENDIAN_BIBE (1 << 6)
+#define SSS_FC_AXI_ENDIAN_WIBE (2 << 6)
+
+/* Feed control - BRDMA control */
+#define SSS_FC_BRDMACFLUSH_OFF (0 << 0)
+#define SSS_FC_BRDMACFLUSH_ON (1 << 0)
+#define SSS_FC_BRDMACSWAP_ON (1 << 1)
+#define SSS_FC_BRDMACARPROT_MASK (0x7 << 2)
+#define SSS_FC_BRDMACARPROT_OFS (2)
+#define SSS_FC_BRDMACARCACHE_MASK (0xF << 5)
+#define SSS_FC_BRDMACARCACHE_OFS (5)
+
+/* Feed control - BTDMA control */
+#define SSS_FC_BTDMACFLUSH_OFF (0 << 0)
+#define SSS_FC_BTDMACFLUSH_ON (1 << 0)
+#define SSS_FC_BTDMACSWAP_ON (1 << 1)
+#define SSS_FC_BTDMACAWPROT_MASK (0x7 << 2)
+#define SSS_FC_BTDMACAWPROT_OFS (2)
+#define SSS_FC_BTDMACAWCACHE_MASK (0xF << 5)
+#define SSS_FC_BTDMACAWCACHE_OFS (5)
+
+/* Feed control - HRDMA control */
+#define SSS_FC_HRDMACFLUSH_OFF (0 << 0)
+#define SSS_FC_HRDMACFLUSH_ON (1 << 0)
+#define SSS_FC_HRDMACSWAP_ON (1 << 1)
+
+/* Feed control - PKDMA control */
+#define SSS_FC_PKDMACBYTESWAP_ON (1 << 3)
+#define SSS_FC_PKDMACDESEND_ON (1 << 2)
+#define SSS_FC_PKDMACTRANSMIT_ON (1 << 1)
+#define SSS_FC_PKDMACFLUSH_ON (1 << 0)
+
+/* Feed control - PKDMA offset */
+#define SSS_FC_SRAMOFFSET_MASK (0xFFF)
+
+/* AES control */
+#define SSS_AES_MODE_MASK (1 << 0)
+#define SSS_AES_MODE_ENC (0 << 0)
+#define SSS_AES_MODE_DEC (1 << 0)
+#define SSS_AES_OPERMODE_MASK (3 << 1)
+#define SSS_AES_OPERMODE_ECB (0 << 1)
+#define SSS_AES_OPERMODE_CBC (1 << 1)
+#define SSS_AES_OPERMODE_CTR (2 << 1)
+/*
+TODO
+CTS MODE define
+*/
+#define SSS_AES_OPERMODE_CTS (3 << 1)
+
+#define SSS_AES_FIFO_MASK (1 << 3)
+#define SSS_AES_FIFO_OFF (0 << 3)
+#define SSS_AES_FIFO_ON (1 << 3)
+#define SSS_AES_KEYSIZE_MASK (3 << 4)
+#define SSS_AES_KEYSIZE_128 (0 << 4)
+#define SSS_AES_KEYSIZE_192 (1 << 4)
+#define SSS_AES_KEYSIZE_256 (2 << 4)
+#define SSS_AES_KEYCNGMODE_MASK (1 << 6)
+#define SSS_AES_KEYCNGMODE_OFF (0 << 6)
+#define SSS_AES_KEYCNGMODE_ON (1 << 6)
+#define SSS_AES_SWAP_MASK (0x1F << 7)
+#define SSS_AES_SWAPKEY_OFF (0 << 7)
+#define SSS_AES_SWAPKEY_ON (1 << 7)
+#define SSS_AES_SWAPCNT_OFF (0 << 8)
+#define SSS_AES_SWAPCNT_ON (1 << 8)
+#define SSS_AES_SWAPIV_OFF (0 << 9)
+#define SSS_AES_SWAPIV_ON (1 << 9)
+#define SSS_AES_SWAPDO_OFF (0 << 10)
+#define SSS_AES_SWAPDO_ON (1 << 10)
+#define SSS_AES_SWAPDI_OFF (0 << 11)
+#define SSS_AES_SWAPDI_ON (1 << 11)
+#define SSS_AES_COUNTERSIZE_MASK (3 << 12)
+#define SSS_AES_COUNTERSIZE_128 (0 << 12)
+#define SSS_AES_COUNTERSIZE_64 (1 << 12)
+#define SSS_AES_COUNTERSIZE_32 (2 << 12)
+#define SSS_AES_COUNTERSIZE_16 (3 << 12)
+
+/* AES status */
+#define SSS_AES_OUTRDY_MASK (1 << 0)
+#define SSS_AES_OUTRDY_OFF (0 << 0)
+#define SSS_AES_OUTRDY_ON (1 << 0)
+#define SSS_AES_INRDY_MASK (1 << 1)
+#define SSS_AES_INRDY_OFF (0 << 1)
+#define SSS_AES_INRDY_ON (1 << 1)
+#define SSS_AES_BUSY_MASK (1 << 2)
+#define SSS_AES_BUSY_OFF (0 << 2)
+#define SSS_AES_BUSY_ON (1 << 2)
+
+/* TDES control */
+#define SSS_TDES_MODE_MASK (1 << 0)
+#define SSS_TDES_MODE_ENC (0 << 0)
+#define SSS_TDES_MODE_DEC (1 << 0)
+#define SSS_TDES_OPERMODE_MASK (1 << 1)
+#define SSS_TDES_OPERMODE_ECB (0 << 1)
+#define SSS_TDES_OPERMODE_CBC (1 << 1)
+#define SSS_TDES_SEL_MASK (3 << 3)
+#define SSS_TDES_SEL_DES (0 << 3)
+#define SSS_TDES_SEL_TDESEDE (1 << 3)
+#define SSS_TDES_SEL_TDESEEE (3 << 3)
+#define SSS_TDES_FIFO_MASK (1 << 5)
+#define SSS_TDES_FIFO_OFF (0 << 5)
+#define SSS_TDES_FIFO_ON (1 << 5)
+#define SSS_TDES_SWAP_MASK (0xF << 6)
+#define SSS_TDES_SWAPKEY_OFF (0 << 6)
+#define SSS_TDES_SWAPKEY_ON (1 << 6)
+#define SSS_TDES_SWAPIV_OFF (0 << 7)
+#define SSS_TDES_SWAPIV_ON (1 << 7)
+#define SSS_TDES_SWAPDO_OFF (0 << 8)
+#define SSS_TDES_SWAPDO_ON (1 << 8)
+#define SSS_TDES_SWAPDI_OFF (0 << 9)
+#define SSS_TDES_SWAPDI_ON (1 << 9)
+
+/* TDES status */
+#define SSS_TDES_OUTRDY_MASK (1 << 0)
+#define SSS_TDES_OUTRDY_OFF (0 << 0)
+#define SSS_TDES_OUTRDY_ON (1 << 0)
+#define SSS_TDES_INRDY_MASK (1 << 1)
+#define SSS_TDES_INRDY_OFF (0 << 1)
+#define SSS_TDES_INRDY_ON (1 << 1)
+#define SSS_TDES_BUSY_MASK (1 << 2)
+#define SSS_TDES_BUSY_OFF (0 << 2)
+#define SSS_TDES_BUSY_ON (1 << 2)
+
+/* Hash control */
+#define SSS_HASH_ENGSEL_MASK (0xF << 0)
+#define SSS_HASH_ENGSEL_SHA1HASH (0x0 << 0)
+#define SSS_HASH_ENGSEL_SHA1HMAC (0x1 << 0)
+#define SSS_HASH_ENGSEL_SHA1HMACIN (0x1 << 0)
+#define SSS_HASH_ENGSEL_SHA1HMACOUT (0x9 << 0)
+#define SSS_HASH_ENGSEL_MD5HASH (0x2 << 0)
+#define SSS_HASH_ENGSEL_MD5HMAC (0x3 << 0)
+#define SSS_HASH_ENGSEL_MD5HMACIN (0x3 << 0)
+#define SSS_HASH_ENGSEL_MD5HMACOUT (0xB << 0)
+#define SSS_HASH_ENGSEL_SHA256HASH (0x4 << 0)
+#define SSS_HASH_ENGSEL_SHA256HMAC (0x5 << 0)
+#define SSS_HASH_ENGSEL_PRNG (0x8 << 0)
+#define SSS_HASH_STARTBIT_ON (1 << 4)
+#define SSS_HASH_USERIV_EN (1 << 5)
+
+/* Hash control 2 */
+#define SSS_HASH_PAUSE_ON (1 << 0)
+
+/* Hash control - FIFO mode */
+#define SSS_HASH_FIFO_MASK (1 << 0)
+#define SSS_HASH_FIFO_OFF (0 << 0)
+#define SSS_HASH_FIFO_ON (1 << 0)
+
+/* Hash control - byte swap */
+#define SSS_HASH_SWAP_MASK (0xF << 0)
+#define SSS_HASH_SWAPKEY_OFF (0 << 0)
+#define SSS_HASH_SWAPKEY_ON (1 << 0)
+#define SSS_HASH_SWAPIV_OFF (0 << 1)
+#define SSS_HASH_SWAPIV_ON (1 << 1)
+#define SSS_HASH_SWAPDO_OFF (0 << 2)
+#define SSS_HASH_SWAPDO_ON (1 << 2)
+#define SSS_HASH_SWAPDI_OFF (0 << 3)
+#define SSS_HASH_SWAPDI_ON (1 << 3)
+
+/* Hash status */
+#define SSS_HASH_BUFRDY_MASK (1 << 0)
+#define SSS_HASH_BUFRDY_OFF (0 << 0)
+#define SSS_HASH_BUFRDY_ON (1 << 0)
+#define SSS_HASH_SEEDSETTING_MASK (1 << 1)
+#define SSS_HASH_SEEDSETTING_OFF (0 << 1)
+#define SSS_HASH_SEEDSETTING_ON (1 << 1)
+#define SSS_HASH_PRNGBUSY_MASK (1 << 2)
+#define SSS_HASH_PRNGBUSY_OFF (0 << 2)
+#define SSS_HASH_PRNGBUSY_ON (1 << 2)
+#define SSS_HASH_PARTIALDONE_MASK (1 << 4)
+#define SSS_HASH_PARTIALDONE_OFF (0 << 4)
+#define SSS_HASH_PARTIALDONE_ON (1 << 4)
+#define SSS_HASH_PRNGDONE_MASK (1 << 5)
+#define SSS_HASH_PRNGDONE_OFF (0 << 5)
+#define SSS_HASH_PRNGDONE_ON (1 << 5)
+#define SSS_HASH_MSGDONE_MASK (1 << 6)
+#define SSS_HASH_MSGDONE_OFF (0 << 6)
+#define SSS_HASH_MSGDONE_ON (1 << 6)
+#define SSS_HASH_PRNGERROR_MASK (1 << 7)
+#define SSS_HASH_PRNGERROR_OFF (0 << 7)
+#define SSS_HASH_PRNGERROR_ON (1 << 7)
+
+#endif /* __CRYPTODXE_H__ */
+
diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/HashDxe/HashDxe.inf b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/HashDxe/HashDxe.inf
new file mode 100644
index 000000000..45ae5fc0a
--- /dev/null
+++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/HashDxe/HashDxe.inf
@@ -0,0 +1,57 @@
+## @file
+#
+# Component description file for Crypto engine module
+#
+# This is the main routine for initializing the Crypto engine support routines.
+#
+# Copyright (c) 2012, Samsung Electronics Co. All rights reserved.<BR>
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = HashDxe
+ FILE_GUID = 2ceb319d-ee89-4ef2-9a0d-7958abf4cd87
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ ENTRY_POINT = HashDxeInitialize
+
+[Sources]
+ HashDxe.c
+
+[Packages]
+ ArmPkg/ArmPkg.dec
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ SamsungPlatformPkg/ExynosPkg/Exynos5250/ExynosPkg.dec
+ SamsungPlatformPkg/SamsungPlatformPkg.dec
+
+[LibraryClasses]
+ UefiDriverEntryPoint
+ UncachedMemoryAllocationLib
+ DebugLib
+ IoLib
+ ArmGicLib
+
+[Guids]
+ gEfiHashAlgorithmSha1Guid
+ gEfiHashAlgorithmSha256Guid
+
+[Protocols]
+ gEfiDevicePathProtocolGuid
+ gEfiHashProtocolGuid
+ gSamsungPlatformGpioProtocolGuid
+
+[Pcd]
+ gExynosPkgTokenSpaceGuid.PcdCmuBase
+ gExynosPkgTokenSpaceGuid.PcdCryptoBase
+
+[Depex]
+ TRUE
diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/OhciDxe/ComponentName.c b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/OhciDxe/ComponentName.c
new file mode 100644
index 000000000..836d0b583
--- /dev/null
+++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/OhciDxe/ComponentName.c
@@ -0,0 +1,231 @@
+/** @file
+ UEFI Component Name(2) protocol implementation for OHCI driver.
+
+Copyright (c) 2004 - 2007, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "Ohci.h"
+
+
+//
+// EFI Component Name Protocol
+//
+
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME_PROTOCOL gOhciComponentName = {
+ OhciComponentNameGetDriverName,
+ OhciComponentNameGetControllerName,
+ "eng"
+};
+
+//
+// EFI Component Name 2 Protocol
+//
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL gOhciComponentName2 = {
+ (EFI_COMPONENT_NAME2_GET_DRIVER_NAME) OhciComponentNameGetDriverName,
+ (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) OhciComponentNameGetControllerName,
+ "en"
+};
+
+
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mOhciDriverNameTable[] = {
+ { "eng;en", L"Usb Ohci Driver" },
+ { NULL, NULL }
+};
+
+
+//
+// EFI Component Name Functions
+//
+
+/**
+ Retrieves a Unicode string that is the user readable name of the driver.
+
+ This function retrieves the user readable name of a driver in the form of a
+ Unicode string. If the driver specified by This has a user readable name in
+ the language specified by Language, then a pointer to the driver name is
+ returned in DriverName, and EFI_SUCCESS is returned. If the driver specified
+ by This does not support the language specified by Language,
+ then EFI_UNSUPPORTED is returned.
+
+ @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
+ EFI_COMPONENT_NAME_PROTOCOL instance.
+
+ @param Language[in] A pointer to a Null-terminated ASCII string
+ array indicating the language. This is the
+ language of the driver name that the caller is
+ requesting, and it must match one of the
+ languages specified in SupportedLanguages. The
+ number of languages supported by a driver is up
+ to the driver writer. Language is specified
+ in RFC 4646 or ISO 639-2 language code format.
+
+ @param DriverName[out] A pointer to the Unicode string to return.
+ This Unicode string is the name of the
+ driver specified by This in the language
+ specified by Language.
+
+ @retval EFI_SUCCESS The Unicode string for the Driver specified by
+ This and the language specified by Language was
+ returned in DriverName.
+
+ @retval EFI_INVALID_PARAMETER Language is NULL.
+
+ @retval EFI_INVALID_PARAMETER DriverName is NULL.
+
+ @retval EFI_UNSUPPORTED The driver specified by This does not support
+ the language specified by Language.
+
+**/
+EFI_STATUS
+EFIAPI
+OhciComponentNameGetDriverName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN CHAR8 *Language,
+ OUT CHAR16 **DriverName
+ )
+{
+ return LookupUnicodeString2 (
+ Language,
+ This->SupportedLanguages,
+ mOhciDriverNameTable,
+ DriverName,
+ (BOOLEAN)(This == &gOhciComponentName)
+ );
+}
+
+/**
+ Retrieves a Unicode string that is the user readable name of the controller
+ that is being managed by a driver.
+
+ This function retrieves the user readable name of the controller specified by
+ ControllerHandle and ChildHandle in the form of a Unicode string. If the
+ driver specified by This has a user readable name in the language specified by
+ Language, then a pointer to the controller name is returned in ControllerName,
+ and EFI_SUCCESS is returned. If the driver specified by This is not currently
+ managing the controller specified by ControllerHandle and ChildHandle,
+ then EFI_UNSUPPORTED is returned. If the driver specified by This does not
+ support the language specified by Language, then EFI_UNSUPPORTED is returned.
+
+ @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
+ EFI_COMPONENT_NAME_PROTOCOL instance.
+
+ @param ControllerHandle[in] The handle of a controller that the driver
+ specified by This is managing. This handle
+ specifies the controller whose name is to be
+ returned.
+
+ @param ChildHandle[in] The handle of the child controller to retrieve
+ the name of. This is an optional parameter that
+ may be NULL. It will be NULL for device
+ drivers. It will also be NULL for a bus drivers
+ that wish to retrieve the name of the bus
+ controller. It will not be NULL for a bus
+ driver that wishes to retrieve the name of a
+ child controller.
+
+ @param Language[in] A pointer to a Null-terminated ASCII string
+ array indicating the language. This is the
+ language of the driver name that the caller is
+ requesting, and it must match one of the
+ languages specified in SupportedLanguages. The
+ number of languages supported by a driver is up
+ to the driver writer. Language is specified in
+ RFC 4646 or ISO 639-2 language code format.
+
+ @param ControllerName[out] A pointer to the Unicode string to return.
+ This Unicode string is the name of the
+ controller specified by ControllerHandle and
+ ChildHandle in the language specified by
+ Language from the point of view of the driver
+ specified by This.
+
+ @retval EFI_SUCCESS The Unicode string for the user readable name in
+ the language specified by Language for the
+ driver specified by This was returned in
+ DriverName.
+
+ @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE.
+
+ @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid
+ EFI_HANDLE.
+
+ @retval EFI_INVALID_PARAMETER Language is NULL.
+
+ @retval EFI_INVALID_PARAMETER ControllerName is NULL.
+
+ @retval EFI_UNSUPPORTED The driver specified by This is not currently
+ managing the controller specified by
+ ControllerHandle and ChildHandle.
+
+ @retval EFI_UNSUPPORTED The driver specified by This does not support
+ the language specified by Language.
+
+**/
+EFI_STATUS
+EFIAPI
+OhciComponentNameGetControllerName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE ChildHandle OPTIONAL,
+ IN CHAR8 *Language,
+ OUT CHAR16 **ControllerName
+ )
+{
+ EFI_STATUS Status;
+ USB_HC_DEV *OhciDev;
+ EFI_USB2_HC_PROTOCOL *Usb2Hc;
+
+ //
+ // This is a device driver, so ChildHandle must be NULL.
+ //
+ if (ChildHandle != NULL) {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // Make sure this driver is currently managing ControllerHandle
+ //
+ Status = EfiTestManagedDevice (
+ ControllerHandle,
+ gOhciDriverBinding.DriverBindingHandle,
+ &gEfiPciIoProtocolGuid
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Get the device context
+ //
+ Status = gBS->OpenProtocol (
+ ControllerHandle,
+ &gEfiUsb2HcProtocolGuid,
+ (VOID **) &Usb2Hc,
+ gOhciDriverBinding.DriverBindingHandle,
+ ControllerHandle,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ OhciDev = OHC_FROM_USB2_HC_PROTO (Usb2Hc);
+
+ return LookupUnicodeString2 (
+ Language,
+ This->SupportedLanguages,
+ OhciDev->CtrlNameTable,
+ ControllerName,
+ (BOOLEAN)(This == &gOhciComponentName)
+ );
+
+}
diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/OhciDxe/ComponentName.h b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/OhciDxe/ComponentName.h
new file mode 100644
index 000000000..f2f68769a
--- /dev/null
+++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/OhciDxe/ComponentName.h
@@ -0,0 +1,145 @@
+/** @file
+
+ This file contains the delarations for componet name routines.
+
+Copyright (c) 2008, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _COMPONENT_NAME_H_
+#define _COMPONENT_NAME_H_
+
+/**
+ Retrieves a Unicode string that is the user readable name of the driver.
+
+ This function retrieves the user readable name of a driver in the form of a
+ Unicode string. If the driver specified by This has a user readable name in
+ the language specified by Language, then a pointer to the driver name is
+ returned in DriverName, and EFI_SUCCESS is returned. If the driver specified
+ by This does not support the language specified by Language,
+ then EFI_UNSUPPORTED is returned.
+
+ @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
+ EFI_COMPONENT_NAME_PROTOCOL instance.
+
+ @param Language[in] A pointer to a Null-terminated ASCII string
+ array indicating the language. This is the
+ language of the driver name that the caller is
+ requesting, and it must match one of the
+ languages specified in SupportedLanguages. The
+ number of languages supported by a driver is up
+ to the driver writer. Language is specified
+ in RFC 4646 or ISO 639-2 language code format.
+
+ @param DriverName[out] A pointer to the Unicode string to return.
+ This Unicode string is the name of the
+ driver specified by This in the language
+ specified by Language.
+
+ @retval EFI_SUCCESS The Unicode string for the Driver specified by
+ This and the language specified by Language was
+ returned in DriverName.
+
+ @retval EFI_INVALID_PARAMETER Language is NULL.
+
+ @retval EFI_INVALID_PARAMETER DriverName is NULL.
+
+ @retval EFI_UNSUPPORTED The driver specified by This does not support
+ the language specified by Language.
+
+**/
+EFI_STATUS
+EFIAPI
+OhciComponentNameGetDriverName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN CHAR8 *Language,
+ OUT CHAR16 **DriverName
+ );
+
+
+/**
+ Retrieves a Unicode string that is the user readable name of the controller
+ that is being managed by a driver.
+
+ This function retrieves the user readable name of the controller specified by
+ ControllerHandle and ChildHandle in the form of a Unicode string. If the
+ driver specified by This has a user readable name in the language specified by
+ Language, then a pointer to the controller name is returned in ControllerName,
+ and EFI_SUCCESS is returned. If the driver specified by This is not currently
+ managing the controller specified by ControllerHandle and ChildHandle,
+ then EFI_UNSUPPORTED is returned. If the driver specified by This does not
+ support the language specified by Language, then EFI_UNSUPPORTED is returned.
+
+ @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
+ EFI_COMPONENT_NAME_PROTOCOL instance.
+
+ @param ControllerHandle[in] The handle of a controller that the driver
+ specified by This is managing. This handle
+ specifies the controller whose name is to be
+ returned.
+
+ @param ChildHandle[in] The handle of the child controller to retrieve
+ the name of. This is an optional parameter that
+ may be NULL. It will be NULL for device
+ drivers. It will also be NULL for a bus drivers
+ that wish to retrieve the name of the bus
+ controller. It will not be NULL for a bus
+ driver that wishes to retrieve the name of a
+ child controller.
+
+ @param Language[in] A pointer to a Null-terminated ASCII string
+ array indicating the language. This is the
+ language of the driver name that the caller is
+ requesting, and it must match one of the
+ languages specified in SupportedLanguages. The
+ number of languages supported by a driver is up
+ to the driver writer. Language is specified in
+ RFC 4646 or ISO 639-2 language code format.
+
+ @param ControllerName[out] A pointer to the Unicode string to return.
+ This Unicode string is the name of the
+ controller specified by ControllerHandle and
+ ChildHandle in the language specified by
+ Language from the point of view of the driver
+ specified by This.
+
+ @retval EFI_SUCCESS The Unicode string for the user readable name in
+ the language specified by Language for the
+ driver specified by This was returned in
+ DriverName.
+
+ @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE.
+
+ @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid
+ EFI_HANDLE.
+
+ @retval EFI_INVALID_PARAMETER Language is NULL.
+
+ @retval EFI_INVALID_PARAMETER ControllerName is NULL.
+
+ @retval EFI_UNSUPPORTED The driver specified by This is not currently
+ managing the controller specified by
+ ControllerHandle and ChildHandle.
+
+ @retval EFI_UNSUPPORTED The driver specified by This does not support
+ the language specified by Language.
+
+**/
+EFI_STATUS
+EFIAPI
+OhciComponentNameGetControllerName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE ChildHandle OPTIONAL,
+ IN CHAR8 *Language,
+ OUT CHAR16 **ControllerName
+ );
+
+#endif
diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/OhciDxe/Ohci.c b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/OhciDxe/Ohci.c
new file mode 100644
index 000000000..d8967a386
--- /dev/null
+++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/OhciDxe/Ohci.c
@@ -0,0 +1,2345 @@
+/** @file
+
+ The OHCI driver model and HC protocol routines.
+
+Copyright (c) 2004 - 2010, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "Ohci.h"
+#include <Protocol/Cpu.h>
+
+EFI_CPU_ARCH_PROTOCOL *gCpu;
+
+EFI_DRIVER_BINDING_PROTOCOL gOhciDriverBinding = {
+ OhciDriverBindingSupported,
+ OhciDriverBindingStart,
+ OhciDriverBindingStop,
+ 0x30,
+ NULL,
+ NULL
+};
+
+/**
+ Provides software reset for the USB host controller according to UEFI 2.0 spec.
+
+ @param This A pointer to the EFI_USB2_HC_PROTOCOL instance.
+ @param Attributes A bit mask of the reset operation to perform. See
+ below for a list of the supported bit mask values.
+
+ @return EFI_SUCCESS The reset operation succeeded.
+ @return EFI_INVALID_PARAMETER Attributes is not valid.
+ @return EFI_UNSUPPORTED This type of reset is not currently supported.
+ @return EFI_DEVICE_ERROR Other errors.
+
+**/
+
+EFI_STATUS
+EFIAPI
+Ohci2Reset (
+ IN EFI_USB2_HC_PROTOCOL *This,
+ IN UINT16 Attributes
+ )
+{
+ DEBUG((EFI_D_INFO, "++%a:%d\n", __FUNCTION__, __LINE__));
+ USB_HC_DEV *Ohc;
+ EFI_TPL OldTpl;
+ UINT32 UsbCtr;
+
+ if ((Attributes == EFI_USB_HC_RESET_GLOBAL_WITH_DEBUG) ||
+ (Attributes == EFI_USB_HC_RESET_HOST_WITH_DEBUG)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ Ohc = OHC_FROM_USB2_HC_PROTO (This);
+
+ OldTpl = gBS->RaiseTPL (OHCI_TPL);
+
+#if 1
+ switch (Attributes) {
+ case EFI_USB_HC_RESET_GLOBAL:
+ //
+ // Stop schedule and set the Global Reset bit in the command register
+ //
+ /*
+ OhciStopHc (Ohc, OHC_GENERIC_TIMEOUT);
+
+ UsbCtr = OhciReadReg(Ohc, HC_CONTROL_OFFSET);
+ UsbCtr &= (1<<9); //all except of RWC is clear
+ OhciWriteReg(Ohc, HC_CONTROL_OFFSET, UsbCtr);
+
+ gBS->Stall (OHC_ROOT_PORT_RECOVERY_STALL);*/
+ break;
+
+ case EFI_USB_HC_RESET_HOST_CONTROLLER:
+ //
+ // Stop schedule and set Host Controller Reset bit to 1
+ //
+ /*
+ OhciStopHc (Ohc, OHC_GENERIC_TIMEOUT);
+
+ UsbCtr = OhciReadReg(Ohc, HC_CONTROL_OFFSET);
+ UsbCtr &= (1<<9); //all except of RWC is clear
+ OhciWriteReg(Ohc, HC_CONTROL_OFFSET, UsbCtr);*/
+ break;
+
+ default:
+ goto ON_INVAILD_PARAMETER;
+ }
+
+ OhcDumpRegs(Ohc);
+
+ //
+ // Delete all old transactions on the USB bus, then
+ // reinitialize the frame list
+ //
+ OhciFreeAllAsyncReq (Ohc);
+ OhciDestoryFrameList (Ohc);
+ OhciInitFrameList (Ohc);
+
+ gBS->RestoreTPL (OldTpl);
+
+ DEBUG((EFI_D_INFO, "--%a:%d\n", __FUNCTION__, __LINE__));
+
+ return EFI_SUCCESS;
+
+ON_INVAILD_PARAMETER:
+
+ gBS->RestoreTPL (OldTpl);
+
+ return EFI_INVALID_PARAMETER;
+#else
+ switch (Attributes) {
+ case EFI_USB_HC_RESET_GLOBAL:
+ //
+ // Stop schedule and set the Global Reset bit in the command register
+ //
+ OhciStopHc (Ohc, OHC_GENERIC_TIMEOUT);
+
+ OhciSetRegBit (Ohc->PciIo, USBCMD_OFFSET, USBCMD_GRESET);
+
+ gBS->Stall (OHC_ROOT_PORT_RESET_STALL);
+
+ //
+ // Clear the Global Reset bit to zero.
+ //
+ OhciClearRegBit (Ohc->PciIo, USBCMD_OFFSET, USBCMD_GRESET);
+
+ gBS->Stall (OHC_ROOT_PORT_RECOVERY_STALL);
+ break;
+
+ case EFI_USB_HC_RESET_HOST_CONTROLLER:
+ //
+ // Stop schedule and set Host Controller Reset bit to 1
+ //
+ OhciStopHc (Ohc, OHC_GENERIC_TIMEOUT);
+
+ OhciSetRegBit (Ohc->PciIo, USBCMD_OFFSET, USBCMD_HCRESET);
+
+ gBS->Stall (OHC_ROOT_PORT_RECOVERY_STALL);
+ break;
+
+ default:
+ goto ON_INVAILD_PARAMETER;
+ }
+
+ //
+ // Delete all old transactions on the USB bus, then
+ // reinitialize the frame list
+ //
+ OhciFreeAllAsyncReq (Ohc);
+ OhciDestoryFrameList (Ohc);
+ OhciInitFrameList (Ohc);
+
+ gBS->RestoreTPL (OldTpl);
+
+ DEBUG((EFI_D_INIT, "---Ohci2Reset()\n"));
+
+ return EFI_SUCCESS;
+
+ON_INVAILD_PARAMETER:
+
+ gBS->RestoreTPL (OldTpl);
+
+ return EFI_INVALID_PARAMETER;
+#endif
+}
+
+
+/**
+ Retrieves current state of the USB host controller according to UEFI 2.0 spec.
+
+ @param This A pointer to the EFI_USB2_HC_PROTOCOL instance.
+ @param State Variable to receive current device state.
+
+ @return EFI_SUCCESS The state is returned.
+ @return EFI_INVALID_PARAMETER State is not valid.
+ @return EFI_DEVICE_ERROR Other errors.
+
+**/
+EFI_STATUS
+EFIAPI
+Ohci2GetState (
+ IN CONST EFI_USB2_HC_PROTOCOL *This,
+ OUT EFI_USB_HC_STATE *State
+ )
+{
+ DEBUG((EFI_D_INFO, "++%a:%d\n", __FUNCTION__, __LINE__));
+ USB_HC_DEV *Ohc;
+ UINT16 UsbSts;
+ UINT16 UsbCmd;
+
+ if (State == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Ohc = OHC_FROM_USB2_HC_PROTO (This);
+#if 1
+ UsbSts = OhciReadReg (Ohc, HC_CONTROL_OFFSET);
+ UsbSts = (UsbSts>>6) & 0x3;
+
+ if (UsbSts == 3) {
+ *State = EfiUsbHcStateSuspend;
+
+ } else if (UsbSts == 2) {
+ *State = EfiUsbHcStateOperational;
+ } else {
+ *State = EfiUsbHcStateHalt;
+ }
+#else
+ UsbCmd = OhciReadReg (Ohc->PciIo, USBCMD_OFFSET);
+ UsbSts = OhciReadReg (Ohc->PciIo, USBSTS_OFFSET);
+
+ if ((UsbCmd & USBCMD_EGSM) !=0 ) {
+ *State = EfiUsbHcStateSuspend;
+
+ } else if ((UsbSts & USBSTS_HCH) != 0) {
+ *State = EfiUsbHcStateHalt;
+
+ } else {
+ *State = EfiUsbHcStateOperational;
+ }
+#endif
+ DEBUG((EFI_D_INFO, "--%a:%d\n", __FUNCTION__, __LINE__));
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Sets the USB host controller to a specific state according to UEFI 2.0 spec.
+
+ @param This A pointer to the EFI_USB2_HC_PROTOCOL instance.
+ @param State Indicates the state of the host controller that will
+ be set.
+
+ @return EFI_SUCCESS Host controller was successfully placed in the state.
+ @return EFI_INVALID_PARAMETER State is invalid.
+ @return EFI_DEVICE_ERROR Failed to set the state.
+
+**/
+EFI_STATUS
+EFIAPI
+Ohci2SetState (
+ IN EFI_USB2_HC_PROTOCOL *This,
+ IN EFI_USB_HC_STATE State
+ )
+{
+ DEBUG((EFI_D_INFO, "++%a:%d\n", __FUNCTION__, __LINE__));
+ EFI_USB_HC_STATE CurState;
+ USB_HC_DEV *Ohc;
+ EFI_TPL OldTpl;
+ EFI_STATUS Status;
+ UINT16 UsbSts;
+
+ Ohc = OHC_FROM_USB2_HC_PROTO (This);
+ Status = Ohci2GetState (This, &CurState);
+
+ if (EFI_ERROR (Status)) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ if (CurState == State) {
+ return EFI_SUCCESS;
+ }
+
+ Status = EFI_SUCCESS;
+ OldTpl = gBS->RaiseTPL (OHCI_TPL);
+
+ switch (State) {
+ case EfiUsbHcStateHalt:
+ Status = OhciStopHc (Ohc, OHC_GENERIC_TIMEOUT);
+ break;
+
+ case EfiUsbHcStateOperational:
+ #if 1
+ UsbSts = OhciReadReg (Ohc, HC_CONTROL_OFFSET);
+ UsbSts &= (1<<9);
+ UsbSts |= (3<<0) | (2<<6);
+ OhciWriteReg (Ohc, HC_CONTROL_OFFSET, UsbSts);
+
+ OhcDumpRegs(Ohc);
+ #else
+ UsbCmd = OhciReadReg (Ohc->PciIo, USBCMD_OFFSET);
+
+ if (CurState == EfiUsbHcStateHalt) {
+ //
+ // Set Run/Stop bit to 1, also set the bandwidht reclamation
+ // point to 64 bytes
+ //
+ UsbCmd |= USBCMD_RS | USBCMD_MAXP;
+ OhciWriteReg (Ohc->PciIo, USBCMD_OFFSET, UsbCmd);
+
+ } else if (CurState == EfiUsbHcStateSuspend) {
+ //
+ // If FGR(Force Global Resume) bit is 0, set it
+ //
+ if ((UsbCmd & USBCMD_FGR) == 0) {
+ UsbCmd |= USBCMD_FGR;
+ OhciWriteReg (Ohc->PciIo, USBCMD_OFFSET, UsbCmd);
+ }
+
+ //
+ // wait 20ms to let resume complete (20ms is specified by OHCI spec)
+ //
+ gBS->Stall (OHC_FORCE_GLOBAL_RESUME_STALL);
+
+ //
+ // Write FGR bit to 0 and EGSM(Enter Global Suspend Mode) bit to 0
+ //
+ UsbCmd &= ~USBCMD_FGR;
+ UsbCmd &= ~USBCMD_EGSM;
+ UsbCmd |= USBCMD_RS;
+ OhciWriteReg (Ohc->PciIo, USBCMD_OFFSET, UsbCmd);
+ }
+#endif
+ break;
+
+ case EfiUsbHcStateSuspend:
+ #if 1
+ Status = EFI_INVALID_PARAMETER;
+ #else
+ Status = Ohci2SetState (This, EfiUsbHcStateHalt);
+
+ if (EFI_ERROR (Status)) {
+ Status = EFI_DEVICE_ERROR;
+ goto ON_EXIT;
+ }
+
+ //
+ // Set Enter Global Suspend Mode bit to 1.
+ //
+ UsbCmd = OhciReadReg (Ohc->PciIo, USBCMD_OFFSET);
+ UsbCmd |= USBCMD_EGSM;
+ OhciWriteReg (Ohc->PciIo, USBCMD_OFFSET, UsbCmd);
+ #endif
+ break;
+
+ default:
+ Status = EFI_INVALID_PARAMETER;
+ break;
+ }
+
+ON_EXIT:
+ gBS->RestoreTPL (OldTpl);
+
+ DEBUG((EFI_D_INFO, "--%a:%d\n", __FUNCTION__, __LINE__));
+ return Status;
+}
+
+/**
+ Retrieves capabilities of USB host controller according to UEFI 2.0 spec.
+
+ @param This A pointer to the EFI_USB2_HC_PROTOCOL instance.
+ @param MaxSpeed A pointer to the max speed USB host controller
+ supports.
+ @param PortNumber A pointer to the number of root hub ports.
+ @param Is64BitCapable A pointer to an integer to show whether USB host
+ controller supports 64-bit memory addressing.
+
+ @return EFI_SUCCESS capabilities were retrieved successfully.
+ @return EFI_INVALID_PARAMETER MaxSpeed or PortNumber or Is64BitCapable is NULL.
+ @return EFI_DEVICE_ERROR An error was encountered.
+
+**/
+EFI_STATUS
+EFIAPI
+Ohci2GetCapability (
+ IN EFI_USB2_HC_PROTOCOL *This,
+ OUT UINT8 *MaxSpeed,
+ OUT UINT8 *PortNumber,
+ OUT UINT8 *Is64BitCapable
+ )
+{
+ DEBUG((EFI_D_INFO, "++%a:%d\n", __FUNCTION__, __LINE__));
+ USB_HC_DEV *Ohc;
+ UINT32 Offset;
+ UINT16 PortSC;
+ UINT32 Index;
+
+ Ohc = OHC_FROM_USB2_HC_PROTO (This);
+
+ if ((NULL == MaxSpeed) || (NULL == PortNumber) || (NULL == Is64BitCapable)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ *MaxSpeed = EFI_USB_SPEED_FULL;
+ *Is64BitCapable = (UINT8) FALSE;
+
+ *PortNumber = 3;
+/*
+ for (Index = 0; Index < USB_MAX_ROOTHUB_PORT; Index++) {
+ Offset = HC_PORT_STATUS_OFFSET + Index * 4;
+ PortSC = OhciReadReg (Ohc, Offset);
+
+ //
+ // Port status's bit 7 is reserved and always returns 1 if
+ // the port number is valid. Intel's UHCI (in EHCI controller)
+ // returns 0 in this bit if port number is invalid. Also, if
+ // PciIo IoRead returns error, 0xFFFF is returned to caller.
+ //
+ if (((PortSC & 0x80) == 0) || (PortSC == 0xFFFF)) {
+ break;
+ }
+ (*PortNumber)++;
+ }*/
+
+ Ohc->RootPorts = *PortNumber;
+
+ DEBUG ((EFI_D_INIT, "Ohci2GetCapability: %d ports\n", (UINT32)Ohc->RootPorts));
+ DEBUG((EFI_D_INFO, "--%a:%d\n", __FUNCTION__, __LINE__));
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Retrieves the current status of a USB root hub port according to UEFI 2.0 spec.
+
+ @param This A pointer to the EFI_USB2_HC_PROTOCOL.
+ @param PortNumber The port to get status.
+ @param PortStatus A pointer to the current port status bits and port
+ status change bits.
+
+ @return EFI_SUCCESS status of the USB root hub port was returned in PortStatus.
+ @return EFI_INVALID_PARAMETER PortNumber is invalid.
+ @return EFI_DEVICE_ERROR Can't read register.
+
+**/
+EFI_STATUS
+EFIAPI
+Ohci2GetRootHubPortStatus (
+ IN CONST EFI_USB2_HC_PROTOCOL *This,
+ IN CONST UINT8 PortNumber,
+ OUT EFI_USB_PORT_STATUS *PortStatus
+ )
+{
+ DEBUG((EFI_D_INFO, "++%a:%d\n", __FUNCTION__, __LINE__));
+ USB_HC_DEV *Ohc;
+ UINT32 Offset;
+ UINT32 PortSC;
+
+
+ Ohc = OHC_FROM_USB2_HC_PROTO (This);
+
+ if (PortStatus == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (PortNumber >= Ohc->RootPorts) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Offset = HC_PORT_STATUS_OFFSET + PortNumber * 4;
+ PortStatus->PortStatus = 0;
+ PortStatus->PortChangeStatus = 0;
+
+ PortSC = OhciReadReg (Ohc, Offset);
+
+ if ((PortSC & USBPORTSC_CCS) != 0) {
+ PortStatus->PortStatus |= USB_PORT_STAT_CONNECTION;
+ }
+
+ if ((PortSC & USBPORTSC_PED) != 0) {
+ PortStatus->PortStatus |= USB_PORT_STAT_ENABLE;
+ }
+
+ if ((PortSC & USBPORTSC_SUSP) != 0) {
+ DEBUG ((EFI_D_INIT, "Ohci2GetRootHubPortStatus: port %d is suspended\n", PortNumber));
+ PortStatus->PortStatus |= USB_PORT_STAT_SUSPEND;
+ }
+
+ if ((PortSC & USBPORTSC_PR) != 0) {
+ PortStatus->PortStatus |= USB_PORT_STAT_RESET;
+ }
+
+ if ((PortSC & USBPORTSC_LSDA) != 0) {
+ PortStatus->PortStatus |= USB_PORT_STAT_LOW_SPEED;
+ }
+
+ //
+ // CHC will always return one in port owner bit
+ //
+ PortStatus->PortStatus |= USB_PORT_STAT_OWNER;
+
+ if ((PortSC & USBPORTSC_CSC) != 0) {
+ PortStatus->PortChangeStatus |= USB_PORT_STAT_C_CONNECTION;
+ }
+
+ if ((PortSC & USBPORTSC_PEDC) != 0) {
+ PortStatus->PortChangeStatus |= USB_PORT_STAT_C_ENABLE;
+ }
+
+ DEBUG((EFI_D_INFO, "--%a:%d\n", __FUNCTION__, __LINE__));
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Sets a feature for the specified root hub port according to UEFI 2.0 spec.
+
+ @param This A pointer to the EFI_USB2_HC_PROTOCOL.
+ @param PortNumber Specifies the root hub port whose feature is
+ requested to be set.
+ @param PortFeature Indicates the feature selector associated with the
+ feature set request.
+
+ @return EFI_SUCCESS PortFeature was set for the root port.
+ @return EFI_INVALID_PARAMETER PortNumber is invalid or PortFeature is invalid.
+ @return EFI_DEVICE_ERROR Can't read register.
+
+**/
+EFI_STATUS
+EFIAPI
+Ohci2SetRootHubPortFeature (
+ IN EFI_USB2_HC_PROTOCOL *This,
+ IN UINT8 PortNumber,
+ IN EFI_USB_PORT_FEATURE PortFeature
+ )
+{
+ DEBUG((EFI_D_INFO, "++%a:%d\n", __FUNCTION__, __LINE__));
+ USB_HC_DEV *Ohc;
+ EFI_TPL OldTpl;
+ UINT32 Offset;
+ UINT32 PortSC;
+ UINT32 Command;
+
+ Ohc = OHC_FROM_USB2_HC_PROTO (This);
+
+ if (PortNumber >= Ohc->RootPorts) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Offset = HC_PORT_STATUS_OFFSET + PortNumber * 4;
+
+ OldTpl = gBS->RaiseTPL (OHCI_TPL);
+ PortSC = OhciReadReg (Ohc, Offset);
+
+ switch (PortFeature) {
+ case EfiUsbPortSuspend:
+ /*
+ Command = OhciReadReg (Ohc, USBCMD_OFFSET);
+ if ((Command & USBCMD_EGSM) == 0) {
+ //
+ // if global suspend is not active, can set port suspend
+ //
+ PortSC &= 0xfff5;
+ PortSC |= USBPORTSC_SUSP;
+ }*/
+ break;
+
+ case EfiUsbPortReset:
+ //PortSC &= ~0xFFFF0000;
+ PortSC = USBPORTSC_PR;
+ break;
+
+ case EfiUsbPortPower:
+ //PortSC &= ~0xFFFF0000;
+ PortSC = USBPORTSC_PPS;
+ break;
+
+ case EfiUsbPortEnable:
+ //PortSC &= ~0xFFFF0000;
+ PortSC = USBPORTSC_PED;
+ break;
+
+ default:
+ gBS->RestoreTPL (OldTpl);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ OhciWriteReg (Ohc, Offset, PortSC);
+ gBS->RestoreTPL (OldTpl);
+
+ DEBUG((EFI_D_INFO, "--%a:%d\n", __FUNCTION__, __LINE__));
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Clears a feature for the specified root hub port according to Uefi 2.0 spec.
+
+ @param This A pointer to the EFI_USB2_HC_PROTOCOL instance.
+ @param PortNumber Specifies the root hub port whose feature is
+ requested to be cleared.
+ @param PortFeature Indicates the feature selector associated with the
+ feature clear request.
+
+ @return EFI_SUCCESS PortFeature was cleared for the USB root hub port.
+ @return EFI_INVALID_PARAMETER PortNumber is invalid or PortFeature is invalid.
+ @return EFI_DEVICE_ERROR Can't read register.
+
+**/
+EFI_STATUS
+EFIAPI
+Ohci2ClearRootHubPortFeature (
+ IN EFI_USB2_HC_PROTOCOL *This,
+ IN UINT8 PortNumber,
+ IN EFI_USB_PORT_FEATURE PortFeature
+ )
+{
+ DEBUG((EFI_D_INFO, "++%a:%d\n", __FUNCTION__, __LINE__));
+ USB_HC_DEV *Ohc;
+ EFI_TPL OldTpl;
+ UINT32 Offset;
+ UINT32 PortSC;
+
+ Ohc = OHC_FROM_USB2_HC_PROTO (This);
+
+ Ohc = OHC_FROM_USB2_HC_PROTO (This);
+
+ if (PortNumber >= Ohc->RootPorts) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Offset = HC_PORT_STATUS_OFFSET + PortNumber * 4;
+
+ OldTpl = gBS->RaiseTPL (OHCI_TPL);
+ PortSC = OhciReadReg (Ohc, Offset);
+
+ switch (PortFeature) {
+ case EfiUsbPortEnable:
+ //PortSC &= ~0xFFFF0000;
+ PortSC = USBPORTSC_CCS;
+ break;
+
+ case EfiUsbPortSuspend:
+ PortSC = 0;
+ /*
+ //
+ // Cause a resume on the specified port if in suspend mode.
+ //
+ PortSC &= ~USBPORTSC_SUSP;*/
+ break;
+
+ case EfiUsbPortPower:
+ PortSC = 0;
+ //PortSC &= ~0xFFFF0000;
+ //
+ // No action
+ //
+ break;
+
+ case EfiUsbPortReset:
+ /*PortSC &= ~0xFFFF0000;
+ //iky temporary
+ PortSC |= USBPORTSC_PRSC;
+ OhciWriteReg (Ohc, Offset, PortSC);
+ while(OhciReadReg(Ohc, Offset) & USBPORTSC_PRSC);
+
+ PortSC = OhciReadReg (Ohc, Offset);
+ PortSC |= USBPORTSC_CSC;
+ PortSC &= ~0xFFFF0000;
+ OhciWriteReg (Ohc, Offset, PortSC);
+
+ PortSC = OhciReadReg (Ohc, Offset);
+ PortSC &= ~0xFFFF0000;
+ PortSC |= USBPORTSC_PED;
+ //PortSC &= ~USBPORTSC_PR;*/
+ break;
+
+ case EfiUsbPortConnectChange:
+ //PortSC &= ~0xFFFF0000;
+ //PortSC |= USBPORTSC_CSC;
+ PortSC = USBPORTSC_CSC;
+ break;
+
+ case EfiUsbPortEnableChange:
+ //PortSC &= ~0xFFFF0000;
+ //PortSC |= USBPORTSC_PEDC;
+ PortSC = USBPORTSC_PEDC;
+ break;
+
+ case EfiUsbPortSuspendChange:
+ //
+ // Root hub does not support this
+ //
+ //PortSC &= ~0xFFFF0000;
+ break;
+
+ case EfiUsbPortOverCurrentChange:
+ //
+ // Root hub does not support this
+ //
+ //PortSC &= ~0xFFFF0000;
+ break;
+
+ case EfiUsbPortResetChange:
+ //
+ // Root hub does not support this
+ //
+ //PortSC &= ~0xFFFF0000;
+ break;
+
+ default:
+ gBS->RestoreTPL (OldTpl);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ OhciWriteReg (Ohc, Offset, PortSC);
+ gBS->RestoreTPL (OldTpl);
+
+ DEBUG((EFI_D_INFO, "--%a:%d\n", __FUNCTION__, __LINE__));
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Submits control transfer to a target USB device accroding to UEFI 2.0 spec.
+
+ @param This A pointer to the EFI_USB2_HC_PROTOCOL instance.
+ @param DeviceAddress Target device address.
+ @param DeviceSpeed Device speed.
+ @param MaximumPacketLength Maximum packet size of the target endpoint.
+ @param Request USB device request to send.
+ @param TransferDirection Data direction of the Data stage in control transfer.
+ @param Data Data to transmit/receive in data stage.
+ @param DataLength Length of the data.
+ @param TimeOut Maximum time, in microseconds, for transfer to complete.
+ @param Translator Transaction translator to be used by this device.
+ @param TransferResult Variable to receive the transfer result.
+
+ @return EFI_SUCCESS The control transfer was completed successfully.
+ @return EFI_OUT_OF_RESOURCES Failed due to lack of resource.
+ @return EFI_INVALID_PARAMETER Some parameters are invalid.
+ @return EFI_TIMEOUT Failed due to timeout.
+ @return EFI_DEVICE_ERROR Failed due to host controller or device error.
+
+**/
+EFI_STATUS
+EFIAPI
+Ohci2ControlTransfer (
+ IN EFI_USB2_HC_PROTOCOL *This,
+ IN UINT8 DeviceAddress,
+ IN UINT8 DeviceSpeed,
+ IN UINTN MaximumPacketLength,
+ IN EFI_USB_DEVICE_REQUEST *Request,
+ IN EFI_USB_DATA_DIRECTION TransferDirection,
+ IN OUT VOID *Data,
+ IN OUT UINTN *DataLength,
+ IN UINTN TimeOut,
+ IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
+ OUT UINT32 *TransferResult
+ )
+{
+ DEBUG((EFI_D_INFO, "++%a:%d\n", __FUNCTION__, __LINE__));
+ USB_HC_DEV *Ohc;
+ OHCI_ED_HW *Ed;
+ EFI_TPL OldTpl;
+ EFI_STATUS Status;
+ OHCI_QH_RESULT QhResult;
+ UINT8 PktId;
+ UINT8 *RequestPhy;
+ VOID *RequestMap;
+ UINT8 *DataPhy;
+ VOID *DataMap;
+ BOOLEAN IsSlowDevice;
+ UINTN TransferDataLength;
+
+ DEBUG((EFI_D_INIT, "+++Ohci2ControlTransfer(DeviceAddr : %d, Data : 0x%p, Datas : %d, Max : %d, Dir : %d)\n", DeviceAddress, Data, *DataLength, MaximumPacketLength, TransferDirection));
+
+ Ohc = OHC_FROM_USB2_HC_PROTO (This);
+ Ed = NULL;
+ DataPhy = NULL;
+ DataMap = NULL;
+ RequestPhy = NULL;
+ RequestMap = NULL;
+
+ IsSlowDevice = (BOOLEAN) ((EFI_USB_SPEED_LOW == DeviceSpeed) ? TRUE : FALSE);
+
+ //
+ // Parameters Checking
+ //
+ if (Request == NULL || TransferResult == NULL) {
+ DEBUG((EFI_D_ERROR, "FAIL! NULL point\n"));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //iky ???
+
+ if (IsSlowDevice && (MaximumPacketLength != 8)) {
+ DEBUG((EFI_D_ERROR, "FAIL! not matched MaximumPacketLength1\n"));
+ //MaximumPacketLength = 8;
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if ((MaximumPacketLength != 8) && (MaximumPacketLength != 16) &&
+ (MaximumPacketLength != 32) && (MaximumPacketLength != 64)) {
+ DEBUG((EFI_D_ERROR, "FAIL! not matched MaximumPacketLength2\n"));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if ((TransferDirection != EfiUsbNoData) && (Data == NULL || DataLength == NULL)) {
+ DEBUG((EFI_D_ERROR, "FAIL! no DATA\n"));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (TransferDirection == EfiUsbNoData) {
+ TransferDataLength = 0;
+ } else {
+ TransferDataLength = *DataLength;
+ }
+
+ *TransferResult = EFI_USB_ERR_SYSTEM;
+ Status = EFI_DEVICE_ERROR;
+
+ //
+ // If errors exist that cause host controller halt,
+ // clear status then return EFI_DEVICE_ERROR.
+ //
+ OhciAckAllInterrupt (Ohc);
+
+ if (!OhciIsHcWorking (Ohc)) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ OldTpl = gBS->RaiseTPL (OHCI_TPL);
+
+ //
+ // Map the Request and data for bus master access,
+ // then create a list of TD for this transfer
+ //
+ Status = OhciMapUserRequest (Ohc, Request, &RequestPhy, &RequestMap);
+
+ if (EFI_ERROR (Status)) {
+ goto ON_EXIT;
+ }
+
+ Status = OhciMapUserData (Ohc, TransferDirection, Data, DataLength, &PktId, &DataPhy, &DataMap);
+
+ if (EFI_ERROR (Status)) {
+ Ohc->PciIo->Unmap (Ohc->PciIo, RequestMap);
+ goto ON_EXIT;
+ }
+
+ Ed = OhciCreateCtrlTds (
+ Ohc,
+ DeviceAddress,
+ PktId,
+ (UINT8*)Request,
+ RequestPhy,
+ (UINT8*)Data,
+ DataPhy,
+ TransferDataLength,
+ (UINT8) MaximumPacketLength,
+ IsSlowDevice
+ );
+
+ if (Ed == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto UNMAP_DATA;
+ }
+
+ gCpu->FlushDataCache (gCpu, (EFI_PHYSICAL_ADDRESS)(UINTN)Ed, sizeof(OHCI_ED_HW), EfiCpuFlushTypeWriteBackInvalidate);
+ {
+ OHCI_TD_HW *Td = Ed->head_td_ptr;
+ OHCI_TD_SW *Before = NULL;
+ OHCI_TD_SW *Current = NULL;
+
+ Ohc->CtrlQh = UsbHcAllocateMem (Ohc->MemPool, sizeof(OHCI_TD_SW));
+ Ohc->CtrlQh->TdHw = NULL;
+ Ohc->CtrlQh->NextTd = NULL;
+
+ Before = Ohc->CtrlQh;
+ do
+ {
+ Current = UsbHcAllocateMem (Ohc->MemPool, sizeof(OHCI_TD_SW));
+ Current->TdHw = NULL;
+ Current->NextTd = NULL;
+ Before->NextTd = Current;
+ Before->TdHw = Td;
+ Before->DataLen = (Td->buffer_end - Td->current_buf_ptr + 1);
+ Before = Current;
+
+ gCpu->FlushDataCache (gCpu, (EFI_PHYSICAL_ADDRESS)(UINTN)Td, sizeof(OHCI_TD_HW), EfiCpuFlushTypeWriteBackInvalidate);
+ } while(Td = Td->next_td);
+ }
+
+ OhciDumpEd(Ed);
+
+#if 1
+ //
+ // According to the speed of the end point, link
+ // the TD to corrosponding queue head, then check
+ // the execution result
+ //
+ OhciLinkTdToQh (Ohc, Ed, 0);
+ Status = OhciExecuteTransfer (Ohc, Ed, TimeOut, IsSlowDevice, &QhResult);
+ OhciUnlinkTdFromQh (Ohc->CtrlQh, NULL);
+
+ Ohc->PciIo->Flush (Ohc);
+
+ *TransferResult = QhResult.Result;
+
+ if (DataLength != NULL) {
+ *DataLength = QhResult.Complete;
+ }
+
+ OhciDestoryTds (Ohc, Ohc->CtrlQh);
+
+UNMAP_DATA:
+ if(DataMap)
+ {
+ DEBUG((EFI_D_INIT, "Unmap(DataMap)\n"));
+ Ohc->PciIo->Unmap (Ohc->PciIo, DataMap);
+ }
+ if(RequestMap)
+ {
+ DEBUG((EFI_D_INIT, "Unmap(RequestMap)\n"));
+ Ohc->PciIo->Unmap (Ohc->PciIo, RequestMap);
+ }
+
+ON_EXIT:
+ gBS->RestoreTPL (OldTpl);
+
+ DEBUG((EFI_D_INFO, "--%a:%d\n", __FUNCTION__, __LINE__));
+
+ return Status;
+#else
+ //
+ // According to the speed of the end point, link
+ // the TD to corrosponding queue head, then check
+ // the execution result
+ //
+ OhciLinkTdToQh (Ohc, Ed);
+ Status = OhciExecuteTransfer (Ohc, Ed, TimeOut, IsSlowDevice, &QhResult);
+ OhciUnlinkTdFromQh (Ohc->CtrlQh, TDs);
+
+ Ohc->PciIo->Flush (Ohc->PciIo);
+
+ *TransferResult = QhResult.Result;
+
+ if (DataLength != NULL) {
+ *DataLength = QhResult.Complete;
+ }
+
+ OhciDestoryTds (Ohc, TDs);
+
+UNMAP_DATA:
+ Ohc->PciIo->Unmap (Ohc->PciIo, DataMap);
+ Ohc->PciIo->Unmap (Ohc->PciIo, RequestMap);
+
+ON_EXIT:
+ gBS->RestoreTPL (OldTpl);
+
+ DEBUG((EFI_D_INFO, "--%a:%d\n", __FUNCTION__, __LINE__));
+
+ return Status;
+#endif
+}
+
+
+/**
+ Submits bulk transfer to a bulk endpoint of a USB device.
+
+ @param This A pointer to the EFI_USB2_HC_PROTOCOL instance.
+ @param DeviceAddress Target device address.
+ @param EndPointAddress Endpoint number and direction.
+ @param DeviceSpeed Device speed.
+ @param MaximumPacketLength Maximum packet size of the target endpoint.
+ @param DataBuffersNumber Number of data buffers prepared for the transfer.
+ @param Data Array of pointers to the buffers of data.
+ @param DataLength On input, size of the data buffer, On output,
+ actually transferred data size.
+ @param DataToggle On input, data toggle to use; On output, next data toggle.
+ @param TimeOut Maximum time out, in microseconds.
+ @param Translator A pointr to the transaction translator data.
+ @param TransferResult Variable to receive transfer result.
+
+ @return EFI_SUCCESS The bulk transfer was completed successfully.
+ @return EFI_OUT_OF_RESOURCES Failed due to lack of resource.
+ @return EFI_INVALID_PARAMETER Some parameters are invalid.
+ @return EFI_TIMEOUT Failed due to timeout.
+ @return EFI_DEVICE_ERROR Failed due to host controller or device error.
+
+**/
+EFI_STATUS
+EFIAPI
+Ohci2BulkTransfer (
+ IN EFI_USB2_HC_PROTOCOL *This,
+ IN UINT8 DeviceAddress,
+ IN UINT8 EndPointAddress,
+ IN UINT8 DeviceSpeed,
+ IN UINTN MaximumPacketLength,
+ IN UINT8 DataBuffersNumber,
+ IN OUT VOID *Data[EFI_USB_MAX_BULK_BUFFER_NUM],
+ IN OUT UINTN *DataLength,
+ IN OUT UINT8 *DataToggle,
+ IN UINTN TimeOut,
+ IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
+ OUT UINT32 *TransferResult
+ )
+{
+ DEBUG((EFI_D_INFO, "++%a:%d\n", __FUNCTION__, __LINE__));
+ EFI_USB_DATA_DIRECTION Direction;
+ EFI_TPL OldTpl;
+ USB_HC_DEV *Ohc;
+ OHCI_TD_HW *TDs;
+ OHCI_QH_SW *BulkQh;
+ OHCI_QH_RESULT QhResult;
+ EFI_STATUS Status;
+ UINT8 PktId;
+ UINT8 *DataPhy;
+ VOID *DataMap;
+#if 1
+ DEBUG((EFI_D_INIT, "+++Ohci2BulkTransfer()\n"));
+ DEBUG((EFI_D_INIT, "---Ohci2BulkTransfer()\n"));
+#else
+ Ohc = OHC_FROM_USB2_HC_PROTO (This);
+ DataPhy = NULL;
+ DataMap = NULL;
+
+ if (DeviceSpeed == EFI_USB_SPEED_LOW) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if ((DataLength == NULL) || (*DataLength == 0) || (Data == NULL) || (TransferResult == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if ((*DataToggle != 1) && (*DataToggle != 0)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if ((MaximumPacketLength != 8) && (MaximumPacketLength != 16) &&
+ (MaximumPacketLength != 32) && (MaximumPacketLength != 64)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ *TransferResult = EFI_USB_ERR_SYSTEM;
+ Status = EFI_OUT_OF_RESOURCES;
+
+ //
+ // If has errors that cause host controller halt,
+ // then return EFI_DEVICE_ERROR directly.
+ //
+ OhciAckAllInterrupt (Ohc);
+
+ if (!OhciIsHcWorking (Ohc->PciIo)) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ OldTpl = gBS->RaiseTPL (OHCI_TPL);
+
+ //
+ // Map the source data buffer for bus master access,
+ // then create a list of TDs
+ //
+ if ((EndPointAddress & 0x80) != 0) {
+ Direction = EfiUsbDataIn;
+ } else {
+ Direction = EfiUsbDataOut;
+ }
+
+ Status = OhciMapUserData (Ohc, Direction, *Data, DataLength, &PktId, &DataPhy, &DataMap);
+
+ if (EFI_ERROR (Status)) {
+ goto ON_EXIT;
+ }
+
+ Status = EFI_OUT_OF_RESOURCES;
+ TDs = OhciCreateBulkOrIntTds (
+ Ohc,
+ DeviceAddress,
+ EndPointAddress,
+ PktId,
+ (UINT8 *)*Data,
+ DataPhy,
+ *DataLength,
+ DataToggle,
+ (UINT8) MaximumPacketLength,
+ FALSE
+ );
+
+ if (TDs == NULL) {
+ Ohc->PciIo->Unmap (Ohc->PciIo, DataMap);
+ goto ON_EXIT;
+ }
+
+
+ //
+ // Link the TDs to bulk queue head. According to the platfore
+ // defintion of OHCI_NO_BW_RECLAMATION, BulkQh is either configured
+ // to do full speed bandwidth reclamation or not.
+ //
+ BulkQh = Ohc->BulkQh;
+
+ OhciLinkTdToQh (Ohc, BulkQh, TDs);
+ Status = OhciExecuteTransfer (Ohc, BulkQh, TDs, TimeOut, FALSE, &QhResult);
+ OhciUnlinkTdFromQh (BulkQh, TDs);
+
+ Ohc->PciIo->Flush (Ohc->PciIo);
+
+ *TransferResult = QhResult.Result;
+ *DataToggle = QhResult.NextToggle;
+ *DataLength = QhResult.Complete;
+
+ OhciDestoryTds (Ohc, TDs);
+ Ohc->PciIo->Unmap (Ohc->PciIo, DataMap);
+
+ON_EXIT:
+ gBS->RestoreTPL (OldTpl);
+#endif
+ return Status;
+}
+
+/**
+ Submits an asynchronous interrupt transfer to an
+ interrupt endpoint of a USB device according to UEFI 2.0 spec.
+
+ @param This A pointer to the EFI_USB2_HC_PROTOCOL instance.
+ @param DeviceAddress Target device address.
+ @param EndPointAddress Endpoint number and direction.
+ @param DeviceSpeed Device speed.
+ @param MaximumPacketLength Maximum packet size of the target endpoint.
+ @param IsNewTransfer If TRUE, submit a new transfer, if FALSE cancel old transfer.
+ @param DataToggle On input, data toggle to use; On output, next data toggle.
+ @param PollingInterval Interrupt poll rate in milliseconds.
+ @param DataLength On input, size of the data buffer, On output,
+ actually transferred data size.
+ @param Translator A pointr to the transaction translator data.
+ @param CallBackFunction Function to call periodically.
+ @param Context User context.
+
+ @return EFI_SUCCESS Transfer was submitted.
+ @return EFI_INVALID_PARAMETER Some parameters are invalid.
+ @return EFI_OUT_OF_RESOURCES Failed due to a lack of resources.
+ @return EFI_DEVICE_ERROR Can't read register.
+
+**/
+EFI_STATUS
+EFIAPI
+Ohci2AsyncInterruptTransfer (
+ IN EFI_USB2_HC_PROTOCOL *This,
+ IN UINT8 DeviceAddress,
+ IN UINT8 EndPointAddress,
+ IN UINT8 DeviceSpeed,
+ IN UINTN MaximumPacketLength,
+ IN BOOLEAN IsNewTransfer,
+ IN OUT UINT8 *DataToggle,
+ IN UINTN PollingInterval,
+ IN UINTN DataLength,
+ IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
+ IN EFI_ASYNC_USB_TRANSFER_CALLBACK CallBackFunction,
+ IN VOID *Context
+ )
+{
+#if 1
+ USB_HC_DEV *Ohc;
+ OHCI_ED_HW *Ed;
+ BOOLEAN IsSlowDevice;
+ OHCI_TD_HW *IntTds;
+ EFI_TPL OldTpl;
+ EFI_STATUS Status;
+ UINT8 *DataPtr;
+ UINT8 *DataPhy;
+ UINT8 PktId;
+ OHCI_QH_RESULT QhResult;
+
+ DEBUG((EFI_D_INIT, "+++Ohci2AsyncInterruptTransfer(EP%d)\n", EndPointAddress));
+
+ Ohc = OHC_FROM_USB2_HC_PROTO (This);
+ IntTds = NULL;
+ DataPtr = NULL;
+ DataPhy = NULL;
+
+ IsSlowDevice = (BOOLEAN) ((EFI_USB_SPEED_LOW == DeviceSpeed) ? TRUE : FALSE);
+
+ if ((EndPointAddress & 0x80) == 0) {
+ DEBUG((EFI_D_ERROR, "FAIL! EndPointAddress ERROR\n"));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Delete Async interrupt transfer request
+ //
+ if (!IsNewTransfer) {
+ OldTpl = gBS->RaiseTPL (OHCI_TPL);
+ Status = OhciRemoveAsyncReq (Ohc, DeviceAddress, EndPointAddress, DataToggle);
+
+ gBS->RestoreTPL (OldTpl);
+ return Status;
+ }
+
+ if (PollingInterval < 1 || PollingInterval > 255) {
+ DEBUG((EFI_D_ERROR, "FAIL! PollingInterval ERROR\n"));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (DataLength == 0) {
+ DEBUG((EFI_D_ERROR, "FAIL! DataLength ERROR\n"));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if ((*DataToggle != 1) && (*DataToggle != 0)) {
+ DEBUG((EFI_D_ERROR, "FAIL! DataToggle ERROR\n"));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // If has errors that cause host controller halt,
+ // then return EFI_DEVICE_ERROR directly.
+ //
+ OhciAckAllInterrupt (Ohc);
+
+ if (!OhciIsHcWorking (Ohc->PciIo)) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ if ((EndPointAddress & 0x80) == 0) {
+ PktId = OUTPUT_PACKET_ID;
+ } else {
+ PktId = INPUT_PACKET_ID;
+ }
+
+ //
+ // Allocate and map source data buffer for bus master access.
+ //
+ DataPtr = UsbHcAllocateMem (Ohc->MemPool, DataLength);
+
+ if (DataPtr == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ DataPhy = (UINT8 *) (UINTN) UsbHcGetPciAddressForHostMem (Ohc->MemPool, DataPtr, DataLength);
+
+ OldTpl = gBS->RaiseTPL (OHCI_TPL);
+
+ /*Qh = OhciCreateQh (Ohc, PollingInterval);
+
+ if (Qh == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto FREE_DATA;
+ }*/
+
+ Ed = OhciCreateBulkOrIntTds (
+ Ohc,
+ DeviceAddress,
+ EndPointAddress,
+ PktId,
+ DataPtr,
+ DataPhy,
+ DataLength,
+ DataToggle,
+ (UINT8) MaximumPacketLength,
+ IsSlowDevice
+ );
+
+ if (Ed == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ DEBUG((EFI_D_ERROR, "FAIL! OhciCreateBulkOrIntTds ERROR\n"));
+ goto DESTORY_QH;
+ }
+
+ gCpu->FlushDataCache (gCpu, (EFI_PHYSICAL_ADDRESS)(UINTN)Ed, sizeof(OHCI_ED_HW), EfiCpuFlushTypeWriteBackInvalidate);
+ {
+ OHCI_TD_HW *Td = Ed->head_td_ptr;
+ OHCI_TD_SW *Before = NULL;
+ OHCI_TD_SW *Current = NULL;
+
+ Ohc->IntrQh = UsbHcAllocateMem (Ohc->MemPool, sizeof(OHCI_TD_SW));
+ Ohc->IntrQh->TdHw = NULL;
+ Ohc->IntrQh->NextTd = NULL;
+
+ Before = Ohc->IntrQh;
+ do
+ {
+ Current = UsbHcAllocateMem (Ohc->MemPool, sizeof(OHCI_TD_SW));
+ Current->TdHw = NULL;
+ Current->NextTd = NULL;
+ Before->NextTd = Current;
+ Before->TdHw = Td;
+ Before->TdHw->gtd_info.b.buffer_rounding = 0;
+ Before->Data = Td->current_buf_ptr;
+ Before->DataLen = (Td->buffer_end - Td->current_buf_ptr + 1);
+ Before = Current;
+
+ gCpu->FlushDataCache (gCpu, (EFI_PHYSICAL_ADDRESS)(UINTN)Td, sizeof(OHCI_TD_HW), EfiCpuFlushTypeWriteBackInvalidate);
+ } while(Td = Td->next_td);
+ }
+
+ OhciDumpEd(Ed);
+
+ OhciLinkTdToQh (Ohc, Ed, 1);
+
+ //
+ // Save QH-TD structures to async Interrupt transfer list,
+ // for monitor interrupt transfer execution routine use.
+ //
+ Status = OhciCreateAsyncReq (
+ Ohc,
+ Ed,
+ Ohc->IntrQh,
+ DeviceAddress,
+ EndPointAddress,
+ DataLength,
+ PollingInterval,
+ DataPtr,
+ CallBackFunction,
+ Context,
+ IsSlowDevice
+ );
+
+ if (EFI_ERROR (Status)) {
+ goto DESTORY_QH;
+ }
+
+ //OhciLinkQhToFrameList (Ohc, Qh);
+
+ gBS->RestoreTPL (OldTpl);
+
+ DEBUG((EFI_D_INIT, "---Ohci2AsyncInterruptTransfer()\n"));
+
+ return EFI_SUCCESS;
+
+DESTORY_QH:
+ //UsbHcFreeMem (Ohc->MemPool, Qh, sizeof (OHCI_QH_SW));
+
+FREE_DATA:
+ UsbHcFreeMem (Ohc->MemPool, DataPtr, DataLength);
+ Ohc->PciIo->Flush (Ohc->PciIo);
+
+ gBS->RestoreTPL (OldTpl);
+
+#else
+ Ohc = OHC_FROM_USB2_HC_PROTO (This);
+ Qh = NULL;
+ IntTds = NULL;
+ DataPtr = NULL;
+ DataPhy = NULL;
+
+ IsSlowDevice = (BOOLEAN) ((EFI_USB_SPEED_LOW == DeviceSpeed) ? TRUE : FALSE);
+
+ if ((EndPointAddress & 0x80) == 0) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Delete Async interrupt transfer request
+ //
+ if (!IsNewTransfer) {
+ OldTpl = gBS->RaiseTPL (OHCI_TPL);
+ Status = OhciRemoveAsyncReq (Ohc, DeviceAddress, EndPointAddress, DataToggle);
+
+ gBS->RestoreTPL (OldTpl);
+ return Status;
+ }
+
+ if (PollingInterval < 1 || PollingInterval > 255) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (DataLength == 0) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if ((*DataToggle != 1) && (*DataToggle != 0)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // If has errors that cause host controller halt,
+ // then return EFI_DEVICE_ERROR directly.
+ //
+ OhciAckAllInterrupt (Ohc);
+
+ if (!OhciIsHcWorking (Ohc->PciIo)) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ if ((EndPointAddress & 0x80) == 0) {
+ PktId = OUTPUT_PACKET_ID;
+ } else {
+ PktId = INPUT_PACKET_ID;
+ }
+
+ //
+ // Allocate and map source data buffer for bus master access.
+ //
+ DataPtr = UsbHcAllocateMem (Ohc->MemPool, DataLength);
+
+ if (DataPtr == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ DataPhy = (UINT8 *) (UINTN) UsbHcGetPciAddressForHostMem (Ohc->MemPool, DataPtr, DataLength);
+
+ OldTpl = gBS->RaiseTPL (OHCI_TPL);
+
+ Qh = OhciCreateQh (Ohc, PollingInterval);
+
+ if (Qh == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto FREE_DATA;
+ }
+
+ IntTds = OhciCreateBulkOrIntTds (
+ Ohc,
+ DeviceAddress,
+ EndPointAddress,
+ PktId,
+ DataPtr,
+ DataPhy,
+ DataLength,
+ DataToggle,
+ (UINT8) MaximumPacketLength,
+ IsSlowDevice
+ );
+
+ if (IntTds == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto DESTORY_QH;
+ }
+
+ OhciLinkTdToQh (Ohc, Qh, IntTds);
+
+ //
+ // Save QH-TD structures to async Interrupt transfer list,
+ // for monitor interrupt transfer execution routine use.
+ //
+ Status = OhciCreateAsyncReq (
+ Ohc,
+ Qh,
+ IntTds,
+ DeviceAddress,
+ EndPointAddress,
+ DataLength,
+ PollingInterval,
+ DataPtr,
+ CallBackFunction,
+ Context,
+ IsSlowDevice
+ );
+
+ if (EFI_ERROR (Status)) {
+ goto DESTORY_QH;
+ }
+
+ OhciLinkQhToFrameList (Ohc, Qh);
+
+ gBS->RestoreTPL (OldTpl);
+
+ DEBUG((EFI_D_INIT, "---Ohci2AsyncInterruptTransfer()\n"));
+
+ return EFI_SUCCESS;
+
+DESTORY_QH:
+ UsbHcFreeMem (Ohc->MemPool, Qh, sizeof (OHCI_QH_SW));
+
+FREE_DATA:
+ UsbHcFreeMem (Ohc->MemPool, DataPtr, DataLength);
+ Ohc->PciIo->Flush (Ohc->PciIo);
+
+ gBS->RestoreTPL (OldTpl);
+#endif
+}
+
+/**
+ Submits synchronous interrupt transfer to an interrupt endpoint
+ of a USB device according to UEFI 2.0 spec.
+
+
+ @param This A pointer to the EFI_USB2_HC_PROTOCOL instance.
+ @param DeviceAddress Target device address.
+ @param EndPointAddress Endpoint number and direction.
+ @param DeviceSpeed Device speed.
+ @param MaximumPacketLength Maximum packet size of the target endpoint.
+ @param Data Array of pointers to the buffers of data.
+ @param DataLength On input, size of the data buffer, On output,
+ actually transferred data size.
+ @param DataToggle On input, data toggle to use; On output, next data toggle.
+ @param TimeOut Maximum time out, in microseconds.
+ @param Translator A pointr to the transaction translator data.
+ @param TransferResult Variable to receive transfer result.
+
+ @return EFI_SUCCESS The transfer was completed successfully.
+ @return EFI_OUT_OF_RESOURCES Failed due to lack of resource.
+ @return EFI_INVALID_PARAMETER Some parameters are invalid.
+ @return EFI_TIMEOUT Failed due to timeout.
+ @return EFI_DEVICE_ERROR Failed due to host controller or device error.
+
+**/
+EFI_STATUS
+EFIAPI
+Ohci2SyncInterruptTransfer (
+ IN EFI_USB2_HC_PROTOCOL *This,
+ IN UINT8 DeviceAddress,
+ IN UINT8 EndPointAddress,
+ IN UINT8 DeviceSpeed,
+ IN UINTN MaximumPacketLength,
+ IN OUT VOID *Data,
+ IN OUT UINTN *DataLength,
+ IN OUT UINT8 *DataToggle,
+ IN UINTN TimeOut,
+ IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
+ OUT UINT32 *TransferResult
+ )
+{
+ EFI_STATUS Status;
+ USB_HC_DEV *Ohc;
+ OHCI_TD_HW *TDs;
+ OHCI_QH_RESULT QhResult;
+ EFI_TPL OldTpl;
+ UINT8 *DataPhy;
+ VOID *DataMap;
+ UINT8 PktId;
+ BOOLEAN IsSlowDevice;
+#if 1
+ DEBUG((EFI_D_INIT, "+++Ohci2SyncInterruptTransfer()\n"));
+ DEBUG((EFI_D_INIT, "---Ohci2SyncInterruptTransfer()\n"));
+#else
+ Ohc = OHC_FROM_USB2_HC_PROTO (This);
+ DataPhy = NULL;
+ DataMap = NULL;
+ TDs = NULL;
+
+ if (DeviceSpeed == EFI_USB_SPEED_HIGH) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ IsSlowDevice = (BOOLEAN) ((EFI_USB_SPEED_LOW == DeviceSpeed) ? TRUE : FALSE);
+
+ if ((DataLength == NULL) || (Data == NULL) || (TransferResult == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if ((EndPointAddress & 0x80) == 0) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if ((*DataToggle != 1) && (*DataToggle != 0)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if ((*DataLength == 0) || (MaximumPacketLength > 64)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (IsSlowDevice && (MaximumPacketLength > 8)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ *TransferResult = EFI_USB_ERR_SYSTEM;
+ Status = EFI_DEVICE_ERROR;
+
+
+ OhciAckAllInterrupt (Ohc);
+
+ if (!OhciIsHcWorking (Ohc->PciIo)) {
+ return Status;
+ }
+
+ OldTpl = gBS->RaiseTPL (OHCI_TPL);
+
+ //
+ // Map the source data buffer for bus master access.
+ // Create Tds list, then link it to the OHC's interrupt list
+ //
+ Status = OhciMapUserData (
+ Ohc,
+ EfiUsbDataIn,
+ Data,
+ DataLength,
+ &PktId,
+ &DataPhy,
+ &DataMap
+ );
+
+ if (EFI_ERROR (Status)) {
+ goto ON_EXIT;
+ }
+
+ TDs = OhciCreateBulkOrIntTds (
+ Ohc,
+ DeviceAddress,
+ EndPointAddress,
+ PktId,
+ (UINT8 *)Data,
+ DataPhy,
+ *DataLength,
+ DataToggle,
+ (UINT8) MaximumPacketLength,
+ IsSlowDevice
+ );
+
+ if (TDs == NULL) {
+ Ohc->PciIo->Unmap (Ohc->PciIo, DataMap);
+
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_EXIT;
+ }
+
+
+ OhciLinkTdToQh (Ohc, Ohc->SyncIntQh, TDs);
+
+ Status = OhciExecuteTransfer (Ohc, Ohc->SyncIntQh, TDs, TimeOut, IsSlowDevice, &QhResult);
+
+ OhciUnlinkTdFromQh (Ohc->SyncIntQh, TDs);
+ Ohc->PciIo->Flush (Ohc->PciIo);
+
+ *TransferResult = QhResult.Result;
+ *DataToggle = QhResult.NextToggle;
+ *DataLength = QhResult.Complete;
+
+ OhciDestoryTds (Ohc, TDs);
+ Ohc->PciIo->Unmap (Ohc->PciIo, DataMap);
+
+ON_EXIT:
+ gBS->RestoreTPL (OldTpl);
+#endif
+ return Status;
+}
+
+
+/**
+ Submits isochronous transfer to a target USB device according to UEFI 2.0 spec.
+
+ @param This A pointer to the EFI_USB2_HC_PROTOCOL instance.
+ @param DeviceAddress Target device address.
+ @param EndPointAddress Endpoint number and direction.
+ @param DeviceSpeed Device speed.
+ @param MaximumPacketLength Maximum packet size of the target endpoint.
+ @param DataBuffersNumber Number of data buffers prepared for the transfer.
+ @param Data Array of pointers to the buffers of data.
+ @param DataLength On input, size of the data buffer, On output,
+ actually transferred data size.
+ @param Translator A pointr to the transaction translator data.
+ @param TransferResult Variable to receive transfer result.
+
+ @return EFI_UNSUPPORTED
+
+**/
+EFI_STATUS
+EFIAPI
+Ohci2IsochronousTransfer (
+ IN EFI_USB2_HC_PROTOCOL *This,
+ IN UINT8 DeviceAddress,
+ IN UINT8 EndPointAddress,
+ IN UINT8 DeviceSpeed,
+ IN UINTN MaximumPacketLength,
+ IN UINT8 DataBuffersNumber,
+ IN OUT VOID *Data[EFI_USB_MAX_ISO_BUFFER_NUM],
+ IN UINTN DataLength,
+ IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
+ OUT UINT32 *TransferResult
+ )
+{
+ DEBUG((EFI_D_INIT, "+++Ohci2IsochronousTransfer()\n"));
+ DEBUG((EFI_D_INIT, "---Ohci2IsochronousTransfer()\n"));
+ return EFI_UNSUPPORTED;
+}
+
+
+/**
+ Submits Async isochronous transfer to a target USB device according to UEFI 2.0 spec.
+
+ @param This A pointer to the EFI_USB2_HC_PROTOCOL instance.
+ @param DeviceAddress Target device address.
+ @param EndPointAddress Endpoint number and direction.
+ @param DeviceSpeed Device speed.
+ @param MaximumPacketLength Maximum packet size of the target endpoint.
+ @param DataBuffersNumber Number of data buffers prepared for the transfer.
+ @param Data Array of pointers to the buffers of data.
+ @param DataLength On input, size of the data buffer, On output,
+ actually transferred data size.
+ @param Translator A pointr to the transaction translator data.
+ @param IsochronousCallBack Function to call when the transfer complete.
+ @param Context Pass to the call back function as parameter.
+
+ @return EFI_UNSUPPORTED
+
+**/
+EFI_STATUS
+EFIAPI
+Ohci2AsyncIsochronousTransfer (
+ IN EFI_USB2_HC_PROTOCOL *This,
+ IN UINT8 DeviceAddress,
+ IN UINT8 EndPointAddress,
+ IN UINT8 DeviceSpeed,
+ IN UINTN MaximumPacketLength,
+ IN UINT8 DataBuffersNumber,
+ IN OUT VOID *Data[EFI_USB_MAX_ISO_BUFFER_NUM],
+ IN UINTN DataLength,
+ IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
+ IN EFI_ASYNC_USB_TRANSFER_CALLBACK IsochronousCallBack,
+ IN VOID *Context
+ )
+{
+ DEBUG((EFI_D_INIT, "+++Ohci2AsyncIsochronousTransfer()\n"));
+ DEBUG((EFI_D_INIT, "---Ohci2AsyncIsochronousTransfer()\n"));
+ return EFI_UNSUPPORTED;
+}
+
+/**
+ Entry point for EFI drivers.
+
+ @param ImageHandle EFI_HANDLE.
+ @param SystemTable EFI_SYSTEM_TABLE.
+
+ @retval EFI_SUCCESS Driver is successfully loaded.
+ @return Others Failed.
+
+**/
+EFI_STATUS
+EFIAPI
+OhciDriverEntryPoint (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS status;
+ DEBUG((EFI_D_INIT, "+++OhciDriverEntryPoint()\n"));
+
+ status = EfiLibInstallDriverBindingComponentName2 (
+ ImageHandle,
+ SystemTable,
+ &gOhciDriverBinding,
+ ImageHandle,
+ &gOhciComponentName,
+ &gOhciComponentName2
+ );
+
+ DEBUG((EFI_D_INIT, "---OhciDriverEntryPoint(%r)\n", status));
+
+ return status;
+}
+
+
+/**
+ Test to see if this driver supports ControllerHandle. Any
+ ControllerHandle that has UsbHcProtocol installed will be supported.
+
+ @param This Protocol instance pointer.
+ @param Controller Handle of device to test.
+ @param RemainingDevicePath Not used.
+
+ @return EFI_SUCCESS This driver supports this device.
+ @return EFI_UNSUPPORTED This driver does not support this device.
+
+**/
+EFI_STATUS
+EFIAPI
+OhciDriverBindingSupported (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ )
+{
+ DEBUG((EFI_D_INFO, "++%a:%d\n", __FUNCTION__, __LINE__));
+ EFI_STATUS OpenStatus;
+ EFI_STATUS Status;
+ EFI_PCI_IO_PROTOCOL *PciIo;
+ USB_CLASSC UsbClassCReg;
+
+ //
+ // Test whether there is PCI IO Protocol attached on the controller handle.
+ //
+ OpenStatus = gBS->OpenProtocol (
+ Controller,
+ &gEfiPciIoProtocolGuid,
+ (VOID **) &PciIo,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_BY_DRIVER
+ );
+
+ if (EFI_ERROR (OpenStatus)) {
+ DEBUG((EFI_D_ERROR, "--%a(OpenProtocol Error):%d\n", __FUNCTION__, __LINE__));
+ return OpenStatus;
+ }
+
+ Status = PciIo->Pci.Read (
+ PciIo,
+ EfiPciIoWidthUint8,
+ PCI_CLASSCODE_OFFSET,
+ sizeof (USB_CLASSC) / sizeof (UINT8),
+ &UsbClassCReg
+ );
+
+ if (EFI_ERROR (Status)) {
+ DEBUG((EFI_D_ERROR, "--%a(Pci.Read Error):%d\n", __FUNCTION__, __LINE__));
+ Status = EFI_UNSUPPORTED;
+ goto ON_EXIT;
+ }
+
+ //
+ // Test whether the controller belongs to OHCI type
+ //
+ if ((UsbClassCReg.BaseCode != PCI_CLASS_SERIAL) ||
+ (UsbClassCReg.SubClassCode != PCI_CLASS_SERIAL_USB) ||
+ (UsbClassCReg.ProgInterface != PCI_IF_OHCI)
+ ) {
+ DEBUG ((EFI_D_ERROR, "FAIL! INTERFACE IS NOT OHCI(%X, %X, %X, %X, %X, %X)\n",
+ UsbClassCReg.BaseCode,
+ PCI_CLASS_SERIAL,
+ UsbClassCReg.SubClassCode,
+ PCI_CLASS_SERIAL_USB,
+ UsbClassCReg.ProgInterface,
+ PCI_IF_OHCI
+ ));
+ Status = EFI_UNSUPPORTED;
+ }
+
+ON_EXIT:
+ gBS->CloseProtocol (
+ Controller,
+ &gEfiPciIoProtocolGuid,
+ This->DriverBindingHandle,
+ Controller
+ );
+
+ DEBUG((EFI_D_INIT, "OhciDriverBindingSupported(%r)\n", Status));
+ DEBUG((EFI_D_INFO, "--%a:%d\n", __FUNCTION__, __LINE__));
+
+ return Status;
+
+}
+
+
+/**
+ Allocate and initialize the empty OHCI device.
+
+ @param PciIo The PCIIO to use.
+ @param OriginalPciAttributes The original PCI attributes.
+
+ @return Allocated OHCI device. If err, return NULL.
+
+**/
+USB_HC_DEV *
+OhciAllocateDev (
+ IN EFI_PCI_IO_PROTOCOL *PciIo,
+ IN UINT64 OriginalPciAttributes
+ )
+{
+ DEBUG((EFI_D_INFO, "++%a:%d\n", __FUNCTION__, __LINE__));
+ USB_HC_DEV *Ohc;
+ EFI_STATUS Status;
+ UINT32 i;
+
+ Ohc = AllocateZeroPool (sizeof (USB_HC_DEV));
+
+ if (Ohc == NULL) {
+ return NULL;
+ }
+
+ //
+ // This driver supports both USB_HC_PROTOCOL and USB2_HC_PROTOCOL.
+ // USB_HC_PROTOCOL is for EFI 1.1 backward compability.
+ //
+ Ohc->Signature = USB_HC_DEV_SIGNATURE;
+ Ohc->Usb2Hc.GetCapability = Ohci2GetCapability;
+ Ohc->Usb2Hc.Reset = Ohci2Reset;
+ Ohc->Usb2Hc.GetState = Ohci2GetState;
+ Ohc->Usb2Hc.SetState = Ohci2SetState;
+ Ohc->Usb2Hc.ControlTransfer = Ohci2ControlTransfer;
+ Ohc->Usb2Hc.BulkTransfer = Ohci2BulkTransfer;
+ Ohc->Usb2Hc.AsyncInterruptTransfer = Ohci2AsyncInterruptTransfer;
+ Ohc->Usb2Hc.SyncInterruptTransfer = Ohci2SyncInterruptTransfer;
+ Ohc->Usb2Hc.IsochronousTransfer = Ohci2IsochronousTransfer;
+ Ohc->Usb2Hc.AsyncIsochronousTransfer = Ohci2AsyncIsochronousTransfer;
+ Ohc->Usb2Hc.GetRootHubPortStatus = Ohci2GetRootHubPortStatus;
+ Ohc->Usb2Hc.SetRootHubPortFeature = Ohci2SetRootHubPortFeature;
+ Ohc->Usb2Hc.ClearRootHubPortFeature = Ohci2ClearRootHubPortFeature;
+ Ohc->Usb2Hc.MajorRevision = 0x1;
+ Ohc->Usb2Hc.MinorRevision = 0x1;
+
+ Ohc->Destory = NULL;
+ Ohc->PciIo = PciIo;
+ Ohc->OriginalPciAttributes = OriginalPciAttributes;
+ Ohc->MemPool = UsbHcInitMemPool (PciIo, TRUE, 0);
+
+ if (Ohc->MemPool == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_ERROR;
+ }
+
+ InitializeListHead (&Ohc->AsyncIntList);
+
+ Status = gBS->CreateEvent (
+ EVT_TIMER | EVT_NOTIFY_SIGNAL,
+ TPL_CALLBACK,
+ OhciMonitorAsyncReqList,
+ Ohc,
+ &Ohc->AsyncIntMonitor
+ );
+
+ if (EFI_ERROR (Status)) {
+ UsbHcFreeMemPool (Ohc->MemPool);
+ goto ON_ERROR;
+ }
+
+ for(i=0; i<15; ++i)
+ {
+ Ohc->EdHw[i] = OhciCreateEd(Ohc, 0, 0, 0, 0);
+ }
+
+ DEBUG((EFI_D_INFO, "--%a:%d\n", __FUNCTION__, __LINE__));
+
+ return Ohc;
+
+ON_ERROR:
+ FreePool (Ohc);
+ return NULL;
+}
+
+
+/**
+ Free the OHCI device and release its associated resources.
+
+ @param Ohc The OHCI device to release.
+
+**/
+VOID
+OhciFreeDev (
+ IN USB_HC_DEV *Ohc
+ )
+{
+ DEBUG((EFI_D_INFO, "++%a:%d\n", __FUNCTION__, __LINE__));
+
+ if (Ohc->AsyncIntMonitor != NULL) {
+ gBS->CloseEvent (Ohc->AsyncIntMonitor);
+ }
+
+ if (Ohc->ExitBootServiceEvent != NULL) {
+ gBS->CloseEvent (Ohc->ExitBootServiceEvent);
+ }
+
+ if (Ohc->MemPool != NULL) {
+ UsbHcFreeMemPool (Ohc->MemPool);
+ }
+
+ if (Ohc->CtrlNameTable != NULL) {
+ FreeUnicodeStringTable (Ohc->CtrlNameTable);
+ }
+
+ FreePool (Ohc);
+
+ DEBUG((EFI_D_INFO, "--%a:%d\n", __FUNCTION__, __LINE__));
+}
+
+
+/**
+ Uninstall all Ohci Interface.
+
+ @param Controller Controller handle.
+ @param This Protocol instance pointer.
+
+**/
+VOID
+OhciCleanDevUp (
+ IN EFI_HANDLE Controller,
+ IN EFI_USB2_HC_PROTOCOL *This
+ )
+{
+ DEBUG((EFI_D_INFO, "++%a:%d\n", __FUNCTION__, __LINE__));
+ USB_HC_DEV *Ohc;
+
+ //
+ // Uninstall the USB_HC and USB_HC2 protocol, then disable the controller
+ //
+ Ohc = OHC_FROM_USB2_HC_PROTO (This);
+ OhciStopHc (Ohc, OHC_GENERIC_TIMEOUT);
+
+ gBS->UninstallProtocolInterface (
+ Controller,
+ &gEfiUsb2HcProtocolGuid,
+ &Ohc->Usb2Hc
+ );
+
+ OhciFreeAllAsyncReq (Ohc);
+ OhciDestoryFrameList (Ohc);
+
+ //
+ // Restore original PCI attributes
+ //
+ Ohc->PciIo->Attributes (
+ Ohc->PciIo,
+ EfiPciIoAttributeOperationSet,
+ Ohc->OriginalPciAttributes,
+ NULL
+ );
+
+ OhciFreeDev (Ohc);
+ DEBUG((EFI_D_INFO, "--%a:%d\n", __FUNCTION__, __LINE__));
+}
+
+/**
+ One notified function to stop the Host Controller when gBS->ExitBootServices() called.
+
+ @param Event Pointer to this event
+ @param Context Event hanlder private data
+
+**/
+VOID
+EFIAPI
+OhcExitBootService (
+ EFI_EVENT Event,
+ VOID *Context
+ )
+{
+ DEBUG((EFI_D_INFO, "++%a:%d\n", __FUNCTION__, __LINE__));
+ USB_HC_DEV *Ohc;
+
+ Ohc = (USB_HC_DEV *) Context;
+
+ //
+ // Stop the Host Controller
+ //
+ OhciStopHc (Ohc, OHC_GENERIC_TIMEOUT);
+
+ //
+ // Reset the Host Controller
+ //
+ OhciSetRegBit (Ohc->PciIo, USBCMD_OFFSET, USBCMD_HCRESET);
+ gBS->Stall (OHC_ROOT_PORT_RECOVERY_STALL);
+ DEBUG((EFI_D_INFO, "--%a:%d\n", __FUNCTION__, __LINE__));
+}
+
+/**
+ Starting the Usb OHCI Driver.
+
+ @param This Protocol instance pointer.
+ @param Controller Handle of device to test.
+ @param RemainingDevicePath Not used.
+
+ @retval EFI_SUCCESS This driver supports this device.
+ @retval EFI_UNSUPPORTED This driver does not support this device.
+ @retval EFI_DEVICE_ERROR This driver cannot be started due to device Error.
+ EFI_OUT_OF_RESOURCES- Failed due to resource shortage.
+
+**/
+EFI_STATUS
+EFIAPI
+OhciDriverBindingStart (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ )
+{
+ DEBUG((EFI_D_INFO, "++%a:%d\n", __FUNCTION__, __LINE__));
+ EFI_STATUS Status;
+ EFI_PCI_IO_PROTOCOL *PciIo;
+ USB_HC_DEV *Ohc;
+ UINT64 Supports;
+ UINT64 OriginalPciAttributes;
+ BOOLEAN PciAttributesSaved;
+ UINT32 CmdStatus;
+ UINT32 Buffer;
+
+ //
+ // Open PCIIO, then enable the EHC device and turn off emulation
+ //
+ Ohc = NULL;
+ Status = gBS->OpenProtocol (
+ Controller,
+ &gEfiPciIoProtocolGuid,
+ (VOID **) &PciIo,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_BY_DRIVER
+ );
+
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "FAIL! OpenProtocol\n"));
+ return Status;
+ }
+
+ PciAttributesSaved = FALSE;
+ //
+ // Save original PCI attributes
+ //
+ Status = PciIo->Attributes (
+ PciIo,
+ EfiPciIoAttributeOperationGet,
+ 0,
+ &OriginalPciAttributes
+ );
+
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "FAIL! Attributes\n"));
+ goto CLOSE_PCIIO;
+ }
+ PciAttributesSaved = TRUE;
+
+ Status = PciIo->Attributes (
+ PciIo,
+ EfiPciIoAttributeOperationSupported,
+ 0,
+ &Supports
+ );
+ if (!EFI_ERROR (Status)) {
+ Supports &= EFI_PCI_DEVICE_ENABLE;
+ Status = PciIo->Attributes (
+ PciIo,
+ EfiPciIoAttributeOperationEnable,
+ Supports,
+ NULL
+ );
+ }
+
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "OhcDriverBindingStart: failed to enable controller\n"));
+ goto CLOSE_PCIIO;
+ }
+
+ gBS->LocateProtocol (&gEfiCpuArchProtocolGuid, NULL, (VOID **)&gCpu);
+
+ Ohc = OhciAllocateDev (PciIo, OriginalPciAttributes);
+
+ if (Ohc == NULL) {
+ DEBUG ((EFI_D_ERROR, "FAIL OhciAllocateDev \n"));
+ Status = EFI_OUT_OF_RESOURCES;
+ goto CLOSE_PCIIO;
+ }
+
+ DEBUG ((EFI_D_ERROR, "OHCI SetTimer\n"));
+ Status = gBS->SetTimer (
+ Ohc->AsyncIntMonitor,
+ TimerPeriodic,
+ OHC_ASYNC_POLL_INTERVAL
+ );
+
+ if (EFI_ERROR (Status)) {
+ goto FREE_OHC;
+ }
+
+ //
+ // Install USB2_HC_PROTOCOL
+ //
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &Controller,
+ &gEfiUsb2HcProtocolGuid,
+ &Ohc->Usb2Hc,
+ NULL
+ );
+
+ if (EFI_ERROR (Status)) {
+ goto FREE_OHC;
+ }
+
+ //
+ // Create event to stop the HC when exit boot service.
+ //
+ Status = gBS->CreateEventEx (
+ EVT_NOTIFY_SIGNAL,
+ TPL_NOTIFY,
+ OhcExitBootService,
+ Ohc,
+ &gEfiEventExitBootServicesGuid,
+ &Ohc->ExitBootServiceEvent
+ );
+ if (EFI_ERROR (Status)) {
+ goto UNINSTALL_USBHC;
+ }
+
+ //
+ // Install the component name protocol
+ //
+ Ohc->CtrlNameTable = NULL;
+
+ AddUnicodeString2 (
+ "eng",
+ gOhciComponentName.SupportedLanguages,
+ &Ohc->CtrlNameTable,
+ L"Usb Universal Host Controller",
+ TRUE
+ );
+ AddUnicodeString2 (
+ "en",
+ gOhciComponentName2.SupportedLanguages,
+ &Ohc->CtrlNameTable,
+ L"Usb Universal Host Controller",
+ FALSE
+ );
+
+
+ //
+ // Start the OHCI hardware, also set its reclamation point to 64 bytes
+ //
+ //take ownership
+
+// OhcDumpRegs(Ohc);
+
+ CmdStatus = OhciReadReg(Ohc, HC_COM_STATUS_OFFSET);
+ OhciWriteReg(Ohc, HC_COM_STATUS_OFFSET, (CmdStatus | (1<<3)));
+
+ do
+ {
+ gBS->Stall(1000);
+ CmdStatus = OhciReadReg(Ohc, HC_COM_STATUS_OFFSET);
+ } while((CmdStatus & (1<<3)));
+
+ //interrupt disable
+ OhciWriteReg(Ohc, HC_INT_DISABLE_OFFSET, 0xFFFFFFFF);
+
+ //interrupt status clear
+ CmdStatus = OhciReadReg(Ohc, HC_INT_STATUS_OFFSET);
+ OhciWriteReg(Ohc, HC_INT_STATUS_OFFSET, CmdStatus);
+
+ //frame interval
+ CmdStatus = OhciReadReg(Ohc, HC_FMINTERVAL_OFFSET);
+ CmdStatus &= 0x8000FFFF;
+ CmdStatus |= (0x800<<16); //256*8
+ OhciWriteReg(Ohc, HC_FMINTERVAL_OFFSET, CmdStatus);
+
+ //set hcca base
+ //
+ // Allocate and Init Host Controller's Frame List Entry
+ //
+
+ #if 1
+ Buffer = UsbHcAllocateMem (Ohc->MemPool, sizeof(OHCI_HCCA));
+ ZeroMem (Buffer, sizeof(OHCI_HCCA));
+ OhciWriteReg(Ohc, HC_HCCA_OFFSET, (UINT32)Buffer);
+ #else
+ Status = OhciInitFrameList (Ohc);
+
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "FAIL OhciInitFrameList\n"));
+ Status = EFI_OUT_OF_RESOURCES;
+ goto FREE_OHC;
+ }
+ #endif
+
+ //Set opertional state
+ CmdStatus = OhciReadReg(Ohc, HC_CONTROL_OFFSET);
+ CmdStatus &= ~(3<<6);
+ CmdStatus |= (2<<6);
+ OhciWriteReg(Ohc, HC_CONTROL_OFFSET, CmdStatus);
+
+ //setPowerSwitchingMode off
+ CmdStatus = OhciReadReg(Ohc, HC_RH_DESCRIPTORA_OFFSET);
+ CmdStatus &= ~(1<<8);
+ OhciWriteReg(Ohc, HC_RH_DESCRIPTORA_OFFSET, CmdStatus);
+
+ //Set global power
+ CmdStatus = OhciReadReg(Ohc, HC_RH_STATUS_OFFSET);
+ CmdStatus |= (1<<16);
+ OhciWriteReg(Ohc, HC_RH_STATUS_OFFSET, CmdStatus);
+
+ OhcDumpRegs(Ohc);
+
+ DEBUG((EFI_D_INFO, "--%a(EFI_SUCCESS):%d\n", __FUNCTION__, __LINE__));
+
+ return EFI_SUCCESS;
+
+UNINSTALL_USBHC:
+ gBS->UninstallMultipleProtocolInterfaces (
+ Controller,
+ &gEfiUsb2HcProtocolGuid,
+ &Ohc->Usb2Hc,
+ NULL
+ );
+
+FREE_OHC:
+ OhciFreeDev (Ohc);
+
+CLOSE_PCIIO:
+ if (PciAttributesSaved) {
+ //
+ // Restore original PCI attributes
+ //
+ PciIo->Attributes (
+ PciIo,
+ EfiPciIoAttributeOperationSet,
+ OriginalPciAttributes,
+ NULL
+ );
+ }
+
+ gBS->CloseProtocol (
+ Controller,
+ &gEfiPciIoProtocolGuid,
+ This->DriverBindingHandle,
+ Controller
+ );
+
+ DEBUG((EFI_D_INFO, "--%a:%d\n", __FUNCTION__, __LINE__));
+ return Status;
+}
+
+
+/**
+ Stop this driver on ControllerHandle. Support stoping any child handles
+ created by this driver.
+
+ @param This Protocol instance pointer.
+ @param Controller Handle of device to stop driver on.
+ @param NumberOfChildren Number of Children in the ChildHandleBuffer.
+ @param ChildHandleBuffer List of handles for the children we need to stop.
+
+ @return EFI_SUCCESS
+ @return others
+
+**/
+EFI_STATUS
+EFIAPI
+OhciDriverBindingStop (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN UINTN NumberOfChildren,
+ IN EFI_HANDLE *ChildHandleBuffer
+ )
+{
+ DEBUG((EFI_D_INFO, "++%a:%d\n", __FUNCTION__, __LINE__));
+ EFI_USB2_HC_PROTOCOL *Usb2Hc;
+ EFI_STATUS Status;
+
+ Status = gBS->OpenProtocol (
+ Controller,
+ &gEfiUsb2HcProtocolGuid,
+ (VOID **) &Usb2Hc,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+
+ //
+ // Test whether the Controller handler passed in is a valid
+ // Usb controller handle that should be supported, if not,
+ // return the error status directly
+ //
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ OhciCleanDevUp (Controller, Usb2Hc);
+
+ gBS->CloseProtocol (
+ Controller,
+ &gEfiPciIoProtocolGuid,
+ This->DriverBindingHandle,
+ Controller
+ );
+
+ DEBUG((EFI_D_INFO, "--%a:%d\n", __FUNCTION__, __LINE__));
+ return EFI_SUCCESS;
+}
+
diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/OhciDxe/Ohci.h b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/OhciDxe/Ohci.h
new file mode 100644
index 000000000..e84e5e868
--- /dev/null
+++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/OhciDxe/Ohci.h
@@ -0,0 +1,229 @@
+/** @file
+
+ The definition for OHCI driver model and HC protocol routines.
+
+Copyright (c) 2004 - 2010, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _EFI_OHCI_H_
+#define _EFI_OHCI_H_
+
+
+#include <Uefi.h>
+
+#include <Protocol/Usb2HostController.h>
+#include <Protocol/UsbHostController.h>
+#include <Protocol/PciIo.h>
+
+#include <Guid/EventGroup.h>
+
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/UefiDriverEntryPoint.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiLib.h>
+#include <Library/BaseLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PcdLib.h>
+
+#include <IndustryStandard/Pci.h>
+
+typedef struct _USB_HC_DEV USB_HC_DEV;
+
+#include "UsbHcMem.h"
+#include "OhciQueue.h"
+#include "OhciReg.h"
+#include "OhciSched.h"
+#include "OhciDebug.h"
+#include "ComponentName.h"
+
+//
+// OHC timeout experience values
+//
+
+#define OHC_1_MICROSECOND 1
+#define OHC_1_MILLISECOND (1000 * OHC_1_MICROSECOND)
+#define OHC_1_SECOND (1000 * OHC_1_MILLISECOND)
+
+//
+// OHCI register operation timeout, set by experience
+//
+#define OHC_GENERIC_TIMEOUT OHC_1_SECOND
+
+//
+// Wait for force global resume(FGR) complete, refers to
+// specification[OHCI11-2.1.1]
+//
+#define OHC_FORCE_GLOBAL_RESUME_STALL (20 * OHC_1_MILLISECOND)
+
+//
+// Wait for roothub port reset and recovery, reset stall
+// is set by experience, and recovery stall refers to
+// specification[OHCI11-2.1.1]
+//
+#define OHC_ROOT_PORT_RESET_STALL (50 * OHC_1_MILLISECOND)
+#define OHC_ROOT_PORT_RECOVERY_STALL (10 * OHC_1_MILLISECOND)
+
+//
+// Sync and Async transfer polling interval, set by experience,
+// and the unit of Async is 100us.
+//
+#define OHC_SYNC_POLL_INTERVAL (1 * OHC_1_MILLISECOND)
+#define OHC_ASYNC_POLL_INTERVAL (50 * 10000UL)
+
+//
+// OHC raises TPL to TPL_NOTIFY to serialize all its operations
+// to protect shared data structures.
+//
+#define OHCI_TPL TPL_NOTIFY
+
+#define USB_HC_DEV_SIGNATURE SIGNATURE_32 ('u', 'h', 'c', 'i')
+
+#pragma pack(1)
+typedef struct {
+ UINT8 ProgInterface;
+ UINT8 SubClassCode;
+ UINT8 BaseCode;
+} USB_CLASSC;
+#pragma pack()
+
+#define OHC_FROM_USB2_HC_PROTO(This) CR(This, USB_HC_DEV, Usb2Hc, USB_HC_DEV_SIGNATURE)
+
+//
+// USB_HC_DEV support the OHCI hardware controller. It schedules
+// the asynchronous interrupt transfer with the same method as
+// EHCI: a reversed tree structure. For synchronous interrupt,
+// control and bulk transfer, it uses three static queue head to
+// schedule them. SyncIntQh is for interrupt transfer. LsCtrlQh is
+// for LOW speed control transfer, and FsCtrlBulkQh is for FULL
+// speed control or bulk transfer. This is because FULL speed contrl
+// or bulk transfer can reclaim the unused bandwidth. Some USB
+// device requires this bandwidth reclamation capability.
+//
+struct _USB_HC_DEV {
+ UINT32 Signature;
+ EFI_USB2_HC_PROTOCOL Usb2Hc;
+ EFI_PCI_IO_PROTOCOL *PciIo;
+ UINT64 OriginalPciAttributes;
+
+ //
+ // Schedule data structures
+ //
+ OHCI_HCCA *Hcca;
+ UINT32 *HccaMapping;
+
+
+ UINT32 *FrameBase; // the buffer pointed by this pointer is used to store pci bus address of the QH descriptor.
+ UINT32 *FrameBaseHostAddr; // the buffer pointed by this pointer is used to store host memory address of the QH descriptor.
+
+ OHCI_TD_SW *CtrlQh;
+ OHCI_TD_SW *IntrQh;
+
+ OHCI_TD_HW *LastTd;
+
+ OHCI_ED_HW *EdHw[15];
+
+ UINT32 *Destory;
+ UINT32 DestroySize;
+ //
+ // Structures to maintain asynchronus interrupt transfers.
+ // When asynchronous interrutp transfer is unlinked from
+ // the frame list, the hardware may still hold a pointer
+ // to it. To synchronize with hardware, its resoureces are
+ // released in two steps using Recycle and RecycleWait.
+ // Check the asynchronous interrupt management routines.
+ //
+ LIST_ENTRY AsyncIntList;
+ EFI_EVENT AsyncIntMonitor;
+ OHCI_ASYNC_REQUEST *Recycle;
+ OHCI_ASYNC_REQUEST *RecycleWait;
+
+
+ UINTN RootPorts;
+ USBHC_MEM_POOL *MemPool;
+ EFI_UNICODE_STRING_TABLE *CtrlNameTable;
+ VOID *FrameMapping;
+
+ //
+ // ExitBootServicesEvent is used to stop the EHC DMA operation
+ // after exit boot service.
+ //
+ EFI_EVENT ExitBootServiceEvent;
+};
+
+extern EFI_DRIVER_BINDING_PROTOCOL gOhciDriverBinding;
+extern EFI_COMPONENT_NAME_PROTOCOL gOhciComponentName;
+extern EFI_COMPONENT_NAME2_PROTOCOL gOhciComponentName2;
+
+/**
+ Test to see if this driver supports ControllerHandle. Any
+ ControllerHandle that has UsbHcProtocol installed will be supported.
+
+ @param This Protocol instance pointer.
+ @param Controller Handle of device to test.
+ @param RemainingDevicePath Not used.
+
+ @return EFI_SUCCESS This driver supports this device.
+ @return EFI_UNSUPPORTED This driver does not support this device.
+
+**/
+EFI_STATUS
+EFIAPI
+OhciDriverBindingSupported (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ );
+
+/**
+ Starting the Usb OHCI Driver.
+
+ @param This Protocol instance pointer.
+ @param Controller Handle of device to test.
+ @param RemainingDevicePath Not used.
+
+ @retval EFI_SUCCESS This driver supports this device.
+ @retval EFI_UNSUPPORTED This driver does not support this device.
+ @retval EFI_DEVICE_ERROR This driver cannot be started due to device Error.
+ EFI_OUT_OF_RESOURCES- Failed due to resource shortage.
+
+**/
+EFI_STATUS
+EFIAPI
+OhciDriverBindingStart (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ );
+
+/**
+ Stop this driver on ControllerHandle. Support stoping any child handles
+ created by this driver.
+
+ @param This Protocol instance pointer.
+ @param Controller Handle of device to stop driver on.
+ @param NumberOfChildren Number of Children in the ChildHandleBuffer.
+ @param ChildHandleBuffer List of handles for the children we need to stop.
+
+ @return EFI_SUCCESS
+ @return others
+
+**/
+EFI_STATUS
+EFIAPI
+OhciDriverBindingStop (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN UINTN NumberOfChildren,
+ IN EFI_HANDLE *ChildHandleBuffer
+ );
+
+#endif
diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/OhciDxe/OhciDebug.c b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/OhciDxe/OhciDebug.c
new file mode 100644
index 000000000..fca45cc06
--- /dev/null
+++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/OhciDxe/OhciDebug.c
@@ -0,0 +1,181 @@
+/** @file
+
+ This file provides the information dump support for Ohci when in debug mode.
+
+Copyright (c) 2007, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "Ohci.h"
+
+
+#ifdef EFI_D_INIT
+#undef EFI_D_INIT
+#define EFI_D_INIT EFI_D_INFO
+#endif
+
+/**
+ Dump the content of QH structure.
+
+ @param QhSw Pointer to software QH structure.
+
+**/
+#if 0
+VOID
+OhciDumpQh (
+ IN OHCI_QH_SW *QhSw
+ )
+{
+ DEBUG ((EFI_D_INFO, "&QhSw @ 0x%p\n", QhSw));
+ DEBUG ((EFI_D_INFO, "QhSw.NextQh - 0x%p\n", QhSw->NextQh));
+ DEBUG ((EFI_D_INFO, "QhSw.TDs - 0x%p\n", QhSw->TDs));
+ DEBUG ((EFI_D_INFO, "QhSw.QhHw:\n"));
+ DEBUG ((EFI_D_INFO, " Horizon Link - %x\n", QhSw->QhHw.HorizonLink));
+ DEBUG ((EFI_D_INFO, " Vertical Link - %x\n\n", QhSw->QhHw.VerticalLink));
+}
+#endif
+
+/**
+ Dump the content of TD structure.
+
+ @param TdSw Pointer to software TD structure.
+
+**/
+VOID
+OhciDumpTdHw (
+ IN OHCI_TD_HW *TdSw
+ )
+{
+ OHCI_TD_HW *CurTdSw;
+
+ DEBUG ((EFI_D_INIT, "\n+++OhciDumpTds()\n"));
+
+ CurTdSw = TdSw;
+
+ while (CurTdSw != NULL) {
+ DEBUG ((EFI_D_INIT, " TdHw @ 0x%p\n", CurTdSw));
+ DEBUG ((EFI_D_INIT, "TdHw.NextTd - 0x%p\n", CurTdSw->next_td));
+ DEBUG ((EFI_D_INIT, "TdHw.StartPtr - 0x%p\n", CurTdSw->current_buf_ptr));
+ DEBUG ((EFI_D_INIT, "TdHw.EndPtr - 0x%p\n", CurTdSw->buffer_end));
+ DEBUG ((EFI_D_INIT, "gtd_info:\n"));
+ DEBUG ((EFI_D_INIT, " buffer_rounding - 0x%x\n", CurTdSw->gtd_info.b.buffer_rounding));
+ DEBUG ((EFI_D_INIT, " pid - 0x%x\n", CurTdSw->gtd_info.b.pid));
+ DEBUG ((EFI_D_INIT, " error_count - 0x%x\n", CurTdSw->gtd_info.b.error_count));
+ DEBUG ((EFI_D_INIT, " condition_code - 0x%x\n", CurTdSw->gtd_info.b.condition_code));
+ DEBUG ((EFI_D_INIT, " data_toggle - 0x%x\n", CurTdSw->gtd_info.b.data_toggle));
+
+ CurTdSw = CurTdSw->next_td;
+ }
+
+ DEBUG ((EFI_D_INIT, "---OhciDumpTds()\n"));
+}
+
+VOID
+OhciDumpEd (
+ IN OHCI_ED_HW *EdHw
+ )
+{
+ DEBUG ((EFI_D_INIT, "\n+++OhciDumpEd()\n"));
+
+ DEBUG ((EFI_D_INIT, "ed_info:\n"));
+ DEBUG ((EFI_D_INIT, " func_addr - 0x%x\n", EdHw->ed_info.b.func_addr));
+ DEBUG ((EFI_D_INIT, " ep_num - 0x%x\n", EdHw->ed_info.b.ep_num));
+ DEBUG ((EFI_D_INIT, " direction - 0x%x\n", EdHw->ed_info.b.direction));
+ DEBUG ((EFI_D_INIT, " speed - 0x%x\n", EdHw->ed_info.b.speed));
+ DEBUG ((EFI_D_INIT, " skip - 0x%x\n", EdHw->ed_info.b.skip));
+ DEBUG ((EFI_D_INIT, " format - 0x%x\n", EdHw->ed_info.b.format));
+ DEBUG ((EFI_D_INIT, " mps - 0x%x\n", EdHw->ed_info.b.mps));
+
+ OhciDumpTdHw(EdHw->head_td_ptr);
+
+ DEBUG ((EFI_D_INIT, "---OhciDumpEd()\n\n"));
+}
+
+VOID
+OhciDumpSWTds (
+ IN OHCI_TD_SW *TdSw
+ )
+{
+ OHCI_TD_SW *CurTdSw;
+ OHCI_TD_HW *TdHw;
+
+ DEBUG ((EFI_D_INIT, "\n+++OhciDumpSWTds()\n"));
+
+ CurTdSw = TdSw;
+ TdHw = CurTdSw->TdHw;
+
+ while (TdHw != NULL) {
+ DEBUG ((EFI_D_INIT, " TdHw @ 0x%p\n", TdHw));
+ DEBUG ((EFI_D_INIT, "TdHw.NextTd - 0x%p\n", TdHw->next_td));
+ DEBUG ((EFI_D_INIT, "TdHw.StartPtr - 0x%p\n", TdHw->current_buf_ptr));
+ DEBUG ((EFI_D_INIT, "TdHw.EndPtr - 0x%p\n", TdHw->buffer_end));
+ DEBUG ((EFI_D_INIT, "TdSw.DataLen - 0x%p\n", CurTdSw->DataLen));
+ DEBUG ((EFI_D_INIT, "gtd_info:\n"));
+ DEBUG ((EFI_D_INIT, " buffer_rounding - 0x%x\n", TdHw->gtd_info.b.buffer_rounding));
+ DEBUG ((EFI_D_INIT, " pid - 0x%x\n", TdHw->gtd_info.b.pid));
+ DEBUG ((EFI_D_INIT, " error_count - 0x%x\n", TdHw->gtd_info.b.error_count));
+ DEBUG ((EFI_D_INIT, " condition_code - 0x%x\n", TdHw->gtd_info.b.condition_code));
+ DEBUG ((EFI_D_INIT, " data_toggle - 0x%x\n", TdHw->gtd_info.b.data_toggle));
+
+ CurTdSw = CurTdSw->NextTd;
+ TdHw = CurTdSw->TdHw;
+ }
+
+ DEBUG ((EFI_D_INIT, "---OhciDumpSWTds()\n\n"));
+}
+
+VOID
+OhcDumpRegs (
+ IN USB_HC_DEV *Ohc
+ )
+{
+ UINT8 Index;
+
+ DEBUG ((EFI_D_INIT, " HC_REVISION_OFFSET = 0x%08x\n", OhciReadReg (Ohc, HC_REVISION_OFFSET)));
+ DEBUG ((EFI_D_INIT, " HC_CONTROL_OFFSET = 0x%08x\n", OhciReadReg (Ohc, HC_CONTROL_OFFSET)));
+ DEBUG ((EFI_D_INIT, " HC_COM_STATUS_OFFSET = 0x%08x\n", OhciReadReg (Ohc, HC_COM_STATUS_OFFSET)));
+ DEBUG ((EFI_D_INIT, " HC_HCCA_OFFSET = 0x%08x\n", OhciReadReg (Ohc, HC_HCCA_OFFSET)));
+ DEBUG ((EFI_D_INIT, " HC_FMINTERVAL_OFFSET = 0x%08x\n", OhciReadReg (Ohc, HC_FMINTERVAL_OFFSET)));
+ DEBUG ((EFI_D_INIT, " HC_INT_DISABLE_OFFSET = 0x%08x\n", OhciReadReg (Ohc, HC_INT_DISABLE_OFFSET)));
+ DEBUG ((EFI_D_INIT, " HC_INT_STATUS_OFFSET = 0x%08x\n", OhciReadReg (Ohc, HC_INT_STATUS_OFFSET)));
+ DEBUG ((EFI_D_INIT, " HC_CTRL_HEADED_OFFSET = 0x%08x\n", OhciReadReg (Ohc, HC_CTRL_HEADED_OFFSET)));
+ DEBUG ((EFI_D_INIT, " HC_CTRL_CURRED_OFFSET = 0x%08x\n", OhciReadReg (Ohc, HC_CTRL_CURRED_OFFSET)));
+ DEBUG ((EFI_D_INIT, " HC_BULK_HEADED_OFFSET = 0x%08x\n", OhciReadReg (Ohc, HC_BULK_HEADED_OFFSET)));
+ DEBUG ((EFI_D_INIT, " HC_BULK_CURRED_OFFSET = 0x%08x\n", OhciReadReg (Ohc, HC_BULK_CURRED_OFFSET)));
+ DEBUG ((EFI_D_INIT, " HC_RH_STATUS_OFFSET = 0x%08x\n", OhciReadReg (Ohc, HC_RH_STATUS_OFFSET)));
+ DEBUG ((EFI_D_INIT, " HC_RH_DESCRIPTORA_OFFSET = 0x%08x\n", OhciReadReg (Ohc, HC_RH_DESCRIPTORA_OFFSET)));
+ DEBUG ((EFI_D_INIT, " HC_RH_DESCRIPTORB_OFFSET = 0x%08x\n", OhciReadReg (Ohc, HC_RH_DESCRIPTORB_OFFSET)));
+
+ for (Index = 0; Index <3; Index++) {
+ DEBUG ((EFI_D_INIT, " HC_PORT_STATUS_OFFSET(%d) = 0x%08x\n", Index, OhciReadReg (Ohc, HC_PORT_STATUS_OFFSET + (4 * Index))));
+ }
+}
+
+VOID
+OhcDumpRequest (
+ IN EFI_USB_DEVICE_REQUEST *Request
+ )
+{
+ DEBUG ((EFI_D_INIT, "RequestType = 0x%X\n", Request->RequestType));
+ DEBUG ((EFI_D_INIT, "Request = 0x%X\n", Request->Request));
+ DEBUG ((EFI_D_INIT, "Value = 0x%X\n", Request->Value));
+ DEBUG ((EFI_D_INIT, "Index = 0x%X\n", Request->Index));
+ DEBUG ((EFI_D_INIT, "Length = 0x%X\n", Request->Length));
+}
+
+VOID
+OhcDumpResult (
+ IN OHCI_QH_RESULT *Result
+ )
+{
+ DEBUG ((EFI_D_INIT, "Result = 0x%X\n", Result->Result));
+ DEBUG ((EFI_D_INIT, "Complete = 0x%X\n", Result->Complete));
+ DEBUG ((EFI_D_INIT, "NextToggle = 0x%X\n", Result->NextToggle));
+} \ No newline at end of file
diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/OhciDxe/OhciDebug.h b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/OhciDxe/OhciDebug.h
new file mode 100644
index 000000000..8155fcc7d
--- /dev/null
+++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/OhciDxe/OhciDebug.h
@@ -0,0 +1,51 @@
+/** @file
+
+ This file contains the definination for host controller debug support routines
+
+Copyright (c) 2007, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _EFI_OHCI_DEBUG_H_
+#define _EFI_OHCI_DEBUG_H_
+
+
+/**
+ Dump the content of QH structure.
+
+ @param QhSw Pointer to software QH structure.
+
+ @return None.
+
+**/
+VOID
+OhciDumpQh (
+ IN OHCI_QH_SW *QhSw
+ );
+
+
+/**
+ Dump the content of TD structure.
+
+ @param TdSw Pointer to software TD structure.
+
+ @return None.
+
+**/
+VOID
+OhciDumpTds (
+ IN OHCI_TD_HW *TdSw
+ );
+
+VOID
+OhcDumpRegs (
+ IN USB_HC_DEV *Ohc
+ );
+#endif
diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/OhciDxe/OhciDxe.inf b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/OhciDxe/OhciDxe.inf
new file mode 100644
index 000000000..344e9cd9c
--- /dev/null
+++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/OhciDxe/OhciDxe.inf
@@ -0,0 +1,88 @@
+## @file
+#
+# Component Description File For OhciDxe Module.
+#
+# OhciDxe driver is responsible for managing the behavior of OHCI controller.
+# It implements the interfaces of monitoring the status of all ports and transferring
+# Control, Bulk, Interrupt and Isochronous requests to Usb1.x device
+#
+# Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = OhciDxe
+ FILE_GUID = 2FB92EFA-2EE0-4bae-9EB6-7464125E1EF7
+ MODULE_TYPE = UEFI_DRIVER
+ VERSION_STRING = 1.0
+
+ ENTRY_POINT = OhciDriverEntryPoint
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF EBC
+#
+# DRIVER_BINDING = gOhciDriverBinding
+# COMPONENT_NAME = gOhciComponentName
+# COMPONENT_NAME2 = gOhciComponentName2
+#
+
+[Sources]
+ OhciSched.c
+ OhciDebug.c
+ UsbHcMem.h
+ OhciDebug.h
+ OhciQueue.c
+ OhciReg.c
+ UsbHcMem.c
+ OhciQueue.h
+ Ohci.c
+ Ohci.h
+ OhciReg.h
+ OhciSched.h
+ ComponentName.c
+ ComponentName.h
+
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+
+[FeaturePcd]
+ gEfiMdeModulePkgTokenSpaceGuid.PcdTurnOffUsbLegacySupport ## SOMETIME_CONSUMES (enable/disable usb legacy support.)
+
+[LibraryClasses]
+ MemoryAllocationLib
+ BaseLib
+ UefiLib
+ UefiBootServicesTableLib
+ UefiDriverEntryPoint
+ BaseMemoryLib
+ DebugLib
+ PcdLib
+
+[Guids]
+ gEfiEventExitBootServicesGuid ## PRODUCES ## Event
+
+[Protocols]
+ gEfiPciIoProtocolGuid ## TO_START
+ gEfiUsb2HcProtocolGuid ## BY_START
+ gEfiCpuArchProtocolGuid
+
+# [Event]
+# ##
+# # Periodic timer event for checking the result of interrupt transfer execution.
+# #
+# EVENT_TYPE_PERIODIC_TIMER ## PRODUCES
+#
diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/OhciDxe/OhciQueue.c b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/OhciDxe/OhciQueue.c
new file mode 100644
index 000000000..f25da6c41
--- /dev/null
+++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/OhciDxe/OhciQueue.c
@@ -0,0 +1,993 @@
+/** @file
+
+ The OHCI register operation routines.
+
+Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "Ohci.h"
+
+
+/**
+ Map address of request structure buffer.
+
+ @param Ohc The OHCI device.
+ @param Request The user request buffer.
+ @param MappedAddr Mapped address of request.
+ @param Map Identificaion of this mapping to return.
+
+ @return EFI_SUCCESS Success.
+ @return EFI_DEVICE_ERROR Fail to map the user request.
+
+**/
+EFI_STATUS
+OhciMapUserRequest (
+ IN USB_HC_DEV *Ohc,
+ IN OUT VOID *Request,
+ OUT UINT8 **MappedAddr,
+ OUT VOID **Map
+ )
+{
+ EFI_STATUS Status;
+ UINTN Len;
+ EFI_PHYSICAL_ADDRESS PhyAddr;
+
+#if 1
+ Len = sizeof (EFI_USB_DEVICE_REQUEST);
+ Status = Ohc->PciIo->Map (
+ Ohc->PciIo,
+ EfiPciIoOperationBusMasterWrite,
+ Request,
+ &Len,
+ &PhyAddr,
+ Map
+ );
+
+ if (!EFI_ERROR (Status)) {
+ *MappedAddr = (UINT8 *) (UINTN) PhyAddr;
+ }
+#else
+ Len = sizeof (EFI_USB_DEVICE_REQUEST);
+ Status = Ohc->PciIo->Map (
+ Ohc->PciIo,
+ EfiPciIoOperationBusMasterRead,
+ Request,
+ &Len,
+ &PhyAddr,
+ Map
+ );
+
+ if (!EFI_ERROR (Status)) {
+ *MappedAddr = (UINT8 *) (UINTN) PhyAddr;
+ }
+#endif
+ return Status;
+}
+
+
+/**
+ Map address of user data buffer.
+
+ @param Ohc The OHCI device.
+ @param Direction Direction of the data transfer.
+ @param Data The user data buffer.
+ @param Len Length of the user data.
+ @param PktId Packet identificaion.
+ @param MappedAddr Mapped address to return.
+ @param Map Identificaion of this mapping to return.
+
+ @return EFI_SUCCESS Success.
+ @return EFI_DEVICE_ERROR Fail to map the user data.
+
+**/
+EFI_STATUS
+OhciMapUserData (
+ IN USB_HC_DEV *Ohc,
+ IN EFI_USB_DATA_DIRECTION Direction,
+ IN VOID *Data,
+ IN OUT UINTN *Len,
+ OUT UINT8 *PktId,
+ OUT UINT8 **MappedAddr,
+ OUT VOID **Map
+ )
+{
+ EFI_STATUS Status;
+ EFI_PHYSICAL_ADDRESS PhyAddr;
+
+ Status = EFI_SUCCESS;
+#if 1
+ switch (Direction) {
+ case EfiUsbDataIn:
+ //
+ // BusMasterWrite means cpu read
+ //
+ *PktId = INPUT_PACKET_ID;
+ Status = Ohc->PciIo->Map (
+ Ohc->PciIo,
+ EfiPciIoOperationBusMasterRead,
+ Data,
+ Len,
+ &PhyAddr,
+ Map
+ );
+
+ if (EFI_ERROR (Status)) {
+ goto EXIT;
+ }
+ DEBUG((EFI_D_INIT, "Read Mapped : %p\n", *Map));
+ *MappedAddr = (UINT8 *) (UINTN) PhyAddr;
+ break;
+
+ case EfiUsbDataOut:
+ *PktId = OUTPUT_PACKET_ID;
+ Status = Ohc->PciIo->Map (
+ Ohc->PciIo,
+ EfiPciIoOperationBusMasterWrite,
+ Data,
+ Len,
+ &PhyAddr,
+ Map
+ );
+
+ if (EFI_ERROR (Status)) {
+ goto EXIT;
+ }
+ DEBUG((EFI_D_INIT, "Write Mapped : %p\n", *Map));
+ *MappedAddr = (UINT8 *) (UINTN) PhyAddr;
+ break;
+
+ case EfiUsbNoData:
+ if ((Len != NULL) && (*Len != 0)) {
+ Status = EFI_INVALID_PARAMETER;
+ goto EXIT;
+ }
+ DEBUG((EFI_D_INIT, "No Mapped : %p\n", *Map));
+ *PktId = OUTPUT_PACKET_ID;
+ *MappedAddr = NULL;
+ *Map = NULL;
+ break;
+
+ default:
+ Status = EFI_INVALID_PARAMETER;
+ }
+#else
+ switch (Direction) {
+ case EfiUsbDataIn:
+ //
+ // BusMasterWrite means cpu read
+ //
+ *PktId = INPUT_PACKET_ID;
+ Status = Ohc->PciIo->Map (
+ Ohc->PciIo,
+ EfiPciIoOperationBusMasterWrite,
+ Data,
+ Len,
+ &PhyAddr,
+ Map
+ );
+
+ if (EFI_ERROR (Status)) {
+ goto EXIT;
+ }
+
+ *MappedAddr = (UINT8 *) (UINTN) PhyAddr;
+ break;
+
+ case EfiUsbDataOut:
+ *PktId = OUTPUT_PACKET_ID;
+ Status = Ohc->PciIo->Map (
+ Ohc->PciIo,
+ EfiPciIoOperationBusMasterRead,
+ Data,
+ Len,
+ &PhyAddr,
+ Map
+ );
+
+ if (EFI_ERROR (Status)) {
+ goto EXIT;
+ }
+
+ *MappedAddr = (UINT8 *) (UINTN) PhyAddr;
+ break;
+
+ case EfiUsbNoData:
+ if ((Len != NULL) && (*Len != 0)) {
+ Status = EFI_INVALID_PARAMETER;
+ goto EXIT;
+ }
+
+ *PktId = OUTPUT_PACKET_ID;
+ *MappedAddr = NULL;
+ *Map = NULL;
+ break;
+
+ default:
+ Status = EFI_INVALID_PARAMETER;
+ }
+#endif
+EXIT:
+ return Status;
+}
+
+
+/**
+ Link the TD To QH.
+
+ @param Ohc The OHCI device.
+ @param Qh The queue head for the TD to link to.
+ @param Td The TD to link.
+
+**/
+VOID
+OhciLinkTdToQh (
+ IN USB_HC_DEV *Ohc,
+ IN OHCI_ED_HW *Ed,
+ IN UINT8 Class
+ )
+{
+#if 1
+ UINT32 cmd;
+
+ if(Class == HC_CLASS_CONTROL) //Controll
+ {
+ /*
+ cmd = OhciReadReg(Ohc, HC_CONTROL_OFFSET);
+ cmd &= ~(1<<5);
+ OhciWriteReg(Ohc, HC_CONTROL_OFFSET, cmd); */
+
+ cmd = OhciReadReg(Ohc, HC_COM_STATUS_OFFSET);
+ cmd |= (1<<1);
+ OhciWriteReg(Ohc, HC_COM_STATUS_OFFSET, cmd);
+
+ OhciWriteReg(Ohc, HC_CTRL_HEADED_OFFSET, Ed);
+
+ cmd = OhciReadReg(Ohc, HC_CONTROL_OFFSET);
+ cmd |= (1<<4);
+ OhciWriteReg(Ohc, HC_CONTROL_OFFSET, cmd);
+ }
+ else//Interrupt
+ {/*
+ cmd = OhciReadReg(Ohc, HC_CONTROL_OFFSET);
+ cmd &= ~(1<<4);
+ OhciWriteReg(Ohc, HC_CONTROL_OFFSET, cmd);
+ */
+ cmd = OhciReadReg(Ohc, HC_COM_STATUS_OFFSET);
+ cmd |= (1<<2);
+ OhciWriteReg(Ohc, HC_COM_STATUS_OFFSET, cmd);
+
+ OhciWriteReg(Ohc, HC_BULK_HEADED_OFFSET, Ed);
+
+ cmd = OhciReadReg(Ohc, HC_CONTROL_OFFSET);
+ cmd |= (1<<5);
+ OhciWriteReg(Ohc, HC_CONTROL_OFFSET, cmd);
+ }
+#else
+ EFI_PHYSICAL_ADDRESS PhyAddr;
+
+ PhyAddr = UsbHcGetPciAddressForHostMem (Ohc->MemPool, Td, sizeof (OHCI_TD_HW));
+
+ ASSERT ((Qh != NULL) && (Td != NULL));
+
+ Qh->QhHw.VerticalLink = QH_VLINK (PhyAddr, FALSE);
+ Qh->TDs = (VOID *) Td;
+#endif
+}
+
+
+/**
+ Unlink TD from the QH.
+
+ @param Qh The queue head to unlink from.
+ @param Td The TD to unlink.
+
+**/
+VOID
+OhciUnlinkTdFromQh (
+ IN OHCI_QH_SW *Qh,
+ IN OHCI_TD_HW *Td
+ )
+{
+#if 1
+#else
+ ASSERT ((Qh != NULL) && (Td != NULL));
+
+ Qh->QhHw.VerticalLink = QH_VLINK (NULL, TRUE);
+ Qh->TDs = NULL;
+#endif
+}
+
+
+/**
+ Append a new TD To the previous TD.
+
+ @param Ohc The OHCI device.
+ @param PrevTd Previous OHCI_TD_HW to be linked to.
+ @param ThisTd TD to link.
+
+**/
+VOID
+OhciAppendTd (
+ IN USB_HC_DEV *Ohc,
+ IN OHCI_TD_HW *PrevTd,
+ IN OHCI_TD_HW *ThisTd
+ )
+{
+ EFI_PHYSICAL_ADDRESS PhyAddr;
+
+ //PhyAddr = UsbHcGetPciAddressForHostMem (Ohc->MemPool, ThisTd, sizeof (OHCI_TD_HW));
+
+ ASSERT ((PrevTd != NULL) && (ThisTd != NULL));
+
+#if 1
+ PrevTd->next_td = (VOID *) ThisTd;
+#else
+ PrevTd->TdHw.NextLink = TD_LINK (PhyAddr, TRUE, FALSE);
+ PrevTd->NextTd = (VOID *) ThisTd;
+#endif
+}
+
+
+/**
+ Delete a list of TDs.
+
+ @param Ohc The OHCI device.
+ @param FirstTd TD link list head.
+
+ @return None.
+
+**/
+VOID
+OhciDestoryTds (
+ IN USB_HC_DEV *Ohc,
+ IN OHCI_TD_SW *FirstTd
+ )
+{
+ OHCI_TD_SW *NextTd;
+ OHCI_TD_SW *ThisTd;
+
+ DEBUG((EFI_D_INIT, "+++OhciDestoryTds()\n"));
+
+ NextTd = FirstTd;
+
+ while (NextTd != NULL) {
+ ThisTd = NextTd;
+ NextTd = ThisTd->NextTd;
+ if(ThisTd->TdHw)
+ {
+ DEBUG((EFI_D_INIT, "Destroy TDHW : %p\n", ThisTd->TdHw));
+ UsbHcFreeMem (Ohc->MemPool, ThisTd->TdHw, sizeof (OHCI_TD_HW));
+ }
+ DEBUG((EFI_D_INIT, "Destroy THSW : %p\n", ThisTd));
+ UsbHcFreeMem (Ohc->MemPool, ThisTd, sizeof (OHCI_TD_SW));
+ }
+
+ DEBUG((EFI_D_INIT, "---OhciDestoryTds()\n"));
+}
+
+
+/**
+ Create an initialize a new queue head.
+
+ @param Ohc The OHCI device.
+ @param Interval The polling interval for the queue.
+
+ @return The newly created queue header.
+
+**/
+OHCI_QH_SW *
+OhciCreateQh (
+ IN USB_HC_DEV *Ohc,
+ IN UINTN Interval
+ )
+{
+ OHCI_QH_SW *Qh;
+#if 1
+#else
+ Qh = UsbHcAllocateMem (Ohc->MemPool, sizeof (OHCI_QH_SW));
+
+ if (Qh == NULL) {
+ return NULL;
+ }
+
+ Qh->QhHw.HorizonLink = QH_HLINK (NULL, TRUE);
+ Qh->QhHw.VerticalLink = QH_VLINK (NULL, TRUE);
+ Qh->Interval = OhciConvertPollRate(Interval);
+ Qh->TDs = NULL;
+ Qh->NextQh = NULL;
+#endif
+ return Qh;
+}
+
+
+/**
+ Create and intialize a TD.
+
+ @param Ohc The OHCI device.
+
+ @return The newly allocated and initialized TD.
+
+**/
+OHCI_TD_HW *
+OhciCreateTd (
+ IN USB_HC_DEV *Ohc
+ )
+{
+ OHCI_TD_HW *Td;
+
+ Td = UsbHcAllocateMem (Ohc->MemPool, sizeof (OHCI_TD_HW));
+ if (Td == NULL) {
+ return NULL;
+ }
+
+ Td->current_buf_ptr = NULL;
+ Td->next_td = NULL;
+ Td->buffer_end = NULL;
+
+ return Td;
+}
+
+
+/**
+ Create and initialize a TD for Setup Stage of a control transfer.
+
+ @param Ohc The OHCI device.
+ @param DevAddr Device address.
+ @param Request A pointer to cpu memory address of Device request.
+ @param RequestPhy A pointer to pci memory address of Device request.
+ @param IsLow Full speed or low speed.
+
+ @return The created setup Td Pointer.
+
+**/
+OHCI_TD_HW *
+OhciCreateSetupTd (
+ IN USB_HC_DEV *Ohc,
+ IN UINT8 DevAddr,
+ IN UINT8 *Request,
+ IN UINT8 *RequestPhy,
+ IN BOOLEAN IsLow
+ )
+{
+ OHCI_TD_HW *Td;
+
+ Td = OhciCreateTd (Ohc);
+
+ if (Td == NULL) {
+ return NULL;
+ }
+#if 1
+ OhcDumpRequest(RequestPhy);
+ DEBUG((EFI_D_INIT, "LowSpeed : %d\n", IsLow));
+
+ Td->gtd_info.data = 0;
+ Td->gtd_info.b.buffer_rounding = 0;
+ Td->gtd_info.b.pid = SETUP_PACKET_ID;
+ Td->gtd_info.b.data_toggle = 2; // DATA0
+ Td->current_buf_ptr = (UINT32)RequestPhy;
+ Td->next_td = NULL;
+ Td->buffer_end = (UINT32)RequestPhy + sizeof (EFI_USB_DEVICE_REQUEST)-1;
+#else
+ Td->TdHw.NextLink = TD_LINK (NULL, TRUE, TRUE);
+ Td->TdHw.ShortPacket = FALSE;
+ Td->TdHw.IsIsoch = FALSE;
+ Td->TdHw.IntOnCpl = FALSE;
+ Td->TdHw.ErrorCount = 0x03;
+ Td->TdHw.Status |= USBTD_ACTIVE;
+ Td->TdHw.DataToggle = 0;
+ Td->TdHw.EndPoint = 0;
+ Td->TdHw.LowSpeed = IsLow ? 1 : 0;
+ Td->TdHw.DeviceAddr = DevAddr & 0x7F;
+ Td->TdHw.MaxPacketLen = (UINT32) (sizeof (EFI_USB_DEVICE_REQUEST) - 1);
+ Td->TdHw.PidCode = SETUP_PACKET_ID;
+ Td->TdHw.DataBuffer = (UINT32) (UINTN) RequestPhy;
+
+ Td->Data = Request;
+ Td->DataLen = (UINT16) sizeof (EFI_USB_DEVICE_REQUEST);
+#endif
+ return Td;
+}
+
+
+/**
+ Create a TD for data.
+
+ @param Ohc The OHCI device.
+ @param DevAddr Device address.
+ @param Endpoint Endpoint number.
+ @param DataPtr A pointer to cpu memory address of Data buffer.
+ @param DataPhyPtr A pointer to pci memory address of Data buffer.
+ @param Len Data length.
+ @param PktId Packet ID.
+ @param Toggle Data toggle value.
+ @param IsLow Full speed or low speed.
+
+ @return Data Td pointer if success, otherwise NULL.
+
+**/
+OHCI_TD_HW *
+OhciCreateDataTd (
+ IN USB_HC_DEV *Ohc,
+ IN UINT8 DevAddr,
+ IN UINT8 Endpoint,
+ IN UINT8 *DataPtr,
+ IN UINT8 *DataPhyPtr,
+ IN UINTN Len,
+ IN UINT8 PktId,
+ IN UINT8 Toggle,
+ IN BOOLEAN IsLow
+ )
+{
+ OHCI_TD_HW *Td;
+
+ //DEBUG((EFI_D_INIT, "+++OhciCreateDataTd(Len : %d)\n", Len));
+
+ //
+ // Code as length - 1, and the max valid length is 0x500
+ //
+ ASSERT (Len <= 0x500);
+
+ Td = OhciCreateTd (Ohc);
+
+ if (Td == NULL) {
+ return NULL;
+ }
+
+#if 1
+ Td->gtd_info.data = 0;
+ Td->gtd_info.b.buffer_rounding = 1; // may be smaller than the defined buffer
+ Td->gtd_info.b.pid = PktId;
+ Td->gtd_info.b.data_toggle = Toggle; // DATA1
+ Td->current_buf_ptr = (UINT32) (UINTN) DataPhyPtr;
+ Td->next_td = NULL;
+ Td->buffer_end = (UINT32) (UINTN) DataPhyPtr + Len-1;
+#else
+ Td->TdHw.NextLink = TD_LINK (NULL, TRUE, TRUE);
+ Td->TdHw.ShortPacket = FALSE;
+ Td->TdHw.IsIsoch = FALSE;
+ Td->TdHw.IntOnCpl = FALSE;
+ Td->TdHw.ErrorCount = 0x03;
+ Td->TdHw.Status = USBTD_ACTIVE;
+ Td->TdHw.LowSpeed = IsLow ? 1 : 0;
+ Td->TdHw.DataToggle = Toggle & 0x01;
+ Td->TdHw.EndPoint = Endpoint & 0x0F;
+ Td->TdHw.DeviceAddr = DevAddr & 0x7F;
+ Td->TdHw.MaxPacketLen = (UINT32) (Len - 1);
+ Td->TdHw.PidCode = (UINT8) PktId;
+ Td->TdHw.DataBuffer = (UINT32) (UINTN) DataPhyPtr;
+
+ Td->Data = DataPtr;
+ Td->DataLen = (UINT16) Len;
+#endif
+
+ //DEBUG((EFI_D_INIT, "---OhciCreateDataTd()\n"));
+
+ return Td;
+}
+
+
+/**
+ Create TD for the Status Stage of control transfer.
+
+ @param Ohc The OHCI device.
+ @param DevAddr Device address.
+ @param PktId Packet ID.
+ @param IsLow Full speed or low speed.
+
+ @return Status Td Pointer.
+
+**/
+OHCI_TD_HW *
+OhciCreateStatusTd (
+ IN USB_HC_DEV *Ohc,
+ IN UINT8 DevAddr,
+ IN UINT8 PktId,
+ IN BOOLEAN IsLow
+ )
+{
+ OHCI_TD_HW *Td;
+
+ Td = OhciCreateTd (Ohc);
+
+ if (Td == NULL) {
+ return NULL;
+ }
+
+#if 1
+ Td->gtd_info.data = 0;
+ Td->gtd_info.b.buffer_rounding = 1; // may be smaller than the defined buffer
+ Td->gtd_info.b.pid = PktId;
+ Td->gtd_info.b.data_toggle = 3; // DATA1
+ Td->current_buf_ptr = 0;
+ Td->next_td = 0;
+ Td->buffer_end = 0;
+#else
+ Td->TdHw.NextLink = TD_LINK (NULL, TRUE, TRUE);
+ Td->TdHw.ShortPacket = FALSE;
+ Td->TdHw.IsIsoch = FALSE;
+ Td->TdHw.IntOnCpl = FALSE;
+ Td->TdHw.ErrorCount = 0x03;
+ Td->TdHw.Status |= USBTD_ACTIVE;
+ Td->TdHw.MaxPacketLen = 0x7FF; //0x7FF: there is no data (refer to OHCI spec)
+ Td->TdHw.DataToggle = 1;
+ Td->TdHw.EndPoint = 0;
+ Td->TdHw.LowSpeed = IsLow ? 1 : 0;
+ Td->TdHw.DeviceAddr = DevAddr & 0x7F;
+ Td->TdHw.PidCode = (UINT8) PktId;
+ Td->TdHw.DataBuffer = (UINT32) (UINTN) NULL;
+
+ Td->Data = NULL;
+ Td->DataLen = 0;
+#endif
+ return Td;
+}
+
+OHCI_ED_HW *
+OhciCreateEd (
+ IN USB_HC_DEV *Ohc,
+ IN UINT8 DeviceAddr,
+ IN UINT32 *QH,
+ IN UINT8 MaxPacket,
+ IN BOOLEAN IsLow
+ )
+{
+ OHCI_ED_HW *Ed;
+
+ Ed = UsbHcAllocateMem (Ohc->MemPool, sizeof (OHCI_ED_HW));
+ if (Ed == NULL) {
+ return NULL;
+ }
+
+ Ed->ed_info.data = 0;
+ Ed->ed_info.b.func_addr = DeviceAddr;
+ Ed->ed_info.b.ep_num = 0;
+ Ed->ed_info.b.direction = 0;
+ Ed->ed_info.b.speed = IsLow?1:0; // speed
+ Ed->ed_info.b.format = 0; // gTD
+ Ed->ed_info.b.mps = MaxPacket;
+ Ed->tail_td_ptr = 0;
+ Ed->head_td_ptr = QH;
+ Ed->next_ed = 0;
+
+ return Ed;
+}
+
+/**
+ Create Tds list for Control Transfer.
+
+ @param Ohc The OHCI device.
+ @param DeviceAddr The device address.
+ @param DataPktId Packet Identification of Data Tds.
+ @param Request A pointer to cpu memory address of request structure buffer to transfer.
+ @param RequestPhy A pointer to pci memory address of request structure buffer to transfer.
+ @param Data A pointer to cpu memory address of user data buffer to transfer.
+ @param DataPhy A pointer to pci memory address of user data buffer to transfer.
+ @param DataLen Length of user data to transfer.
+ @param MaxPacket Maximum packet size for control transfer.
+ @param IsLow Full speed or low speed.
+
+ @return The Td list head for the control transfer.
+
+**/
+OHCI_ED_HW *
+OhciCreateCtrlTds (
+ IN USB_HC_DEV *Ohc,
+ IN UINT8 DeviceAddr,
+ IN UINT8 DataPktId,
+ IN UINT8 *Request,
+ IN UINT8 *RequestPhy,
+ IN UINT8 *Data,
+ IN UINT8 *DataPhy,
+ IN UINTN DataLen,
+ IN UINT8 MaxPacket,
+ IN BOOLEAN IsLow
+ )
+{
+ OHCI_ED_HW *Ed;
+ OHCI_TD_HW *SetupTd;
+ OHCI_TD_HW *FirstDataTd;
+ OHCI_TD_HW *DataTd;
+ OHCI_TD_HW *PrevDataTd;
+ OHCI_TD_HW *StatusTd;
+ UINT8 DataToggle;
+ UINT8 StatusPktId;
+ UINTN ThisTdLen;
+
+
+ DataTd = NULL;
+ SetupTd = NULL;
+ FirstDataTd = NULL;
+ PrevDataTd = NULL;
+ StatusTd = NULL;
+
+ //
+ // Create setup packets for the transfer
+ //
+ SetupTd = OhciCreateSetupTd (Ohc, DeviceAddr, Request, RequestPhy, IsLow);
+
+ if (SetupTd == NULL) {
+ return NULL;
+ }
+
+ //
+ // Create data packets for the transfer
+ //
+ DataToggle = 1;
+ DEBUG((EFI_D_INIT, "Max Len %d, Dat Len ; %d\n", MaxPacket, DataLen));
+ while (DataLen > 0) {
+ //
+ // PktSize is the data load size in each Td.
+ //
+ ThisTdLen = (DataLen > MaxPacket ? MaxPacket : DataLen);
+
+ DataTd = OhciCreateDataTd (
+ Ohc,
+ DeviceAddr,
+ 0,
+ Data, //cpu memory address
+ DataPhy, //Pci memory address
+ ThisTdLen,
+ DataPktId,
+ (DataToggle + 2),
+ IsLow
+ );
+
+ if (DataTd == NULL) {
+ goto FREE_TD;
+ }
+
+ if (FirstDataTd == NULL) {
+ FirstDataTd = DataTd;
+ FirstDataTd->next_td = NULL;
+ } else {
+ OhciAppendTd (Ohc, PrevDataTd, DataTd);
+ }
+
+ DataToggle ^= 1;
+ PrevDataTd = DataTd;
+ Data += ThisTdLen;
+ DataPhy += ThisTdLen;
+ DataLen -= ThisTdLen;
+ }
+
+ //
+ // Status packet is on the opposite direction to data packets
+ //
+ if (OUTPUT_PACKET_ID == DataPktId) {
+ StatusPktId = INPUT_PACKET_ID;
+ } else {
+ StatusPktId = OUTPUT_PACKET_ID;
+ }
+
+ StatusTd = OhciCreateStatusTd (Ohc, DeviceAddr, StatusPktId, IsLow);
+
+ if (StatusTd == NULL) {
+ DEBUG((EFI_D_ERROR, "FAIL! OhciCreateStatusTd\n"));
+ goto FREE_TD;
+ }
+
+ //
+ // Link setup Td -> data Tds -> status Td together
+ //
+ if (FirstDataTd != NULL) {
+ OhciAppendTd (Ohc, SetupTd, FirstDataTd);
+ OhciAppendTd (Ohc, PrevDataTd, StatusTd);
+ } else {
+ OhciAppendTd (Ohc, SetupTd, StatusTd);
+ }
+
+ //iky
+
+ Ed = Ohc->EdHw[0];
+ Ed->ed_info.data = 0;
+ Ed->ed_info.b.func_addr = DeviceAddr;
+ Ed->ed_info.b.ep_num = 0;
+ Ed->ed_info.b.direction = 0;
+ Ed->ed_info.b.speed = IsLow?1:0; // speed
+ Ed->ed_info.b.format = 0; // gTD
+ Ed->ed_info.b.mps = MaxPacket;
+ Ed->tail_td_ptr = 0;
+ Ed->head_td_ptr = SetupTd;
+ Ed->next_ed = 0;
+
+ Ohc->LastTd = StatusTd;
+
+ return Ed;
+
+FREE_TD:
+ if (SetupTd != NULL) {
+ OhciDestoryTds (Ohc, SetupTd);
+ }
+
+ if (FirstDataTd != NULL) {
+ OhciDestoryTds (Ohc, FirstDataTd);
+ }
+
+ return NULL;
+}
+
+
+/**
+ Create Tds list for Bulk/Interrupt Transfer.
+
+ @param Ohc USB_HC_DEV.
+ @param DevAddr Address of Device.
+ @param EndPoint Endpoint Number.
+ @param PktId Packet Identification of Data Tds.
+ @param Data A pointer to cpu memory address of user data buffer to transfer.
+ @param DataPhy A pointer to pci memory address of user data buffer to transfer.
+ @param DataLen Length of user data to transfer.
+ @param DataToggle Data Toggle Pointer.
+ @param MaxPacket Maximum packet size for Bulk/Interrupt transfer.
+ @param IsLow Is Low Speed Device.
+
+ @return The Tds list head for the bulk transfer.
+
+**/
+OHCI_TD_HW *
+OhciCreateBulkOrIntTds (
+ IN USB_HC_DEV *Ohc,
+ IN UINT8 DevAddr,
+ IN UINT8 EndPoint,
+ IN UINT8 PktId,
+ IN UINT8 *Data,
+ IN UINT8 *DataPhy,
+ IN UINTN DataLen,
+ IN OUT UINT8 *DataToggle,
+ IN UINT8 MaxPacket,
+ IN BOOLEAN IsLow
+ )
+{
+ OHCI_ED_HW *Ed;
+ OHCI_TD_HW *DataTd;
+ OHCI_TD_HW *FirstDataTd;
+ OHCI_TD_HW *PrevDataTd;
+ UINTN ThisTdLen;
+ UINT8 EP;
+#if 1
+ EP = EndPoint >> 7;
+ DEBUG((EFI_D_INIT, "+++OhciCreateBulkOrIntTds(EP%d : %p)\n", EP, Ohc->EdHw[EP]));
+
+ DataTd = NULL;
+ FirstDataTd = NULL;
+ PrevDataTd = NULL;
+ //
+ // Create data packets for the transfer
+ //
+ while (DataLen > 0) {
+ //
+ // PktSize is the data load size that each Td.
+ //
+ ThisTdLen = DataLen;
+
+ if (DataLen > MaxPacket) {
+ ThisTdLen = MaxPacket;
+ }
+
+ DataTd = OhciCreateDataTd (
+ Ohc,
+ DevAddr,
+ EndPoint,
+ Data,
+ DataPhy,
+ ThisTdLen,
+ PktId,
+ (*DataToggle + 2),
+ IsLow
+ );
+
+ if (DataTd == NULL) {
+ DEBUG((EFI_D_ERROR, "FAIL! OhciCreateDataTd\n"));
+ goto FREE_TD;
+ }
+/*
+ if (PktId == INPUT_PACKET_ID) {
+ DataTd->gtd_info.b.buffer_rounding = 1;
+ }
+*/
+ if (FirstDataTd == NULL) {
+ FirstDataTd = DataTd;
+ FirstDataTd->next_td = NULL;
+ } else {
+ OhciAppendTd (Ohc, PrevDataTd, DataTd);
+ }
+
+ *DataToggle ^= 1;
+ PrevDataTd = DataTd;
+ Data += ThisTdLen;
+ DataPhy += ThisTdLen;
+ DataLen -= ThisTdLen;
+ }
+
+ Ed = Ohc->EdHw[EP];
+ Ed->ed_info.data = 0;
+ Ed->ed_info.b.func_addr = DevAddr;
+ Ed->ed_info.b.ep_num = EP;
+ Ed->ed_info.b.direction = 0; //IN DIRECTION
+ Ed->ed_info.b.speed = IsLow?1:0; // speed
+ Ed->ed_info.b.format = 0; // gTD
+ Ed->ed_info.b.mps = MaxPacket;
+ Ed->tail_td_ptr = 0;
+ Ed->head_td_ptr = FirstDataTd;
+ Ed->next_ed = 0;
+
+ Ohc->LastTd = PrevDataTd;
+
+ DEBUG((EFI_D_INIT, "---OhciCreateBulkOrIntTds()\n"));
+
+ return Ed;
+
+FREE_TD:
+ if (FirstDataTd != NULL) {
+ OhciDestoryTds (Ohc, FirstDataTd);
+ }
+
+ return NULL;
+#else
+ DataTd = NULL;
+ FirstDataTd = NULL;
+ PrevDataTd = NULL;
+
+ //
+ // Create data packets for the transfer
+ //
+ while (DataLen > 0) {
+ //
+ // PktSize is the data load size that each Td.
+ //
+ ThisTdLen = DataLen;
+
+ if (DataLen > MaxPacket) {
+ ThisTdLen = MaxPacket;
+ }
+
+ DataTd = OhciCreateDataTd (
+ Ohc,
+ DevAddr,
+ EndPoint,
+ Data,
+ DataPhy,
+ ThisTdLen,
+ PktId,
+ *DataToggle,
+ IsLow
+ );
+
+ if (DataTd == NULL) {
+ goto FREE_TD;
+ }
+
+ if (PktId == INPUT_PACKET_ID) {
+ DataTd->TdHw.ShortPacket = TRUE;
+ }
+
+ if (FirstDataTd == NULL) {
+ FirstDataTd = DataTd;
+ FirstDataTd->NextTd = NULL;
+ } else {
+ OhciAppendTd (Ohc, PrevDataTd, DataTd);
+ }
+
+ *DataToggle ^= 1;
+ PrevDataTd = DataTd;
+ Data += ThisTdLen;
+ DataPhy += ThisTdLen;
+ DataLen -= ThisTdLen;
+ }
+
+ return FirstDataTd;
+
+FREE_TD:
+ if (FirstDataTd != NULL) {
+ OhciDestoryTds (Ohc, FirstDataTd);
+ }
+#endif
+}
diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/OhciDxe/OhciQueue.h b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/OhciDxe/OhciQueue.h
new file mode 100644
index 000000000..8c22c95e6
--- /dev/null
+++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/OhciDxe/OhciQueue.h
@@ -0,0 +1,395 @@
+/** @file
+
+ The definition for OHCI register operation routines.
+
+Copyright (c) 2007, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _EFI_OHCI_QUEUE_H_
+#define _EFI_OHCI_QUEUE_H_
+
+#if 1
+//==================================================================
+// data structure
+//
+// <OHCI>
+//
+
+typedef union
+{
+ UINT32 data;
+ struct {
+ // bit[6:0] : function address
+ unsigned func_addr : 7;
+ // bit[10:7] : endpoint number
+ unsigned ep_num : 4;
+ // bit[12:11] : direction
+ unsigned direction : 2;
+ // bit[13] : speed
+ unsigned speed : 1;
+ // bit[14] : skip (1->skip this ED)
+ unsigned skip : 1;
+ // bit[15] : format (0->gTD, 1->isoTD)
+ unsigned format : 1;
+ // bit[26:16] : maximum packet size
+ unsigned mps : 11;
+ // bit[31:27] :
+ unsigned reserved31_27 : 5;
+ }b;
+}ed_info_t;
+
+typedef struct
+{
+ ed_info_t ed_info;
+ UINT32 tail_td_ptr;
+ UINT32 head_td_ptr;
+ UINT32 next_ed;
+} OHCI_ED_HW;
+
+typedef union
+{
+ UINT32 data;
+ struct {
+ // bit[17:0] :
+ unsigned reserved17_0 : 18;
+ // bit[18] : buffer rounding (0->exactly fill the defined buffer, 1->may be smaller than the defined buffer)
+ unsigned buffer_rounding : 1;
+ // bit[20:19] : pid (0->setup, 1->out, 2->in, 3->reserved)
+ unsigned pid : 2;
+ // bit[23:21] : delay interrupt
+ unsigned delay_interrupt : 3;
+ // bit[25:24] : data toggle
+ unsigned data_toggle : 2;
+ // bit[27:26] : error count
+ unsigned error_count : 2;
+ // bit[31:28] : condition code
+ unsigned condition_code : 4;
+ }b;
+}gtd_info_t;
+
+typedef struct
+{
+ gtd_info_t gtd_info;
+ UINT32 current_buf_ptr;
+ UINT32 next_td;
+ UINT32 buffer_end;
+} OHCI_TD_HW;
+
+typedef struct _OHCI_TD_SW OHCI_TD_SW;
+
+struct _OHCI_TD_SW{
+ OHCI_TD_HW *TdHw;
+ OHCI_TD_SW *NextTd;
+ UINT32 *Data;
+ UINT32 DataLen;
+};
+
+struct _OHCI_HCCA {
+#define NUM_INTS 32
+ UINT32 int_table [NUM_INTS]; /* periodic schedule */
+
+ /*
+ * OHCI defines u16 frame_no, followed by u16 zero pad.
+ * Since some processors can't do 16 bit bus accesses,
+ * portable access must be a 32 bits wide.
+ */
+ UINT32 frame_no; /* current frame number */
+ UINT32 done_head; /* info returned for an interrupt */
+ UINT8 reserved_for_hc [116];
+ UINT8 what [4]; /* spec only identifies 252 bytes :) */
+} __attribute__ ((aligned(256)));
+
+typedef struct _OHCI_HCCA OHCI_HCCA;
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+typedef struct {
+ UINT32 HorizonLink;
+ UINT32 VerticalLink;
+} OHCI_QH_HW;
+
+typedef struct _OHCI_QH_SW OHCI_QH_SW;
+
+struct _OHCI_QH_SW {
+ OHCI_QH_HW QhHw;
+ OHCI_QH_SW *NextQh;
+ OHCI_TD_HW *TDs;
+ UINTN Interval;
+};
+#else
+//
+// Macroes used to set various links in OHCI's driver.
+// In this OHCI driver, QH's horizontal link always pointers to other QH,
+// and its vertical link always pointers to TD. TD's next pointer always
+// pointers to other sibling TD. Frame link always pointers to QH because
+// ISO transfer isn't supported.
+//
+// We should use UINT32 to access these pointers to void race conditions
+// with hardware.
+//
+#define QH_HLINK(Pointer, Terminate) \
+ (((UINT32) ((UINTN) (Pointer)) & 0xFFFFFFF0) | 0x02 | ((Terminate) ? 0x01 : 0))
+
+#define QH_VLINK(Pointer, Terminate) \
+ (((UINT32) ((UINTN) (Pointer)) & 0xFFFFFFF0) | ((Terminate) ? 0x01 : 0))
+
+#define TD_LINK(Pointer, VertFirst, Terminate) \
+ (((UINT32) ((UINTN) (Pointer)) & 0xFFFFFFF0) | \
+ ((VertFirst) ? 0x04 : 0) | ((Terminate) ? 0x01 : 0))
+
+#define LINK_TERMINATED(Link) (((Link) & 0x01) != 0)
+
+#define OHCI_ADDR(QhOrTd) ((VOID *) (UINTN) ((QhOrTd) & 0xFFFFFFF0))
+
+#pragma pack(1)
+//
+// Both links in QH has this internal structure:
+// Next pointer: 28, Reserved: 2, NextIsQh: 1, Terminate: 1
+// This is the same as frame list entry.
+//
+typedef struct {
+ UINT32 HorizonLink;
+ UINT32 VerticalLink;
+} OHCI_QH_HW;
+
+//
+// Next link in TD has this internal structure:
+// Next pointer: 28, Reserved: 1, Vertical First: 1, NextIsQh: 1, Terminate: 1
+//
+typedef struct {
+ UINT32 NextLink;
+ UINT32 ActualLen : 11;
+ UINT32 Reserved1 : 5;
+ UINT32 Status : 8;
+ UINT32 IntOnCpl : 1;
+ UINT32 IsIsoch : 1;
+ UINT32 LowSpeed : 1;
+ UINT32 ErrorCount : 2;
+ UINT32 ShortPacket : 1;
+ UINT32 Reserved2 : 2;
+ UINT32 PidCode : 8;
+ UINT32 DeviceAddr : 7;
+ UINT32 EndPoint : 4;
+ UINT32 DataToggle : 1;
+ UINT32 Reserved3 : 1;
+ UINT32 MaxPacketLen: 11;
+ UINT32 DataBuffer;
+} OHCI_TD_HW;
+#pragma pack()
+
+typedef struct _OHCI_TD_SW OHCI_TD_SW;
+typedef struct _OHCI_QH_SW OHCI_QH_SW;
+
+struct _OHCI_QH_SW {
+ OHCI_QH_HW QhHw;
+ OHCI_QH_SW *NextQh;
+ OHCI_TD_SW *TDs;
+ UINTN Interval;
+};
+
+struct _OHCI_TD_SW {
+ OHCI_TD_HW TdHw;
+ OHCI_TD_SW *NextTd;
+ UINT8 *Data;
+ UINT16 DataLen;
+};
+#endif
+
+/**
+ Link the TD To QH.
+
+ @param Ohc The OHCI device.
+ @param Qh The queue head for the TD to link to.
+ @param Td The TD to link.
+
+**/
+VOID
+OhciLinkTdToQh (
+ IN USB_HC_DEV *Ohc,
+ IN OHCI_ED_HW *Ed,
+ IN UINT8 Class
+ );
+
+
+/**
+ Unlink TD from the QH.
+
+ @param Qh The queue head to unlink from.
+ @param Td The TD to unlink.
+
+ @return None.
+
+**/
+VOID
+OhciUnlinkTdFromQh (
+ IN OHCI_QH_SW *Qh,
+ IN OHCI_TD_HW *Td
+ );
+
+/**
+ Map address of request structure buffer.
+
+ @param Ohc The OHCI device.
+ @param Request The user request buffer.
+ @param MappedAddr Mapped address of request.
+ @param Map Identificaion of this mapping to return.
+
+ @return EFI_SUCCESS Success.
+ @return EFI_DEVICE_ERROR Fail to map the user request.
+
+**/
+EFI_STATUS
+OhciMapUserRequest (
+ IN USB_HC_DEV *Ohc,
+ IN OUT VOID *Request,
+ OUT UINT8 **MappedAddr,
+ OUT VOID **Map
+ );
+
+
+/**
+ Map address of user data buffer.
+
+ @param Ohc The OHCI device.
+ @param Direction Direction of the data transfer.
+ @param Data The user data buffer.
+ @param Len Length of the user data.
+ @param PktId Packet identificaion.
+ @param MappedAddr Mapped address to return.
+ @param Map Identificaion of this mapping to return.
+
+ @return EFI_SUCCESS Success.
+ @return EFI_DEVICE_ERROR Fail to map the user data.
+
+**/
+EFI_STATUS
+OhciMapUserData (
+ IN USB_HC_DEV *Ohc,
+ IN EFI_USB_DATA_DIRECTION Direction,
+ IN VOID *Data,
+ IN OUT UINTN *Len,
+ OUT UINT8 *PktId,
+ OUT UINT8 **MappedAddr,
+ OUT VOID **Map
+ );
+
+
+/**
+ Delete a list of TDs.
+
+ @param Ohc The OHCI device.
+ @param FirstTd TD link list head.
+
+ @return None.
+
+**/
+VOID
+OhciDestoryTds (
+ IN USB_HC_DEV *Ohc,
+ IN OHCI_TD_SW *FirstTd
+ );
+
+
+/**
+ Create an initialize a new queue head.
+
+ @param Ohc The OHCI device.
+ @param Interval The polling interval for the queue.
+
+ @return The newly created queue header.
+
+**/
+OHCI_QH_SW *
+OhciCreateQh (
+ IN USB_HC_DEV *Ohc,
+ IN UINTN Interval
+ );
+
+
+/**
+ Create Tds list for Control Transfer.
+
+ @param Ohc The OHCI device.
+ @param DeviceAddr The device address.
+ @param DataPktId Packet Identification of Data Tds.
+ @param Request A pointer to cpu memory address of request structure buffer to transfer.
+ @param RequestPhy A pointer to pci memory address of request structure buffer to transfer.
+ @param Data A pointer to cpu memory address of user data buffer to transfer.
+ @param DataPhy A pointer to pci memory address of user data buffer to transfer.
+ @param DataLen Length of user data to transfer.
+ @param MaxPacket Maximum packet size for control transfer.
+ @param IsLow Full speed or low speed.
+
+ @return The Td list head for the control transfer.
+
+**/
+OHCI_ED_HW *
+OhciCreateCtrlTds (
+ IN USB_HC_DEV *Ohc,
+ IN UINT8 DeviceAddr,
+ IN UINT8 DataPktId,
+ IN UINT8 *Request,
+ IN UINT8 *RequestPhy,
+ IN UINT8 *Data,
+ IN UINT8 *DataPhy,
+ IN UINTN DataLen,
+ IN UINT8 MaxPacket,
+ IN BOOLEAN IsLow
+ );
+
+
+/**
+ Create Tds list for Bulk/Interrupt Transfer.
+
+ @param Ohc USB_HC_DEV.
+ @param DevAddr Address of Device.
+ @param EndPoint Endpoint Number.
+ @param PktId Packet Identification of Data Tds.
+ @param Data A pointer to cpu memory address of user data buffer to transfer.
+ @param DataPhy A pointer to pci memory address of user data buffer to transfer.
+ @param DataLen Length of user data to transfer.
+ @param DataToggle Data Toggle Pointer.
+ @param MaxPacket Maximum packet size for Bulk/Interrupt transfer.
+ @param IsLow Is Low Speed Device.
+
+ @return The Tds list head for the bulk transfer.
+
+**/
+OHCI_TD_HW *
+OhciCreateBulkOrIntTds (
+ IN USB_HC_DEV *Ohc,
+ IN UINT8 DevAddr,
+ IN UINT8 EndPoint,
+ IN UINT8 PktId,
+ IN UINT8 *Data,
+ IN UINT8 *DataPhy,
+ IN UINTN DataLen,
+ IN OUT UINT8 *DataToggle,
+ IN UINT8 MaxPacket,
+ IN BOOLEAN IsLow
+ );
+
+#endif
diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/OhciDxe/OhciReg.c b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/OhciDxe/OhciReg.c
new file mode 100644
index 000000000..29879027e
--- /dev/null
+++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/OhciDxe/OhciReg.c
@@ -0,0 +1,292 @@
+/** @file
+
+ The OHCI register operation routines.
+
+Copyright (c) 2007, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "Ohci.h"
+
+
+/**
+ Read a OHCI register.
+
+ @param PciIo The EFI_PCI_IO_PROTOCOL to use.
+ @param Offset Register offset to USB_BAR_INDEX.
+
+ @return Content of register.
+
+**/
+UINT32
+OhciReadReg (
+ IN USB_HC_DEV *Ohc,
+ IN UINT32 Offset
+ )
+{
+ UINT32 Data;
+ EFI_STATUS Status;
+
+ Status = Ohc->PciIo->Mem.Read (
+ Ohc->PciIo,
+ EfiPciIoWidthUint32,
+ OHC_BAR_INDEX,
+ (UINT64) (Offset),
+ 1,
+ &Data
+ );
+
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "OhcReadOpReg: Pci Io Read error - %r at %d\n", Status, Offset));
+ Data = 0xFFFF;
+ }
+
+ return Data;
+}
+
+
+/**
+ Write data to OHCI register.
+
+ @param PciIo The EFI_PCI_IO_PROTOCOL to use.
+ @param Offset Register offset to USB_BAR_INDEX.
+ @param Data Data to write.
+
+**/
+VOID
+OhciWriteReg (
+ IN USB_HC_DEV *Ohc,
+ IN UINT32 Offset,
+ IN UINT32 Data
+ )
+{
+ EFI_STATUS Status;
+
+ Status = Ohc->PciIo->Mem.Write (
+ Ohc->PciIo,
+ EfiPciIoWidthUint32,
+ OHC_BAR_INDEX,
+ (UINT64) (Offset),
+ 1,
+ &Data
+ );
+
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "OhcWriteOpReg: Pci Io Write error: %r at %d\n", Status, Offset));
+ }
+}
+
+
+/**
+ Set a bit of the OHCI Register.
+
+ @param PciIo The EFI_PCI_IO_PROTOCOL to use.
+ @param Offset Register offset to USB_BAR_INDEX.
+ @param Bit The bit to set.
+
+**/
+VOID
+OhciSetRegBit (
+ IN USB_HC_DEV *Ohc,
+ IN UINT32 Offset,
+ IN UINT16 Bit
+ )
+{
+ UINT16 Data;
+
+ Data = OhciReadReg (Ohc, Offset);
+ Data = (UINT16) (Data |Bit);
+ OhciWriteReg (Ohc, Offset, Data);
+}
+
+
+/**
+ Clear a bit of the OHCI Register.
+
+ @param PciIo The PCI_IO protocol to access the PCI.
+ @param Offset Register offset to USB_BAR_INDEX.
+ @param Bit The bit to clear.
+
+**/
+VOID
+OhciClearRegBit (
+ IN USB_HC_DEV *Ohc,
+ IN UINT32 Offset,
+ IN UINT16 Bit
+ )
+{
+ UINT16 Data;
+
+ Data = OhciReadReg (Ohc, Offset);
+ Data = (UINT16) (Data & ~Bit);
+ OhciWriteReg (Ohc, Offset, Data);
+}
+
+
+/**
+ Clear all the interrutp status bits, these bits
+ are Write-Clean.
+
+ @param Ohc The OHCI device.
+
+**/
+VOID
+OhciAckAllInterrupt (
+ IN USB_HC_DEV *Ohc
+ )
+{
+ //OhciWriteReg (Ohc, USBSTS_OFFSET, 0x3F);
+
+ //
+ // If current HC is halted, re-enable it. Host Controller Process Error
+ // is a temporary error status.
+ //
+ if (!OhciIsHcWorking (Ohc)) {
+ DEBUG ((EFI_D_ERROR, "OhciAckAllInterrupt: re-enable the OHCI from system error\n"));
+ Ohc->Usb2Hc.SetState (&Ohc->Usb2Hc, EfiUsbHcStateOperational);
+ }
+}
+
+
+/**
+ Stop the host controller.
+
+ @param Ohc The OHCI device.
+ @param Timeout Max time allowed.
+
+ @retval EFI_SUCCESS The host controller is stopped.
+ @retval EFI_TIMEOUT Failed to stop the host controller.
+
+**/
+EFI_STATUS
+OhciStopHc (
+ IN USB_HC_DEV *Ohc,
+ IN UINTN Timeout
+ )
+{
+#if 1
+/*
+ UINT32 UsbCtr;
+ UsbCtr = OhciReadReg(Ohc, HC_CONTROL_OFFSET);
+ UsbCtr &= (1<<9); //all except of RWC is clear
+ OhciWriteReg(Ohc, HC_CONTROL_OFFSET, UsbCtr);
+*/
+ return EFI_SUCCESS;
+#else
+ UINT16 UsbSts;
+ UINTN Index;
+ OhciClearRegBit (Ohc, USBCMD_OFFSET, USBCMD_RS);
+
+ //
+ // ensure the HC is in halt status after send the stop command
+ // Timeout is in us unit.
+ //
+ for (Index = 0; Index < (Timeout / 50) + 1; Index++) {
+ UsbSts = OhciReadReg (Ohc, USBSTS_OFFSET);
+
+ if ((UsbSts & USBSTS_HCH) == USBSTS_HCH) {
+ return EFI_SUCCESS;
+ }
+
+ gBS->Stall (50);
+ }
+
+ return EFI_TIMEOUT;
+#endif
+}
+
+
+/**
+ Check whether the host controller operates well.
+
+ @param PciIo The PCI_IO protocol to use.
+
+ @retval TRUE Host controller is working.
+ @retval FALSE Host controller is halted or system error.
+
+**/
+BOOLEAN
+OhciIsHcWorking (
+ IN USB_HC_DEV *Ohc
+ )
+{
+ UINT16 UsbSts;
+ /*
+ UsbSts = OhciReadReg (Ohc, USBSTS_OFFSET);
+
+ if ((UsbSts & (USBSTS_HCPE | USBSTS_HSE | USBSTS_HCH)) != 0) {
+ DEBUG ((EFI_D_ERROR, "OhciIsHcWorking: current USB state is %x\n", UsbSts));
+ return FALSE;
+ }
+ */
+ return TRUE;
+}
+
+
+/**
+ Set the OHCI frame list base address. It can't use
+ OhciWriteReg which access memory in UINT16.
+
+ @param PciIo The EFI_PCI_IO_PROTOCOL to use.
+ @param Addr Address to set.
+
+**/
+/*
+VOID
+OhciSetFrameListBaseAddr (
+ IN USB_HC_DEV *Ohc,
+ IN VOID *Addr
+ )
+{
+ EFI_STATUS Status;
+ UINT32 Data;
+
+ Data = (UINT32) ((UINTN) Addr & 0xFFFFF000);
+
+ Status = PciIo->Io.Write (
+ PciIo,
+ EfiPciIoWidthUint32,
+ USB_BAR_INDEX,
+ (UINT64) USB_FRAME_BASE_OFFSET,
+ 1,
+ &Data
+ );
+
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "OhciSetFrameListBaseAddr: PciIo Io.Write error: %r\n", Status));
+ }
+}
+*/
+
+/**
+ Disable USB Emulation.
+
+ @param PciIo The EFI_PCI_IO_PROTOCOL protocol to use.
+
+**/
+
+/*
+VOID
+OhciTurnOffUsbEmulation (
+ IN EFI_PCI_IO_PROTOCOL *PciIo
+ )
+{
+ UINT16 Command;
+
+ Command = 0;
+
+ PciIo->Pci.Write (
+ PciIo,
+ EfiPciIoWidthUint16,
+ USB_EMULATION_OFFSET,
+ 1,
+ &Command
+ );
+}*/
diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/OhciDxe/OhciReg.h b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/OhciDxe/OhciReg.h
new file mode 100644
index 000000000..729720e98
--- /dev/null
+++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/OhciDxe/OhciReg.h
@@ -0,0 +1,286 @@
+/** @file
+
+ The definition for OHCI register operation routines.
+
+Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _EFI_OHCI_REG_H_
+#define _EFI_OHCI_REG_H_
+
+//
+// OHCI register offset
+//
+
+#define OHCI_FRAME_NUM 1024
+
+//
+// Register offset and PCI related staff
+//
+#define USB_BAR_INDEX 4
+
+#define USBCMD_OFFSET 0
+#define USBSTS_OFFSET 2
+#define USBINTR_OFFSET 4
+//#define HC_PORT_STATUS_OFFSET 0x10
+#define USB_FRAME_NO_OFFSET 6
+#define USB_FRAME_BASE_OFFSET 8
+#define USB_EMULATION_OFFSET 0xC0
+
+// Register offset for OHCI
+#define INC4(a) ((a)+4)
+#define HC_REVISION_OFFSET 0x0
+#define HC_CONTROL_OFFSET INC4(HC_REVISION_OFFSET)
+#define HC_COM_STATUS_OFFSET INC4(HC_CONTROL_OFFSET)
+#define HC_INT_STATUS_OFFSET INC4(HC_COM_STATUS_OFFSET)
+#define HC_INT_ENABLE_OFFSET INC4(HC_INT_STATUS_OFFSET)
+#define HC_INT_DISABLE_OFFSET INC4(HC_INT_ENABLE_OFFSET)
+#define HC_HCCA_OFFSET INC4(HC_INT_DISABLE_OFFSET)
+#define HC_PERIOD_CUTTENTED_OFFSET INC4(HC_HCCA_OFFSET)
+
+
+#define HC_PRID_HEADED_OFFSET 0x40
+#define HC_PRID_CURRED_OFFSET 0x1C
+#define HC_CTRL_HEADED_OFFSET 0x20
+#define HC_CTRL_CURRED_OFFSET 0x24
+#define HC_BULK_HEADED_OFFSET 0x28
+#define HC_BULK_CURRED_OFFSET 0x2C
+
+#define HC_FMINTERVAL_OFFSET 0x34
+#define HC_RH_DESCRIPTORA_OFFSET 0x48
+#define HC_RH_DESCRIPTORB_OFFSET 0x4C
+#define HC_RH_STATUS_OFFSET 0x50
+#define HC_PORT_STATUS_OFFSET 0x54
+
+
+#define HC_CLASS_CONTROL 0
+#define HC_CLASS_INTERRUPT 1
+
+//
+// Packet IDs
+//
+#define SETUP_PACKET_ID 0x0
+#define OUTPUT_PACKET_ID 0x1
+#define INPUT_PACKET_ID 0x2
+#define ERROR_PACKET_ID 0x3
+
+//
+// USB port status and control bit definition.
+//
+#define USBPORTSC_CCS BIT0 // Current Connect Status
+#define USBPORTSC_PED BIT1 // Port Enable / Disable
+#define USBPORTSC_SUSP BIT2 // Suspend
+#define USBPORTSC_POCI BIT3 // OVER CURRNET INDICATOR
+#define USBPORTSC_PR BIT4 // Port Reset
+
+#define USBPORTSC_PPS BIT8 // Port Power
+#define USBPORTSC_LSDA BIT9 // Low Speed Device Attached
+
+#define USBPORTSC_CSC BIT16 // Connect Status Change
+#define USBPORTSC_PEDC BIT17 // Enable Change
+#define USBPORTSC_PSSC BIT18 // Suspend Change
+#define USBPORTSC_OCIC BIT19 // Over Currnet Change
+#define USBPORTSC_PRSC BIT20 // Reset Change
+
+
+
+
+
+//
+// OHCI Spec said it must implement 2 ports each host at least,
+// and if more, check whether the bit7 of PORTSC is always 1.
+// So here assume the max of port number each host is 16.
+//
+#define USB_MAX_ROOTHUB_PORT 0x0F
+
+//
+// Command register bit definitions
+//
+#define USBCMD_RS BIT0 // Run/Stop
+#define USBCMD_HCRESET BIT1 // Host reset
+#define USBCMD_GRESET BIT2 // Global reset
+#define USBCMD_EGSM BIT3 // Global Suspend Mode
+#define USBCMD_FGR BIT4 // Force Global Resume
+#define USBCMD_SWDBG BIT5 // SW Debug mode
+#define USBCMD_CF BIT6 // Config Flag (sw only)
+#define USBCMD_MAXP BIT7 // Max Packet (0 = 32, 1 = 64)
+
+//
+// USB Status register bit definitions
+//
+#define USBSTS_USBINT BIT0 // Interrupt due to IOC
+#define USBSTS_ERROR BIT1 // Interrupt due to error
+#define USBSTS_RD BIT2 // Resume Detect
+#define USBSTS_HSE BIT3 // Host System Error
+#define USBSTS_HCPE BIT4 // Host Controller Process Error
+#define USBSTS_HCH BIT5 // HC Halted
+
+#define USBTD_ACTIVE BIT7 // TD is still active
+#define USBTD_STALLED BIT6 // TD is stalled
+#define USBTD_BUFFERR BIT5 // Buffer underflow or overflow
+#define USBTD_BABBLE BIT4 // Babble condition
+#define USBTD_NAK BIT3 // NAK is received
+#define USBTD_CRC BIT2 // CRC/Time out error
+#define USBTD_BITSTUFF BIT1 // Bit stuff error
+
+#define OHC_BAR_INDEX 0 // how many bytes away from USB_BASE to 0x10
+
+/**
+ Read a OHCI register.
+
+ @param PciIo The EFI_PCI_IO_PROTOCOL to use.
+ @param Offset Register offset to USB_BAR_INDEX.
+
+ @return Content of register.
+
+**/
+UINT32
+OhciReadReg (
+ IN USB_HC_DEV *Ohc,
+ IN UINT32 Offset
+ );
+
+
+
+/**
+ Write data to OHCI register.
+
+ @param PciIo The EFI_PCI_IO_PROTOCOL to use.
+ @param Offset Register offset to USB_BAR_INDEX.
+ @param Data Data to write.
+
+ @return None.
+
+**/
+VOID
+OhciWriteReg (
+ IN USB_HC_DEV *Ohc,
+ IN UINT32 Offset,
+ IN UINT32 Data
+ );
+
+
+
+/**
+ Set a bit of the OHCI Register.
+
+ @param PciIo The EFI_PCI_IO_PROTOCOL to use.
+ @param Offset Register offset to USB_BAR_INDEX.
+ @param Bit The bit to set.
+
+ @return None.
+
+**/
+VOID
+OhciSetRegBit (
+ IN USB_HC_DEV *Ohc,
+ IN UINT32 Offset,
+ IN UINT16 Bit
+ );
+
+
+
+/**
+ Clear a bit of the OHCI Register.
+
+ @param PciIo The PCI_IO protocol to access the PCI.
+ @param Offset Register offset to USB_BAR_INDEX.
+ @param Bit The bit to clear.
+
+ @return None.
+
+**/
+VOID
+OhciClearRegBit (
+ IN USB_HC_DEV *Ohc,
+ IN UINT32 Offset,
+ IN UINT16 Bit
+ );
+
+
+/**
+ Clear all the interrutp status bits, these bits
+ are Write-Clean.
+
+ @param Ohc The OHCI device.
+
+ @return None.
+
+**/
+VOID
+OhciAckAllInterrupt (
+ IN USB_HC_DEV *Ohc
+ );
+
+
+/**
+ Stop the host controller.
+
+ @param Ohc The OHCI device.
+ @param Timeout Max time allowed.
+
+ @retval EFI_SUCCESS The host controller is stopped.
+ @retval EFI_TIMEOUT Failed to stop the host controller.
+
+**/
+EFI_STATUS
+OhciStopHc (
+ IN USB_HC_DEV *Ohc,
+ IN UINTN Timeout
+ );
+
+
+
+/**
+ Check whether the host controller operates well.
+
+ @param PciIo The PCI_IO protocol to use.
+
+ @retval TRUE Host controller is working.
+ @retval FALSE Host controller is halted or system error.
+
+**/
+BOOLEAN
+OhciIsHcWorking (
+ IN USB_HC_DEV *Ohc
+ );
+
+
+/**
+ Set the OHCI frame list base address. It can't use
+ OhciWriteReg which access memory in UINT16.
+
+ @param PciIo The EFI_PCI_IO_PROTOCOL to use.
+ @param Addr Address to set.
+
+ @return None.
+
+**/
+VOID
+OhciSetFrameListBaseAddr (
+ IN USB_HC_DEV *Ohc,
+ IN VOID *Addr
+ );
+
+
+/**
+ Disable USB Emulation.
+
+ @param PciIo The EFI_PCI_IO_PROTOCOL protocol to use.
+
+ @return None.
+
+**/
+VOID
+OhciTurnOffUsbEmulation (
+ IN USB_HC_DEV *Ohc
+ );
+#endif
diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/OhciDxe/OhciSched.c b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/OhciDxe/OhciSched.c
new file mode 100644
index 000000000..a8f99a3d4
--- /dev/null
+++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/OhciDxe/OhciSched.c
@@ -0,0 +1,1254 @@
+/** @file
+
+ The EHCI register operation routines.
+
+Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "Ohci.h"
+
+
+/**
+ Create Frame List Structure.
+
+ @param Ohc OHCI device.
+
+ @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
+ @retval EFI_UNSUPPORTED Map memory fail.
+ @retval EFI_SUCCESS Success.
+
+**/
+EFI_STATUS
+OhciInitFrameList (
+ IN USB_HC_DEV *Ohc
+ )
+{
+ EFI_PHYSICAL_ADDRESS MappedAddr;
+ EFI_STATUS Status;
+ VOID *Buffer;
+ VOID *Mapping;
+ UINTN Pages;
+ UINTN Bytes;
+ UINTN Index;
+ EFI_PHYSICAL_ADDRESS PhyAddr;
+
+ DEBUG((EFI_D_INIT, "+++OhciInitFrameList()\n"));
+
+ //
+ // The Frame List is a common buffer that will be
+ // accessed by both the cpu and the usb bus master
+ // at the same time. The Frame List ocupies 4K bytes,
+ // and must be aligned on 4-Kbyte boundaries.
+ //
+ Bytes = 4096;
+ Pages = EFI_SIZE_TO_PAGES (Bytes);
+
+ Status = Ohc->PciIo->AllocateBuffer (
+ Ohc->PciIo,
+ AllocateAnyPages,
+ EfiBootServicesData,
+ Pages,
+ &Buffer,
+ 0
+ );
+
+ if (EFI_ERROR (Status)) {
+ DEBUG((EFI_D_ERROR, "FAIL! AllocateBuffer\n"));
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ Status = Ohc->PciIo->Map (
+ Ohc->PciIo,
+ EfiPciIoOperationBusMasterCommonBuffer,
+ Buffer,
+ &Bytes,
+ &MappedAddr,
+ &Mapping
+ );
+
+#if 1
+ if (EFI_ERROR (Status) || (Bytes != 4096)) {
+ DEBUG((EFI_D_ERROR, "FAIL! Map\n"));
+ Status = EFI_UNSUPPORTED;
+ return Status;
+ }
+
+ Ohc->Hcca = (UINT32 *) (UINTN) Buffer;
+ Ohc->HccaMapping = Mapping;
+
+ OhciWriteReg(Ohc, HC_HCCA_OFFSET, (UINT32)Buffer);
+
+ return EFI_SUCCESS;
+
+#else
+ if (EFI_ERROR (Status) || (Bytes != 4096)) {
+ DEBUG((EFI_D_ERROR, "FAIL! Map\n"));
+ Status = EFI_UNSUPPORTED;
+ goto ON_ERROR;
+ }
+
+
+ Ohc->FrameBase = (UINT32 *) (UINTN) Buffer;
+ Ohc->FrameMapping = Mapping;
+
+ //
+ // Tell the Host Controller where the Frame List lies,
+ // by set the Frame List Base Address Register.
+ //
+ //OhciSetFrameListBaseAddr (Ohc->PciIo, (VOID *) (UINTN) MappedAddr);
+
+ //
+ // Allocate the QH used by sync interrupt/control/bulk transfer.
+ // FS ctrl/bulk queue head is set to loopback so additional BW
+ // can be reclaimed. Notice, LS don't support bulk transfer and
+ // also doesn't support BW reclamation.
+ //
+ Ohc->SyncIntQh = OhciCreateQh (Ohc, 1);
+ Ohc->CtrlQh = OhciCreateQh (Ohc, 1);
+ Ohc->BulkQh = OhciCreateQh (Ohc, 1);
+
+ if ((Ohc->SyncIntQh == NULL) || (Ohc->CtrlQh == NULL) || (Ohc->BulkQh == NULL)) {
+ Ohc->PciIo->Unmap (Ohc->PciIo, Mapping);
+ DEBUG((EFI_D_ERROR, "FAIL! NULL1\n"));
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_ERROR;
+ }
+
+ //
+ // +-------------+
+ // | |
+ // Link the three together: SyncIntQh->CtrlQh->BulkQh <---------+
+ // Each frame entry is linked to this sequence of QH. These QH
+ // will remain on the schedul, never got removed
+ //
+ PhyAddr = UsbHcGetPciAddressForHostMem (Ohc->MemPool, Ohc->CtrlQh, sizeof (OHCI_QH_HW));
+ Ohc->SyncIntQh->QhHw.HorizonLink = QH_HLINK (PhyAddr, FALSE);
+ Ohc->SyncIntQh->NextQh = Ohc->CtrlQh;
+
+ PhyAddr = UsbHcGetPciAddressForHostMem (Ohc->MemPool, Ohc->BulkQh, sizeof (OHCI_QH_HW));
+ Ohc->CtrlQh->QhHw.HorizonLink = QH_HLINK (PhyAddr, FALSE);
+ Ohc->CtrlQh->NextQh = Ohc->BulkQh;
+
+ //
+ // Some old platform such as Intel's Tiger 4 has a difficult time
+ // in supporting the full speed bandwidth reclamation in the previous
+ // mentioned form. Most new platforms don't suffer it.
+ //
+ Ohc->BulkQh->QhHw.HorizonLink = QH_HLINK (PhyAddr, FALSE);
+
+ Ohc->BulkQh->NextQh = NULL;
+
+ Ohc->FrameBaseHostAddr = AllocateZeroPool (4096);
+ if (Ohc->FrameBaseHostAddr == NULL) {
+ DEBUG((EFI_D_ERROR, "FAIL! NULL2\n"));
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_ERROR;
+ }
+
+ PhyAddr = UsbHcGetPciAddressForHostMem (Ohc->MemPool, Ohc->SyncIntQh, sizeof (OHCI_QH_HW));
+ for (Index = 0; Index < OHCI_FRAME_NUM; Index++) {
+ Ohc->FrameBase[Index] = QH_HLINK (PhyAddr, FALSE);
+ Ohc->FrameBaseHostAddr[Index] = (UINT32)(UINTN)Ohc->SyncIntQh;
+ }
+
+ DEBUG((EFI_D_INIT, "---OhciInitFrameList()\n"));
+
+ return EFI_SUCCESS;
+
+ON_ERROR:
+ if (Ohc->SyncIntQh != NULL) {
+ UsbHcFreeMem (Ohc->MemPool, Ohc->SyncIntQh, sizeof (OHCI_QH_SW));
+ }
+
+ if (Ohc->CtrlQh != NULL) {
+ UsbHcFreeMem (Ohc->MemPool, Ohc->CtrlQh, sizeof (OHCI_QH_SW));
+ }
+
+ if (Ohc->BulkQh != NULL) {
+ UsbHcFreeMem (Ohc->MemPool, Ohc->BulkQh, sizeof (OHCI_QH_SW));
+ }
+
+ Ohc->PciIo->FreeBuffer (Ohc->PciIo, Pages, Buffer);
+ return Status;
+#endif
+}
+
+
+/**
+ Destory FrameList buffer.
+
+ @param Ohc The OHCI device.
+
+**/
+VOID
+OhciDestoryFrameList (
+ IN USB_HC_DEV *Ohc
+ )
+{
+ //
+ // Unmap the common buffer for framelist entry,
+ // and free the common buffer.
+ // Ohci's frame list occupy 4k memory.
+ //
+ DEBUG((EFI_D_INIT, "+++OhciDestoryFrameList()\n"));
+
+#if 1
+#else
+ Ohc->PciIo->Unmap (Ohc->PciIo, Ohc->FrameMapping);
+
+ Ohc->PciIo->FreeBuffer (
+ Ohc->PciIo,
+ EFI_SIZE_TO_PAGES (4096),
+ (VOID *) Ohc->FrameBase
+ );
+
+ if (Ohc->FrameBaseHostAddr != NULL) {
+ FreePool (Ohc->FrameBaseHostAddr);
+ }
+
+ if (Ohc->SyncIntQh != NULL) {
+ UsbHcFreeMem (Ohc->MemPool, Ohc->SyncIntQh, sizeof (OHCI_QH_SW));
+ }
+
+ if (Ohc->CtrlQh != NULL) {
+ UsbHcFreeMem (Ohc->MemPool, Ohc->CtrlQh, sizeof (OHCI_QH_SW));
+ }
+
+ if (Ohc->BulkQh != NULL) {
+ UsbHcFreeMem (Ohc->MemPool, Ohc->BulkQh, sizeof (OHCI_QH_SW));
+ }
+
+ Ohc->FrameBase = NULL;
+ Ohc->FrameBaseHostAddr = NULL;
+ Ohc->SyncIntQh = NULL;
+ Ohc->CtrlQh = NULL;
+ Ohc->BulkQh = NULL;
+#endif
+ DEBUG((EFI_D_INIT, "---OhciDestoryFrameList()\n"));
+}
+
+
+/**
+ Convert the poll rate to the maxium 2^n that is smaller
+ than Interval.
+
+ @param Interval The poll rate to convert.
+
+ @return The converted poll rate.
+
+**/
+UINTN
+OhciConvertPollRate (
+ IN UINTN Interval
+ )
+{
+ UINTN BitCount;
+
+ ASSERT (Interval != 0);
+
+ //
+ // Find the index (1 based) of the highest non-zero bit
+ //
+ BitCount = 0;
+
+ while (Interval != 0) {
+ Interval >>= 1;
+ BitCount++;
+ }
+
+ return (UINTN)1 << (BitCount - 1);
+}
+
+
+/**
+ Link a queue head (for asynchronous interrupt transfer) to
+ the frame list.
+
+ @param Ohc The OHCI device.
+ @param Qh The queue head to link into.
+
+**/
+VOID
+OhciLinkQhToFrameList (
+ USB_HC_DEV *Ohc,
+ OHCI_QH_SW *Qh
+ )
+{
+ UINTN Index;
+ OHCI_QH_SW *Prev;
+ OHCI_QH_SW *Next;
+ EFI_PHYSICAL_ADDRESS PhyAddr;
+ EFI_PHYSICAL_ADDRESS QhPciAddr;
+
+#if 1
+#else
+ ASSERT ((Ohc->FrameBase != NULL) && (Qh != NULL));
+
+ QhPciAddr = UsbHcGetPciAddressForHostMem (Ohc->MemPool, Qh, sizeof (OHCI_QH_HW));
+
+ for (Index = 0; Index < OHCI_FRAME_NUM; Index += Qh->Interval) {
+ //
+ // First QH can't be NULL because we always keep static queue
+ // heads on the frame list
+ //
+ ASSERT (!LINK_TERMINATED (Ohc->FrameBase[Index]));
+ Next = (OHCI_QH_SW*)(UINTN)Ohc->FrameBaseHostAddr[Index];
+ Prev = NULL;
+
+ //
+ // Now, insert the queue head (Qh) into this frame:
+ // 1. Find a queue head with the same poll interval, just insert
+ // Qh after this queue head, then we are done.
+ //
+ // 2. Find the position to insert the queue head into:
+ // Previous head's interval is bigger than Qh's
+ // Next head's interval is less than Qh's
+ // Then, insert the Qh between then
+ //
+ // This method is very much the same as that used by EHCI.
+ // Because each QH's interval is round down to 2^n, poll
+ // rate is correct.
+ //
+ while (Next->Interval > Qh->Interval) {
+ Prev = Next;
+ Next = Next->NextQh;
+ ASSERT (Next != NULL);
+ }
+
+ //
+ // The entry may have been linked into the frame by early insertation.
+ // For example: if insert a Qh with Qh.Interval == 4, and there is a Qh
+ // with Qh.Interval == 8 on the frame. If so, we are done with this frame.
+ // It isn't necessary to compare all the QH with the same interval to
+ // Qh. This is because if there is other QH with the same interval, Qh
+ // should has been inserted after that at FrameBase[0] and at FrameBase[0] it is
+ // impossible (Next == Qh)
+ //
+ if (Next == Qh) {
+ continue;
+ }
+
+ if (Next->Interval == Qh->Interval) {
+ //
+ // If there is a QH with the same interval, it locates at
+ // FrameBase[0], and we can simply insert it after this QH. We
+ // are all done.
+ //
+ ASSERT ((Index == 0) && (Qh->NextQh == NULL));
+
+ Prev = Next;
+ Next = Next->NextQh;
+
+ Qh->NextQh = Next;
+ Prev->NextQh = Qh;
+
+ Qh->QhHw.HorizonLink = Prev->QhHw.HorizonLink;
+
+ Prev->QhHw.HorizonLink = QH_HLINK (QhPciAddr, FALSE);
+ break;
+ }
+
+ //
+ // OK, find the right position, insert it in. If Qh's next
+ // link has already been set, it is in position. This is
+ // guarranted by 2^n polling interval.
+ //
+ if (Qh->NextQh == NULL) {
+ Qh->NextQh = Next;
+ PhyAddr = UsbHcGetPciAddressForHostMem (Ohc->MemPool, Next, sizeof (OHCI_QH_HW));
+ Qh->QhHw.HorizonLink = QH_HLINK (PhyAddr, FALSE);
+ }
+
+ if (Prev == NULL) {
+ Ohc->FrameBase[Index] = QH_HLINK (QhPciAddr, FALSE);
+ Ohc->FrameBaseHostAddr[Index] = (UINT32)(UINTN)Qh;
+ } else {
+ Prev->NextQh = Qh;
+ Prev->QhHw.HorizonLink = QH_HLINK (QhPciAddr, FALSE);
+ }
+ }
+#endif
+}
+
+
+/**
+ Unlink QH from the frame list is easier: find all
+ the precedence node, and pointer there next to QhSw's
+ next.
+
+ @param Ohc The OHCI device.
+ @param Qh The queue head to unlink.
+
+**/
+VOID
+OhciUnlinkQhFromFrameList (
+ USB_HC_DEV *Ohc,
+ OHCI_QH_SW *Qh
+ )
+{
+ UINTN Index;
+ OHCI_QH_SW *Prev;
+ OHCI_QH_SW *This;
+#if 1
+#else
+ ASSERT ((Ohc->FrameBase != NULL) && (Qh != NULL));
+
+ for (Index = 0; Index < OHCI_FRAME_NUM; Index += Qh->Interval) {
+ //
+ // Frame link can't be NULL because we always keep static
+ // queue heads on the frame list
+ //
+ ASSERT (!LINK_TERMINATED (Ohc->FrameBase[Index]));
+ This = (OHCI_QH_SW*)(UINTN)Ohc->FrameBaseHostAddr[Index];
+ Prev = NULL;
+
+ //
+ // Walk through the frame's QH list to find the
+ // queue head to remove
+ //
+ while ((This != NULL) && (This != Qh)) {
+ Prev = This;
+ This = This->NextQh;
+ }
+
+ //
+ // Qh may have already been unlinked from this frame
+ // by early action.
+ //
+ if (This == NULL) {
+ continue;
+ }
+
+ if (Prev == NULL) {
+ //
+ // Qh is the first entry in the frame
+ //
+ Ohc->FrameBase[Index] = Qh->QhHw.HorizonLink;
+ Ohc->FrameBaseHostAddr[Index] = (UINT32)(UINTN)Qh->NextQh;
+ } else {
+ Prev->NextQh = Qh->NextQh;
+ Prev->QhHw.HorizonLink = Qh->QhHw.HorizonLink;
+ }
+ }
+#endif
+}
+
+
+/**
+ Check TDs Results.
+
+ @param Ohc This OHCI device.
+ @param Td OHCI_TD_HW to check.
+ @param IsLow Is Low Speed Device.
+ @param QhResult Return the result of this TD list.
+
+ @return Whether the TD's result is finialized.
+
+**/
+BOOLEAN
+OhciCheckTdStatus (
+ IN USB_HC_DEV *Ohc,
+ IN OHCI_ED_HW *Ed,
+ IN BOOLEAN IsLow,
+ OUT OHCI_QH_RESULT *QhResult,
+ IN UINT8 Class
+ )
+{
+ UINTN Len;
+ UINT8 State;
+ BOOLEAN Finished;
+ OHCI_TD_SW *CurTdSw;
+ OHCI_TD_HW *TdHw;
+
+ Finished = TRUE;
+
+ if(Class == HC_CLASS_CONTROL)
+ CurTdSw = Ohc->CtrlQh;
+ else // HC_CLASS_INTERRUPT
+ CurTdSw = Ohc->IntrQh;
+
+ TdHw = CurTdSw->TdHw;
+ //
+ // Initialize the data toggle to that of the first
+ // TD. The next toggle to use is either:
+ // 1. first TD's toggle if no TD is executed OK
+ // 2. the next toggle of last executed-OK TD
+ //
+ QhResult->Result = EFI_USB_NOERROR;
+ QhResult->NextToggle = (UINT8)(TdHw->gtd_info.b.data_toggle & 1);
+ QhResult->Complete = 0;
+
+#if 1
+ if(Class == HC_CLASS_CONTROL)
+ {
+ while(Ohc->Hcca->done_head != Ohc->LastTd)
+ {
+ DEBUG((EFI_D_ERROR, ".\n"));
+ OhciWriteReg(Ohc, HC_INT_STATUS_OFFSET, 0x2);
+ }
+ }
+ else
+ {
+ OhciWriteReg(Ohc, HC_INT_STATUS_OFFSET, 0x2);
+ if(Ohc->Hcca->done_head != Ohc->LastTd)
+ {
+ Finished = FALSE;
+ QhResult->Complete = 0;
+ return Finished;
+ }
+ }
+
+ Ohc->Hcca->done_head = NULL;
+ DEBUG((EFI_D_ERROR, ">\n"));
+
+ while (TdHw != NULL) {
+ if(TdHw->current_buf_ptr == NULL)
+ {
+ if(TdHw->gtd_info.b.error_count != 0)
+ {
+ QhResult->Result |= EFI_USB_ERR_NOTEXECUTE;
+ DEBUG((EFI_D_ERROR, "FAIL! EXECUTE ERROR1\n"));
+ Finished = TRUE;
+ OhciDumpSWTds(Ohc->CtrlQh);
+ OhcDumpRegs(Ohc);
+ goto ON_EXIT;
+ }
+
+ if(TdHw->gtd_info.b.condition_code != 0)
+ {
+ switch(TdHw->gtd_info.b.condition_code)
+ {
+ case 4: //stall
+ QhResult->Result |= EFI_USB_ERR_STALL;
+ DEBUG((EFI_D_ERROR, "FAIL! EFI_USB_ERR_STALL\n"));
+ break;
+ default :
+ QhResult->Result |= EFI_USB_ERR_NOTEXECUTE;
+ DEBUG((EFI_D_ERROR, "FAIL! EXECUTE ERROR2\n"));
+ break;
+ }
+
+ Finished = TRUE;
+ OhciDumpSWTds(Ohc->CtrlQh);
+ OhcDumpRegs(Ohc);
+ goto ON_EXIT;
+ }
+
+ QhResult->NextToggle = (TdHw->gtd_info.b.data_toggle & 1) ? 0 : 1;
+ //
+ // This TD is finished OK or met short packet read. Update the
+ // transfer length if it isn't a SETUP.
+ //
+
+ if (TdHw->gtd_info.b.pid != SETUP_PACKET_ID) {
+ QhResult->Complete += CurTdSw->DataLen;
+ }
+
+ //
+ // Short packet condition for full speed input TD, also
+ // terminate the transfer
+ //
+ /*
+ if (!IsLow && (TdHw->ShortPacket == 1) && (Len < Td->DataLen)) {
+ DEBUG ((EFI_D_INFO, "OhciCheckTdStatus: short packet read occured\n"));
+
+ Finished = TRUE;
+ goto ON_EXIT;
+ }*/
+ } // if(TdHw->current_buf_ptr == NULL)
+ /*else
+ {
+ QhResult->Result |= EFI_USB_ERR_NOTEXECUTE;
+ DEBUG((EFI_D_ERROR, "FAIL! EXECUTE ERROR3\n"));
+ Finished = TRUE;
+ goto ON_EXIT;
+ }*/
+ CurTdSw = CurTdSw->NextTd;
+ TdHw = CurTdSw->TdHw;
+ }
+
+ if(!Finished)
+ {
+ OhciDumpSWTds(Ohc->CtrlQh);
+ OhcDumpRegs(Ohc);
+ }
+#else
+ while (Td != NULL) {
+ TdHw = &Td->TdHw;
+ State = (UINT8)TdHw->Status;
+
+ //
+ // OHCI will set STALLED bit when it abort the execution
+ // of TD list. There are several reasons:
+ // 1. BABBLE error happened
+ // 2. Received a STALL response
+ // 3. Error count decreased to zero.
+ //
+ // It also set CRC/Timeout/NAK/Buffer Error/BitStuff Error
+ // bits when corresponding conditions happen. But these
+ // conditions are not deadly, that is a TD can successfully
+ // completes even these bits are set. But it is likely that
+ // upper layer won't distinguish these condtions. So, only
+ // set these bits when TD is actually halted.
+ //
+ if ((State & USBTD_STALLED) != 0) {
+ if ((State & USBTD_BABBLE) != 0) {
+ QhResult->Result |= EFI_USB_ERR_BABBLE;
+
+ } else if (TdHw->ErrorCount != 0) {
+ QhResult->Result |= EFI_USB_ERR_STALL;
+ }
+
+ if ((State & USBTD_CRC) != 0) {
+ QhResult->Result |= EFI_USB_ERR_CRC;
+ }
+
+ if ((State & USBTD_BUFFERR) != 0) {
+ QhResult->Result |= EFI_USB_ERR_BUFFER;
+ }
+
+ if ((Td->TdHw.Status & USBTD_BITSTUFF) != 0) {
+ QhResult->Result |= EFI_USB_ERR_BITSTUFF;
+ }
+
+ if (TdHw->ErrorCount == 0) {
+ QhResult->Result |= EFI_USB_ERR_TIMEOUT;
+ }
+
+ Finished = TRUE;
+ goto ON_EXIT;
+
+ } else if ((State & USBTD_ACTIVE) != 0) {
+ //
+ // The TD is still active, no need to check further.
+ //
+ QhResult->Result |= EFI_USB_ERR_NOTEXECUTE;
+
+ Finished = FALSE;
+ goto ON_EXIT;
+
+ } else {
+ //
+ // Update the next data toggle, it is always the
+ // next to the last known-good TD's data toggle if
+ // any TD is executed OK
+ //
+ QhResult->NextToggle = (UINT8) (1 - (UINT8)TdHw->DataToggle);
+
+ //
+ // This TD is finished OK or met short packet read. Update the
+ // transfer length if it isn't a SETUP.
+ //
+ Len = (TdHw->ActualLen + 1) & 0x7FF;
+
+ if (TdHw->PidCode != SETUP_PACKET_ID) {
+ QhResult->Complete += Len;
+ }
+
+ //
+ // Short packet condition for full speed input TD, also
+ // terminate the transfer
+ //
+ if (!IsLow && (TdHw->ShortPacket == 1) && (Len < Td->DataLen)) {
+ DEBUG ((EFI_D_INFO, "OhciCheckTdStatus: short packet read occured\n"));
+
+ Finished = TRUE;
+ goto ON_EXIT;
+ }
+ }
+
+ Td = Td->NextTd;
+ }
+#endif
+
+ON_EXIT:
+ //
+ // Check whether HC is halted. Don't move this up. It must be
+ // called after data toggle is successfully updated.
+ //
+ if (!OhciIsHcWorking (Ohc->PciIo)) {
+ QhResult->Result |= EFI_USB_ERR_SYSTEM;
+ Finished = TRUE;
+ }
+
+ if (Finished) {
+ Ohc->PciIo->Flush (Ohc->PciIo);
+ }
+
+ OhciAckAllInterrupt (Ohc);
+ return Finished;
+}
+
+
+/**
+ Check the result of the transfer.
+
+ @param Ohc The OHCI device.
+ @param Qh The queue head of the transfer.
+ @param Td The first TDs of the transfer.
+ @param TimeOut TimeOut value in milliseconds.
+ @param IsLow Is Low Speed Device.
+ @param QhResult The variable to return result.
+
+ @retval EFI_SUCCESS The transfer finished with success.
+ @retval EFI_DEVICE_ERROR Transfer failed.
+
+**/
+EFI_STATUS
+OhciExecuteTransfer (
+ IN USB_HC_DEV *Ohc,
+ IN OHCI_ED_HW *Ed,
+ IN UINTN TimeOut,
+ IN BOOLEAN IsLow,
+ OUT OHCI_QH_RESULT *QhResult
+ )
+{
+ UINTN Index;
+ UINTN Delay;
+ BOOLEAN Finished;
+ EFI_STATUS Status;
+
+ DEBUG((EFI_D_INIT, "+++OhciExecuteTransfer()\n"));
+
+ Finished = FALSE;
+ Status = EFI_SUCCESS;
+ Delay = (TimeOut * OHC_1_MILLISECOND / OHC_SYNC_POLL_INTERVAL) + 1;
+
+ for (Index = 0; Index < Delay; Index++) {
+ Finished = OhciCheckTdStatus (Ohc, Ed, IsLow, QhResult, HC_CLASS_CONTROL);
+
+ //
+ // Transfer is OK or some error occured (TD inactive)
+ //
+ if (Finished) {
+ DEBUG((EFI_D_INIT, "SUCCESS! OhciExecuteTransfer\n"));
+ break;
+ }
+
+ gBS->Stall (OHC_SYNC_POLL_INTERVAL);
+ }
+
+ if (!Finished) {
+ DEBUG ((EFI_D_ERROR, "OhciExecuteTransfer: execution not finished for %dms\n", (UINT32)TimeOut));
+ //OhciDumpQh (Qh);
+ //OhciDumpTds (Td);
+
+ Status = EFI_TIMEOUT;
+
+ } else if (QhResult->Result != EFI_USB_NOERROR) {
+ DEBUG ((EFI_D_ERROR, "OhciExecuteTransfer: execution failed with result %x\n", QhResult->Result));
+ //OhciDumpQh (Qh);
+ //OhciDumpTds (Td);
+
+ Status = EFI_DEVICE_ERROR;
+ }
+
+ DEBUG((EFI_D_INIT, "---OhciExecuteTransfer()\n"));
+
+ return Status;
+}
+
+
+/**
+ Update Async Request, QH and TDs.
+
+ @param Ohc The OHCI device.
+ @param AsyncReq The OHCI asynchronous transfer to update.
+ @param Result Transfer reslut.
+ @param NextToggle The toggle of next data.
+
+**/
+VOID
+OhciUpdateAsyncReq (
+ IN USB_HC_DEV *Ohc,
+ IN OHCI_ASYNC_REQUEST *AsyncReq,
+ IN UINT32 Result,
+ IN UINT32 NextToggle
+ )
+{
+ OHCI_ED_HW *EdHw;
+ OHCI_TD_SW *FirstTd;
+ OHCI_TD_SW *Td;
+ OHCI_TD_HW *TdHw;
+
+ UINT8 *DataPtr, *DataPhy;
+
+ //DEBUG((EFI_D_INIT, "+++OhciUpdateAsyncReq()\n"));
+
+ EdHw = AsyncReq->EdHw;
+ FirstTd = AsyncReq->TdSw;
+
+ if (Result == EFI_USB_NOERROR) {
+ //
+ // The last transfer succeeds. Then we need to update
+ // the Qh and Td for next round of transfer.
+ // 1. Update the TD's data toggle
+ // 2. Activate all the TDs
+ // 3. Link the TD to the queue head again since during
+ // execution, queue head's TD pointer is changed by
+ // hardware.
+ //
+
+ for (Td = FirstTd; Td != NULL; Td = Td->NextTd) {
+ TdHw = Td->TdHw;
+ if(TdHw != NULL)
+ {
+ //
+ // Allocate and map source data buffer for bus master access.
+ //
+ DataPtr = UsbHcAllocateMem (Ohc->MemPool, Td->DataLen);
+
+ if (DataPtr == NULL) {
+ DEBUG((EFI_D_ERROR, "FAIL! UsbHcAllocateMem\n"));
+ return;
+ }
+
+ DataPhy = (UINT8 *) (UINTN) UsbHcGetPciAddressForHostMem (Ohc->MemPool, DataPtr, Td->DataLen);
+
+ Ohc->Destory = Td->Data;
+ Ohc->DestroySize = Td->DataLen;
+ TdHw->current_buf_ptr = DataPhy;
+ TdHw->buffer_end = DataPhy + Td->DataLen - 1;
+ TdHw->gtd_info.b.data_toggle = NextToggle + 2;
+
+ if(Td->NextTd)
+ {
+ TdHw->next_td = Td->NextTd->TdHw;
+ }
+
+ NextToggle = NextToggle ? 0 : 1;
+ }
+ }
+
+ EdHw->head_td_ptr = FirstTd->TdHw;
+
+ //OhciDumpEd(EdHw);
+
+ OhciLinkTdToQh (Ohc, EdHw, HC_CLASS_INTERRUPT);
+
+ //DEBUG((EFI_D_INIT, "---OhciUpdateAsyncReq()\n"));
+
+ return ;
+ }
+}
+
+
+/**
+ Create Async Request node, and Link to List.
+
+ @param Ohc The OHCI device.
+ @param Qh The queue head of the transfer.
+ @param FirstTd First TD of the transfer.
+ @param DevAddr Device Address.
+ @param EndPoint EndPoint Address.
+ @param DataLen Data length.
+ @param Interval Polling Interval when inserted to frame list.
+ @param Data Data buffer, unmapped.
+ @param Callback Callback after interrupt transfeer.
+ @param Context Callback Context passed as function parameter.
+ @param IsLow Is Low Speed.
+
+ @retval EFI_SUCCESS An asynchronous transfer is created.
+ @retval EFI_INVALID_PARAMETER Paremeter is error.
+ @retval EFI_OUT_OF_RESOURCES Failed because of resource shortage.
+
+**/
+EFI_STATUS
+OhciCreateAsyncReq (
+ IN USB_HC_DEV *Ohc,
+ IN OHCI_ED_HW *EdHw,
+ IN OHCI_TD_SW *TdSw,
+ IN UINT8 DevAddr,
+ IN UINT8 EndPoint,
+ IN UINTN DataLen,
+ IN UINTN Interval,
+ IN UINT8 *Data,
+ IN EFI_ASYNC_USB_TRANSFER_CALLBACK Callback,
+ IN VOID *Context,
+ IN BOOLEAN IsLow
+ )
+{
+ OHCI_ASYNC_REQUEST *AsyncReq;
+
+ DEBUG((EFI_D_INIT, "+++OhciCreateAsyncReq()\n"));
+
+ AsyncReq = AllocatePool (sizeof (OHCI_ASYNC_REQUEST));
+
+ if (AsyncReq == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ //
+ // Fill Request field. Data is allocated host memory, not mapped
+ //
+ AsyncReq->Signature = OHCI_ASYNC_INT_SIGNATURE;
+ AsyncReq->DevAddr = DevAddr;
+ AsyncReq->EndPoint = EndPoint;
+ AsyncReq->DataLen = DataLen;
+ AsyncReq->Interval = OhciConvertPollRate(Interval);
+ AsyncReq->Data = Data;
+ AsyncReq->Callback = Callback;
+ AsyncReq->Context = Context;
+ AsyncReq->EdHw = EdHw;
+ AsyncReq->TdSw = TdSw;
+ AsyncReq->IsLow = IsLow;
+
+ //
+ // Insert the new interrupt transfer to the head of the list.
+ // The interrupt transfer's monitor function scans the whole
+ // list from head to tail. The new interrupt transfer MUST be
+ // added to the head of the list.
+ //
+ InsertHeadList (&(Ohc->AsyncIntList), &(AsyncReq->Link));
+
+ DEBUG((EFI_D_INIT, "---OhciCreateAsyncReq()\n"));
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Free an asynchronous request's resource such as memory.
+
+ @param Ohc The OHCI device.
+ @param AsyncReq The asynchronous request to free.
+
+**/
+VOID
+OhciFreeAsyncReq (
+ IN USB_HC_DEV *Ohc,
+ IN OHCI_ASYNC_REQUEST *AsyncReq
+ )
+{
+ ASSERT ((Ohc != NULL) && (AsyncReq != NULL));
+
+ DEBUG((EFI_D_ERROR, "+++OhciFreeAsyncReq()\n"));
+
+ OhciDestoryTds (Ohc, AsyncReq->TdSw);
+
+ if (AsyncReq->Data != NULL) {
+ UsbHcFreeMem (Ohc->MemPool, AsyncReq->Data, AsyncReq->DataLen);
+ }
+
+ gBS->FreePool (AsyncReq);
+
+ DEBUG((EFI_D_ERROR, "+++OhciFreeAsyncReq()\n"));
+}
+
+
+/**
+ Unlink an asynchronous request's from OHC's asynchronus list.
+ also remove the queue head from the frame list. If FreeNow,
+ release its resource also. Otherwise, add the request to the
+ OHC's recycle list to wait for a while before release the memory.
+ Until then, hardware won't hold point to the request.
+
+ @param Ohc The OHCI device.
+ @param AsyncReq The asynchronous request to free.
+ @param FreeNow If TRUE, free the resource immediately, otherwise
+ add the request to recycle wait list.
+
+**/
+VOID
+OhciUnlinkAsyncReq (
+ IN USB_HC_DEV *Ohc,
+ IN OHCI_ASYNC_REQUEST *AsyncReq,
+ IN BOOLEAN FreeNow
+ )
+{
+ ASSERT ((Ohc != NULL) && (AsyncReq != NULL));
+
+ DEBUG((EFI_D_INIT, "+++OhciUnlinkAsyncReq()\n"));
+#if 1
+#else
+ RemoveEntryList (&(AsyncReq->Link));
+ OhciUnlinkQhFromFrameList (Ohc, AsyncReq->QhSw);
+
+ if (FreeNow) {
+ OhciFreeAsyncReq (Ohc, AsyncReq);
+ } else {
+ //
+ // To sychronize with hardware, mark the queue head as inactive
+ // then add AsyncReq to OHC's recycle list
+ //
+ AsyncReq->QhSw->QhHw.VerticalLink = QH_VLINK (NULL, TRUE);
+ AsyncReq->Recycle = Ohc->RecycleWait;
+ Ohc->RecycleWait = AsyncReq;
+ }
+#endif
+ DEBUG((EFI_D_INIT, "---OhciUnlinkAsyncReq()\n"));
+}
+
+
+/**
+ Delete Async Interrupt QH and TDs.
+
+ @param Ohc The OHCI device.
+ @param DevAddr Device Address.
+ @param EndPoint EndPoint Address.
+ @param Toggle The next data toggle to use.
+
+ @retval EFI_SUCCESS The request is deleted.
+ @retval EFI_INVALID_PARAMETER Paremeter is error.
+ @retval EFI_NOT_FOUND The asynchronous isn't found.
+
+**/
+EFI_STATUS
+OhciRemoveAsyncReq (
+ IN USB_HC_DEV *Ohc,
+ IN UINT8 DevAddr,
+ IN UINT8 EndPoint,
+ OUT UINT8 *Toggle
+ )
+{
+ EFI_STATUS Status;
+ OHCI_ASYNC_REQUEST *AsyncReq;
+ OHCI_QH_RESULT QhResult;
+ LIST_ENTRY *Link;
+ BOOLEAN Found;
+
+ Status = EFI_SUCCESS;
+
+ //
+ // If no asynchronous interrupt transaction exists
+ //
+ if (IsListEmpty (&(Ohc->AsyncIntList))) {
+ return EFI_SUCCESS;
+ }
+
+ //
+ // Find the asynchronous transfer to this device/endpoint pair
+ //
+ Found = FALSE;
+ Link = Ohc->AsyncIntList.ForwardLink;
+
+ do {
+ AsyncReq = OHCI_ASYNC_INT_FROM_LINK (Link);
+ Link = Link->ForwardLink;
+
+ if ((AsyncReq->DevAddr == DevAddr) && (AsyncReq->EndPoint == EndPoint)) {
+ Found = TRUE;
+ break;
+ }
+
+ } while (Link != &(Ohc->AsyncIntList));
+
+ if (!Found) {
+ return EFI_NOT_FOUND;
+ }
+
+ //
+ // Check the result of the async transfer then update it
+ // to get the next data toggle to use.
+ //
+ OhciCheckTdStatus (Ohc, AsyncReq->EdHw, AsyncReq->IsLow, &QhResult, HC_CLASS_INTERRUPT);
+ *Toggle = QhResult.NextToggle;
+
+ //
+ // Don't release the request now, keep it to synchronize with hardware.
+ //
+ OhciUnlinkAsyncReq (Ohc, AsyncReq, FALSE);
+ return Status;
+}
+
+
+/**
+ Recycle the asynchronouse request. When a queue head
+ is unlinked from frame list, host controller hardware
+ may still hold a cached pointer to it. To synchronize
+ with hardware, the request is released in two steps:
+ first it is linked to the OHC's RecycleWait list. At
+ the next time OhciMonitorAsyncReqList is fired, it is
+ moved to OHC's Recylelist. Then, at another timer
+ activation, all the requests on Recycle list is freed.
+ This guarrantes that each unlink queue head keeps
+ existing for at least 50ms, far enough for the hardware
+ to clear its cache.
+
+ @param Ohc The OHCI device.
+
+**/
+VOID
+OhciRecycleAsyncReq (
+ IN USB_HC_DEV *Ohc
+ )
+{
+ OHCI_ASYNC_REQUEST *Req;
+ OHCI_ASYNC_REQUEST *Next;
+
+ Req = Ohc->Recycle;
+
+ while (Req != NULL) {
+ Next = Req->Recycle;
+ OhciFreeAsyncReq (Ohc, Req);
+ Req = Next;
+ }
+
+ Ohc->Recycle = Ohc->RecycleWait;
+ Ohc->RecycleWait = NULL;
+}
+
+
+
+/**
+ Release all the asynchronous transfers on the lsit.
+
+ @param Ohc The OHCI device.
+
+**/
+VOID
+OhciFreeAllAsyncReq (
+ IN USB_HC_DEV *Ohc
+ )
+{
+ LIST_ENTRY *Head;
+ OHCI_ASYNC_REQUEST *AsyncReq;
+
+ DEBUG((EFI_D_INIT, "+++OhciFreeAllAsyncReq()\n"));
+
+ //
+ // Call OhciRecycleAsyncReq twice. The requests on Recycle
+ // will be released at the first call; The requests on
+ // RecycleWait will be released at the second call.
+ //
+ OhciRecycleAsyncReq (Ohc);
+ OhciRecycleAsyncReq (Ohc);
+
+ Head = &(Ohc->AsyncIntList);
+
+ if (IsListEmpty (Head)) {
+ return;
+ }
+
+ while (!IsListEmpty (Head)) {
+ AsyncReq = OHCI_ASYNC_INT_FROM_LINK (Head->ForwardLink);
+ OhciUnlinkAsyncReq (Ohc, AsyncReq, TRUE);
+ }
+
+ DEBUG((EFI_D_INIT, "---OhciFreeAllAsyncReq()\n"));
+}
+
+
+/**
+ Interrupt transfer periodic check handler.
+
+ @param Event The event of the time.
+ @param Context Context of the event, pointer to USB_HC_DEV.
+
+**/
+VOID
+EFIAPI
+OhciMonitorAsyncReqList (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ OHCI_ASYNC_REQUEST *AsyncReq;
+ LIST_ENTRY *Link;
+ USB_HC_DEV *Ohc;
+ VOID *Data;
+ BOOLEAN Finished;
+ OHCI_QH_RESULT QhResult;
+ UINT32 Inputs;
+
+ DEBUG((EFI_D_INFO, "++%a : %d\n", __FUNCTION__, __LINE__));
+
+ Ohc = (USB_HC_DEV *) Context;
+
+ //
+ // Recycle the asynchronous requests expired, and promote
+ // requests waiting to be recycled the next time when this
+ // timer expires
+ //
+
+ if(Ohc->Destory)
+ {
+ DEBUG((EFI_D_ERROR, "%a (Destoryed) : %d\n", __FUNCTION__, __LINE__));
+ UsbHcFreeMem (Ohc->MemPool, Ohc->Destory, Ohc->DestroySize);
+ Ohc->Destory = NULL;
+ Ohc->DestroySize = 0;
+ }
+ //OhciRecycleAsyncReq (Ohc);
+
+ if (IsListEmpty (&(Ohc->AsyncIntList))) {
+ DEBUG((EFI_D_ERROR, "%a (IsListEmpty) : %d\n", __FUNCTION__, __LINE__));
+ return ;
+ }
+
+ //
+ // This loop must be delete safe
+ //
+ Link = Ohc->AsyncIntList.ForwardLink;
+
+ do {
+ AsyncReq = OHCI_ASYNC_INT_FROM_LINK (Link);
+ Link = Link->ForwardLink;
+
+ Finished = OhciCheckTdStatus (Ohc, AsyncReq->EdHw, AsyncReq->IsLow, &QhResult, HC_CLASS_INTERRUPT);
+
+ if (!Finished) {
+ continue;
+ }
+
+ //
+ // Copy the data to temporary buffer if there are some
+ // data transferred. We may have zero-length packet
+ //
+ Data = NULL;
+
+ if (QhResult.Complete != 0) {
+ Data = AllocatePool (QhResult.Complete);
+
+ if (Data == NULL) {
+ return ;
+ }
+
+ CopyMem (Data, AsyncReq->TdSw->Data, QhResult.Complete);
+
+ Inputs = QhResult.Complete;
+ DEBUG((EFI_D_INIT, "INPUT : "));
+ while(Inputs--)
+ {
+ DEBUG((EFI_D_INIT, "0x%02X ", ((UINT8*)Data)[QhResult.Complete - Inputs -1]));
+ }
+ DEBUG((EFI_D_INIT, "\n"));
+ }
+
+ OhciUpdateAsyncReq (Ohc, AsyncReq, QhResult.Result, QhResult.NextToggle);
+
+ //
+ // Now, either transfer is SUCCESS or met errors since
+ // we have skipped to next transfer earlier if current
+ // transfer is still active.
+ //
+ if (QhResult.Result == EFI_USB_NOERROR) {
+ AsyncReq->Callback (Data, QhResult.Complete, AsyncReq->Context, QhResult.Result);
+ } else {
+ //
+ // Leave error recovery to its related device driver.
+ // A common case of the error recovery is to re-submit
+ // the interrupt transfer. When an interrupt transfer
+ // is re-submitted, its position in the linked list is
+ // changed. It is inserted to the head of the linked
+ // list, while this function scans the whole list from
+ // head to tail. Thus, the re-submitted interrupt transfer's
+ // callback function will not be called again in this round.
+ //
+ AsyncReq->Callback (NULL, 0, AsyncReq->Context, QhResult.Result);
+ }
+
+ if (Data != NULL) {
+ gBS->FreePool (Data);
+ }
+ } while (Link != &(Ohc->AsyncIntList));
+
+ DEBUG((EFI_D_INFO, "--%a : %d\n", __FUNCTION__, __LINE__));
+}
diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/OhciDxe/OhciSched.h b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/OhciDxe/OhciSched.h
new file mode 100644
index 000000000..2a3fd7c13
--- /dev/null
+++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/OhciDxe/OhciSched.h
@@ -0,0 +1,270 @@
+/** @file
+
+ The definition for EHCI register operation routines.
+
+Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _EFI_OHCI_SCHED_H_
+#define _EFI_OHCI_SCHED_H_
+
+
+#define OHCI_ASYNC_INT_SIGNATURE SIGNATURE_32 ('u', 'h', 'c', 'a')
+//
+// The failure mask for USB transfer return status. If any of
+// these bit is set, the transfer failed. EFI_USB_ERR_NOEXECUTE
+// and EFI_USB_ERR_NAK are not considered as error condition:
+// the transfer is still going on.
+//
+#define USB_ERR_FAIL_MASK (EFI_USB_ERR_STALL | EFI_USB_ERR_BUFFER | \
+ EFI_USB_ERR_BABBLE | EFI_USB_ERR_CRC | \
+ EFI_USB_ERR_TIMEOUT | EFI_USB_ERR_BITSTUFF | \
+ EFI_USB_ERR_SYSTEM)
+
+
+//
+// Structure to return the result of OHCI QH execution.
+// Result is the final result of the QH's QTD. NextToggle
+// is the next data toggle to use. Complete is the actual
+// length of data transferred.
+//
+typedef struct {
+ UINT32 Result;
+ UINT8 NextToggle;
+ UINTN Complete;
+} OHCI_QH_RESULT;
+
+typedef struct _OHCI_ASYNC_REQUEST OHCI_ASYNC_REQUEST;
+
+//
+// Structure used to manager the asynchronous interrupt transfers.
+//
+struct _OHCI_ASYNC_REQUEST{
+ UINTN Signature;
+ LIST_ENTRY Link;
+ OHCI_ASYNC_REQUEST *Recycle;
+
+ //
+ // Endpoint attributes
+ //
+ UINT8 DevAddr;
+ UINT8 EndPoint;
+ BOOLEAN IsLow;
+ UINTN Interval;
+
+ //
+ // Data and OHC structures
+ //
+ OHCI_TD_SW *TdSw;
+ OHCI_ED_HW *EdHw;
+ UINT8 *Data; // Allocated host memory, not mapped memory
+ UINTN DataLen;
+ VOID *Mapping;
+
+ //
+ // User callback and its context
+ //
+ EFI_ASYNC_USB_TRANSFER_CALLBACK Callback;
+ VOID *Context;
+};
+
+#define OHCI_ASYNC_INT_FROM_LINK(a) \
+ CR (a, OHCI_ASYNC_REQUEST, Link, OHCI_ASYNC_INT_SIGNATURE)
+
+
+/**
+ Create Frame List Structure.
+
+ @param Ohc The OHCI device.
+
+ @return EFI_OUT_OF_RESOURCES Can't allocate memory resources.
+ @return EFI_UNSUPPORTED Map memory fail.
+ @return EFI_SUCCESS Success.
+
+**/
+EFI_STATUS
+OhciInitFrameList (
+ IN USB_HC_DEV *Ohc
+ );
+
+/**
+ Destory FrameList buffer.
+
+ @param Ohc The OHCI device.
+
+ @return None.
+
+**/
+VOID
+OhciDestoryFrameList (
+ IN USB_HC_DEV *Ohc
+ );
+
+
+/**
+ Convert the poll rate to the maxium 2^n that is smaller
+ than Interval.
+
+ @param Interval The poll rate to convert.
+
+ @return The converted poll rate.
+
+**/
+UINTN
+OhciConvertPollRate (
+ IN UINTN Interval
+ );
+
+
+/**
+ Link a queue head (for asynchronous interrupt transfer) to
+ the frame list.
+
+ @param Ohc The OHCI device.
+ @param Qh The queue head to link into.
+
+**/
+VOID
+OhciLinkQhToFrameList (
+ USB_HC_DEV *Ohc,
+ OHCI_QH_SW *Qh
+ );
+
+
+/**
+ Unlink QH from the frame list is easier: find all
+ the precedence node, and pointer there next to QhSw's
+ next.
+
+ @param Ohc The OHCI device.
+ @param Qh The queue head to unlink.
+
+**/
+VOID
+OhciUnlinkQhFromFrameList (
+ USB_HC_DEV *Ohc,
+ OHCI_QH_SW *Qh
+ );
+
+
+/**
+ Check the result of the transfer.
+
+ @param Ohc The OHCI device.
+ @param Qh The queue head of the transfer.
+ @param Td The first TDs of the transfer.
+ @param TimeOut TimeOut value in milliseconds.
+ @param IsLow Is Low Speed Device.
+ @param QhResult The variable to return result.
+
+ @retval EFI_SUCCESS The transfer finished with success.
+ @retval EFI_DEVICE_ERROR Transfer failed.
+
+**/
+EFI_STATUS
+OhciExecuteTransfer (
+ IN USB_HC_DEV *Ohc,
+ IN OHCI_ED_HW *Ed,
+ IN UINTN TimeOut,
+ IN BOOLEAN IsLow,
+ OUT OHCI_QH_RESULT *QhResult
+ );
+
+
+/**
+ Create Async Request node, and Link to List.
+
+ @param Ohc The OHCI device.
+ @param Qh The queue head of the transfer.
+ @param FirstTd First TD of the transfer.
+ @param DevAddr Device Address.
+ @param EndPoint EndPoint Address.
+ @param DataLen Data length.
+ @param Interval Polling Interval when inserted to frame list.
+ @param Data Data buffer, unmapped.
+ @param Callback Callback after interrupt transfeer.
+ @param Context Callback Context passed as function parameter.
+ @param IsLow Is Low Speed.
+
+ @retval EFI_SUCCESS An asynchronous transfer is created.
+ @retval EFI_INVALID_PARAMETER Paremeter is error.
+ @retval EFI_OUT_OF_RESOURCES Failed because of resource shortage.
+
+**/
+EFI_STATUS
+OhciCreateAsyncReq (
+ IN USB_HC_DEV *Ohc,
+ IN OHCI_ED_HW *EdHw,
+ IN OHCI_TD_SW *TdSw,
+ IN UINT8 DevAddr,
+ IN UINT8 EndPoint,
+ IN UINTN DataLen,
+ IN UINTN Interval,
+ IN UINT8 *Data,
+ IN EFI_ASYNC_USB_TRANSFER_CALLBACK Callback,
+ IN VOID *Context,
+ IN BOOLEAN IsLow
+ );
+
+
+/**
+ Delete Async Interrupt QH and TDs.
+
+ @param Ohc The OHCI device.
+ @param DevAddr Device Address.
+ @param EndPoint EndPoint Address.
+ @param Toggle The next data toggle to use.
+
+ @retval EFI_SUCCESS The request is deleted.
+ @retval EFI_INVALID_PARAMETER Paremeter is error.
+ @retval EFI_NOT_FOUND The asynchronous isn't found.
+
+**/
+EFI_STATUS
+OhciRemoveAsyncReq (
+ IN USB_HC_DEV *Ohc,
+ IN UINT8 DevAddr,
+ IN UINT8 EndPoint,
+ OUT UINT8 *Toggle
+ );
+
+
+/**
+ Release all the asynchronous transfers on the lsit.
+
+ @param Ohc The OHCI device.
+
+ @return None.
+
+**/
+VOID
+OhciFreeAllAsyncReq (
+ IN USB_HC_DEV *Ohc
+ );
+
+
+/**
+ Interrupt transfer periodic check handler.
+
+ @param Event The event of the time.
+ @param Context Context of the event, pointer to USB_HC_DEV.
+
+ @return None.
+
+**/
+VOID
+EFIAPI
+OhciMonitorAsyncReqList (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ );
+
+#endif
diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/OhciDxe/UsbHcMem.c b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/OhciDxe/UsbHcMem.c
new file mode 100644
index 000000000..919c05023
--- /dev/null
+++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/OhciDxe/UsbHcMem.c
@@ -0,0 +1,564 @@
+/** @file
+
+ The routine procedure for uhci memory allocate/free.
+
+Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "Ohci.h"
+
+
+/**
+ Allocate a block of memory to be used by the buffer pool.
+
+ @param Pool The buffer pool to allocate memory for.
+ @param Pages How many pages to allocate.
+
+ @return The allocated memory block or NULL if failed.
+
+**/
+USBHC_MEM_BLOCK *
+UsbHcAllocMemBlock (
+ IN USBHC_MEM_POOL *Pool,
+ IN UINTN Pages
+ )
+{
+ USBHC_MEM_BLOCK *Block;
+ EFI_PCI_IO_PROTOCOL *PciIo;
+ VOID *BufHost;
+ VOID *Mapping;
+ EFI_PHYSICAL_ADDRESS MappedAddr;
+ UINTN Bytes;
+ EFI_STATUS Status;
+
+ PciIo = Pool->PciIo;
+
+ Block = AllocateZeroPool (sizeof (USBHC_MEM_BLOCK));
+ if (Block == NULL) {
+ return NULL;
+ }
+
+ //
+ // each bit in the bit array represents USBHC_MEM_UNIT
+ // bytes of memory in the memory block.
+ //
+ ASSERT (USBHC_MEM_UNIT * 8 <= EFI_PAGE_SIZE);
+
+ Block->BufLen = EFI_PAGES_TO_SIZE (Pages);
+ Block->BitsLen = Block->BufLen / (USBHC_MEM_UNIT * 8);
+ Block->Bits = AllocateZeroPool (Block->BitsLen);
+
+ if (Block->Bits == NULL) {
+ gBS->FreePool (Block);
+ return NULL;
+ }
+
+ //
+ // Allocate the number of Pages of memory, then map it for
+ // bus master read and write.
+ //
+ Status = PciIo->AllocateBuffer (
+ PciIo,
+ AllocateAnyPages,
+ EfiBootServicesData,
+ Pages,
+ &BufHost,
+ 0
+ );
+
+ if (EFI_ERROR (Status)) {
+ goto FREE_BITARRAY;
+ }
+
+ Bytes = EFI_PAGES_TO_SIZE (Pages);
+ Status = PciIo->Map (
+ PciIo,
+ EfiPciIoOperationBusMasterCommonBuffer,
+ BufHost,
+ &Bytes,
+ &MappedAddr,
+ &Mapping
+ );
+
+ if (EFI_ERROR (Status) || (Bytes != EFI_PAGES_TO_SIZE (Pages))) {
+ goto FREE_BUFFER;
+ }
+
+ //
+ // Check whether the data structure used by the host controller
+ // should be restricted into the same 4G
+ //
+ if (Pool->Check4G && (Pool->Which4G != USB_HC_HIGH_32BIT (MappedAddr))) {
+ PciIo->Unmap (PciIo, Mapping);
+ goto FREE_BUFFER;
+ }
+
+ Block->BufHost = BufHost;
+ Block->Buf = (UINT8 *) ((UINTN) MappedAddr);
+ Block->Mapping = Mapping;
+
+ return Block;
+
+FREE_BUFFER:
+ PciIo->FreeBuffer (PciIo, Pages, BufHost);
+
+FREE_BITARRAY:
+ gBS->FreePool (Block->Bits);
+ gBS->FreePool (Block);
+ return NULL;
+}
+
+
+/**
+ Free the memory block from the memory pool.
+
+ @param Pool The memory pool to free the block from.
+ @param Block The memory block to free.
+
+**/
+VOID
+UsbHcFreeMemBlock (
+ IN USBHC_MEM_POOL *Pool,
+ IN USBHC_MEM_BLOCK *Block
+ )
+{
+ EFI_PCI_IO_PROTOCOL *PciIo;
+
+ ASSERT ((Pool != NULL) && (Block != NULL));
+
+ PciIo = Pool->PciIo;
+
+ //
+ // Unmap the common buffer then free the structures
+ //
+ PciIo->Unmap (PciIo, Block->Mapping);
+ PciIo->FreeBuffer (PciIo, EFI_SIZE_TO_PAGES (Block->BufLen), Block->BufHost);
+
+ gBS->FreePool (Block->Bits);
+ gBS->FreePool (Block);
+}
+
+
+/**
+ Alloc some memory from the block.
+
+ @param Block The memory block to allocate memory from.
+ @param Units Number of memory units to allocate.
+
+ @return EFI_SUCCESS The needed memory is allocated.
+ @return EFI_NOT_FOUND Can't find the free memory.
+
+**/
+VOID *
+UsbHcAllocMemFromBlock (
+ IN USBHC_MEM_BLOCK *Block,
+ IN UINTN Units
+ )
+{
+ UINTN Byte;
+ UINT8 Bit;
+ UINTN StartByte;
+ UINT8 StartBit;
+ UINTN Available;
+ UINTN Count;
+
+ ASSERT ((Block != 0) && (Units != 0));
+
+ StartByte = 0;
+ StartBit = 0;
+ Available = 0;
+
+ for (Byte = 0, Bit = 0; Byte < Block->BitsLen;) {
+ //
+ // If current bit is zero, the corresponding memory unit is
+ // available, otherwise we need to restart our searching.
+ // Available counts the consective number of zero bit.
+ //
+ if (!USB_HC_BIT_IS_SET (Block->Bits[Byte], Bit)) {
+ Available++;
+
+ if (Available >= Units) {
+ break;
+ }
+
+ NEXT_BIT (Byte, Bit);
+
+ } else {
+ NEXT_BIT (Byte, Bit);
+
+ Available = 0;
+ StartByte = Byte;
+ StartBit = Bit;
+ }
+ }
+
+ if (Available < Units) {
+ return NULL;
+ }
+
+ //
+ // Mark the memory as allocated
+ //
+ Byte = StartByte;
+ Bit = StartBit;
+
+ for (Count = 0; Count < Units; Count++) {
+ ASSERT (!USB_HC_BIT_IS_SET (Block->Bits[Byte], Bit));
+
+ Block->Bits[Byte] = (UINT8) (Block->Bits[Byte] | (UINT8) USB_HC_BIT (Bit));
+ NEXT_BIT (Byte, Bit);
+ }
+
+ return Block->Buf + (StartByte * 8 + StartBit) * USBHC_MEM_UNIT;
+}
+
+/**
+ Calculate the corresponding pci bus address according to the Mem parameter.
+
+ @param Pool The memory pool of the host controller.
+ @param Mem The pointer to host memory.
+ @param Size The size of the memory region.
+
+ @return the pci memory address
+**/
+EFI_PHYSICAL_ADDRESS
+UsbHcGetPciAddressForHostMem (
+ IN USBHC_MEM_POOL *Pool,
+ IN VOID *Mem,
+ IN UINTN Size
+ )
+{
+ USBHC_MEM_BLOCK *Head;
+ USBHC_MEM_BLOCK *Block;
+ UINTN AllocSize;
+ EFI_PHYSICAL_ADDRESS PhyAddr;
+ UINTN Offset;
+
+ Head = Pool->Head;
+ AllocSize = USBHC_MEM_ROUND (Size);
+
+ if (Mem == NULL) {
+ return 0;
+ }
+
+ for (Block = Head; Block != NULL; Block = Block->Next) {
+ //
+ // scan the memory block list for the memory block that
+ // completely contains the allocated memory.
+ //
+ if ((Block->BufHost <= (UINT8 *) Mem) && (((UINT8 *) Mem + AllocSize) <= (Block->BufHost + Block->BufLen))) {
+ break;
+ }
+ }
+
+ ASSERT ((Block != NULL));
+ //
+ // calculate the pci memory address for host memory address.
+ //
+ Offset = (UINT8 *)Mem - Block->BufHost;
+ PhyAddr = (EFI_PHYSICAL_ADDRESS)(UINTN) (Block->Buf + Offset);
+ return PhyAddr;
+}
+
+/**
+ Insert the memory block to the pool's list of the blocks.
+
+ @param Head The head of the memory pool's block list.
+ @param Block The memory block to insert.
+
+**/
+VOID
+UsbHcInsertMemBlockToPool (
+ IN USBHC_MEM_BLOCK *Head,
+ IN USBHC_MEM_BLOCK *Block
+ )
+{
+ ASSERT ((Head != NULL) && (Block != NULL));
+ Block->Next = Head->Next;
+ Head->Next = Block;
+}
+
+
+/**
+ Is the memory block empty?
+
+ @param Block The memory block to check.
+
+ @return TRUE The memory block is empty.
+ @return FALSE The memory block isn't empty.
+
+**/
+BOOLEAN
+UsbHcIsMemBlockEmpty (
+ IN USBHC_MEM_BLOCK *Block
+ )
+{
+ UINTN Index;
+
+ for (Index = 0; Index < Block->BitsLen; Index++) {
+ if (Block->Bits[Index] != 0) {
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+
+/**
+ Unlink the memory block from the pool's list.
+
+ @param Head The block list head of the memory's pool.
+ @param BlockToUnlink The memory block to unlink.
+
+**/
+VOID
+UsbHcUnlinkMemBlock (
+ IN USBHC_MEM_BLOCK *Head,
+ IN USBHC_MEM_BLOCK *BlockToUnlink
+ )
+{
+ USBHC_MEM_BLOCK *Block;
+
+ ASSERT ((Head != NULL) && (BlockToUnlink != NULL));
+
+ for (Block = Head; Block != NULL; Block = Block->Next) {
+ if (Block->Next == BlockToUnlink) {
+ Block->Next = BlockToUnlink->Next;
+ BlockToUnlink->Next = NULL;
+ break;
+ }
+ }
+}
+
+
+/**
+ Initialize the memory management pool for the host controller.
+
+ @param PciIo The PciIo that can be used to access the host controller.
+ @param Check4G Whether the host controller requires allocated memory
+ from one 4G address space.
+ @param Which4G The 4G memory area each memory allocated should be from.
+
+ @return EFI_SUCCESS The memory pool is initialized.
+ @return EFI_OUT_OF_RESOURCE Fail to init the memory pool.
+
+**/
+USBHC_MEM_POOL *
+UsbHcInitMemPool (
+ IN EFI_PCI_IO_PROTOCOL *PciIo,
+ IN BOOLEAN Check4G,
+ IN UINT32 Which4G
+ )
+{
+ USBHC_MEM_POOL *Pool;
+
+ Pool = AllocatePool (sizeof (USBHC_MEM_POOL));
+
+ if (Pool == NULL) {
+ return Pool;
+ }
+
+ Pool->PciIo = PciIo;
+ Pool->Check4G = Check4G;
+ Pool->Which4G = Which4G;
+ Pool->Head = UsbHcAllocMemBlock (Pool, USBHC_MEM_DEFAULT_PAGES);
+
+ if (Pool->Head == NULL) {
+ gBS->FreePool (Pool);
+ Pool = NULL;
+ }
+
+ return Pool;
+}
+
+
+/**
+ Release the memory management pool.
+
+ @param Pool The USB memory pool to free.
+
+ @return EFI_SUCCESS The memory pool is freed.
+ @return EFI_DEVICE_ERROR Failed to free the memory pool.
+
+**/
+EFI_STATUS
+UsbHcFreeMemPool (
+ IN USBHC_MEM_POOL *Pool
+ )
+{
+ USBHC_MEM_BLOCK *Block;
+
+ ASSERT (Pool->Head != NULL);
+
+ //
+ // Unlink all the memory blocks from the pool, then free them.
+ // UsbHcUnlinkMemBlock can't be used to unlink and free the
+ // first block.
+ //
+ for (Block = Pool->Head->Next; Block != NULL; Block = Pool->Head->Next) {
+ UsbHcUnlinkMemBlock (Pool->Head, Block);
+ UsbHcFreeMemBlock (Pool, Block);
+ }
+
+ UsbHcFreeMemBlock (Pool, Pool->Head);
+ gBS->FreePool (Pool);
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Allocate some memory from the host controller's memory pool
+ which can be used to communicate with host controller.
+
+ @param Pool The host controller's memory pool.
+ @param Size Size of the memory to allocate.
+
+ @return The allocated memory or NULL.
+
+**/
+VOID *
+UsbHcAllocateMem (
+ IN USBHC_MEM_POOL *Pool,
+ IN UINTN Size
+ )
+{
+ USBHC_MEM_BLOCK *Head;
+ USBHC_MEM_BLOCK *Block;
+ USBHC_MEM_BLOCK *NewBlock;
+ VOID *Mem;
+ UINTN AllocSize;
+ UINTN Pages;
+
+ Mem = NULL;
+ AllocSize = USBHC_MEM_ROUND (Size);
+ Head = Pool->Head;
+ ASSERT (Head != NULL);
+
+ //
+ // First check whether current memory blocks can satisfy the allocation.
+ //
+ for (Block = Head; Block != NULL; Block = Block->Next) {
+ Mem = UsbHcAllocMemFromBlock (Block, AllocSize / USBHC_MEM_UNIT);
+
+ if (Mem != NULL) {
+ ZeroMem (Mem, Size);
+ break;
+ }
+ }
+
+ if (Mem != NULL) {
+ return Mem;
+ }
+
+ //
+ // Create a new memory block if there is not enough memory
+ // in the pool. If the allocation size is larger than the
+ // default page number, just allocate a large enough memory
+ // block. Otherwise allocate default pages.
+ //
+ if (AllocSize > EFI_PAGES_TO_SIZE (USBHC_MEM_DEFAULT_PAGES)) {
+ Pages = EFI_SIZE_TO_PAGES (AllocSize) + 1;
+ } else {
+ Pages = USBHC_MEM_DEFAULT_PAGES;
+ }
+
+ NewBlock = UsbHcAllocMemBlock (Pool, Pages);
+
+ if (NewBlock == NULL) {
+ DEBUG ((EFI_D_INFO, "UsbHcAllocateMem: failed to allocate block\n"));
+ return NULL;
+ }
+
+ //
+ // Add the new memory block to the pool, then allocate memory from it
+ //
+ UsbHcInsertMemBlockToPool (Head, NewBlock);
+ Mem = UsbHcAllocMemFromBlock (NewBlock, AllocSize / USBHC_MEM_UNIT);
+
+ if (Mem != NULL) {
+ ZeroMem (Mem, Size);
+ }
+
+ return Mem;
+}
+
+
+/**
+ Free the allocated memory back to the memory pool.
+
+ @param Pool The memory pool of the host controller.
+ @param Mem The memory to free.
+ @param Size The size of the memory to free.
+
+**/
+VOID
+UsbHcFreeMem (
+ IN USBHC_MEM_POOL *Pool,
+ IN VOID *Mem,
+ IN UINTN Size
+ )
+{
+ USBHC_MEM_BLOCK *Head;
+ USBHC_MEM_BLOCK *Block;
+ UINT8 *ToFree;
+ UINTN AllocSize;
+ UINTN Byte;
+ UINTN Bit;
+ UINTN Count;
+
+ Head = Pool->Head;
+ AllocSize = USBHC_MEM_ROUND (Size);
+ ToFree = (UINT8 *) Mem;
+
+ for (Block = Head; Block != NULL; Block = Block->Next) {
+ //
+ // scan the memory block list for the memory block that
+ // completely contains the memory to free.
+ //
+ if ((Block->Buf <= ToFree) && ((ToFree + AllocSize) <= (Block->Buf + Block->BufLen))) {
+ //
+ // compute the start byte and bit in the bit array
+ //
+ Byte = ((ToFree - Block->Buf) / USBHC_MEM_UNIT) / 8;
+ Bit = ((ToFree - Block->Buf) / USBHC_MEM_UNIT) % 8;
+
+ //
+ // reset associated bits in bit arry
+ //
+ for (Count = 0; Count < (AllocSize / USBHC_MEM_UNIT); Count++) {
+ ASSERT (USB_HC_BIT_IS_SET (Block->Bits[Byte], Bit));
+
+ Block->Bits[Byte] = (UINT8) (Block->Bits[Byte] ^ USB_HC_BIT (Bit));
+ NEXT_BIT (Byte, Bit);
+ }
+
+ break;
+ }
+ }
+
+ //
+ // If Block == NULL, it means that the current memory isn't
+ // in the host controller's pool. This is critical because
+ // the caller has passed in a wrong memory point
+ //
+ ASSERT (Block != NULL);
+
+ //
+ // Release the current memory block if it is empty and not the head
+ //
+ if ((Block != Head) && UsbHcIsMemBlockEmpty (Block)) {
+ UsbHcUnlinkMemBlock (Head, Block);
+ UsbHcFreeMemBlock (Pool, Block);
+ }
+
+ return ;
+}
diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/OhciDxe/UsbHcMem.h b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/OhciDxe/UsbHcMem.h
new file mode 100644
index 000000000..5192abd2f
--- /dev/null
+++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/OhciDxe/UsbHcMem.h
@@ -0,0 +1,161 @@
+/** @file
+
+ This file contains the definination for host controller memory management routines
+
+Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _EFI_EHCI_MEM_H_
+#define _EFI_EHCI_MEM_H_
+
+#define USB_HC_BIT(a) ((UINTN)(1 << (a)))
+
+#define USB_HC_BIT_IS_SET(Data, Bit) \
+ ((BOOLEAN)(((Data) & USB_HC_BIT(Bit)) == USB_HC_BIT(Bit)))
+
+#define USB_HC_HIGH_32BIT(Addr64) \
+ ((UINT32)(RShiftU64((UINTN)(Addr64), 32) & 0XFFFFFFFF))
+
+
+typedef struct _USBHC_MEM_BLOCK USBHC_MEM_BLOCK;
+struct _USBHC_MEM_BLOCK {
+ UINT8 *Bits; // Bit array to record which unit is allocated
+ UINTN BitsLen;
+ UINT8 *Buf;
+ UINT8 *BufHost;
+ UINTN BufLen; // Memory size in bytes
+ VOID *Mapping;
+ USBHC_MEM_BLOCK *Next;
+};
+
+//
+// USBHC_MEM_POOL is used to manage the memory used by USB
+// host controller. EHCI requires the control memory and transfer
+// data to be on the same 4G memory.
+//
+typedef struct _USBHC_MEM_POOL {
+ EFI_PCI_IO_PROTOCOL *PciIo;
+ BOOLEAN Check4G;
+ UINT32 Which4G;
+ USBHC_MEM_BLOCK *Head;
+} USBHC_MEM_POOL;
+
+//
+// Memory allocation unit, must be 2^n, n>4
+//
+#define USBHC_MEM_UNIT 64
+
+#define USBHC_MEM_UNIT_MASK (USBHC_MEM_UNIT - 1)
+#define USBHC_MEM_DEFAULT_PAGES 16
+
+#define USBHC_MEM_ROUND(Len) (((Len) + USBHC_MEM_UNIT_MASK) & (~USBHC_MEM_UNIT_MASK))
+
+//
+// Advance the byte and bit to the next bit, adjust byte accordingly.
+//
+#define NEXT_BIT(Byte, Bit) \
+ do { \
+ (Bit)++; \
+ if ((Bit) > 7) { \
+ (Byte)++; \
+ (Bit) = 0; \
+ } \
+ } while (0)
+
+
+/**
+ Initialize the memory management pool for the host controller.
+
+ @param PciIo The PciIo that can be used to access the host controller.
+ @param Check4G Whether the host controller requires allocated memory
+ from one 4G address space.
+ @param Which4G The 4G memory area each memory allocated should be from.
+
+ @retval EFI_SUCCESS The memory pool is initialized.
+ @retval EFI_OUT_OF_RESOURCE Fail to init the memory pool.
+
+**/
+USBHC_MEM_POOL *
+UsbHcInitMemPool (
+ IN EFI_PCI_IO_PROTOCOL *PciIo,
+ IN BOOLEAN Check4G,
+ IN UINT32 Which4G
+ );
+
+
+/**
+ Release the memory management pool.
+
+ @param Pool The USB memory pool to free.
+
+ @return EFI_SUCCESS The memory pool is freed.
+ @return EFI_DEVICE_ERROR Failed to free the memory pool.
+
+**/
+EFI_STATUS
+UsbHcFreeMemPool (
+ IN USBHC_MEM_POOL *Pool
+ );
+
+
+
+/**
+ Allocate some memory from the host controller's memory pool
+ which can be used to communicate with host controller.
+
+ @param Pool The host controller's memory pool.
+ @param Size Size of the memory to allocate.
+
+ @return The allocated memory or NULL.
+
+**/
+VOID *
+UsbHcAllocateMem (
+ IN USBHC_MEM_POOL *Pool,
+ IN UINTN Size
+ );
+
+
+
+/**
+ Free the allocated memory back to the memory pool.
+
+ @param Pool The memory pool of the host controller.
+ @param Mem The memory to free.
+ @param Size The size of the memory to free.
+
+ @return None.
+
+**/
+VOID
+UsbHcFreeMem (
+ IN USBHC_MEM_POOL *Pool,
+ IN VOID *Mem,
+ IN UINTN Size
+ );
+
+/**
+ Calculate the corresponding pci bus address according to the Mem parameter.
+
+ @param Pool The memory pool of the host controller.
+ @param Mem The pointer to host memory.
+ @param Size The size of the memory region.
+
+ @return the pci memory address
+**/
+EFI_PHYSICAL_ADDRESS
+UsbHcGetPciAddressForHostMem (
+ IN USBHC_MEM_POOL *Pool,
+ IN VOID *Mem,
+ IN UINTN Size
+ );
+
+#endif
diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/PciEmulation/Exynos5_USB.c b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/PciEmulation/Exynos5_USB.c
new file mode 100644
index 000000000..e89ba4b0a
--- /dev/null
+++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/PciEmulation/Exynos5_USB.c
@@ -0,0 +1,353 @@
+/** @file
+
+ Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <Uefi.h>
+#include <Exynos5_USB2Phy.h>
+#include <Exynos5_USB3Phy.h>
+#include <Exynos5_USB3Drd.h>
+
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiLib.h>
+#include <Library/PcdLib.h>
+#include <Library/IoLib.h>
+#include <Library/TimerLib.h>
+#include <Protocol/ExynosGpio.h>
+#include <Platform/ArmPlatform.h>
+
+#define PHY_ENABLE (1 << 0)
+#define PHY_DISABLE (0)
+
+enum usb_phy_type {
+ USB_PHY = (0x1 << 0),
+ USB_PHY0 = (0x1 << 0),
+ USB_PHY1 = (0x1 << 1),
+ USB_PHY_HSIC0 = (0x1 << 1),
+ USB_PHY_HSIC1 = (0x1 << 2),
+};
+
+
+static void usb_clk_get(enum usb_clk_type clk_type)
+{
+ if( clk_type == USBOTG_CLK) {
+ MmioWrite32(CLK_GATE_IP_FSYS, MmioRead32(CLK_GATE_IP_FSYS) | (1<<7));
+ } else if( clk_type == USBHOST_CLK) {
+ MmioWrite32(CLK_GATE_IP_FSYS, MmioRead32(CLK_GATE_IP_FSYS) | (1<<18));
+ } else if( clk_type == USBDRD30_CLK) {
+ MmioWrite32(CLK_GATE_IP_FSYS, MmioRead32(CLK_GATE_IP_FSYS) | (1<<19));
+ } else {
+ DEBUG ((EFI_D_ERROR, "FAIL! usb_clk_get\n"));
+ }
+
+ return;
+}
+
+static void usb_clk_put(enum usb_clk_type clk_type)
+{
+ if( clk_type == USBOTG_CLK) {
+ MmioWrite32(CLK_GATE_IP_FSYS, MmioRead32(CLK_GATE_IP_FSYS) & ~ (1<<7));
+ } else if( clk_type == USBHOST_CLK) {
+ MmioWrite32(CLK_GATE_IP_FSYS, MmioRead32(CLK_GATE_IP_FSYS) & ~ (1<<18));
+ } else if( clk_type == USBDRD30_CLK) {
+ MmioWrite32(CLK_GATE_IP_FSYS, MmioRead32(CLK_GATE_IP_FSYS) & ~ (1<<19));
+ } else {
+ DEBUG ((EFI_D_ERROR, "FAIL! usb_clk_get\n"));
+ }
+
+ return;
+}
+
+//------------------------------------------------------------------------------------
+
+//////////
+// Function Name : USBPHY_Ctr48MhzClk
+// Function Desctiption : This function sets clk48m_ohci in Suspend Mode.
+// Input : NONE
+// Output : NONE
+// Version :
+void USBPHY_Ctr48MhzClk(UINT8 bEnable_48Mhz)
+{
+
+ UINT32 uTemp;
+
+ uTemp = MmioRead32(rUPHY_OHCICTRL);
+ uTemp &= ~(1<<2);
+ uTemp |= bEnable_48Mhz<<2;
+ MmioWrite32(rUPHY_OHCICTRL, uTemp);
+}
+
+static int exynos5_usb_host_phy20_is_on(void)
+{
+ return (MmioRead32(EXYNOS5_USB2_PHY_HOST_CTRL0) & HOST_CTRL0_PHYSWRSTALL) ? 0 : 1;
+}
+
+static void exynos5_usb_phy_control(enum usb_phy_type phy_type , int on)
+{
+ if (phy_type & USB_PHY0)
+ MmioWrite32(EXYNOS5_USBDEV_PHY_CONTROL, on);
+ if (phy_type & USB_PHY1)
+ MmioWrite32(EXYNOS5_USBHOST_PHY_CONTROL, on);
+}
+
+void exynos5_usb_phy20_init(void)
+{
+ EFI_STATUS Status;
+ EXYNOS_GPIO *Gpio;
+ UINT32 hostphy_ctrl0;
+ UINT32 hsic_ctrl;
+ UINT32 ehcictrl;
+
+ DEBUG ((EFI_D_ERROR, "exynos5_usb_phy20_init START $$$\n"));
+
+ Status = gBS->LocateProtocol(&gSamsungPlatformGpioProtocolGuid, NULL, (VOID **)&Gpio);
+ ASSERT_EFI_ERROR(Status);
+
+ if(PcdGetBool(PcdExynos5250Evt1))
+ {
+ Gpio->Set(Gpio, USB_2_EVT1, GPIO_MODE_OUTPUT_1);
+ Gpio->SetPull(Gpio, USB_2_EVT1, GPIO_PULL_NONE);
+ }
+
+ if (exynos5_usb_host_phy20_is_on())
+ {
+ DEBUG ((EFI_D_ERROR, "Already power on PHY $$$\n"));
+ return;
+ }
+
+ // Must be enable usbhost & usbotg clk
+ usb_clk_get(USBHOST_CLK);
+ usb_clk_get(USBOTG_CLK);
+
+ MmioWrite32(ETC6PUD, (MmioRead32(ETC6PUD) & ~(0x3 << 14)) | (0x3 << 14));
+
+ exynos5_usb_phy_control(USB_PHY1, PHY_ENABLE);
+
+ /* Host and Device should be set at the same time */
+ hostphy_ctrl0 = MmioRead32(EXYNOS5_USB2_PHY_HOST_CTRL0);
+ hostphy_ctrl0 &= ~(HOST_CTRL0_FSEL_MASK);
+
+ /* 2.0 phy reference clock configuration */
+ // default reference clock 24MZ
+ hostphy_ctrl0 |= CLKSEL_24M;
+
+ /* COMMON Block configuration during suspend */
+ hostphy_ctrl0 &= ~(HOST_CTRL0_COMMONONN);
+
+ /* host phy reset */
+ hostphy_ctrl0 &= ~(HOST_CTRL0_PHYSWRST | HOST_CTRL0_PHYSWRSTALL | HOST_CTRL0_SIDDQ);
+ hostphy_ctrl0 &= ~(HOST_CTRL0_FORCESUSPEND | HOST_CTRL0_FORCESLEEP);
+ hostphy_ctrl0 |= (HOST_CTRL0_LINKSWRST | HOST_CTRL0_UTMISWRST);
+ MmioWrite32(EXYNOS5_USB2_PHY_HOST_CTRL0, hostphy_ctrl0);
+ MicroSecondDelay(10);
+ MicroSecondDelay(10);
+ hostphy_ctrl0 &= ~(HOST_CTRL0_LINKSWRST | HOST_CTRL0_UTMISWRST);
+ MmioWrite32(EXYNOS5_USB2_PHY_HOST_CTRL0, hostphy_ctrl0);
+
+ DEBUG ((EFI_D_ERROR, "exynos5_usb_phy20_init Clk set $$$\n"));
+
+ /* HSIC phy reset */
+ hsic_ctrl = (HSIC_CTRL_REFCLKDIV(0x24) | HSIC_CTRL_REFCLKSEL(0x2) |HSIC_CTRL_PHYSWRST);
+ MmioWrite32(PHY_HSIC_CTRL1, hsic_ctrl);
+ MmioWrite32(PHY_HSIC_CTRL2, hsic_ctrl);
+ MicroSecondDelay(10);
+ MicroSecondDelay(10);
+ hsic_ctrl = (HSIC_CTRL_REFCLKDIV(0x24) | HSIC_CTRL_REFCLKSEL(0x2));
+ MmioWrite32(PHY_HSIC_CTRL1, hsic_ctrl);
+ MmioWrite32(PHY_HSIC_CTRL2, hsic_ctrl);
+
+ MicroSecondDelay(80);
+ MicroSecondDelay(80);
+
+ /* enable EHCI DMA burst */
+ ehcictrl = MmioRead32(PHY_HOST_EHCICTRL);
+ ehcictrl |= (EHCICTRL_ENAINCRXALIGN | EHCICTRL_ENAINCR4 |EHCICTRL_ENAINCR8 | EHCICTRL_ENAINCR16);
+ MmioWrite32(PHY_HOST_EHCICTRL, ehcictrl);
+
+ DEBUG ((EFI_D_ERROR, "exynos5_usb_phy20_init END $$$\n"));
+}
+
+void exynos5_usb_phy20_off(void)
+{
+ UINT32 uTemp;
+
+ uTemp = MmioRead32(rUPHY_USBCTRL0);
+ uTemp |= (0x1<<9);
+ MmioWrite32(rUPHY_USBCTRL0, uTemp);
+
+ usb_clk_put(USBOTG_CLK);
+ usb_clk_put(USBHOST_CLK);
+}
+
+
+void exynos5_usb_phy30_init(void)
+{
+ UINT32 reg;
+ DEBUG ((EFI_D_ERROR, "exynos5_usb_phy30_init START $$$\n"));
+
+ MmioWrite32(0x10020548, 0x0BF00000);
+ usb_clk_get(USBDRD30_CLK);
+
+ exynos5_usb_phy_control(USB_PHY0, PHY_ENABLE);
+
+ /* Reset USB 3.0 PHY */
+ MmioWrite32(EXYNOS_USB3_PHYREG0, 0x00000000);
+ MmioWrite32(EXYNOS_USB3_PHYPARAM0, 0x24d4e6e4);
+ MmioWrite32(EXYNOS_USB3_PHYRESUME, 0x00000000);
+
+ if(PcdGetBool(PcdExynos5250Evt1))
+ {
+ MmioWrite32(EXYNOS_USB3_LINKSYSTEM, 0x08000000);
+ MmioWrite32(EXYNOS_USB3_PHYPARAM1, 0x03fff81C);
+ MmioWrite32(EXYNOS_USB3_PHYBATCHG, 0x00000004);
+ } else {
+ MmioWrite32(EXYNOS_USB3_LINKSYSTEM, 0x087FFFC0);
+ MmioWrite32(EXYNOS_USB3_PHYPARAM1, 0x03fff820);
+ MmioWrite32(EXYNOS_USB3_PHYBATCHG, 0x00000000);
+ MmioWrite32(EXYNOS_USB3_LINKPORT, (MmioRead32(EXYNOS_USB3_LINKPORT) & ~(0x3<<4)) |(0x3<<2));
+ }
+
+ /* UTMI Power Control */
+ MmioWrite32(EXYNOS_USB3_PHYUTMI, EXYNOS_USB3_PHYUTMI_OTGDISABLE);
+
+ if(PcdGetBool(PcdExynos5250Evt1))
+ {
+ /* Set 100MHz external clock */
+ reg = EXYNOS_USB3_PHYCLKRST_PORTRESET |
+ /* HS PLL uses ref_pad_clk{p,m} or ref_alt_clk_{p,m}
+ * as reference */
+ EXYNOS_USB3_PHYCLKRST_REFCLKSEL(3) |
+ /* Digital power supply in normal operating mode */
+ EXYNOS_USB3_PHYCLKRST_RETENABLEN |
+ /* 0x27-100MHz, 0x2a-24MHz, 0x31-20MHz, 0x38-19.2MHz */
+ EXYNOS_USB3_PHYCLKRST_FSEL(0x5) |
+ /* 0x19-100MHz, 0x68-24MHz, 0x7d-20Mhz */
+ EXYNOS_USB3_PHYCLKRST_MPLL_MULTIPLIER(0x68) |
+ EXYNOS_USB3_PHYCLKRST_SSC_REF_CLK_SEL(0x88) |
+ /* Enable ref clock for SS function */
+ EXYNOS_USB3_PHYCLKRST_REF_SSP_EN |
+ /* Enable spread spectrum */
+ EXYNOS_USB3_PHYCLKRST_SSC_EN;
+ } else {
+ /* Set 100MHz external clock */
+ reg = EXYNOS_USB3_PHYCLKRST_PORTRESET |
+ /* HS PLL uses ref_pad_clk{p,m} or ref_alt_clk_{p,m}
+ * as reference */
+ EXYNOS_USB3_PHYCLKRST_REFCLKSEL(2) |
+ /* Digital power supply in normal operating mode */
+ EXYNOS_USB3_PHYCLKRST_RETENABLEN |
+ /* 0x27-100MHz, 0x2a-24MHz, 0x31-20MHz, 0x38-19.2MHz */
+ EXYNOS_USB3_PHYCLKRST_FSEL(0x27) |
+ /* 0x19-100MHz, 0x68-24MHz, 0x7d-20Mhz */
+ EXYNOS_USB3_PHYCLKRST_MPLL_MULTIPLIER(0x19) |
+ EXYNOS_USB3_PHYCLKRST_SSC_REF_CLK_SEL(0x00) |
+ /* Enable ref clock for SS function */
+ EXYNOS_USB3_PHYCLKRST_REF_SSP_EN |
+ /* Enable spread spectrum */
+ EXYNOS_USB3_PHYCLKRST_SSC_EN |
+ EXYNOS_USB3_PHYCLKRST_COMMONONN;
+ }
+ MmioWrite32(EXYNOS_USB3_PHYCLKRST, reg);
+
+ MicroSecondDelay(10);
+ MicroSecondDelay(10);
+
+ reg &= ~(EXYNOS_USB3_PHYCLKRST_PORTRESET);
+
+ MmioWrite32(EXYNOS_USB3_PHYCLKRST, reg);
+ DEBUG ((EFI_D_ERROR, "exynos5_usb_phy30_init END $$$\n"));
+
+}
+
+void exynos_xhci_phy_set(void)
+{
+ /* The reset values:
+ * GUSB2PHYCFG(0) = 0x00002400
+ * GUSB3PIPECTL(0) = 0x00260002
+ */
+ // orr32
+ MmioWrite32(EXYNOS5_USB3_DRD_BASEADDR + EXYNOS_USB3_GCTL,
+ (MmioRead32(EXYNOS5_USB3_DRD_BASEADDR + EXYNOS_USB3_GCTL) | EXYNOS_USB3_GCTL_CoreSoftReset));
+ // orr32
+ MmioWrite32(EXYNOS5_USB3_DRD_BASEADDR + EXYNOS_USB3_GUSB2PHYCFG(0),
+ (MmioRead32(EXYNOS5_USB3_DRD_BASEADDR + EXYNOS_USB3_GUSB2PHYCFG(0)) | EXYNOS_USB3_GUSB2PHYCFGx_PHYSoftRst));
+ // orr32
+ MmioWrite32(EXYNOS5_USB3_DRD_BASEADDR + EXYNOS_USB3_GUSB3PIPECTL(0),
+ (MmioRead32(EXYNOS5_USB3_DRD_BASEADDR + EXYNOS_USB3_GUSB3PIPECTL(0)) | EXYNOS_USB3_GUSB3PIPECTLx_PHYSoftRst));
+
+ exynos5_usb_phy30_init();
+
+ // bic32
+ MmioWrite32(EXYNOS5_USB3_DRD_BASEADDR + EXYNOS_USB3_GUSB2PHYCFG(0),
+ (MmioRead32(EXYNOS5_USB3_DRD_BASEADDR + EXYNOS_USB3_GUSB2PHYCFG(0)) & ~EXYNOS_USB3_GUSB2PHYCFGx_PHYSoftRst));
+ // bic32
+ MmioWrite32(EXYNOS5_USB3_DRD_BASEADDR + EXYNOS_USB3_GUSB3PIPECTL(0),
+ (MmioRead32(EXYNOS5_USB3_DRD_BASEADDR + EXYNOS_USB3_GUSB3PIPECTL(0)) & ~EXYNOS_USB3_GUSB3PIPECTLx_PHYSoftRst));
+ // bic32
+ MmioWrite32(EXYNOS5_USB3_DRD_BASEADDR + EXYNOS_USB3_GCTL,
+ (MmioRead32(EXYNOS5_USB3_DRD_BASEADDR + EXYNOS_USB3_GCTL) & ~EXYNOS_USB3_GCTL_CoreSoftReset));
+ // bic32
+ MmioWrite32(EXYNOS5_USB3_DRD_BASEADDR + EXYNOS_USB3_GUSB2PHYCFG(0),
+ (MmioRead32(EXYNOS5_USB3_DRD_BASEADDR + EXYNOS_USB3_GUSB2PHYCFG(0)) & ~(EXYNOS_USB3_GUSB2PHYCFGx_SusPHY |
+ EXYNOS_USB3_GUSB2PHYCFGx_EnblSlpM |
+ EXYNOS_USB3_GUSB2PHYCFGx_USBTrdTim_MASK)));
+
+ // orr32
+ MmioWrite32(EXYNOS5_USB3_DRD_BASEADDR + EXYNOS_USB3_GUSB2PHYCFG(0),
+ (MmioRead32(EXYNOS5_USB3_DRD_BASEADDR + EXYNOS_USB3_GUSB2PHYCFG(0)) | EXYNOS_USB3_GUSB2PHYCFGx_USBTrdTim(9)));
+
+ // bic32
+ MmioWrite32(EXYNOS5_USB3_DRD_BASEADDR + EXYNOS_USB3_GUSB3PIPECTL(0),
+ (MmioRead32(EXYNOS5_USB3_DRD_BASEADDR + EXYNOS_USB3_GUSB3PIPECTL(0)) & ~EXYNOS_USB3_GUSB3PIPECTLx_SuspSSPhy));
+
+
+ DEBUG ((EFI_D_ERROR, "GUSB2PHYCFG(0)=0x%08x, GUSB3PIPECTL(0)=0x%08x\n",
+ MmioRead32(EXYNOS5_USB3_DRD_BASEADDR + EXYNOS_USB3_GUSB2PHYCFG(0)),
+ MmioRead32(EXYNOS5_USB3_DRD_BASEADDR + EXYNOS_USB3_GUSB3PIPECTL(0))));
+
+ /* Global core init */
+ MmioWrite32(EXYNOS5_USB3_DRD_BASEADDR + EXYNOS_USB3_GSBUSCFG0,
+ EXYNOS_USB3_GSBUSCFG0_INCR16BrstEna |
+ EXYNOS_USB3_GSBUSCFG0_INCR8BrstEna |
+ EXYNOS_USB3_GSBUSCFG0_INCR4BrstEna);
+
+ MmioWrite32(EXYNOS5_USB3_DRD_BASEADDR + EXYNOS_USB3_GSBUSCFG1,
+ EXYNOS_USB3_GSBUSCFG1_BREQLIMIT(0x3));
+
+ MmioWrite32(EXYNOS5_USB3_DRD_BASEADDR + EXYNOS_USB3_GTXTHRCFG, 0x0);
+ MmioWrite32(EXYNOS5_USB3_DRD_BASEADDR + EXYNOS_USB3_GRXTHRCFG, 0x0);
+}
+
+UINT32 exynos_xhci_change_mode(void)
+{
+ UINT32 gctl;
+
+ gctl = MmioRead32(EXYNOS5_USB3_DRD_BASEADDR + EXYNOS_USB3_GCTL);
+ gctl &= ~(EXYNOS_USB3_GCTL_PrtCapDir_MASK |
+ EXYNOS_USB3_GCTL_FRMSCLDWN_MASK |
+ EXYNOS_USB3_GCTL_RAMClkSel_MASK);
+
+ gctl |= (EXYNOS_USB3_GCTL_FRMSCLDWN(0x1e85) | /* Power Down Scale */
+ EXYNOS_USB3_GCTL_RAMClkSel(0x2) | /* Ram Clock Select */
+ EXYNOS_USB3_GCTL_DisScramble);
+
+ gctl |= EXYNOS_USB3_GCTL_PrtCapDir(0x1);/* 0x1 : Host */
+
+ MmioWrite32(EXYNOS5_USB3_DRD_BASEADDR + EXYNOS_USB3_GCTL, gctl);
+
+ DEBUG ((EFI_D_ERROR, "Change xHCI host mode %x\n", gctl));
+ return gctl;
+}
+
diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/PciEmulation/Exynos5_USB2Phy.h b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/PciEmulation/Exynos5_USB2Phy.h
new file mode 100644
index 000000000..fce6ca830
--- /dev/null
+++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/PciEmulation/Exynos5_USB2Phy.h
@@ -0,0 +1,114 @@
+#ifndef _EFI_EXYNOS5_USB2_PHY_H_
+#define _EFI_EXYNOS5_USB2_PHY_H_
+
+#define USB_XHCI_HCCAPBASE (0x12000000) //Gaia
+#define USB_EHCI_HCCAPBASE (0x12110000) //Gaia
+#define USB_OHCI_HCCAPBASE (USB_EHCI_HCCAPBASE + 0x10000)
+
+#define EXYNOS5_USB2_PHY_HOST_CTRL0 0x12130000 //Gaia
+
+#define HOST_CTRL0_PHYSWRSTALL (0x1 << 31)
+#define CLKSEL_50M (0x7 << 16)
+#define CLKSEL_24M (0x5 << 16)
+#define CLKSEL_20M (0x4 << 16)
+#define CLKSEL_19200K (0x3 << 16)
+#define CLKSEL_12M (0x2 << 16)
+#define CLKSEL_10M (0x1 << 16)
+#define CLKSEL_9600K (0x0 << 16)
+#define HOST_CTRL0_FSEL_MASK (0x7 << 16)
+#define HOST_CTRL0_COMMONONN (0x1 << 9)
+#define HOST_CTRL0_PHYSWRST (0x1 << 0)
+#define HOST_CTRL0_SIDDQ (0x1 << 6)
+#define HOST_CTRL0_FORCESLEEP (0x1 << 5)
+#define HOST_CTRL0_FORCESUSPEND (0x1 << 4)
+#define HOST_CTRL0_LINKSWRST (0x1 << 1)
+#define HOST_CTRL0_UTMISWRST (0x1 << 2)
+#define HSIC_CTRL_REFCLKDIV(val) ((val&0x7f) << 16)
+#define HSIC_CTRL_REFCLKSEL(val) ((val&0x3) << 23)
+#define HSIC_CTRL_PHYSWRST (0x1 << 0)
+#define PHY_HSIC_CTRL1 (EXYNOS5_USB2_PHY_HOST_CTRL0 + 0x10)
+#define PHY_HSIC_CTRL2 (EXYNOS5_USB2_PHY_HOST_CTRL0 + 0x20)
+#define PHY_HOST_EHCICTRL (EXYNOS5_USB2_PHY_HOST_CTRL0 + 0x30)
+#define EHCICTRL_ENAINCRXALIGN (0x1 << 29)
+#define EHCICTRL_ENAINCR4 (0x1 << 28)
+#define EHCICTRL_ENAINCR8 (0x1 << 27)
+#define EHCICTRL_ENAINCR16 (0x1 << 26)
+
+//CMU
+#define CLK_GATE_IP_FSYS 0x10020944 //GAIA
+
+//GPIO
+#define ETC6PUD (0x114002A8) //(0x11400000 + 0x2A8)
+
+//PMU
+#define EXYNOS5_USBDEV_PHY_CONTROL (0x10040000 + 0x0704)
+#define EXYNOS5_USBHOST_PHY_CONTROL (0x10040000 + 0x0708)
+
+
+//--------------------- for gaia ----------
+#define UHOST_FIN 48000000
+#define USBDEV_FIN 12000000
+
+#define USBHOST_AHB_INCR16 0x2000000
+#define USBHOST_AHB_INCR8 0x1000000
+#define USBHOST_AHB_INCR4 0x0800000
+#define USBHOST_AHB_INCRs 0x3800000
+#define USBHOST_AHB_INCRx 0x3c00000
+#define USBHOST_AHB_SINGLE 0x0000000
+
+typedef enum
+{
+ REFCLK_XTAL = 0x0, //XO : form Crystal
+ REFCLK_OSC = 0x1, //XO : OSC 1.8V Clock
+ REFCLK_PLL = 0x2, //PLL form CLKCORE
+}USBPHY_REFCLK;
+
+typedef enum
+{
+ FSEL_9_6M = 0x0,
+ FSEL_10M = 0x1,
+ FSEL_12M = 0x2,
+ FSEL_19_2M = 0x3,
+ FSEL_20M = 0x4,
+ FSEL_24M = 0x5,
+ FSEL_48M = 0x6, //Reserved
+ FSEL_50M = 0x7,
+}USBPHY_REFSEL;
+
+#define USBPHY_RETENABLE 1 //Retention Mode Enable == 1, Normal Operation mode must be 1.
+
+void USBPHY_Ctr48MhzClk(UINT8 bEnable_48Mhz);
+void usb_host_phy_off(void);
+
+//-------------------------------------------------------
+//OTG
+
+enum USBPHY_CON_SFR
+{
+ rUPHY_USBCTRL0 = EXYNOS5_USB2_PHY_HOST_CTRL0+0x0000,
+ rUPHY_USBTUNE0 = EXYNOS5_USB2_PHY_HOST_CTRL0+0x0004,
+ rUPHY_HSICCTRL1 = EXYNOS5_USB2_PHY_HOST_CTRL0+0x0010,
+ rUPHY_HSICTUNE1 = EXYNOS5_USB2_PHY_HOST_CTRL0+0x0014,
+ rUPHY_HSICCTRL2 = EXYNOS5_USB2_PHY_HOST_CTRL0+0x0020,
+ rUPHY_HSICTUNE2 = EXYNOS5_USB2_PHY_HOST_CTRL0+0x0024,
+
+ rUPHY_EHCICTRL = EXYNOS5_USB2_PHY_HOST_CTRL0+0x0030,
+ rUPHY_OHCICTRL = EXYNOS5_USB2_PHY_HOST_CTRL0+0x0034,
+
+ rUPHY_USBOTG_SYS = EXYNOS5_USB2_PHY_HOST_CTRL0+0x0038,
+ rUPHY_USBOTG_TUNE = EXYNOS5_USB2_PHY_HOST_CTRL0+0x0040,
+};
+
+enum usb_clk_type {
+ USBOTG_CLK, USBHOST_CLK, USBDRD30_CLK
+};
+
+//-------------------------------------------------------
+// Functions
+//-------------------------------------------------------
+
+void exynos5_usb_phy20_init(void);
+
+#endif
+
+
diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/PciEmulation/Exynos5_USB3Drd.h b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/PciEmulation/Exynos5_USB3Drd.h
new file mode 100644
index 000000000..09b66e1d5
--- /dev/null
+++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/PciEmulation/Exynos5_USB3Drd.h
@@ -0,0 +1,403 @@
+/* include/linux/usb/exynos_usb3_drd.h
+ *
+ * Copyright (c) 2012 Samsung Electronics Co. Ltd
+ * Author: Anton Tikhomirov <av.tikhomirov@samsung.com>
+ *
+ * Exynos SuperSpeed USB 3.0 DRD Controller global and OTG registers
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __LINUX_USB_EXYNOS_USB3_DRD_H
+#define __LINUX_USB_EXYNOS_USB3_DRD_H
+
+#define EXYNOS5_USB3_DRD_BASEADDR 0x12000000
+
+/* Global registers */
+#define EXYNOS_USB3_GSBUSCFG0 0xC100
+#define EXYNOS_USB3_GSBUSCFG0_SBusStoreAndForward (1 << 12)
+#define EXYNOS_USB3_GSBUSCFG0_DatBigEnd (1 << 11)
+#define EXYNOS_USB3_GSBUSCFG0_INCR256BrstEna (1 << 7)
+#define EXYNOS_USB3_GSBUSCFG0_INCR128BrstEna (1 << 6)
+#define EXYNOS_USB3_GSBUSCFG0_INCR64BrstEna (1 << 5)
+#define EXYNOS_USB3_GSBUSCFG0_INCR32BrstEna (1 << 4)
+#define EXYNOS_USB3_GSBUSCFG0_INCR16BrstEna (1 << 3)
+#define EXYNOS_USB3_GSBUSCFG0_INCR8BrstEna (1 << 2)
+#define EXYNOS_USB3_GSBUSCFG0_INCR4BrstEna (1 << 1)
+#define EXYNOS_USB3_GSBUSCFG0_INCRBrstEna (1 << 0)
+
+#define EXYNOS_USB3_GSBUSCFG1 0xC104
+#define EXYNOS_USB3_GSBUSCFG1_EN1KPAGE (1 << 12)
+#define EXYNOS_USB3_GSBUSCFG1_BREQLIMIT_MASK (0xf << 8)
+#define EXYNOS_USB3_GSBUSCFG1_BREQLIMIT_SHIFT 8
+#define EXYNOS_USB3_GSBUSCFG1_BREQLIMIT(_x) ((_x) << 8)
+
+#define EXYNOS_USB3_GTXTHRCFG 0xC108
+#define EXYNOS_USB3_GTXTHRCFG_USBTxPktCntSel (1 << 29)
+#define EXYNOS_USB3_GTXTHRCFG_USBTxPktCnt_MASK (0xf << 24)
+#define EXYNOS_USB3_GTXTHRCFG_USBTxPktCnt_SHIFT 24
+#define EXYNOS_USB3_GTXTHRCFG_USBTxPktCnt(_x) ((_x) << 24)
+#define EXYNOS_USB3_GTXTHRCFG_USBMaxTxBurstSize_MASK (0xff << 16)
+#define EXYNOS_USB3_GTXTHRCFG_USBMaxTxBurstSize_SHIFT 16
+#define EXYNOS_USB3_GTXTHRCFG_USBMaxTxBurstSize(_x) ((_x) << 16)
+
+#define EXYNOS_USB3_GRXTHRCFG 0xC10C
+#define EXYNOS_USB3_GRXTHRCFG_USBRxPktCntSel (1 << 29)
+#define EXYNOS_USB3_GRXTHRCFG_USBRxPktCnt_MASK (0xf << 24)
+#define EXYNOS_USB3_GRXTHRCFG_USBRxPktCnt_SHIFT 24
+#define EXYNOS_USB3_GRXTHRCFG_USBRxPktCnt(_x) ((_x) << 24)
+#define EXYNOS_USB3_GRXTHRCFG_USBMaxRxBurstSize_MASK (0x1f << 19)
+#define EXYNOS_USB3_GRXTHRCFG_USBMaxRxBurstSize_SHIFT 19
+#define EXYNOS_USB3_GRXTHRCFG_USBMaxRxBurstSize(_x) ((_x) << 19)
+
+#define EXYNOS_USB3_GCTL 0xC110
+#define EXYNOS_USB3_GCTL_PwrDnScale_MASK (0x1fff << 19)
+#define EXYNOS_USB3_GCTL_PwrDnScale_SHIFT 19
+#define EXYNOS_USB3_GCTL_PwrDnScale(_x) ((_x) << 19)
+#define EXYNOS_USB3_GCTL_U2RSTECN (1 << 16)
+#define EXYNOS_USB3_GCTL_FRMSCLDWN_MASK (0x3 << 14)
+#define EXYNOS_USB3_GCTL_FRMSCLDWN_SHIFT 14
+#define EXYNOS_USB3_GCTL_FRMSCLDWN(_x) ((_x) << 14)
+#define EXYNOS_USB3_GCTL_PrtCapDir_MASK (0x3 << 12)
+#define EXYNOS_USB3_GCTL_PrtCapDir_SHIFT 12
+#define EXYNOS_USB3_GCTL_PrtCapDir(_x) ((_x) << 12)
+#define EXYNOS_USB3_GCTL_CoreSoftReset (1 << 11)
+#define EXYNOS_USB3_GCTL_LocalLpBkEn (1 << 10)
+#define EXYNOS_USB3_GCTL_LpbkEn (1 << 9)
+#define EXYNOS_USB3_GCTL_DebugAttach (1 << 8)
+#define EXYNOS_USB3_GCTL_RAMClkSel_MASK (0x3 << 6)
+#define EXYNOS_USB3_GCTL_RAMClkSel_SHIFT 6
+#define EXYNOS_USB3_GCTL_RAMClkSel(_x) ((_x) << 6)
+#define EXYNOS_USB3_GCTL_ScaleDown_MASK (0x3 << 4)
+#define EXYNOS_USB3_GCTL_ScaleDown_SHIFT 4
+#define EXYNOS_USB3_GCTL_ScaleDown(_x) ((_x) << 4)
+#define EXYNOS_USB3_GCTL_DisScramble (1 << 3)
+#define EXYNOS_USB3_GCTL_SsPwrClmp (1 << 2)
+#define EXYNOS_USB3_GCTL_HsFsLsPwrClmp (1 << 1)
+#define EXYNOS_USB3_GCTL_DsblClkGtng (1 << 0)
+
+#define EXYNOS_USB3_GEVTEN 0xC114
+#define EXYNOS_USB3_GEVTEN_I2CEvtEn (1 << 1)
+#define EXYNOS_USB3_GEVTEN_ULPICKEvtEn (1 << 0)
+#define EXYNOS_USB3_GEVTEN_I2CCKEvtEn (1 << 0)
+
+#define EXYNOS_USB3_GSTS 0xC118
+#define EXYNOS_USB3_GSTS_CBELT_MASK (0xfff << 20)
+#define EXYNOS_USB3_GSTS_CBELT_SHIFT 20
+#define EXYNOS_USB3_GSTS_CBELT(_x) ((_x) << 20)
+#define EXYNOS_USB3_GSTS_OTG_IP (1 << 10)
+#define EXYNOS_USB3_GSTS_BC_IP (1 << 9)
+#define EXYNOS_USB3_GSTS_ADP_IP (1 << 8)
+#define EXYNOS_USB3_GSTS_Host_IP (1 << 7)
+#define EXYNOS_USB3_GSTS_Device_IP (1 << 6)
+#define EXYNOS_USB3_GSTS_CSRTimeout (1 << 5)
+#define EXYNOS_USB3_GSTS_BusErrAddrVld (1 << 4)
+#define EXYNOS_USB3_GSTS_CurMod_MASK (0x3 << 0)
+#define EXYNOS_USB3_GSTS_CurMod_SHIFT 0
+#define EXYNOS_USB3_GSTS_CurMod(_x) ((_x) << 0)
+
+#define EXYNOS_USB3_GSNPSID 0xC120
+
+#define EXYNOS_USB3_GGPIO 0xC124
+#define EXYNOS_USB3_GGPIO_GPO_MASK (0xffff << 16)
+#define EXYNOS_USB3_GGPIO_GPO_SHIFT 16
+#define EXYNOS_USB3_GGPIO_GPO(_x) ((_x) << 16)
+#define EXYNOS_USB3_GGPIO_GPI_MASK (0xffff << 0)
+#define EXYNOS_USB3_GGPIO_GPI_SHIFT 0
+#define EXYNOS_USB3_GGPIO_GPI(_x) ((x) << 0)
+
+#define EXYNOS_USB3_GUID 0xC128
+
+#define EXYNOS_USB3_GUCTL 0xC12C
+#define EXYNOS_USB3_GUCTL_SprsCtrlTransEn (1 << 17)
+#define EXYNOS_USB3_GUCTL_ResBwHSEPS (1 << 16)
+#define EXYNOS_USB3_GUCTL_CMdevAddr (1 << 15)
+#define EXYNOS_USB3_GUCTL_USBHstInAutoRetryEn (1 << 14)
+#define EXYNOS_USB3_GUCTL_USBHstInMaxBurst_MASK (0x7 << 11)
+#define EXYNOS_USB3_GUCTL_USBHstInMaxBurst_SHIFT 11
+#define EXYNOS_USB3_GUCTL_USBHstInMaxBurst(_x) ((_x) << 11)
+#define EXYNOS_USB3_GUCTL_DTCT_MASK (0x3 << 9)
+#define EXYNOS_USB3_GUCTL_DTCT_SHIFT 9
+#define EXYNOS_USB3_GUCTL_DTCT(_x) ((_x) << 9)
+#define EXYNOS_USB3_GUCTL_DTFT_MASK (0x1ff << 0)
+#define EXYNOS_USB3_GUCTL_DTFT_SHIFT 0
+#define EXYNOS_USB3_GUCTL_DTFT(_x) ((_x) << 0)
+
+#define EXYNOS_USB3_GBUSERRADDR_31_0 0xC130
+#define EXYNOS_USB3_GBUSERRADDR_63_32 0xC134
+#define EXYNOS_USB3_GPRTBIMAP_31_0 0xC138
+#define EXYNOS_USB3_GPRTBIMAP_63_32 0xC13C
+
+#define EXYNOS_USB3_GHWPARAMS0 0xC140
+#define EXYNOS_USB3_GHWPARAMS1 0xC144
+#define EXYNOS_USB3_GHWPARAMS2 0xC148
+#define EXYNOS_USB3_GHWPARAMS3 0xC14C
+#define EXYNOS_USB3_GHWPARAMS4 0xC150
+#define EXYNOS_USB3_GHWPARAMS5 0xC154
+#define EXYNOS_USB3_GHWPARAMS6 0xC158
+#define EXYNOS_USB3_GHWPARAMS7 0xC15C
+
+#define EXYNOS_USB3_GDBGFIFOSPACE 0xC160
+#define EXYNOS_USB3_GDBGLTSSM 0xC164
+
+#define EXYNOS_USB3_GDBGLSPMUX 0xC170
+#define EXYNOS_USB3_GDBGLSP 0xC174
+#define EXYNOS_USB3_GDBGEPINFO0 0xC178
+#define EXYNOS_USB3_GDBGEPINFO1 0xC17C
+
+#define EXYNOS_USB3_GPRTBIMAP_HS_31_0 0xC180
+#define EXYNOS_USB3_GPRTBIMAP_HS_63_32 0xC184
+#define EXYNOS_USB3_GPRTBIMAP_FS_31_0 0xC188
+#define EXYNOS_USB3_GPRTBIMAP_FS_63_32 0xC18C
+
+#define EXYNOS_USB3_GUSB2PHYCFG(_a) (0xC200 + ((_a) * 0x04))
+#define EXYNOS_USB3_GUSB2PHYCFGx_PHYSoftRst (1 << 31)
+#define EXYNOS_USB3_GUSB2PHYCFGx_PhyIntrNum_MASK (0x3f << 19)
+#define EXYNOS_USB3_GUSB2PHYCFGx_PhyIntrNum_SHIFT 19
+#define EXYNOS_USB3_GUSB2PHYCFGx_PhyIntrNum(_x) ((_x) << 19)
+#define EXYNOS_USB3_GUSB2PHYCFGx_ULPIExtVbusIndicator (1 << 18)
+#define EXYNOS_USB3_GUSB2PHYCFGx_ULPIExtVbusDrv (1 << 17)
+#define EXYNOS_USB3_GUSB2PHYCFGx_ULPIClkSusM (1 << 16)
+#define EXYNOS_USB3_GUSB2PHYCFGx_ULPIAutoRes (1 << 15)
+#define EXYNOS_USB3_GUSB2PHYCFGx_PhyLPwrClkSel (1 << 14)
+#define EXYNOS_USB3_GUSB2PHYCFGx_USBTrdTim_MASK (0xf << 10)
+#define EXYNOS_USB3_GUSB2PHYCFGx_USBTrdTim_SHIFT 10
+#define EXYNOS_USB3_GUSB2PHYCFGx_USBTrdTim(_x) ((_x) << 10)
+#define EXYNOS_USB3_GUSB2PHYCFGx_EnblSlpM (1 << 8)
+#define EXYNOS_USB3_GUSB2PHYCFGx_PHYSel (1 << 7)
+#define EXYNOS_USB3_GUSB2PHYCFGx_SusPHY (1 << 6)
+#define EXYNOS_USB3_GUSB2PHYCFGx_FSIntf (1 << 5)
+#define EXYNOS_USB3_GUSB2PHYCFGx_ULPI_UTMI_Sel (1 << 4)
+#define EXYNOS_USB3_GUSB2PHYCFGx_PHYIf (1 << 3)
+#define EXYNOS_USB3_GUSB2PHYCFGx_TOutCal_MASK (0x7 << 0)
+#define EXYNOS_USB3_GUSB2PHYCFGx_TOutCal_SHIFT 0
+#define EXYNOS_USB3_GUSB2PHYCFGx_TOutCal(_x) ((_x) << 0)
+
+#define EXYNOS_USB3_GUSB2I2CCTL(_a) (0xC240 + ((_a) * 0x04))
+
+#define EXYNOS_USB3_GUSB2PHYACC(_a) (0xC280 + ((_a) * 0x04))
+#define EXYNOS_USB3_GUSB2PHYACCx_DisUlpiDrvr (1 << 26)
+#define EXYNOS_USB3_GUSB2PHYACCx_NewRegReq (1 << 25)
+#define EXYNOS_USB3_GUSB2PHYACCx_VStsDone (1 << 24)
+#define EXYNOS_USB3_GUSB2PHYACCx_VStsBsy (1 << 23)
+#define EXYNOS_USB3_GUSB2PHYACCx_RegWr (1 << 22)
+#define EXYNOS_USB3_GUSB2PHYACCx_RegAddr_MASK (0x3f << 16)
+#define EXYNOS_USB3_GUSB2PHYACCx_RegAddr_SHIFT 16
+#define EXYNOS_USB3_GUSB2PHYACCx_RegAddr(_x) ((_x) << 16)
+/* Next 2 fields are overlaping. Is it error in user manual? */
+#define EXYNOS_USB3_GUSB2PHYACCx_VCtrl_MASK (0xff << 8)
+#define EXYNOS_USB3_GUSB2PHYACCx_VCtrl_SHIFT 8
+#define EXYNOS_USB3_GUSB2PHYACCx_VCtrl(_x) ((_x) << 8)
+/*--------*/
+#define EXYNOS_USB3_GUSB2PHYACCx_ExtRegAddr_MASK (0x3f << 8)
+#define EXYNOS_USB3_GUSB2PHYACCx_ExtRegAddr_SHIFT 8
+#define EXYNOS_USB3_GUSB2PHYACCx_ExtRegAddr(_x) ((_x) << 8)
+/*--------*/
+#define EXYNOS_USB3_GUSB2PHYACCx_RegData_MASK (0xff << 0)
+#define EXYNOS_USB3_GUSB2PHYACCx_RegData_SHIFT 0
+#define EXYNOS_USB3_GUSB2PHYACCx_RegData(_x) ((_x) << 0)
+
+#define EXYNOS_USB3_GUSB3PIPECTL(_a) (0xC2C0 + ((_a) * 0x04))
+#define EXYNOS_USB3_GUSB3PIPECTLx_PHYSoftRst (1 << 31)
+#define EXYNOS_USB3_GUSB3PIPECTLx_request_p1p2p3 (1 << 24)
+#define EXYNOS_USB3_GUSB3PIPECTLx_StartRxdetU3RxDet (1 << 23)
+#define EXYNOS_USB3_GUSB3PIPECTLx_DisRxDetU3RxDet (1 << 22)
+#define EXYNOS_USB3_GUSB3PIPECTLx_delay_p1p2p3_MASK (0x7 << 19)
+#define EXYNOS_USB3_GUSB3PIPECTLx_delay_p1p2p3_SHIFT 19
+#define EXYNOS_USB3_GUSB3PIPECTLx_delay_p1p2p3(_x) ((_x) << 19)
+#define EXYNOS_USB3_GUSB3PIPECTLx_delay_phy_pwr_p1p2p3 (1 << 18)
+#define EXYNOS_USB3_GUSB3PIPECTLx_SuspSSPhy (1 << 17)
+#define EXYNOS_USB3_GUSB3PIPECTLx_DatWidth_MASK (0x3 << 15)
+#define EXYNOS_USB3_GUSB3PIPECTLx_DatWidth_SHIFT 15
+#define EXYNOS_USB3_GUSB3PIPECTLx_DatWidth(_x) ((_x) << 15)
+#define EXYNOS_USB3_GUSB3PIPECTLx_AbortRxDetInU2 (1 << 14)
+#define EXYNOS_USB3_GUSB3PIPECTLx_SkipRxDet (1 << 13)
+#define EXYNOS_USB3_GUSB3PIPECTLx_LFPSP0Algn (1 << 12)
+#define EXYNOS_USB3_GUSB3PIPECTLx_P3P2TranOK (1 << 11)
+#define EXYNOS_USB3_GUSB3PIPECTLx_LFPSFilt (1 << 9)
+#define EXYNOS_USB3_GUSB3PIPECTLx_TxSwing (1 << 6)
+#define EXYNOS_USB3_GUSB3PIPECTLx_TxMargin_MASK (0x7 << 3)
+#define EXYNOS_USB3_GUSB3PIPECTLx_TxMargin_SHIFT 3
+#define EXYNOS_USB3_GUSB3PIPECTLx_TxMargin(_x) ((_x) << 3)
+#define EXYNOS_USB3_GUSB3PIPECTLx_TxDeemphasis_MASK (0x3 << 1)
+#define EXYNOS_USB3_GUSB3PIPECTLx_TxDeemphasis_SHIFT 1
+#define EXYNOS_USB3_GUSB3PIPECTLx_TxDeemphasis(_x) ((_x) << 1)
+#define EXYNOS_USB3_GUSB3PIPECTLx_ElasticBufferMode (1 << 0)
+
+#define EXYNOS_USB3_GTXFIFOSIZ(_a) (0xC300 + ((_a) * 0x04))
+#define EXYNOS_USB3_GTXFIFOSIZx_TxFStAddr_n_MASK (0xffff << 16)
+#define EXYNOS_USB3_GTXFIFOSIZx_TxFStAddr_n_SHIFT 16
+#define EXYNOS_USB3_GTXFIFOSIZx_TxFStAddr_n(_x) ((_x) << 16)
+#define EXYNOS_USB3_GTXFIFOSIZx_TxFDep_n_MASK (0xffff << 0)
+#define EXYNOS_USB3_GTXFIFOSIZx_TxFDep_n_SHIFT 0
+#define EXYNOS_USB3_GTXFIFOSIZx_TxFDep_n(_x) ((_x) << 0)
+
+#define EXYNOS_USB3_GRXFIFOSIZ(_a) (0xC380 + ((_a) * 0x04))
+#define EXYNOS_USB3_GRXFIFOSIZx_RxFStAddr_n_MASK (0xffff << 16)
+#define EXYNOS_USB3_GRXFIFOSIZx_RxFStAddr_n_SHIFT 16
+#define EXYNOS_USB3_GRXFIFOSIZx_RxFStAddr_n(_x) ((_x) << 16)
+#define EXYNOS_USB3_GRXFIFOSIZx_RxFDep_n_MASK (0xffff << 0)
+#define EXYNOS_USB3_GRXFIFOSIZx_RxFDep_n_SHIFT 0
+#define EXYNOS_USB3_GRXFIFOSIZx_RxFDep_n(_x) ((_x) << 0)
+
+#define EXYNOS_USB3_GEVNTADR_31_0(_a) (0xC400 + ((_a) * 0x10))
+#define EXYNOS_USB3_GEVNTADR_63_32(_a) (0xC404 + ((_a) * 0x10))
+
+#define EXYNOS_USB3_GEVNTSIZ(_a) (0xC408 + ((_a) * 0x10))
+#define EXYNOS_USB3_GEVNTSIZx_EvntIntMask (1 << 31)
+#define EXYNOS_USB3_GEVNTSIZx_EVNTSiz_MASK (0xffff << 0)
+#define EXYNOS_USB3_GEVNTSIZx_EVNTSiz_SHIFT 0
+#define EXYNOS_USB3_GEVNTSIZx_EVNTSiz(x) ((_x) << 0)
+
+#define EXYNOS_USB3_GEVNTCOUNT(_a) (0xC40C + ((_a) * 0x10))
+#define EXYNOS_USB3_GEVNTCOUNTx_EVNTCount_MASK (0xffff << 0)
+#define EXYNOS_USB3_GEVNTCOUNTx_EVNTCount_SHIFT 0
+#define EXYNOS_USB3_GEVNTCOUNTx_EVNTCount(_x) ((_x) << 0)
+
+/* Event Buffer Content for Device Endpoint-Specific Events (DEPEVT) */
+#define EXYNOS_USB3_DEPEVT_EventParam_MASK (0xffff << 16)
+#define EXYNOS_USB3_DEPEVT_EventParam_SHIFT 16
+#define EXYNOS_USB3_DEPEVT_EventParam(_x) ((_x) << 16)
+#define EXYNOS_USB3_DEPEVT_EventStatus_MASK (0xf << 12)
+#define EXYNOS_USB3_DEPEVT_EventStatus_SHIFT 12
+#define EXYNOS_USB3_DEPEVT_EventStatus_CTL_MASK (0x3 << 12)
+#define EXYNOS_USB3_DEPEVT_EventStatus_CTL_SETUP (0 << 12)
+#define EXYNOS_USB3_DEPEVT_EventStatus_CTL_DATA (1 << 12)
+#define EXYNOS_USB3_DEPEVT_EventStatus_CTL_STATUS (2 << 12)
+#define EXYNOS_USB3_DEPEVT_EventStatus_BUSERR (1 << 12)
+#define EXYNOS_USB3_DEPEVT_EVENT_MASK (0xf << 6)
+#define EXYNOS_USB3_DEPEVT_EVENT_SHIFT 6
+#define EXYNOS_USB3_DEPEVT_EVENT_EPCmdCmplt (7 << 6)
+#define EXYNOS_USB3_DEPEVT_EVENT_StreamEvt (6 << 6)
+#define EXYNOS_USB3_DEPEVT_EVENT_RxTxfifoEvt (4 << 6)
+#define EXYNOS_USB3_DEPEVT_EVENT_XferNotReady (3 << 6)
+#define EXYNOS_USB3_DEPEVT_EVENT_XferInProgress (2 << 6)
+#define EXYNOS_USB3_DEPEVT_EVENT_XferComplete (1 << 6)
+#define EXYNOS_USB3_DEPEVT_EPNUM_MASK (0x1f << 1)
+#define EXYNOS_USB3_DEPEVT_EPNUM_SHIFT 1
+#define EXYNOS_USB3_DEPEVT_EPNUM(_x) ((_x) << 1)
+
+/* Event Buffer Content for Device-Specific Events (DEVT) */
+#define EXYNOS_USB3_DEVT_EventParam_MASK (0xf << 16)
+#define EXYNOS_USB3_DEVT_EventParam_SHIFT 16
+#define EXYNOS_USB3_DEVT_EventParam_SS (1 << 20)
+#define EXYNOS_USB3_DEVT_EventParam(_x) ((_x) << 16)
+#define EXYNOS_USB3_DEVT_EVENT_MASK (0xf << 8)
+#define EXYNOS_USB3_DEVT_EVENT_SHIFT 8
+#define EXYNOS_USB3_DEVT_EVENT_VndrDevTstRcved (12 << 8)
+#define EXYNOS_USB3_DEVT_EVENT_EvntOverflow (11 << 8)
+#define EXYNOS_USB3_DEVT_EVENT_CmdCmplt (10 << 8)
+#define EXYNOS_USB3_DEVT_EVENT_ErrticErr (9 << 8)
+#define EXYNOS_USB3_DEVT_EVENT_Sof (7 << 8)
+#define EXYNOS_USB3_DEVT_EVENT_EOPF (6 << 8)
+#define EXYNOS_USB3_DEVT_EVENT_WkUpEvt (4 << 8)
+#define EXYNOS_USB3_DEVT_EVENT_ULStChng (3 << 8)
+#define EXYNOS_USB3_DEVT_EVENT_ConnectDone (2 << 8)
+#define EXYNOS_USB3_DEVT_EVENT_USBRst (1 << 8)
+#define EXYNOS_USB3_DEVT_EVENT_DisconnEvt (0 << 8)
+
+#define EXYNOS_USB3_GHWPARAMS8 0xC600
+
+/* USB 2.0 OTG and Battery Charger registers */
+#define EXYNOS_USB3_OCFG 0xCC00
+#define EXYNOS_USB3_OCFG_OTG_Version (1 << 2)
+#define EXYNOS_USB3_OCFG_HNPCap (1 << 1)
+#define EXYNOS_USB3_OCFG_SRPCap (1 << 0)
+
+#define EXYNOS_USB3_OCTL 0xCC04
+#define EXYNOS_USB3_OCTL_PeriMode (1 << 6)
+#define EXYNOS_USB3_OCTL_PrtPwrCtl (1 << 5)
+#define EXYNOS_USB3_OCTL_HNPReq (1 << 4)
+#define EXYNOS_USB3_OCTL_SesReq (1 << 3)
+#define EXYNOS_USB3_OCTL_TermSelDLPulse (1 << 2)
+#define EXYNOS_USB3_OCTL_DevSetHNPEn (1 << 1)
+#define EXYNOS_USB3_OCTL_HstSetHNPEn (1 << 0)
+
+#define EXYNOS_USB3_OEVT 0xCC08
+#define EXYNOS_USB3_OEVT_DeviceMode (1 << 31)
+#define EXYNOS_USB3_OEVT_OTGConIDStsChngEvnt (1 << 24)
+#define EXYNOS_USB3_OEVT_OTGADevBHostEndEvnt (1 << 20)
+#define EXYNOS_USB3_OEVT_OTGADevHostEvnt (1 << 19)
+#define EXYNOS_USB3_OEVT_OTGADevHNPChngEvnt (1 << 18)
+#define EXYNOS_USB3_OEVT_OTGADevSRPDetEvnt (1 << 17)
+#define EXYNOS_USB3_OEVT_OTGADevSessEndDetEvnt (1 << 16)
+#define EXYNOS_USB3_OEVT_OTGBDevBHostEndEvnt (1 << 11)
+#define EXYNOS_USB3_OEVT_OTGBDevHNPChngEvnt (1 << 10)
+#define EXYNOS_USB3_OEVT_OTGBDevSessVldDetEvnt (1 << 9)
+#define EXYNOS_USB3_OEVT_OTGBDevVBUSChngEvnt (1 << 8)
+#define EXYNOS_USB3_OEVT_BSesVld (1 << 3)
+#define EXYNOS_USB3_OEVT_HstNegSts (1 << 2)
+#define EXYNOS_USB3_OEVT_SesReqSts (1 << 1)
+#define EXYNOS_USB3_OEVT_OEVTError (1 << 0)
+
+#define EXYNOS_USB3_OEVTEN 0xCC0C
+#define EXYNOS_USB3_OEVTEN_OTGConIDStsChngEvntEn (1 << 24)
+#define EXYNOS_USB3_OEVTEN_OTGADevBHostEndEvntEn (1 << 20)
+#define EXYNOS_USB3_OEVTEN_OTGADevHostEvntEn (1 << 19)
+#define EXYNOS_USB3_OEVTEN_OTGADevHNPChngEvntEn (1 << 18)
+#define EXYNOS_USB3_OEVTEN_OTGADevSRPDetEvntEn (1 << 17)
+#define EXYNOS_USB3_OEVTEN_OTGADevSessEndDetEvntEn (1 << 16)
+#define EXYNOS_USB3_OEVTEN_OTGBDevBHostEndEvntEn (1 << 11)
+#define EXYNOS_USB3_OEVTEN_OTGBDevHNPChngEvntEn (1 << 10)
+#define EXYNOS_USB3_OEVTEN_OTGBDevSessVldDetEvntEn (1 << 9)
+#define EXYNOS_USB3_OEVTEN_OTGBDevVBUSChngEvntEn (1 << 8)
+
+#define EXYNOS_USB3_OSTS 0xCC10
+#define EXYNOS_USB3_OSTS_OTG_state_MASK (0xf << 8)
+#define EXYNOS_USB3_OSTS_OTG_state_SHIFT 8
+#define EXYNOS_USB3_OSTS_OTG_state(_x) ((_x) << 8)
+#define EXYNOS_USB3_OSTS_PeripheralState (1 << 4)
+#define EXYNOS_USB3_OSTS_xHCIPrtPower (1 << 3)
+#define EXYNOS_USB3_OSTS_BSesVld (1 << 2)
+#define EXYNOS_USB3_OSTS_VbusVld (1 << 1)
+#define EXYNOS_USB3_OSTS_ConIDSts (1 << 0)
+
+#define EXYNOS_USB3_ADPCFG 0xCC20
+#define EXYNOS_USB3_ADPCFG_PrbPer_MASK (0x3 << 30)
+#define EXYNOS_USB3_ADPCFG_PrbPer_SHIFT 30
+#define EXYNOS_USB3_ADPCFG_PrbPer(_x) ((_x) << 30)
+#define EXYNOS_USB3_ADPCFG_PrbDelta_MASK (0x3 << 28)
+#define EXYNOS_USB3_ADPCFG_PrbDelta_SHIFT 28
+#define EXYNOS_USB3_ADPCFG_PrbDelta(_x) ((_x) << 28)
+#define EXYNOS_USB3_ADPCFG_PrbDschg_MASK (0x3 << 26)
+#define EXYNOS_USB3_ADPCFG_PrbDschg_SHIFT 26
+#define EXYNOS_USB3_ADPCFG_PrbDschg(_x) ((_x) << 26)
+
+#define EXYNOS_USB3_ADPCTL 0xCC24
+#define EXYNOS_USB3_ADPCTL_EnaPrb (1 << 28)
+#define EXYNOS_USB3_ADPCTL_EnaSns (1 << 27)
+#define EXYNOS_USB3_ADPCTL_ADPEn (1 << 26)
+#define EXYNOS_USB3_ADPCTL_ADPRes (1 << 25)
+#define EXYNOS_USB3_ADPCTL_WB (1 << 24)
+
+#define EXYNOS_USB3_ADPEVT 0xCC28
+#define EXYNOS_USB3_ADPEVT_AdpPrbEvnt (1 << 28)
+#define EXYNOS_USB3_ADPEVT_AdpSnsEvnt (1 << 27)
+#define EXYNOS_USB3_ADPEVT_AdpTmoutEvnt (1 << 26)
+#define EXYNOS_USB3_ADPEVT_ADPRstCmpltEvnt (1 << 25)
+#define EXYNOS_USB3_ADPEVT_RTIM_MASK (0x7ff << 0)
+#define EXYNOS_USB3_ADPEVT_RTIM_SHIFT 0
+#define EXYNOS_USB3_ADPEVT_RTIM(_x) ((_x) << 0)
+
+#define EXYNOS_USB3_ADPEVTEN 0xCC2C
+#define EXYNOS_USB3_ADPEVTEN_AdpPrbEvntEn (1 << 28)
+#define EXYNOS_USB3_ADPEVTEN_AdpSnsEvntEn (1 << 27)
+#define EXYNOS_USB3_ADPEVTEN_AdpTmoutEvntEn (1 << 26)
+#define EXYNOS_USB3_ADPEVTEN_ADPRstCmpltEvntEn (1 << 25)
+
+#define EXYNOS_USB3_BCFG 0xCC30
+#define EXYNOS_USB3_BCFG_IDDIG_SEL (1 << 1)
+#define EXYNOS_USB3_BCFG_CHIRP_EN (1 << 0)
+
+#define EXYNOS_USB3_BCEVT 0xCC38
+#define EXYNOS_USB3_BCEVT_MV_ChngEvnt (1 << 24)
+#define EXYNOS_USB3_BCEVT_MultValIdBc_MASK (0x1f << 0)
+#define EXYNOS_USB3_BCEVT_MultValIdBc_SHIFT 0
+#define EXYNOS_USB3_BCEVT_MultValIdBc(_x) ((_x) << 0)
+
+#define EXYNOS_USB3_BCEVTEN 0xCC3C
+#define EXYNOS_USB3_BCEVTEN_MV_ChngEvntEn (1 << 24)
+
+#endif /* __LINUX_USB_EXYNOS_USB3_DRD_H */
diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/PciEmulation/Exynos5_USB3Phy.h b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/PciEmulation/Exynos5_USB3Phy.h
new file mode 100644
index 000000000..f903e0cdc
--- /dev/null
+++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/PciEmulation/Exynos5_USB3Phy.h
@@ -0,0 +1,80 @@
+#ifndef _EFI_EXYNOS5_USB3_PHY_H_
+#define _EFI_EXYNOS5_USB3_PHY_H_
+
+#define EXYNOS5_USB3_PHY_HOST_CTRL0 0x12100000
+
+#define EXYNOS_USB3_LINKSYSTEM (EXYNOS5_USB3_PHY_HOST_CTRL0 + 0x04)
+#define EXYNOS_USB3_PHYUTMI (EXYNOS5_USB3_PHY_HOST_CTRL0 + 0x08)
+#define EXYNOS_USB3_PHYPIPE (EXYNOS5_USB3_PHY_HOST_CTRL0 + 0x0C)
+#define EXYNOS_USB3_PHYCLKRST (EXYNOS5_USB3_PHY_HOST_CTRL0 + 0x10)
+#define EXYNOS_USB3_PHYREG0 (EXYNOS5_USB3_PHY_HOST_CTRL0 + 0x14)
+#define EXYNOS_USB3_PHYREG1 (EXYNOS5_USB3_PHY_HOST_CTRL0 + 0x18)
+#define EXYNOS_USB3_PHYPARAM0 (EXYNOS5_USB3_PHY_HOST_CTRL0 + 0x1C)
+#define EXYNOS_USB3_PHYPARAM1 (EXYNOS5_USB3_PHY_HOST_CTRL0 + 0x20)
+#define EXYNOS_USB3_PHYTERM (EXYNOS5_USB3_PHY_HOST_CTRL0 + 0x24)
+#define EXYNOS_USB3_PHYTEST (EXYNOS5_USB3_PHY_HOST_CTRL0 + 0x28)
+#define EXYNOS_USB3_PHYADP (EXYNOS5_USB3_PHY_HOST_CTRL0 + 0x2C)
+#define EXYNOS_USB3_PHYBATCHG (EXYNOS5_USB3_PHY_HOST_CTRL0 + 0x30)
+#define EXYNOS_USB3_PHYRESUME (EXYNOS5_USB3_PHY_HOST_CTRL0 + 0x34)
+#define EXYNOS_USB3_LINKPORT (EXYNOS5_USB3_PHY_HOST_CTRL0 + 0x44)
+
+
+#define EXYNOS_USB3_PHYUTMI_OTGDISABLE (1 << 6)
+#define EXYNOS_USB3_PHYUTMI_FORCESUSPEND (1 << 1)
+#define EXYNOS_USB3_PHYUTMI_FORCESLEEP (1 << 0)
+
+#define EXYNOS_USB3_PHYCLKRST_SSC_REF_CLK_SEL_MASK (0xff << 23)
+#define EXYNOS_USB3_PHYCLKRST_SSC_REF_CLK_SEL_SHIFT (23)
+#define EXYNOS_USB3_PHYCLKRST_SSC_REF_CLK_SEL_LIMIT (0xff)
+#define EXYNOS_USB3_PHYCLKRST_SSC_REF_CLK_SEL(_x) ((_x) << 23)
+
+#define EXYNOS_USB3_PHYCLKRST_SSC_RANGE_MASK (0x03 << 21)
+#define EXYNOS_USB3_PHYCLKRST_SSC_RANGE_SHIFT (21)
+#define EXYNOS_USB3_PHYCLKRST_SSC_RANGE_LIMIT (0x03)
+#define EXYNOS_USB3_PHYCLKRST_SSC_RANGE(_x) ((_x) << 21)
+
+#define EXYNOS_USB3_PHYCLKRST_SSC_EN (1 << 20)
+#define EXYNOS_USB3_PHYCLKRST_REF_SSP_EN (1 << 19)
+#define EXYNOS_USB3_PHYCLKRST_REF_CLKDIV2 (1 << 18)
+
+#define EXYNOS_USB3_PHYCLKRST_MPLL_MULTIPLIER_MASK (0x7f << 11)
+#define EXYNOS_USB3_PHYCLKRST_MPLL_MULTIPLIER_SHIFT (11)
+#define EXYNOS_USB3_PHYCLKRST_MPLL_MULTIPLIER_LIMIT (0x7f)
+#define EXYNOS_USB3_PHYCLKRST_MPLL_MULTIPLIER(_x) ((_x) << 11)
+
+#define EXYNOS_USB3_PHYCLKRST_SSC_EN (1 << 20)
+#define EXYNOS_USB3_PHYCLKRST_REF_SSP_EN (1 << 19)
+#define EXYNOS_USB3_PHYCLKRST_REF_CLKDIV2 (1 << 18)
+
+#define EXYNOS_USB3_PHYCLKRST_MPLL_MULTIPLIER_MASK (0x7f << 11)
+#define EXYNOS_USB3_PHYCLKRST_MPLL_MULTIPLIER_SHIFT (11)
+#define EXYNOS_USB3_PHYCLKRST_MPLL_MULTIPLIER_LIMIT (0x7f)
+#define EXYNOS_USB3_PHYCLKRST_MPLL_MULTIPLIER(_x) ((_x) << 11)
+
+#define EXYNOS_USB3_PHYCLKRST_FSEL_MASK (0x3f << 5)
+#define EXYNOS_USB3_PHYCLKRST_FSEL_SHIFT (5)
+#define EXYNOS_USB3_PHYCLKRST_FSEL_LIMIT (0x3f)
+#define EXYNOS_USB3_PHYCLKRST_FSEL(_x) ((_x) << 5)
+
+#define EXYNOS_USB3_PHYCLKRST_RETENABLEN (1 << 4)
+
+#define EXYNOS_USB3_PHYCLKRST_REFCLKSEL_MASK (0x03 << 2)
+#define EXYNOS_USB3_PHYCLKRST_REFCLKSEL_SHIFT (2)
+#define EXYNOS_USB3_PHYCLKRST_REFCLKSEL_LIMIT (0x03)
+#define EXYNOS_USB3_PHYCLKRST_REFCLKSEL(_x) ((_x) << 2)
+
+#define EXYNOS_USB3_PHYCLKRST_PORTRESET (1 << 1)
+#define EXYNOS_USB3_PHYCLKRST_COMMONONN (1 << 0)
+
+
+//-------------------------------------------------------
+// Functions
+//-------------------------------------------------------
+
+void exynos5_usb_phy30_init(void);
+void exynos_xhci_phy_set(void);
+UINT32 exynos_xhci_change_mode(void);
+
+#endif
+
+
diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/PciEmulation/PciEmulation.c b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/PciEmulation/PciEmulation.c
new file mode 100644
index 000000000..a4295cc85
--- /dev/null
+++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/PciEmulation/PciEmulation.c
@@ -0,0 +1,684 @@
+/** @file
+
+ Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "PciEmulation.h"
+#include "Exynos5_USB2Phy.h"
+#include "Exynos5_USB3Phy.h"
+#include "Exynos5_USB3Drd.h"
+
+#define HOST_CONTROLLER_OPERATION_REG_SIZE 0x44
+#define USBDRD_CONTROLLER_OPERATION_REG_SIZE 0x400
+
+typedef struct {
+ ACPI_HID_DEVICE_PATH AcpiDevicePath;
+ PCI_DEVICE_PATH PciDevicePath;
+ EFI_DEVICE_PATH_PROTOCOL EndDevicePath;
+} EFI_PCI_IO_DEVICE_PATH;
+
+typedef struct {
+ UINT32 Signature;
+ EFI_PCI_IO_DEVICE_PATH DevicePath;
+ EFI_PCI_IO_PROTOCOL PciIoProtocol;
+ PCI_TYPE00 *ConfigSpace;
+ PCI_ROOT_BRIDGE RootBridge;
+ UINTN Segment;
+} EFI_PCI_IO_PRIVATE_DATA;
+
+#define EFI_PCI_IO_PRIVATE_DATA_SIGNATURE SIGNATURE_32('p', 'c', 'i', 'o')
+#define EFI_PCI_IO_PRIVATE_DATA_FROM_THIS(a) CR(a, EFI_PCI_IO_PRIVATE_DATA, PciIoProtocol, EFI_PCI_IO_PRIVATE_DATA_SIGNATURE)
+
+EFI_PCI_IO_DEVICE_PATH PciIoDevicePathTemplateUSB2 =
+{
+ {
+ { ACPI_DEVICE_PATH, ACPI_DP, sizeof (ACPI_HID_DEVICE_PATH), 0},
+ EISA_PNP_ID(0x0A03), // HID
+ 0 // UID
+ },
+ {
+ { HARDWARE_DEVICE_PATH, HW_PCI_DP, sizeof (PCI_DEVICE_PATH), 0},
+ 0,
+ 0
+ },
+ { END_DEVICE_PATH_TYPE, END_ENTIRE_DEVICE_PATH_SUBTYPE, sizeof (EFI_DEVICE_PATH_PROTOCOL), 0}
+};
+
+EFI_PCI_IO_DEVICE_PATH PciIoDevicePathTemplateUSB3 =
+{
+ {
+ { ACPI_DEVICE_PATH, ACPI_DP, sizeof (ACPI_HID_DEVICE_PATH), 0},
+ EISA_PNP_ID(0x0A03), // HID
+ 1 // UID
+ },
+ {
+ { HARDWARE_DEVICE_PATH, HW_PCI_DP, sizeof (PCI_DEVICE_PATH), 0},
+ 0,
+ 1
+ },
+ { END_DEVICE_PATH_TYPE, END_ENTIRE_DEVICE_PATH_SUBTYPE, sizeof (EFI_DEVICE_PATH_PROTOCOL), 0}
+};
+
+EFI_PCI_IO_DEVICE_PATH PciIoDevicePathTemplateUSB1 =
+{
+ {
+ { ACPI_DEVICE_PATH, ACPI_DP, sizeof (ACPI_HID_DEVICE_PATH), 0},
+ EISA_PNP_ID(0x0A03), // HID
+ 2 // UID
+ },
+ {
+ { HARDWARE_DEVICE_PATH, HW_PCI_DP, sizeof (PCI_DEVICE_PATH), 0},
+ 0,
+ 2
+ },
+ { END_DEVICE_PATH_TYPE, END_ENTIRE_DEVICE_PATH_SUBTYPE, sizeof (EFI_DEVICE_PATH_PROTOCOL), 0}
+};
+
+
+STATIC
+VOID
+ConfigureUSBHost (
+ VOID
+ )
+{
+ DEBUG((EFI_D_INFO, "++%a:%d\n", __func__, __LINE__));
+
+ exynos5_usb_phy20_init();
+#if defined(XHCI_SUPPORT)
+ exynos5_usb_phy30_init();
+ exynos_xhci_change_mode();
+ exynos_xhci_phy_set();
+#endif
+
+ DEBUG((EFI_D_INFO, "--%a:%d\n", __FUNCTION__, __LINE__));
+}
+
+
+EFI_STATUS
+PciIoPollMem (
+ IN EFI_PCI_IO_PROTOCOL *This,
+ IN EFI_PCI_IO_PROTOCOL_WIDTH Width,
+ IN UINT8 BarIndex,
+ IN UINT64 Offset,
+ IN UINT64 Mask,
+ IN UINT64 Value,
+ IN UINT64 Delay,
+ OUT UINT64 *Result
+ )
+{
+ ASSERT (FALSE);
+ return EFI_UNSUPPORTED;
+}
+
+EFI_STATUS
+PciIoPollIo (
+ IN EFI_PCI_IO_PROTOCOL *This,
+ IN EFI_PCI_IO_PROTOCOL_WIDTH Width,
+ IN UINT8 BarIndex,
+ IN UINT64 Offset,
+ IN UINT64 Mask,
+ IN UINT64 Value,
+ IN UINT64 Delay,
+ OUT UINT64 *Result
+ )
+{
+ ASSERT (FALSE);
+ return EFI_UNSUPPORTED;
+}
+
+EFI_STATUS
+PciIoMemRead (
+ IN EFI_PCI_IO_PROTOCOL *This,
+ IN EFI_PCI_IO_PROTOCOL_WIDTH Width,
+ IN UINT8 BarIndex,
+ IN UINT64 Offset,
+ IN UINTN Count,
+ IN OUT VOID *Buffer
+ )
+{
+ EFI_PCI_IO_PRIVATE_DATA *Private = EFI_PCI_IO_PRIVATE_DATA_FROM_THIS(This);
+
+ DEBUG((EFI_D_INFO, "++%a:%d\n", __FUNCTION__, __LINE__));
+ DEBUG((EFI_D_INFO, "--%a:%d\n", __FUNCTION__, __LINE__));
+ return PciRootBridgeIoMemRead (&Private->RootBridge.Io,
+ (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,
+ Private->ConfigSpace->Device.Bar[BarIndex] + Offset,
+ Count,
+ Buffer
+ );
+}
+
+EFI_STATUS
+PciIoMemWrite (
+ IN EFI_PCI_IO_PROTOCOL *This,
+ IN EFI_PCI_IO_PROTOCOL_WIDTH Width,
+ IN UINT8 BarIndex,
+ IN UINT64 Offset,
+ IN UINTN Count,
+ IN OUT VOID *Buffer
+ )
+{
+ EFI_PCI_IO_PRIVATE_DATA *Private = EFI_PCI_IO_PRIVATE_DATA_FROM_THIS(This);
+
+ DEBUG((EFI_D_INFO, "++%a:%d\n", __FUNCTION__, __LINE__));
+ DEBUG((EFI_D_INFO, "--%a:%d\n", __FUNCTION__, __LINE__));
+ return PciRootBridgeIoMemWrite (&Private->RootBridge.Io,
+ (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,
+ Private->ConfigSpace->Device.Bar[BarIndex] + Offset,
+ Count,
+ Buffer
+ );
+}
+
+EFI_STATUS
+PciIoIoRead (
+ IN EFI_PCI_IO_PROTOCOL *This,
+ IN EFI_PCI_IO_PROTOCOL_WIDTH Width,
+ IN UINT8 BarIndex,
+ IN UINT64 Offset,
+ IN UINTN Count,
+ IN OUT VOID *Buffer
+ )
+{
+ ASSERT (FALSE);
+ return EFI_UNSUPPORTED;
+}
+
+EFI_STATUS
+PciIoIoWrite (
+ IN EFI_PCI_IO_PROTOCOL *This,
+ IN EFI_PCI_IO_PROTOCOL_WIDTH Width,
+ IN UINT8 BarIndex,
+ IN UINT64 Offset,
+ IN UINTN Count,
+ IN OUT VOID *Buffer
+ )
+{
+ ASSERT (FALSE);
+ return EFI_UNSUPPORTED;
+}
+
+EFI_STATUS
+PciIoPciRead (
+ IN EFI_PCI_IO_PROTOCOL *This,
+ IN EFI_PCI_IO_PROTOCOL_WIDTH Width,
+ IN UINT32 Offset,
+ IN UINTN Count,
+ IN OUT VOID *Buffer
+ )
+{
+ EFI_PCI_IO_PRIVATE_DATA *Private = EFI_PCI_IO_PRIVATE_DATA_FROM_THIS(This);
+
+ DEBUG((EFI_D_INFO, "++%a:%d\n", __FUNCTION__, __LINE__));
+ DEBUG((EFI_D_INFO, "--%a:%d\n", __FUNCTION__, __LINE__));
+ return PciRootBridgeIoMemRW ((EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH)Width,
+ Count,
+ TRUE,
+ (PTR)(UINTN)Buffer,
+ TRUE,
+ (PTR)(UINTN)(((UINT8 *)Private->ConfigSpace) + Offset)
+ );
+}
+
+EFI_STATUS
+PciIoPciWrite (
+ IN EFI_PCI_IO_PROTOCOL *This,
+ IN EFI_PCI_IO_PROTOCOL_WIDTH Width,
+ IN UINT32 Offset,
+ IN UINTN Count,
+ IN OUT VOID *Buffer
+ )
+{
+ EFI_PCI_IO_PRIVATE_DATA *Private = EFI_PCI_IO_PRIVATE_DATA_FROM_THIS(This);
+
+ DEBUG((EFI_D_INFO, "++%a:%d\n", __FUNCTION__, __LINE__));
+ DEBUG((EFI_D_INFO, "--%a:%d\n", __FUNCTION__, __LINE__));
+ return PciRootBridgeIoMemRW ((EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) Width,
+ Count,
+ TRUE,
+ (PTR)(UINTN)(((UINT8 *)Private->ConfigSpace) + Offset),
+ TRUE,
+ (PTR)(UINTN)Buffer
+ );
+}
+
+EFI_STATUS
+PciIoCopyMem (
+ IN EFI_PCI_IO_PROTOCOL *This,
+ IN EFI_PCI_IO_PROTOCOL_WIDTH Width,
+ IN UINT8 DestBarIndex,
+ IN UINT64 DestOffset,
+ IN UINT8 SrcBarIndex,
+ IN UINT64 SrcOffset,
+ IN UINTN Count
+ )
+{
+ ASSERT (FALSE);
+ return EFI_UNSUPPORTED;
+}
+
+EFI_STATUS
+PciIoMap (
+ IN EFI_PCI_IO_PROTOCOL *This,
+ IN EFI_PCI_IO_PROTOCOL_OPERATION Operation,
+ IN VOID *HostAddress,
+ IN OUT UINTN *NumberOfBytes,
+ OUT EFI_PHYSICAL_ADDRESS *DeviceAddress,
+ OUT VOID **Mapping
+ )
+{
+ DMA_MAP_OPERATION DmaOperation;
+
+ DEBUG((EFI_D_INFO, "++%a:%d\n", __FUNCTION__, __LINE__));
+ if (Operation == EfiPciIoOperationBusMasterRead) {
+ DmaOperation = MapOperationBusMasterRead;
+ } else if (Operation == EfiPciIoOperationBusMasterWrite) {
+ DmaOperation = MapOperationBusMasterWrite;
+ } else if (Operation == EfiPciIoOperationBusMasterCommonBuffer) {
+ DmaOperation = MapOperationBusMasterCommonBuffer;
+ } else {
+ return EFI_INVALID_PARAMETER;
+ }
+ DEBUG((EFI_D_INFO, "--%a:%d\n", __FUNCTION__, __LINE__));
+ return DmaMap (DmaOperation, HostAddress, NumberOfBytes, DeviceAddress, Mapping);
+}
+
+EFI_STATUS
+PciIoUnmap (
+ IN EFI_PCI_IO_PROTOCOL *This,
+ IN VOID *Mapping
+ )
+{
+ DEBUG((EFI_D_INFO, "++%a:%d\n", __FUNCTION__, __LINE__));
+ DEBUG((EFI_D_INFO, "--%a:%d\n", __FUNCTION__, __LINE__));
+ return DmaUnmap (Mapping);
+}
+
+EFI_STATUS
+PciIoAllocateBuffer (
+ IN EFI_PCI_IO_PROTOCOL *This,
+ IN EFI_ALLOCATE_TYPE Type,
+ IN EFI_MEMORY_TYPE MemoryType,
+ IN UINTN Pages,
+ OUT VOID **HostAddress,
+ IN UINT64 Attributes
+ )
+{
+ DEBUG((EFI_D_INFO, "++%a:%d\n", __FUNCTION__, __LINE__));
+ if (Attributes & EFI_PCI_ATTRIBUTE_INVALID_FOR_ALLOCATE_BUFFER) {
+ // Check this
+ return EFI_UNSUPPORTED;
+ }
+
+ DEBUG((EFI_D_INFO, "--%a:%d\n", __FUNCTION__, __LINE__));
+ return DmaAllocateBuffer (MemoryType, Pages, HostAddress);
+}
+
+
+EFI_STATUS
+PciIoFreeBuffer (
+ IN EFI_PCI_IO_PROTOCOL *This,
+ IN UINTN Pages,
+ IN VOID *HostAddress
+ )
+{
+ DEBUG((EFI_D_INFO, "++%a:%d\n", __FUNCTION__, __LINE__));
+ DEBUG((EFI_D_INFO, "--%a:%d\n", __FUNCTION__, __LINE__));
+ return DmaFreeBuffer (Pages, HostAddress);
+}
+
+
+EFI_STATUS
+PciIoFlush (
+ IN EFI_PCI_IO_PROTOCOL *This
+ )
+{
+ DEBUG((EFI_D_INFO, "++%a:%d\n", __FUNCTION__, __LINE__));
+ DEBUG((EFI_D_INFO, "--%a:%d\n", __FUNCTION__, __LINE__));
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+PciIoGetLocation (
+ IN EFI_PCI_IO_PROTOCOL *This,
+ OUT UINTN *SegmentNumber,
+ OUT UINTN *BusNumber,
+ OUT UINTN *DeviceNumber,
+ OUT UINTN *FunctionNumber
+ )
+{
+ DEBUG((EFI_D_INFO, "++%a:%d\n", __FUNCTION__, __LINE__));
+ EFI_PCI_IO_PRIVATE_DATA *Private = EFI_PCI_IO_PRIVATE_DATA_FROM_THIS(This);
+
+ if (SegmentNumber != NULL) {
+ *SegmentNumber = Private->Segment;
+ }
+
+ if (BusNumber != NULL) {
+ *BusNumber = 0xff;
+ }
+
+ if (DeviceNumber != NULL) {
+ *DeviceNumber = 0;
+ }
+
+ if (FunctionNumber != NULL) {
+ *FunctionNumber = 0;
+ }
+
+ DEBUG((EFI_D_INFO, "--%a:%d\n", __FUNCTION__, __LINE__));
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+PciIoAttributes (
+ IN EFI_PCI_IO_PROTOCOL *This,
+ IN EFI_PCI_IO_PROTOCOL_ATTRIBUTE_OPERATION Operation,
+ IN UINT64 Attributes,
+ OUT UINT64 *Result OPTIONAL
+ )
+{
+ DEBUG((EFI_D_INFO, "++%a:%d\n", __FUNCTION__, __LINE__));
+ switch (Operation) {
+ case EfiPciIoAttributeOperationGet:
+ case EfiPciIoAttributeOperationSupported:
+ if (Result == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+ // We are not a real PCI device so just say things we kind of do
+ *Result = EFI_PCI_IO_ATTRIBUTE_MEMORY | EFI_PCI_IO_ATTRIBUTE_BUS_MASTER | EFI_PCI_DEVICE_ENABLE;
+ break;
+
+ case EfiPciIoAttributeOperationSet:
+ case EfiPciIoAttributeOperationEnable:
+ case EfiPciIoAttributeOperationDisable:
+ // Since we are not a real PCI device no enable/set or disable operations exist.
+ DEBUG((EFI_D_INFO, "--%a(Set:1, Enable:2, Disable:3)(%d):%d\n", __FUNCTION__, Operation,__LINE__));
+ return EFI_SUCCESS;
+
+ default:
+ ASSERT (FALSE);
+ return EFI_INVALID_PARAMETER;
+ };
+ DEBUG((EFI_D_INFO, "--%a(Get:0, Supported:4)(%d):%d\n", __FUNCTION__, Operation,__LINE__));
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+PciIoGetBarAttributes (
+ IN EFI_PCI_IO_PROTOCOL *This,
+ IN UINT8 BarIndex,
+ OUT UINT64 *Supports, OPTIONAL
+ OUT VOID **Resources OPTIONAL
+ )
+{
+ ASSERT (FALSE);
+ return EFI_UNSUPPORTED;
+}
+
+EFI_STATUS
+PciIoSetBarAttributes (
+ IN EFI_PCI_IO_PROTOCOL *This,
+ IN UINT64 Attributes,
+ IN UINT8 BarIndex,
+ IN OUT UINT64 *Offset,
+ IN OUT UINT64 *Length
+ )
+{
+ ASSERT (FALSE);
+ return EFI_UNSUPPORTED;
+}
+
+EFI_PCI_IO_PROTOCOL PciIoTemplate =
+{
+ PciIoPollMem,
+ PciIoPollIo,
+ PciIoMemRead,
+ PciIoMemWrite,
+ PciIoIoRead,
+ PciIoIoWrite,
+ PciIoPciRead,
+ PciIoPciWrite,
+ PciIoCopyMem,
+ PciIoMap,
+ PciIoUnmap,
+ PciIoAllocateBuffer,
+ PciIoFreeBuffer,
+ PciIoFlush,
+ PciIoGetLocation,
+ PciIoAttributes,
+ PciIoGetBarAttributes,
+ PciIoSetBarAttributes,
+ 0,
+ 0
+};
+
+EFI_STATUS
+EFIAPI
+PciEmulationEntryPoint (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ EFI_HANDLE HandleUSB2;
+ EFI_PCI_IO_PRIVATE_DATA *PrivateUSB2;
+#if defined(OHCI_SUPPORT)
+ EFI_HANDLE HandleUSB1;
+ EFI_PCI_IO_PRIVATE_DATA *PrivateUSB1;
+#endif
+#if defined(XHCI_SUPPORT)
+ EFI_HANDLE HandleUSB3;
+ EFI_PCI_IO_PRIVATE_DATA *PrivateUSB3;
+#endif
+ UINT8 CapabilityLength;
+ UINT8 PhysicalPorts;
+#if defined(OHCI_SUPPORT)
+#else
+ UINTN Count;
+#endif
+
+ //Configure USB host for Exynos.
+ ConfigureUSBHost();
+
+ // Create a private structure for USB 2.0
+ PrivateUSB2 = AllocatePool(sizeof(EFI_PCI_IO_PRIVATE_DATA));
+ if (PrivateUSB2 == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ return Status;
+ }
+ PrivateUSB2->Signature = EFI_PCI_IO_PRIVATE_DATA_SIGNATURE; // Fill in signature
+ PrivateUSB2->RootBridge.Signature = PCI_ROOT_BRIDGE_SIGNATURE; // Fake Root Bridge structure needs a signature too
+ PrivateUSB2->RootBridge.MemoryStart = USB_EHCI_HCCAPBASE; // Get the USB capability register base
+ PrivateUSB2->Segment = 0; // Default to segment zero
+
+
+#if defined(XHCI_SUPPORT)
+ // Create a private structure for USB 3.0
+ PrivateUSB3 = AllocatePool(sizeof(EFI_PCI_IO_PRIVATE_DATA));
+ if (PrivateUSB3 == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ return Status;
+ }
+ PrivateUSB3->Signature = EFI_PCI_IO_PRIVATE_DATA_SIGNATURE; // Fill in signature
+ PrivateUSB3->RootBridge.Signature = PCI_ROOT_BRIDGE_SIGNATURE; // Fake Root Bridge structure needs a signature too
+ PrivateUSB3->RootBridge.MemoryStart = USB_XHCI_HCCAPBASE; // Get the USB capability register base
+ PrivateUSB3->Segment = 0; // Default to segment zero
+#endif
+
+#if defined(OHCI_SUPPORT)
+ // Create a private structure for USB 1.0
+ PrivateUSB1 = AllocatePool(sizeof(EFI_PCI_IO_PRIVATE_DATA));
+ if (PrivateUSB1 == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ return Status;
+ }
+ PrivateUSB1->Signature = EFI_PCI_IO_PRIVATE_DATA_SIGNATURE; // Fill in signature
+ PrivateUSB1->RootBridge.Signature = PCI_ROOT_BRIDGE_SIGNATURE; // Fake Root Bridge structure needs a signature too
+ PrivateUSB1->RootBridge.MemoryStart = USB_OHCI_HCCAPBASE; // Get the USB capability register base
+ PrivateUSB1->Segment = 0; // Default to segment zero
+#endif
+
+ // USB 2.0
+ // Find out the capability register length and number of physical ports.
+ CapabilityLength = MmioRead8(PrivateUSB2->RootBridge.MemoryStart);
+ PhysicalPorts = (MmioRead32 (PrivateUSB2->RootBridge.MemoryStart + 0x4)) & 0x0000000F;
+
+ // Calculate the total size of the USB registers.
+ PrivateUSB2->RootBridge.MemorySize = CapabilityLength + (HOST_CONTROLLER_OPERATION_REG_SIZE + ((4 * PhysicalPorts) - 1));
+
+ // Enable Port Power bit in Port status and control registers in EHCI register space.
+ // Port Power Control (PPC) bit in the HCSPARAMS register is already set which indicates
+ // host controller implementation includes port power control.
+ for (Count = 0; Count < PhysicalPorts; Count++) {
+ MmioOr32 ((PrivateUSB2->RootBridge.MemoryStart + CapabilityLength + HOST_CONTROLLER_OPERATION_REG_SIZE + 4*Count), 0x00001000);
+ }
+
+#if defined(XHCI_SUPPORT)
+ // USB 3.0
+ // Find out the capability register length and number of physical ports.
+ CapabilityLength = MmioRead8(PrivateUSB3->RootBridge.MemoryStart);
+ PhysicalPorts = ((MmioRead32 (PrivateUSB3->RootBridge.MemoryStart + 0x4)) & 0xFF000000) >> 24;
+
+ // Calculate the total size of the USB registers.
+ // 0x20 0x400 0x10
+ //Private->RootBridge.MemorySize = CapabilityLength + (USBDRD_CONTROLLER_OPERATION_REG_SIZE + (0x10 * (PhysicalPorts - 1)));
+ PrivateUSB3->RootBridge.MemorySize = 0x100000;
+
+ for (Count = 0; Count < PhysicalPorts; Count++) {
+ MmioOr32 (PrivateUSB3->RootBridge.MemoryStart + CapabilityLength + USBDRD_CONTROLLER_OPERATION_REG_SIZE + (0x10 * Count), 0x00000200);
+ }
+#endif
+
+#if defined(OHCI_SUPPORT)
+ CapabilityLength = 0;
+ PhysicalPorts = 3;
+ PrivateUSB1->RootBridge.MemorySize = 0x60;
+#endif
+
+
+ // USB 2.0
+ // Create fake PCI config space.
+ PrivateUSB2->ConfigSpace = AllocateZeroPool(sizeof(PCI_TYPE00));
+ if (PrivateUSB2->ConfigSpace == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ FreePool(PrivateUSB2);
+ return Status;
+ }
+
+ // Configure PCI config space
+ PrivateUSB2->ConfigSpace->Hdr.VendorId = 0x3530;
+ PrivateUSB2->ConfigSpace->Hdr.DeviceId = 0x3530;
+ PrivateUSB2->ConfigSpace->Hdr.ClassCode[0] = 0x20;
+ PrivateUSB2->ConfigSpace->Hdr.ClassCode[1] = 0x03;
+ PrivateUSB2->ConfigSpace->Hdr.ClassCode[2] = 0x0C;
+ PrivateUSB2->ConfigSpace->Device.Bar[0] = PrivateUSB2->RootBridge.MemoryStart;
+
+#if defined(XHCI_SUPPORT)
+ // USB 3.0
+ // Create fake PCI config space.
+ PrivateUSB3->ConfigSpace = AllocateZeroPool(sizeof(PCI_TYPE00));
+ if (PrivateUSB3->ConfigSpace == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ FreePool(PrivateUSB3);
+ return Status;
+ }
+
+ // Configure PCI config space
+ PrivateUSB3->ConfigSpace->Hdr.VendorId = 0x3530;
+ PrivateUSB3->ConfigSpace->Hdr.DeviceId = 0x3530;
+ PrivateUSB3->ConfigSpace->Hdr.ClassCode[0] = 0x30; /* 0x20 : EHIC, 0x30 : XHCI */
+ PrivateUSB3->ConfigSpace->Hdr.ClassCode[1] = 0x03;
+ PrivateUSB3->ConfigSpace->Hdr.ClassCode[2] = 0x0C;
+ PrivateUSB3->ConfigSpace->Device.Bar[0] = PrivateUSB3->RootBridge.MemoryStart;
+#endif
+
+#if defined(OHCI_SUPPORT)
+ // USB 1.0
+ // Create fake PCI config space.
+ PrivateUSB1->ConfigSpace = AllocateZeroPool(sizeof(PCI_TYPE00));
+ if (PrivateUSB1->ConfigSpace == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ FreePool(PrivateUSB1);
+ return Status;
+ }
+
+ // Configure PCI config space
+ PrivateUSB1->ConfigSpace->Hdr.VendorId = 0x3530;
+ PrivateUSB1->ConfigSpace->Hdr.DeviceId = 0x3530;
+ PrivateUSB1->ConfigSpace->Hdr.ClassCode[0] = 0x10;
+ PrivateUSB1->ConfigSpace->Hdr.ClassCode[1] = 0x03;
+ PrivateUSB1->ConfigSpace->Hdr.ClassCode[2] = 0x0C;
+ PrivateUSB1->ConfigSpace->Device.Bar[0] = PrivateUSB2->RootBridge.MemoryStart;
+#endif
+
+
+ HandleUSB2 = NULL;
+
+ // USB 2.0
+ // Unique device path.
+ CopyMem(&PrivateUSB2->DevicePath, &PciIoDevicePathTemplateUSB2, sizeof(PciIoDevicePathTemplateUSB2));
+ PrivateUSB2->DevicePath.AcpiDevicePath.UID = 0;
+ // Copy protocol structure
+ CopyMem(&PrivateUSB2->PciIoProtocol, &PciIoTemplate, sizeof(PciIoTemplate));
+
+ Status = gBS->InstallMultipleProtocolInterfaces(&HandleUSB2,
+ &gEfiPciIoProtocolGuid, &PrivateUSB2->PciIoProtocol,
+ &gEfiDevicePathProtocolGuid, &PrivateUSB2->DevicePath,
+ NULL);
+ if (EFI_ERROR(Status)) {
+ DEBUG((EFI_D_ERROR, "PciEmulationEntryPoint InstallMultipleProtocolInterfaces() failed.\n"));
+ }
+
+#if defined(XHCI_SUPPORT)
+ HandleUSB3 = NULL;
+
+ // USB 3.0
+ // Unique device path.
+ CopyMem(&PrivateUSB3->DevicePath, &PciIoDevicePathTemplateUSB3, sizeof(PciIoDevicePathTemplateUSB3));
+ PrivateUSB3->DevicePath.AcpiDevicePath.UID = 1;
+ // Copy protocol structure
+ CopyMem(&PrivateUSB3->PciIoProtocol, &PciIoTemplate, sizeof(PciIoTemplate));
+
+
+ Status = gBS->InstallMultipleProtocolInterfaces(&HandleUSB3,
+ &gEfiPciIoProtocolGuid, &PrivateUSB3->PciIoProtocol,
+ &gEfiDevicePathProtocolGuid, &PrivateUSB3->DevicePath,
+ NULL);
+ if (EFI_ERROR(Status)) {
+ DEBUG((EFI_D_ERROR, "PciEmulationEntryPoint InstallMultipleProtocolInterfaces() failed.\n"));
+ }
+#endif
+
+#if defined(OHCI_SUPPORT)
+ HandleUSB1 = NULL;
+
+ // USB 1.0
+ // Unique device path.
+ CopyMem(&PrivateUSB1->DevicePath, &PciIoDevicePathTemplateUSB1, sizeof(PciIoDevicePathTemplateUSB1));
+ PrivateUSB1->DevicePath.AcpiDevicePath.UID = 2;
+ // Copy protocol structure
+ CopyMem(&PrivateUSB1->PciIoProtocol, &PciIoTemplate, sizeof(PciIoTemplate));
+
+ Status = gBS->InstallMultipleProtocolInterfaces(&HandleUSB1,
+ &gEfiPciIoProtocolGuid, &PrivateUSB1->PciIoProtocol,
+ &gEfiDevicePathProtocolGuid, &PrivateUSB1->DevicePath,
+ NULL);
+ if (EFI_ERROR(Status)) {
+ DEBUG((EFI_D_ERROR, "PciEmulationEntryPoint InstallMultipleProtocolInterfaces() failed.\n"));
+ }
+#endif
+
+
+ return Status;
+}
+
diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/PciEmulation/PciEmulation.h b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/PciEmulation/PciEmulation.h
new file mode 100644
index 000000000..7f0e3106e
--- /dev/null
+++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/PciEmulation/PciEmulation.h
@@ -0,0 +1,290 @@
+/** @file
+
+ Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _PCI_ROOT_BRIDGE_H_
+#define _PCI_ROOT_BRIDGE_H_
+
+#include <PiDxe.h>
+
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/DxeServicesTableLib.h>
+#include <Library/IoLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PciLib.h>
+#include <Library/UefiLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/DmaLib.h>
+
+#include <Protocol/EmbeddedExternalDevice.h>
+#include <Protocol/DevicePath.h>
+#include <Protocol/PciIo.h>
+#include <Protocol/PciRootBridgeIo.h>
+#include <Protocol/PciHostBridgeResourceAllocation.h>
+
+#include <IndustryStandard/Pci22.h>
+#include <IndustryStandard/Acpi.h>
+
+
+//#define OHCI_SUPPORT
+#define XHCI_SUPPORT
+
+
+#define EFI_RESOURCE_NONEXISTENT 0xFFFFFFFFFFFFFFFFULL
+#define EFI_RESOURCE_LESS 0xFFFFFFFFFFFFFFFEULL
+#define EFI_RESOURCE_SATISFIED 0x0000000000000000ULL
+
+
+typedef struct {
+ ACPI_HID_DEVICE_PATH AcpiDevicePath;
+ EFI_DEVICE_PATH_PROTOCOL EndDevicePath;
+} EFI_PCI_ROOT_BRIDGE_DEVICE_PATH;
+
+
+#define ACPI_CONFIG_IO 0
+#define ACPI_CONFIG_MMIO 1
+#define ACPI_CONFIG_BUS 2
+
+typedef struct {
+ EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR Desc[3];
+ EFI_ACPI_END_TAG_DESCRIPTOR EndDesc;
+} ACPI_CONFIG_INFO;
+
+
+#define PCI_ROOT_BRIDGE_SIGNATURE SIGNATURE_32 ('P', 'c', 'i', 'F')
+
+typedef struct {
+ UINT32 Signature;
+ EFI_HANDLE Handle;
+ EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL Io;
+ EFI_PCI_ROOT_BRIDGE_DEVICE_PATH DevicePath;
+
+ UINT8 StartBus;
+ UINT8 EndBus;
+ UINT16 Type;
+ UINT32 MemoryStart;
+ UINT32 MemorySize;
+ UINTN IoOffset;
+ UINT32 IoStart;
+ UINT32 IoSize;
+ UINT64 PciAttributes;
+
+ ACPI_CONFIG_INFO *Config;
+
+} PCI_ROOT_BRIDGE;
+
+
+#define INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS(a) CR (a, PCI_ROOT_BRIDGE, Io, PCI_ROOT_BRIDGE_SIGNATURE)
+
+
+typedef union {
+ UINT8 volatile *buf;
+ UINT8 volatile *ui8;
+ UINT16 volatile *ui16;
+ UINT32 volatile *ui32;
+ UINT64 volatile *ui64;
+ UINTN volatile ui;
+} PTR;
+
+
+
+EFI_STATUS
+EFIAPI
+PciRootBridgeIoPollMem (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
+ IN UINT64 Address,
+ IN UINT64 Mask,
+ IN UINT64 Value,
+ IN UINT64 Delay,
+ OUT UINT64 *Result
+ );
+
+EFI_STATUS
+EFIAPI
+PciRootBridgeIoPollIo (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
+ IN UINT64 Address,
+ IN UINT64 Mask,
+ IN UINT64 Value,
+ IN UINT64 Delay,
+ OUT UINT64 *Result
+ );
+
+EFI_STATUS
+EFIAPI
+PciRootBridgeIoMemRead (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
+ IN UINT64 Address,
+ IN UINTN Count,
+ IN OUT VOID *Buffer
+ );
+
+EFI_STATUS
+EFIAPI
+PciRootBridgeIoMemWrite (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
+ IN UINT64 Address,
+ IN UINTN Count,
+ IN OUT VOID *Buffer
+ );
+
+EFI_STATUS
+EFIAPI
+PciRootBridgeIoIoRead (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
+ IN UINT64 UserAddress,
+ IN UINTN Count,
+ IN OUT VOID *UserBuffer
+ );
+
+EFI_STATUS
+EFIAPI
+PciRootBridgeIoIoWrite (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
+ IN UINT64 UserAddress,
+ IN UINTN Count,
+ IN OUT VOID *UserBuffer
+ );
+
+EFI_STATUS
+EFIAPI
+PciRootBridgeIoCopyMem (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
+ IN UINT64 DestAddress,
+ IN UINT64 SrcAddress,
+ IN UINTN Count
+ );
+
+EFI_STATUS
+EFIAPI
+PciRootBridgeIoPciRead (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
+ IN UINT64 Address,
+ IN UINTN Count,
+ IN OUT VOID *Buffer
+ );
+
+EFI_STATUS
+EFIAPI
+PciRootBridgeIoPciWrite (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
+ IN UINT64 Address,
+ IN UINTN Count,
+ IN OUT VOID *Buffer
+ );
+
+EFI_STATUS
+EFIAPI
+PciRootBridgeIoMap (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION Operation,
+ IN VOID *HostAddress,
+ IN OUT UINTN *NumberOfBytes,
+ OUT EFI_PHYSICAL_ADDRESS *DeviceAddress,
+ OUT VOID **Mapping
+ );
+
+EFI_STATUS
+EFIAPI
+PciRootBridgeIoUnmap (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ IN VOID *Mapping
+ );
+
+EFI_STATUS
+EFIAPI
+PciRootBridgeIoAllocateBuffer (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ IN EFI_ALLOCATE_TYPE Type,
+ IN EFI_MEMORY_TYPE MemoryType,
+ IN UINTN Pages,
+ OUT VOID **HostAddress,
+ IN UINT64 Attributes
+ );
+
+EFI_STATUS
+EFIAPI
+PciRootBridgeIoFreeBuffer (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ IN UINTN Pages,
+ OUT VOID *HostAddress
+ );
+
+EFI_STATUS
+EFIAPI
+PciRootBridgeIoFlush (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This
+ );
+
+EFI_STATUS
+EFIAPI
+PciRootBridgeIoGetAttributes (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ OUT UINT64 *Supported,
+ OUT UINT64 *Attributes
+ );
+
+EFI_STATUS
+EFIAPI
+PciRootBridgeIoSetAttributes (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ IN UINT64 Attributes,
+ IN OUT UINT64 *ResourceBase,
+ IN OUT UINT64 *ResourceLength
+ );
+
+EFI_STATUS
+EFIAPI
+PciRootBridgeIoConfiguration (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ OUT VOID **Resources
+ );
+
+//
+// Private Function Prototypes
+//
+EFI_STATUS
+EFIAPI
+PciRootBridgeIoMemRW (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
+ IN UINTN Count,
+ IN BOOLEAN InStrideFlag,
+ IN PTR In,
+ IN BOOLEAN OutStrideFlag,
+ OUT PTR Out
+ );
+
+BOOLEAN
+PciIoMemAddressValid (
+ IN EFI_PCI_IO_PROTOCOL *This,
+ IN UINT64 Address
+ );
+
+EFI_STATUS
+EmulatePciIoForEhci (
+ INTN MvPciIfMaxIf
+ );
+
+#endif
+
diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/PciEmulation/PciEmulation.inf b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/PciEmulation/PciEmulation.inf
new file mode 100644
index 000000000..f56fe6c04
--- /dev/null
+++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/PciEmulation/PciEmulation.inf
@@ -0,0 +1,64 @@
+/** @file
+
+ Copyright (c) 2009, Apple Inc. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = ExynosPciEmulation
+ FILE_GUID = feaa2e2b-53ac-4d5e-ae10-1efd5da4a2ba
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+
+ ENTRY_POINT = PciEmulationEntryPoint
+
+[Sources.common]
+ Exynos5_USB2Phy.h
+ Exynos5_USB3Phy.h
+ Exynos5_USB.c
+ PciRootBridgeIo.c
+ PciEmulation.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ IntelFrameworkPkg/IntelFrameworkPkg.dec
+ ArmPkg/ArmPkg.dec
+ EmbeddedPkg/EmbeddedPkg.dec
+ SamsungPlatformPkg/ExynosPkg/Exynos5250/ExynosPkg.dec
+ SamsungPlatformPkg/SamsungPlatformPkg.dec
+
+[LibraryClasses]
+ BaseLib
+ DxeServicesTableLib
+ UefiLib
+ UefiBootServicesTableLib
+ UefiDriverEntryPoint
+ UefiRuntimeServicesTableLib
+ IoLib
+ DmaLib
+ TimerLib
+
+[Pcd]
+ gExynosPkgTokenSpaceGuid.PcdExynos5250Evt1
+
+[Protocols]
+ gEfiPciRootBridgeIoProtocolGuid
+ gEfiDevicePathProtocolGuid
+ gEfiPciHostBridgeResourceAllocationProtocolGuid
+ gEfiPciIoProtocolGuid
+ gSamsungPlatformGpioProtocolGuid ## GPIO Protocol
+
+[Depex]
+ gEfiMetronomeArchProtocolGuid
+
+
diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/PciEmulation/PciRootBridgeIo.c b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/PciEmulation/PciRootBridgeIo.c
new file mode 100644
index 000000000..2f5b1aa1d
--- /dev/null
+++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/PciEmulation/PciRootBridgeIo.c
@@ -0,0 +1,306 @@
+/** @file
+
+ Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "PciEmulation.h"
+
+BOOLEAN
+PciRootBridgeMemAddressValid (
+ IN PCI_ROOT_BRIDGE *Private,
+ IN UINT64 Address
+ )
+{
+ if ((Address >= Private->MemoryStart) && (Address < (Private->MemoryStart + Private->MemorySize))) {
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+
+EFI_STATUS
+PciRootBridgeIoMemRW (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
+ IN UINTN Count,
+ IN BOOLEAN InStrideFlag,
+ IN PTR In,
+ IN BOOLEAN OutStrideFlag,
+ OUT PTR Out
+ )
+{
+ UINTN Stride;
+ UINTN InStride;
+ UINTN OutStride;
+
+
+ Width = (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) (Width & 0x03);
+ Stride = (UINTN)1 << Width;
+ InStride = InStrideFlag ? Stride : 0;
+ OutStride = OutStrideFlag ? Stride : 0;
+
+ //
+ // Loop for each iteration and move the data
+ //
+ switch (Width) {
+ case EfiPciWidthUint8:
+ for (;Count > 0; Count--, In.buf += InStride, Out.buf += OutStride) {
+ *In.ui8 = *Out.ui8;
+ }
+ break;
+ case EfiPciWidthUint16:
+ for (;Count > 0; Count--, In.buf += InStride, Out.buf += OutStride) {
+ *In.ui16 = *Out.ui16;
+ }
+ break;
+ case EfiPciWidthUint32:
+ for (;Count > 0; Count--, In.buf += InStride, Out.buf += OutStride) {
+ *In.ui32 = *Out.ui32;
+ }
+ break;
+ default:
+ return EFI_INVALID_PARAMETER;
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+PciRootBridgeIoPciRW (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ IN BOOLEAN Write,
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
+ IN UINT64 UserAddress,
+ IN UINTN Count,
+ IN OUT VOID *UserBuffer
+ )
+{
+ return EFI_SUCCESS;
+}
+
+/**
+ Enables a PCI driver to access PCI controller registers in the PCI root bridge memory space.
+
+ @param This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
+ @param Width Signifies the width of the memory operations.
+ @param Address The base address of the memory operations.
+ @param Count The number of memory operations to perform.
+ @param Buffer For read operations, the destination buffer to store the results. For write
+ operations, the source buffer to write data from.
+
+ @retval EFI_SUCCESS The data was read from or written to the PCI root bridge.
+ @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
+ @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
+
+**/
+EFI_STATUS
+EFIAPI
+PciRootBridgeIoMemRead (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
+ IN UINT64 Address,
+ IN UINTN Count,
+ IN OUT VOID *Buffer
+ )
+{
+ PCI_ROOT_BRIDGE *Private;
+ UINTN AlignMask;
+ PTR In;
+ PTR Out;
+
+ if ( Buffer == NULL ) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Private = INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS (This);
+
+ if (!PciRootBridgeMemAddressValid (Private, Address)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ AlignMask = (1 << (Width & 0x03)) - 1;
+ if (Address & AlignMask) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ In.buf = Buffer;
+ Out.buf = (VOID *)(UINTN) Address;
+
+ switch (Width) {
+ case EfiPciWidthUint8:
+ case EfiPciWidthUint16:
+ case EfiPciWidthUint32:
+ case EfiPciWidthUint64:
+ return PciRootBridgeIoMemRW (Width, Count, TRUE, In, TRUE, Out);
+
+ case EfiPciWidthFifoUint8:
+ case EfiPciWidthFifoUint16:
+ case EfiPciWidthFifoUint32:
+ case EfiPciWidthFifoUint64:
+ return PciRootBridgeIoMemRW (Width, Count, TRUE, In, FALSE, Out);
+
+ case EfiPciWidthFillUint8:
+ case EfiPciWidthFillUint16:
+ case EfiPciWidthFillUint32:
+ case EfiPciWidthFillUint64:
+ return PciRootBridgeIoMemRW (Width, Count, FALSE, In, TRUE, Out);
+
+ default:
+ break;
+ }
+
+ return EFI_INVALID_PARAMETER;
+}
+
+
+
+/**
+ Enables a PCI driver to access PCI controller registers in the PCI root bridge memory space.
+
+ @param This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
+ @param Width Signifies the width of the memory operations.
+ @param Address The base address of the memory operations.
+ @param Count The number of memory operations to perform.
+ @param Buffer For read operations, the destination buffer to store the results. For write
+ operations, the source buffer to write data from.
+
+ @retval EFI_SUCCESS The data was read from or written to the PCI root bridge.
+ @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
+ @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
+
+**/
+EFI_STATUS
+EFIAPI
+PciRootBridgeIoMemWrite (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
+ IN UINT64 Address,
+ IN UINTN Count,
+ IN OUT VOID *Buffer
+ )
+{
+ PCI_ROOT_BRIDGE *Private;
+ UINTN AlignMask;
+ PTR In;
+ PTR Out;
+
+ if ( Buffer == NULL ) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Private = INSTANCE_FROM_PCI_ROOT_BRIDGE_IO_THIS (This);
+
+ if (!PciRootBridgeMemAddressValid (Private, Address)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ AlignMask = (1 << (Width & 0x03)) - 1;
+ if (Address & AlignMask) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ In.buf = (VOID *)(UINTN) Address;
+ Out.buf = Buffer;
+
+ switch (Width) {
+ case EfiPciWidthUint8:
+ case EfiPciWidthUint16:
+ case EfiPciWidthUint32:
+ case EfiPciWidthUint64:
+ return PciRootBridgeIoMemRW (Width, Count, TRUE, In, TRUE, Out);
+
+ case EfiPciWidthFifoUint8:
+ case EfiPciWidthFifoUint16:
+ case EfiPciWidthFifoUint32:
+ case EfiPciWidthFifoUint64:
+ return PciRootBridgeIoMemRW (Width, Count, FALSE, In, TRUE, Out);
+
+ case EfiPciWidthFillUint8:
+ case EfiPciWidthFillUint16:
+ case EfiPciWidthFillUint32:
+ case EfiPciWidthFillUint64:
+ return PciRootBridgeIoMemRW (Width, Count, TRUE, In, FALSE, Out);
+
+ default:
+ break;
+ }
+
+ return EFI_INVALID_PARAMETER;
+}
+
+/**
+ Enables a PCI driver to access PCI controller registers in the PCI root bridge memory space.
+
+ @param This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
+ @param Width Signifies the width of the memory operations.
+ @param Address The base address of the memory operations.
+ @param Count The number of memory operations to perform.
+ @param Buffer For read operations, the destination buffer to store the results. For write
+ operations, the source buffer to write data from.
+
+ @retval EFI_SUCCESS The data was read from or written to the PCI root bridge.
+ @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
+ @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
+
+**/
+EFI_STATUS
+EFIAPI
+PciRootBridgeIoPciRead (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
+ IN UINT64 Address,
+ IN UINTN Count,
+ IN OUT VOID *Buffer
+ )
+{
+ if (Buffer == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ return PciRootBridgeIoPciRW (This, FALSE, Width, Address, Count, Buffer);
+}
+
+
+
+/**
+ Enables a PCI driver to access PCI controller registers in the PCI root bridge memory space.
+
+ @param This A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
+ @param Width Signifies the width of the memory operations.
+ @param Address The base address of the memory operations.
+ @param Count The number of memory operations to perform.
+ @param Buffer For read operations, the destination buffer to store the results. For write
+ operations, the source buffer to write data from.
+
+ @retval EFI_SUCCESS The data was read from or written to the PCI root bridge.
+ @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
+ @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
+
+**/
+EFI_STATUS
+EFIAPI
+PciRootBridgeIoPciWrite (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
+ IN UINT64 Address,
+ IN UINTN Count,
+ IN OUT VOID *Buffer
+ )
+{
+ if (Buffer == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ return PciRootBridgeIoPciRW (This, TRUE, Width, Address, Count, Buffer);
+}
+
+
diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/RngDxe/RngDxe.c b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/RngDxe/RngDxe.c
new file mode 100644
index 000000000..7254bd1fa
--- /dev/null
+++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/RngDxe/RngDxe.c
@@ -0,0 +1,120 @@
+/** @file
+ Implement EFI Random Number Generator runtime services via Rng Lib.
+
+ Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <Uefi.h>
+
+#include <Library/IoLib.h>
+#include <Library/PcdLib.h>
+#include <Library/DebugLib.h>
+#include <Library/ArmGicLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+
+#include <Protocol/ExynosRng.h>
+
+#include "RngDxe.h"
+
+#define CLKDIV 512
+#define RNGSEL 5
+
+/**
+ * Generates a pseudorandom byte stream of the specified size.
+ *
+ * If Output is NULL, then return FALSE.
+ *
+ * @param[out] Output Pointer to buffer to receive random value
+ * @param[in] Size Size of random bytes to generate
+ *
+ * @retval TRUE Pseudorandom byte stream generated successfully.
+ * @retval FALSE Pseudorandom number generator fails to generate due to lack of entropy.
+ *
+ **/
+EFI_STATUS
+EFIAPI
+RngDxeRandomBytes (
+ IN CONST EFI_RNG_PROTOCOL *This,
+ OUT UINT8 *Output,
+ IN UINTN Size
+ )
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ UINT32 TRNGBase;
+ UINT32 value, count, fifo_addr;
+
+ TRNGBase = PcdGet32(PcdCryptoBase);
+
+ /* Set Clock Divider */
+ MmioWrite32(TRNGBase + TRNG_CLKDIV, CLKDIV);
+
+ /* Select RNG Engine */
+ value = TRNG_ENABLE | TRNG_MANUAL_ENABLE | RNGSEL;
+ MmioWrite32(TRNGBase + TRNG_CTRL, value);
+
+ /* Select and Enable Post Processor */
+ value = TRNG_POST_ENABLE | TRNG_POST_SEL_LFSR;
+ MmioWrite32(TRNGBase + TRNG_POST_CTRL, value);
+
+ /* Disable Online Tester */
+ MmioWrite32(TRNGBase + TRNG_ONLINE_CTRL, 0);
+
+ /* Set FIFO pointer as number of random bits */
+ MmioWrite32(TRNGBase + TRNG_FIFO_CTRL, Size << 3);
+
+ /* Poll FIFO pointer until TRNG_FIFO_CTRL.FIFOPTR == 0 */
+ while (MmioRead32(TRNGBase + TRNG_FIFO_CTRL));
+
+ /* Read TRNG FIFO */
+ for (count = 0; count < (Size >> 2); count++) {
+ fifo_addr = TRNG_FIFO_0 + (count << 2);
+ value = MmioRead32(TRNGBase + fifo_addr);
+ CopyMem((UINT8 *)((UINT32)Output + (count << 2)), &value, sizeof(value));
+ }
+
+ return Status;
+}
+
+EFI_RNG_PROTOCOL gRng = {
+ RngDxeRandomBytes
+};
+
+/**
+ Initialize the state information for the RngDxe
+
+ @param ImageHandle of the loaded driver
+ @param SystemTable Pointer to the System Table
+
+ @retval EFI_SUCCESS Protocol registered
+ @retval EFI_OUT_OF_RESOURCES Cannot allocate protocol data structure
+ @retval EFI_DEVICE_ERROR Hardware problems
+
+**/
+EFI_STATUS
+EFIAPI
+RngDxeInitialize (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+
+ Status = gBS->InstallMultipleProtocolInterfaces(
+ &ImageHandle,
+ &gSamsungPlatformRngProtocolGuid,
+ &gRng,
+ NULL
+ );
+
+ return Status;
+}
diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/RngDxe/RngDxe.h b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/RngDxe/RngDxe.h
new file mode 100644
index 000000000..6a1ab107e
--- /dev/null
+++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/RngDxe/RngDxe.h
@@ -0,0 +1,40 @@
+#ifndef __CRYPTRAND_H__
+#define __CRYPTRAND_H__
+
+/*
+ * TRNG SFR Address
+ */
+#define SSS_TRNG_OFFSET (0x600)
+
+#define TRNG_CLKDIV (SSS_TRNG_OFFSET + 0x00)
+#define TRNG_CTRL (SSS_TRNG_OFFSET + 0x20)
+#define TRNG_POST_CTRL (SSS_TRNG_OFFSET + 0x30)
+#define TRNG_ONLINE_CTRL (SSS_TRNG_OFFSET + 0x40)
+#define TRNG_ONLINE_STAT (SSS_TRNG_OFFSET + 0x44)
+#define TRNG_ONLINE_MAXCHI2 (SSS_TRNG_OFFSET + 0x48)
+
+#define TRNG_FIFO_CTRL (SSS_TRNG_OFFSET + 0x50)
+#define TRNG_FIFO_0 (SSS_TRNG_OFFSET + 0x80)
+#define TRNG_FIFO_1 (SSS_TRNG_OFFSET + 0x84)
+#define TRNG_FIFO_2 (SSS_TRNG_OFFSET + 0x88)
+#define TRNG_FIFO_3 (SSS_TRNG_OFFSET + 0x8C)
+#define TRNG_FIFO_4 (SSS_TRNG_OFFSET + 0x90)
+#define TRNG_FIFO_5 (SSS_TRNG_OFFSET + 0x94)
+#define TRNG_FIFO_6 (SSS_TRNG_OFFSET + 0x98)
+#define TRNG_FIFO_7 (SSS_TRNG_OFFSET + 0x9C)
+
+/* TRNG CTRL */
+#define TRNG_ENABLE (0x1 << 31)
+#define TRNG_MANUAL_ENABLE (0x1 << 30)
+
+/* TRNG POST CTRL */
+#define TRNG_POST_ENABLE (0x1 << 31)
+#define TRNG_POST_SEL_BYPASS (0x0 << 0)
+#define TRNG_POST_SEL_LFSR (0x1 << 0)
+#define TRNG_POST_SEL_VON (0x2 << 0)
+#define TRNG_POST_SEL_XOR (0x3 << 0)
+
+/* TRNG ONLINE CTRL */
+#define TRNG_ONLINE_TESTER_ENABLE (0x1 << 31)
+#endif
+
diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/RngDxe/RngDxe.inf b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/RngDxe/RngDxe.inf
new file mode 100644
index 000000000..87c0e3490
--- /dev/null
+++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/RngDxe/RngDxe.inf
@@ -0,0 +1,49 @@
+#/** @file
+# CryptRand library implementation
+#
+#
+# Copyright (c) 2012, Samsung Electronics Co. All rights reserved.<BR>
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#**/
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = RngDxe
+ FILE_GUID = cc605e80-ef94-4d5c-9153-364c92b0adc1
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ ENTRY_POINT = RngDxeInitialize
+
+[Sources]
+ RngDxe.c
+
+[Packages]
+ ArmPkg/ArmPkg.dec
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ SamsungPlatformPkg/ExynosPkg/Exynos5250/ExynosPkg.dec
+ SamsungPlatformPkg/SamsungPlatformPkg.dec
+
+[LibraryClasses]
+ UefiDriverEntryPoint
+ UncachedMemoryAllocationLib
+ DebugLib
+ IoLib
+
+[Guids]
+
+[Protocols]
+ gSamsungPlatformRngProtocolGuid
+
+[Pcd]
+ gExynosPkgTokenSpaceGuid.PcdCryptoBase
+
+[Depex]
+ TRUE
diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/SDHCDxe_EVT1/SDHCDxe.c b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/SDHCDxe_EVT1/SDHCDxe.c
new file mode 100755
index 000000000..0c3a219a4
--- /dev/null
+++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/SDHCDxe_EVT1/SDHCDxe.c
@@ -0,0 +1,1348 @@
+/** @file
+ MMC/SD Card driver for Secure Digital Host Controller
+
+ This driver always produces a BlockIo protocol but it starts off with no Media
+ present. A TimerCallBack detects when media is inserted or removed and after
+ a media change event a call to BlockIo ReadBlocks/WriteBlocks will cause the
+ media to be detected (or removed) and the BlockIo Media structure will get
+ updated. No MMC/SD Card harward registers are updated until the first BlockIo
+ ReadBlocks/WriteBlocks after media has been insterted (booting with a card
+ plugged in counts as an insertion event).
+
+ Copyright (c) 2012, Samsung Electronics Co. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+
+#include <Library/TimerLib.h>
+#include <Library/PcdLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Protocol/ExynosGpio.h>
+#include <Platform/ArmPlatform.h>
+#include <Platform/Exynos5250.h>
+#include <Platform/Arndale5250.h>
+
+#include "SDHCDxe.h"
+
+
+#define DateInformation "20120810_001"
+
+
+MSHC_OPERATION_MODE MSHC_operation_mode=MSHC_FIFO;
+//MSHC_OPERATION_MODE MSHC_operation_mode=MSHC_IDMA;
+
+
+//#undef EFI_D_INFO
+//#define EFI_D_INFO 1
+
+
+CARD_INFO gCardInfo;
+EFI_EVENT gTimerEvent;
+BOOLEAN gMediaChange = FALSE;
+
+
+EFI_BLOCK_IO_MEDIA gSDMMCMedia = {
+ SIGNATURE_32('s','d','h','c'), // MediaId
+ TRUE, // RemovableMedia
+ FALSE, // MediaPresent
+ FALSE, // LogicalPartition
+ FALSE, // ReadOnly
+ FALSE, // WriteCaching
+ 512, // BlockSize
+ 4, // IoAlign
+ 0, // Pad
+ 0 // LastBlock
+};
+
+typedef struct {
+ VENDOR_DEVICE_PATH Mmc;
+ EFI_DEVICE_PATH End;
+} MSHC_DEVICE_PATH;
+
+MSHC_DEVICE_PATH gMSHCDevicePath = {
+ {
+ HARDWARE_DEVICE_PATH,
+ HW_VENDOR_DP,
+ (UINT8)(sizeof(VENDOR_DEVICE_PATH)),
+ (UINT8)((sizeof(VENDOR_DEVICE_PATH)) >> 8),
+ 0x3a02e7fe, 0x649, 0x4fb4, 0xbe, 0x4f, 0xa8, 0x62, 0xca, 0x18, 0x72, 0xa9
+ },
+ {
+ END_DEVICE_PATH_TYPE,
+ END_ENTIRE_DEVICE_PATH_SUBTYPE,
+ sizeof (EFI_DEVICE_PATH_PROTOCOL),
+ 0
+ }
+};
+
+
+//
+// Internal Functions
+//
+
+
+VOID
+ParseCardCIDData (
+ UINT32 Response0,
+ UINT32 Response1,
+ UINT32 Response2,
+ UINT32 Response3
+ )
+{
+ gCardInfo.CIDData.MDT = ((Response0 >> 8) & 0xFFF);
+ gCardInfo.CIDData.PSN = (((Response0 >> 24) & 0xFF) | ((Response1 & 0xFFFFFF) << 8));
+ gCardInfo.CIDData.PRV = ((Response1 >> 24) & 0xFF);
+ gCardInfo.CIDData.PNM[4] = ((Response2) & 0xFF);
+ gCardInfo.CIDData.PNM[3] = ((Response2 >> 8) & 0xFF);
+ gCardInfo.CIDData.PNM[2] = ((Response2 >> 16) & 0xFF);
+ gCardInfo.CIDData.PNM[1] = ((Response2 >> 24) & 0xFF);
+ gCardInfo.CIDData.PNM[0] = ((Response3) & 0xFF);
+ gCardInfo.CIDData.OID = ((Response3 >> 8) & 0xFFFF);
+ gCardInfo.CIDData.MID = ((Response3 >> 24) & 0xFF);
+}
+
+
+EFI_STATUS
+MSHC_SendCmd (
+ UINTN Cmd,
+ UINTN CmdInterruptEnableVal,
+ UINTN CmdArgument
+ )
+{
+ UINTN MmcStatus = 0;
+ volatile UINTN RetryCount = 0;
+ int cmd_flags = 0;
+ int timeout=0;
+ UINT32 SdMmcBaseAddr;
+ //UINT32 MSHCRintStatus=0;
+
+ DEBUG ((EFI_D_INFO, "CMD = %d Argument=0x%x\n", (Cmd&0x3F), CmdArgument));
+
+ timeout = MAX_RETRY_COUNT;
+ SdMmcBaseAddr = PcdGet32(PcdSdMmcBase);
+
+ //1. Check if Data busy or not
+ while(MmioRead32(SdMmcBaseAddr + MSHCI_STATUS) & (DATA_BUSY))
+ {
+ if (timeout == 0)
+ {
+ DEBUG ((EFI_D_ERROR, "SDHC::MSHC_SendCmd timeout : CMD = %d\n", Cmd));
+ return EFI_DEVICE_ERROR;
+ }
+ timeout--;
+ MicroSecondDelay(1);
+ }
+
+ // 2. Check if Raw interrupt is command done
+ /*MSHCRintStatus = MmioRead32(SdMmcBaseAddr + MSHCI_RINTSTS);
+ if ((MSHCRintStatus & (INTMSK_CDONE|INTMSK_ACD)) == 0)
+ {
+ DEBUG ((EFI_D_ERROR, "MSHC::MSHC_SendCmd interrupt error : INT = %x\n", MmioRead32(SdMmcBaseAddr + MSHCI_RINTSTS)));
+ } */
+
+ // 3. Clear Raw interrupt
+ MmioWrite32 ((SdMmcBaseAddr + MSHCI_RINTSTS), INTMSK_ALL);
+
+ // 4. prepare data
+ //mshci_reset_fifo();
+
+ //5. Set command argument register
+ MmioWrite32 ((SdMmcBaseAddr + MSHCI_CMDARG), CmdArgument);
+
+ // 6. transfer data
+
+ //Enable interrupt enable events to occur
+ // EVT1 do not need interrupt mask, use Raw interrupt
+ //MmioWrite32 ((SdMmcBaseAddr + MSHCI_INTMSK), CmdInterruptEnableVal);
+
+ // 7. trasfer data
+
+ //8. Send a command
+ cmd_flags = (Cmd & 0x3F);
+ if(Cmd & (RSPTYP48 | RSPTYP48B | RSPTYP136))
+ {
+ cmd_flags |= CMD_RESP_EXP_BIT;
+ if(Cmd & RSPTYP136)
+ cmd_flags |= CMD_RESP_LENGTH_BIT;
+ }
+
+ //if((Cmd==CMD17)|(Cmd==CMD18)|(Cmd==CMD8))
+ if((Cmd==CMD17)|(Cmd==CMD18))
+ {
+ cmd_flags |= CMD_DATA_EXP_BIT;
+ //DEBUG ((EFI_D_ERROR, "MSHC::MSHC_SendCmd Read\n"));
+ }
+
+ if((Cmd==CMD24)|(Cmd==CMD25))
+ {
+ cmd_flags |= CMD_DATA_EXP_BIT | CMD_RW_BIT;
+ //DEBUG ((EFI_D_ERROR, "MSHC::MSHC_SendCmd Write\n"));
+
+ }
+
+ if (Cmd & ENCMDCRC)
+ {
+ cmd_flags |= CMD_CHECK_CRC_BIT;
+ }
+ //cmd_flags |= (CMD_STRT_BIT | CMD_USE_HOLD_REG | CMD_WAIT_PRV_DAT_BIT|CMD_SENT_AUTO_STOP_BIT);
+ cmd_flags |= (CMD_STRT_BIT | CMD_USE_HOLD_REG | CMD_WAIT_PRV_DAT_BIT);
+ DEBUG ((EFI_D_INFO, "CMD flag = 0x%x\n", cmd_flags));
+ MmioWrite32 ((SdMmcBaseAddr + MSHCI_CMD), cmd_flags);
+ MicroSecondDelay(1);
+
+ //9. Check for the Raw interrupt
+ //wait for command complete by busy waiting.
+ for (RetryCount; RetryCount<MAX_RETRY_COUNT; RetryCount++)
+ {
+ MmcStatus = MmioRead32(SdMmcBaseAddr + MSHCI_RINTSTS);
+ if (MmcStatus & INTMSK_CDONE)
+ {
+ break;
+ }
+ }
+
+ if (RetryCount == MAX_RETRY_COUNT)
+ {
+ DEBUG ((EFI_D_ERROR, "SDHC::MSHC_SendCmd timeout CMD:%d RINT:0x%x\n",(Cmd&0x3F) ,MmcStatus));
+ return EFI_TIMEOUT;
+ }
+
+ if(MmcStatus & INTMSK_RTO)
+ {
+ DEBUG ((EFI_D_ERROR, "SDHC::MSHC_SendCmd Response timeout CMD:%d RINT:0x%x\n", (Cmd & 0x3F),MmcStatus));
+ return EFI_TIMEOUT;
+
+ }
+ else if (MmcStatus & INTMSK_RE)
+ {
+ DEBUG ((EFI_D_ERROR, "SDHC::MSHC_SendCmd Response Error RINT:0x%x\n", MmcStatus));
+ return EFI_TIMEOUT;
+ }
+ else if(MmcStatus & INTMSK_RCRC)
+ DEBUG ((EFI_D_ERROR, "SDHC::MSHC_SendCmd Response CRC Err RINT:0x%x\n", MmcStatus));
+ else if(MmcStatus & INTMSK_DCRC)
+ DEBUG ((EFI_D_ERROR, "SDHC::MSHC_SendCmd Data CRC Err RINT:0x%x\n", MmcStatus));
+ else if(MmcStatus & INTMSK_HLE)
+ DEBUG ((EFI_D_ERROR, "SDHC::MSHC_SendCmd HLE Err RINT:0x%x\n", MmcStatus));
+ else if(MmcStatus & INTMSK_SBE)
+ DEBUG ((EFI_D_ERROR, "SDHC::MSHC_SendCmd SBE Err RINT:0x%x\n", MmcStatus));
+ else if(MmcStatus & INTMSK_EBE)
+ DEBUG ((EFI_D_ERROR, "SDHC::MSHC_SendCmd EBE Err RINT:0x%x\n", MmcStatus));
+
+ return EFI_SUCCESS;
+}
+
+static const UINT32 FreqUnit[4]={10, 100, 1000, 10000};
+static const UINT8 MultiFactor[16]={0, 10, 12, 13, 15, 20, 26, 30, 35, 40, 45, 52, 55, 60, 70, 80};
+
+void PrintCardInfo()
+{
+#if !defined(MDEPKG_NDEBUG)
+ UINT8 TransSpeed = gCardInfo.CSDData.TRAN_SPEED;
+
+ DEBUG ((EFI_D_INFO, "SDHC::READ_BL_LEN %d\n", gCardInfo.CSDData.READ_BL_LEN));
+ DEBUG ((EFI_D_INFO, "SDHC::CSize %d\n", gCardInfo.CSDData.C_SIZELow2 | (gCardInfo.CSDData.C_SIZEHigh10 << 2)));
+ DEBUG ((EFI_D_INFO, "SDHC::MULTI %d\n", gCardInfo.CSDData.C_SIZE_MULT));
+ DEBUG ((EFI_D_INFO, "SDHC::Speed %d\n", (FreqUnit[TransSpeed&0x7]*MultiFactor[TransSpeed>>3])));
+#endif
+}
+
+
+#define EXT_CSD_SIZE 128
+UINT32 Ext_csd[EXT_CSD_SIZE];
+VOID GetEXTCSD()
+{
+ gCardInfo.NumBlocks = 0x1D4C000;
+ DEBUG ((EFI_D_INFO, "SDHC:: default block number : 0x1D4C000"));
+
+ UINTN cmdarg = 0;
+ EFI_STATUS Status = EFI_SUCCESS;
+
+ cmdarg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) |
+ (EXT_CSD_HS_TIMING << 16) |
+ (0 << 8);
+ Status = MSHC_SendCmd (ACMD6, ACMD6_INT_EN, cmdarg);
+
+ cmdarg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) |
+ (EXT_CSD_BUS_WIDTH << 16) |
+ (EXT_CSD_BUS_WIDTH_1 << 8);
+ Status = MSHC_SendCmd (ACMD6, ACMD6_INT_EN, cmdarg);
+
+ cmdarg = 0;
+ Status = MSHC_SendCmd (CMD8, CMD8_INT_EN, cmdarg);
+
+ gCardInfo.BlockSize = BLEN_512BYTES;
+
+ if (!EFI_ERROR(Status))
+ {
+ DEBUG ((EFI_D_INFO, "SDHC::EXT CSD \n"));
+ PrepareTransfer(&Ext_csd[0], 1, READ);
+ //MSHC_ReadDMA(&Ext_csd[0], 1);
+ MSHC_ReadFIFO(EXT_CSD_SIZE, &Ext_csd[0]);
+ gCardInfo.NumBlocks = Ext_csd[EXT_CSD_SEC_CNT/4];
+ MicroSecondDelay(1000);
+ DEBUG ((1, "SDHC::Size:%dMB\n", (gCardInfo.NumBlocks/2048)));
+ }
+
+}
+
+VOID
+GetBlockInformation (
+ UINTN *BlockSize,
+ UINTN *NumBlocks
+ )
+{
+ CSD_SDV2 *CsdSDV2Data;
+ UINTN CardSize;
+
+
+ if (gCardInfo.CardType == SD_CARD_2_HIGH) {
+ CsdSDV2Data = (CSD_SDV2 *)&gCardInfo.CSDData;
+
+ //Populate BlockSize.
+ *BlockSize = (0x1UL << CsdSDV2Data->READ_BL_LEN);
+
+ //Calculate Total number of blocks.
+ CardSize = CsdSDV2Data->C_SIZELow16 | (CsdSDV2Data->C_SIZEHigh6 << 2);
+ *NumBlocks = ((CardSize + 1) * 1024);
+ }
+ else if(gCardInfo.CardType == MMC_CARD)
+ {
+ //Populate BlockSize.
+ *BlockSize = (0x1UL << gCardInfo.CSDData.READ_BL_LEN);
+
+ //Calculate Total number of blocks.
+ CardSize = gCardInfo.CSDData.C_SIZELow2 | (gCardInfo.CSDData.C_SIZEHigh10 << 2);
+ *NumBlocks = (CardSize + 1) * (1 << (gCardInfo.CSDData.C_SIZE_MULT + 2));
+ *NumBlocks *= (*BlockSize);
+ }
+
+ //For >=2G card, BlockSize may be 1K, but the transfer size is 512 bytes.
+ if (*BlockSize > 512) {
+ DEBUG ((EFI_D_INFO, "SDHC::BlockSize:%d\n", *BlockSize));
+ *NumBlocks = MultU64x32(*NumBlocks, *BlockSize/2);
+ *BlockSize = 512;
+ }
+
+ DEBUG ((EFI_D_INFO, "Card type: 0x%x, BlockSize: 0x%x, NumBlocks: 0x%x\n", gCardInfo.CardType, *BlockSize, *NumBlocks));
+}
+
+
+VOID
+GetCardConfigurationData (
+ VOID
+ )
+{
+ UINTN BlockSize;
+ UINTN NumBlocks;
+ // UINTN ClockFrequencySelect;
+
+ //Calculate BlockSize and Total number of blocks in the detected card.
+ GetBlockInformation(&BlockSize, &NumBlocks);
+ gCardInfo.BlockSize = BlockSize;
+ gCardInfo.NumBlocks = NumBlocks;
+
+}
+
+EFI_STATUS
+PerformCardIdenfication (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ UINTN CmdArgument = 0;
+ UINTN Response = 0;
+ UINTN RetryCount = 0;
+ UINTN TempRes0,TempRes1,TempRes2,TempRes3;
+ BOOLEAN SDCmd8Supported = FALSE;
+ UINT32 SdMmcBaseAddr;
+
+ SdMmcBaseAddr = PcdGet32(PcdSdMmcBase);
+
+ //Send CMD0 command.
+ Status = MSHC_SendCmd (CMD0, CMD0_INT_EN, CmdArgument);
+ if (EFI_ERROR(Status)) {
+ DEBUG ((EFI_D_ERROR, "Cmd0 fails.\n"));
+ return Status;
+ }
+
+ DEBUG ((EFI_D_INFO, "CMD0 response: %x\n", MmioRead32 ((SdMmcBaseAddr + MSHCI_RESP0))));
+
+ //Send CMD8 command. (New v2.00 command for Voltage check)
+ //Only 2.7V - 3.6V is supported for SD2.0, only SD 2.0 card can pass.
+ //MMC & SD1.1 card will fail this command.
+ CmdArgument = CMD8_ARG;
+ Status = MSHC_SendCmd (CMD8, CMD8_INT_EN, CmdArgument);
+ if (Status == EFI_SUCCESS) {
+ Response = MmioRead32 ((SdMmcBaseAddr + MSHCI_RESP0));
+ DEBUG ((EFI_D_INFO, "CMD8 success. CMD8 response: %x\n", Response));
+ if (Response != CmdArgument) {
+ return EFI_DEVICE_ERROR;
+ }
+ DEBUG ((EFI_D_INFO, "Card is SD2.0\n"));
+ SDCmd8Supported = TRUE; //Supports high capacity.
+ } else {
+ DEBUG ((EFI_D_INFO, "CMD8 fails. Not an SD2.0 card.\n"));
+ }
+
+ //Poll till card is busy
+ while (RetryCount < MAX_RETRY_COUNT) {
+ //Send CMD55 command.
+ CmdArgument = 0;
+ Status = MSHC_SendCmd (CMD55, CMD55_INT_EN, CmdArgument);
+ if (Status == EFI_SUCCESS) {
+ DEBUG ((EFI_D_INFO, "CMD55 success. CMD55 response: %x\n", MmioRead32 ((SdMmcBaseAddr + MSHCI_RESP0))));
+ gCardInfo.CardType = SD_CARD;
+ } else {
+ DEBUG ((EFI_D_ERROR, "CMD55 fails.\n"));
+ gCardInfo.CardType = MMC_CARD;
+ }
+
+ //Send appropriate command for the card type which got detected.
+ if (gCardInfo.CardType == SD_CARD) {
+ CmdArgument = ((UINTN *) &(gCardInfo.OCRData))[0];
+
+ //Set HCS bit.
+ if (SDCmd8Supported) {
+ CmdArgument |= HCS;
+ }
+
+ Status = MSHC_SendCmd (ACMD41, ACMD41_INT_EN, CmdArgument);
+ if (EFI_ERROR(Status)) {
+ DEBUG ((EFI_D_ERROR, "ACMD41 fails.\n"));
+ return Status;
+ }
+ ((UINT32 *) &(gCardInfo.OCRData))[0] = MmioRead32 ((SdMmcBaseAddr + MSHCI_RESP0));
+ DEBUG ((EFI_D_INFO, "SD card detected. ACMD41 OCR: %x\n", ((UINT32 *) &(gCardInfo.OCRData))[0]));
+ } else if (gCardInfo.CardType == MMC_CARD) {
+ CmdArgument = 0;
+ Status = MSHC_SendCmd (CMD1, CMD1_INT_EN, CmdArgument);
+ if (EFI_ERROR(Status)) {
+ DEBUG ((EFI_D_ERROR, "CMD1 fails.\n"));
+ return Status;
+ }
+ Response = MmioRead32 ((SdMmcBaseAddr + MSHCI_RESP0));
+ DEBUG ((EFI_D_INFO, "MMC card detected. CMD1 response: %x\n", Response));
+
+ //NOTE: For now, I am skipping this since I only have an SD card.
+ //Compare card OCR and host OCR (Section 22.6.1.3.2.4)
+ return EFI_UNSUPPORTED; //For now, MMC is not supported.
+ }
+
+ //Poll the card until it is out of its power-up sequence.
+ if (gCardInfo.OCRData.Busy == 1) {
+
+ if (SDCmd8Supported) {
+ gCardInfo.CardType = SD_CARD_2;
+ }
+
+ //Card is ready. Check CCS (Card capacity status) bit (bit#30).
+ //SD 2.0 standard card will response with CCS 0, SD high capacity card will respond with CCS 1.
+ if (gCardInfo.OCRData.AccessMode & BIT1) {
+ gCardInfo.CardType = SD_CARD_2_HIGH;
+ DEBUG ((EFI_D_INFO, "High capacity card.\n"));
+ } else {
+ DEBUG ((EFI_D_INFO, "Standard capacity card.\n"));
+ }
+
+ break;
+ }
+
+ gBS->Stall(1000);
+ RetryCount++;
+ }
+
+ if (RetryCount == MAX_RETRY_COUNT) {
+ DEBUG ((EFI_D_ERROR, "Timeout error. RetryCount: %d\n", RetryCount));
+ return EFI_TIMEOUT;
+ }
+
+ //Read CID data.
+ CmdArgument = 0;
+ Status = MSHC_SendCmd (CMD2, CMD2_INT_EN, CmdArgument);
+ if (EFI_ERROR(Status)) {
+ DEBUG ((EFI_D_ERROR, "CMD2 fails. Status: %x\n", Status));
+ return Status;
+ }
+
+ DEBUG ((EFI_D_INFO, "CMD2 response: %x %x %x %x\n", MmioRead32 ((SdMmcBaseAddr + MSHCI_RESP0)), \
+ MmioRead32 ((SdMmcBaseAddr + MSHCI_RESP1)), \
+ MmioRead32 ((SdMmcBaseAddr + MSHCI_RESP2)), \
+ MmioRead32 ((SdMmcBaseAddr + MSHCI_RESP3))));
+
+ TempRes0 = MmioRead32 ((SdMmcBaseAddr + MSHCI_RESP0));
+ TempRes1 = MmioRead32 ((SdMmcBaseAddr + MSHCI_RESP1));
+ TempRes2 = MmioRead32 ((SdMmcBaseAddr + MSHCI_RESP2));
+ TempRes3 = MmioRead32 ((SdMmcBaseAddr + MSHCI_RESP3));
+
+ //Parse CID register data.
+ ParseCardCIDData(TempRes0 << 8, (TempRes1 << 8) | (TempRes0 >> 24),
+ (TempRes2 << 8) | (TempRes1 >> 24), (TempRes3 << 8) | (TempRes2 >> 24));
+
+ //Read RCA
+ CmdArgument = 0;
+ Status = MSHC_SendCmd (CMD3, CMD3_INT_EN, CmdArgument);
+ if (EFI_ERROR(Status)) {
+ DEBUG ((EFI_D_ERROR, "CMD3 fails. Status: %x\n", Status));
+ return Status;
+ }
+
+ //Set RCA for the detected card. RCA is CMD3 response.
+ gCardInfo.RCA = (MmioRead32 ((SdMmcBaseAddr + MSHCI_RESP0)) >> 16);
+ DEBUG ((EFI_D_INFO, "CMD3 response: RCA %x\n", gCardInfo.RCA));
+
+ gBS->Stall(1000); //Need Debug by wprkfgur
+
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+GetCardSpecificData (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ UINTN CmdArgument;
+ UINTN TempRes[4],i;
+ UINT32 SdMmcBaseAddr;
+
+ SdMmcBaseAddr = PcdGet32(PcdSdMmcBase);
+
+ //Send CMD9 to retrieve CSD.
+ CmdArgument = gCardInfo.RCA << 16;
+ Status = MSHC_SendCmd (CMD9, CMD9_INT_EN, CmdArgument);
+ if (EFI_ERROR(Status)) {
+ DEBUG ((EFI_D_ERROR, "CMD9 fails. Status: %x\n", Status));
+ return Status;
+ }
+
+ TempRes[0] = MmioRead32 ((SdMmcBaseAddr + MSHCI_RESP0));
+ TempRes[1] = MmioRead32 ((SdMmcBaseAddr + MSHCI_RESP1));
+ TempRes[2] = MmioRead32 ((SdMmcBaseAddr + MSHCI_RESP2));
+ TempRes[3] = MmioRead32 ((SdMmcBaseAddr + MSHCI_RESP3));
+
+ //Populate 128-bit CSD register data.
+
+ for (i = 0 ; i < 4; i++) {
+ ((UINT32 *)&(gCardInfo.CSDData))[i] = TempRes[i];
+ }
+
+ DEBUG ((EFI_D_INFO, "CMD9 response: %x %x %x %x\n", ((UINT32 *)&(gCardInfo.CSDData))[0], ((UINT32 *)&(gCardInfo.CSDData))[1], ((UINT32 *)&(gCardInfo.CSDData))[2], ((UINT32 *)&(gCardInfo.CSDData))[3]));
+ PrintCardInfo();
+ //Calculate total number of blocks and max. data transfer rate supported by the detected card.
+ GetCardConfigurationData();
+ return Status;
+}
+
+EFI_STATUS
+PerformCardConfiguration (
+ VOID
+ )
+{
+ UINTN CmdArgument = 0;
+ EFI_STATUS Status;
+ UINT32 SdMmcBaseAddr;
+ //UINTN FifoCount = 0;
+ //UINTN Count=0;
+
+ SdMmcBaseAddr = PcdGet32(PcdSdMmcBase);
+
+ //Send CMD7
+ CmdArgument = gCardInfo.RCA << 16;
+ Status = MSHC_SendCmd (CMD7, CMD7_INT_EN, CmdArgument);
+ if (EFI_ERROR(Status)) {
+ DEBUG ((EFI_D_ERROR, "CMD7 fails. Status: %x\n", Status));
+ return Status;
+ }
+
+ if ((gCardInfo.CardType != UNKNOWN_CARD) && (gCardInfo.CardType != MMC_CARD)) {
+ // We could read SCR register, but SD Card Phys spec stats any SD Card shall
+ // set SCR.SD_BUS_WIDTHS to support 4-bit mode, so why bother?
+
+ // Send ACMD6 (application specific commands must be prefixed with CMD55)
+ Status = MSHC_SendCmd (CMD55, CMD55_INT_EN, CmdArgument);
+ if (!EFI_ERROR (Status)) {
+ // set device into 4-bit data bus mode
+ Status = MSHC_SendCmd (ACMD6, ACMD6_INT_EN, 0x2);
+ if (!EFI_ERROR (Status)) {
+ // Set host controler into 4-bit mode
+ MmioOr32 ((SdMmcBaseAddr + MSHCI_CTYPE), CARD_WIDTH14);
+ DEBUG ((EFI_D_INFO, "SD Memory Card set to 4-bit mode\n"));
+ }
+ }
+ }
+
+ //Send CMD16 to set the block length
+ CmdArgument = gCardInfo.BlockSize;
+ Status = MSHC_SendCmd (CMD16, CMD16_INT_EN, CmdArgument);
+ if (EFI_ERROR(Status)) {
+ DEBUG ((EFI_D_ERROR, "CMD16 fails. Status: %x\n", Status));
+ return Status;
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+ReadBlockData (
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ OUT VOID *Buffer,
+ IN UINTN BlockCount
+ )
+{
+ EFI_STATUS Status = EFI_INVALID_PARAMETER;
+ UINTN DataSize = This->Media->BlockSize/4;
+
+ DEBUG ((EFI_D_INFO, "SDHC::ReadBlockData start \n"));
+
+ if(MSHC_operation_mode == MSHC_FIFO)
+ {
+ Status = MSHC_ReadFIFO(DataSize, Buffer);
+ }
+
+ else if(MSHC_operation_mode == MSHC_IDMA)
+ {
+ Status = MSHC_ReadDMA(Buffer, BlockCount);
+ }
+
+ return Status;
+}
+
+
+EFI_STATUS
+WriteBlockData (
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ OUT VOID *Buffer,
+ IN UINTN BlockCount
+ )
+{
+ EFI_STATUS Status = EFI_INVALID_PARAMETER;
+ UINTN DataSize = This->Media->BlockSize/4;
+
+ if(MSHC_operation_mode == MSHC_FIFO)
+ {
+ Status = MSHC_WriteFIFO(DataSize, Buffer);
+ }
+ else if(MSHC_operation_mode == MSHC_IDMA)
+ {
+ Status = MSHC_WriteDMA(Buffer, BlockCount);
+ }
+
+ return Status;
+}
+
+
+EFI_STATUS
+TransferBlock (
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ IN UINTN Lba,
+ IN OUT VOID *Buffer,
+ IN UINTN BlockCount,
+ IN OPERATION_TYPE OperationType
+ )
+{
+ EFI_STATUS Status;
+ UINTN Cmd = 0;
+ UINTN CmdInterruptEnable = 0;
+ UINTN CmdArgument = 0;
+
+ // 1. FIFO reset
+ // MSHC_SendCmd do the fifo reset
+
+ // 2. prepare transfer
+
+ DEBUG ((EFI_D_INFO, "SDHC::TransferBlock : Lba = %d, Buffer = 0x%x, Type = %d\n", Lba, Buffer, OperationType));
+ //Populate the command information based on the operation type.
+ if (OperationType == READ)
+ {
+ if(BlockCount>1)
+ {
+ Cmd = CMD18; //multi block read
+ CmdInterruptEnable = CMD18_INT_EN;
+ }
+ else
+ {
+ Cmd = CMD17; //Single block read
+ CmdInterruptEnable = CMD17_INT_EN;
+ }
+
+ }
+ else if (OperationType == WRITE)
+ {
+ if(BlockCount>1)
+ {
+ Cmd = CMD25; //multi block write
+ CmdInterruptEnable = CMD25_INT_EN;
+ }
+ else
+ {
+ Cmd = CMD24; //Single block write
+ CmdInterruptEnable = CMD24_INT_EN;
+ }
+ }
+ PrepareTransfer(Buffer, BlockCount, OperationType);
+
+ //Set command argument based on the card access mode (Byte mode or Block mode)
+ if (gCardInfo.OCRData.AccessMode & BIT1) {
+ CmdArgument = Lba;
+ } else {
+ CmdArgument = Lba * This->Media->BlockSize;
+ }
+
+ //Send Command.
+ Status = MSHC_SendCmd (Cmd, CmdInterruptEnable, CmdArgument);
+ if (EFI_ERROR(Status)) {
+ DEBUG ((EFI_D_ERROR, "CMD%d fails. Status: %x\n", (Cmd&0x3F), Status));
+ return Status;
+ }
+
+ DEBUG ((EFI_D_INFO, "CMD%d succeed! \n", (Cmd&0x3F)));
+
+ //Read or Write data.
+ if (OperationType == READ) {
+ Status = ReadBlockData (This, Buffer, BlockCount);
+ if (EFI_ERROR(Status)) {
+ DEBUG((EFI_D_ERROR, "ReadBlockData fails.\n"));
+ return Status;
+ }
+ } else if (OperationType == WRITE) {
+ Status = WriteBlockData (This, Buffer, BlockCount);
+ if (EFI_ERROR(Status)) {
+ DEBUG((EFI_D_ERROR, "WriteBlockData fails.\n"));
+ return Status;
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+BOOLEAN
+CardPresent (
+ VOID
+ )
+{
+ EXYNOS_GPIO *Gpio;
+ EFI_STATUS Status;
+ UINT32 Val;
+
+ Status = gBS->LocateProtocol(&gSamsungPlatformGpioProtocolGuid, NULL, (VOID **)&Gpio);
+ ASSERT_EFI_ERROR(Status);
+
+ Gpio->Get(Gpio,SD_2_EVT1_CDn,&Val);
+
+ if(Val)
+ {
+ //DEBUG((EFI_D_INFO, "SDHC::CardPresent %d\n", Val));
+ return FALSE;
+ }
+ else
+ return TRUE;
+
+}
+
+EFI_STATUS
+DetectCard (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ //UINT32 SdMmcBaseAddr;
+
+ //DEBUG ((EFI_D_INFO, "===================================\n"));
+ DEBUG ((EFI_D_INFO, "===SDHC: Version %a ===\n", DateInformation));
+ //DEBUG ((EFI_D_INFO, "===================================\n"));
+
+ //SdMmcBaseAddr = PcdGet32(PcdSdMmcBase);
+
+ if (!CardPresent ()) {
+ return EFI_NO_MEDIA;
+ }
+
+ //Initialize MMC host controller clocks.
+ Status = InitializeMSHC ();
+ if (EFI_ERROR(Status)) {
+ DEBUG ((EFI_D_ERROR, "Initialize MMC host controller fails. Status: %x\n", Status));
+ return Status;
+ }
+
+ // EVT1 InitializeSDHC do the SW Reset
+ //Soft reset for all.
+ //MmioWrite32((SdMmcBaseAddr + SDHC_SWRST_OFFSET), SRA);
+ //gBS->Stall(1000);
+ //while ((MmioRead32 ((SdMmcBaseAddr + SDHC_SWRST_OFFSET)) & SRA) != 0x0);
+
+ //Set the clock frequency to 400KHz.
+ UpdateMSHCClkFrequency (MSHC_CLK_400);
+
+ //Card idenfication
+ Status = PerformCardIdenfication ();
+ if (EFI_ERROR(Status)) {
+ DEBUG ((EFI_D_ERROR, "No MMC/SD card detected.\n"));
+ return Status;
+ }
+
+ //Get CSD (Card specific data) for the detected card.
+ Status = GetCardSpecificData();
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ //Configure the card in data transfer mode.
+ Status = PerformCardConfiguration();
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+
+ //Patch the Media structure.
+ gSDMMCMedia.LastBlock = (gCardInfo.NumBlocks - 1);
+ gSDMMCMedia.BlockSize = gCardInfo.BlockSize;
+ // gSDMMCMedia.BlockSize = 512;
+ gSDMMCMedia.ReadOnly = 0;
+ gSDMMCMedia.MediaPresent = TRUE;
+ gSDMMCMedia.MediaId++;
+
+ UpdateMSHCClkFrequency(MSHC_CLK_25M);
+ DEBUG ((EFI_D_INFO, "SD Card Media Change on Handle 0x%08x\n", gImageHandle));
+
+ return Status;
+}
+
+
+EFI_STATUS
+SdReadWrite (
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ IN UINTN Lba,
+ OUT VOID *Buffer,
+ IN UINTN BufferSize,
+ IN OPERATION_TYPE OperationType
+ )
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ UINTN RetryCount = 0;
+ UINTN BlockCount;
+ UINTN BytesToBeTranferedThisPass = 0;
+ UINTN BytesRemainingToBeTransfered=0;
+ EFI_TPL OldTpl;
+ BOOLEAN Update;
+ UINT32 SdMmcBaseAddr;
+
+ SdMmcBaseAddr = PcdGet32(PcdSdMmcBase);
+ Update = FALSE;
+
+ DEBUG ((EFI_D_INFO, "SDHC::SDHCInitialize is called \n"));
+ if (gMediaChange) {
+ Update = TRUE;
+ Status = DetectCard();
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "SDHC::SDHCInitialize:Card Detect Fail\n"));
+ gSDMMCMedia.MediaPresent = FALSE;
+ gSDMMCMedia.LastBlock = 0;
+ gSDMMCMedia.BlockSize = 512; // Should be zero but there is a bug in DiskIo
+ gSDMMCMedia.ReadOnly = FALSE;
+ }
+ gMediaChange = FALSE;
+ } else if (!gSDMMCMedia.MediaPresent) {
+ Status = EFI_NO_MEDIA;
+ goto Done;
+ }
+
+ if (Update) {
+ DEBUG ((EFI_D_INFO, "SD Card ReinstallProtocolInterface ()\n"));
+ gBS->ReinstallProtocolInterface (
+ gImageHandle,
+ &gEfiBlockIoProtocolGuid,
+ &gBlockIo,
+ &gBlockIo);
+ }
+DEBUG ((EFI_D_INFO, "SDHC::SDHCInitialize:CardInfo : LastBlock = %ld, BlockSize = %d\n", gSDMMCMedia.LastBlock, gSDMMCMedia.BlockSize));
+
+
+ if (Buffer == NULL) {
+ Status = EFI_INVALID_PARAMETER;
+ goto Done;
+ }
+
+ if (Lba > This->Media->LastBlock) {
+ Status = EFI_INVALID_PARAMETER;
+ goto Done;
+ }
+
+ if ((BufferSize % This->Media->BlockSize) != 0) {
+ Status = EFI_BAD_BUFFER_SIZE;
+ goto Done;
+ }
+
+ //Check if the data lines are not in use.
+ while ((RetryCount++ < MAX_RETRY_COUNT) && (MmioRead32 ((SdMmcBaseAddr + MSHCI_STATUS)) & DATA_BUSY));
+ if (RetryCount == MAX_RETRY_COUNT) {
+ Status = EFI_TIMEOUT;
+ DEBUG ((EFI_D_ERROR, "MSHC::SdReadWrite EFI_TIMEOUT\n"));
+ goto Done;
+ }
+
+ OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
+
+ BytesRemainingToBeTransfered = BufferSize;
+
+ if(MSHC_operation_mode == MSHC_IDMA)
+ {
+ while (BytesRemainingToBeTransfered > 0) {
+ // Turn OFF DMA path until it is debugged
+ BytesToBeTranferedThisPass = (BytesRemainingToBeTransfered >= MAX_MSHC_TRANSFER_SIZE) ? MAX_MSHC_TRANSFER_SIZE : BytesRemainingToBeTransfered;
+ //BytesToBeTranferedThisPass = This->Media->BlockSize;
+
+ BlockCount = BytesToBeTranferedThisPass/This->Media->BlockSize;
+ Status = TransferBlock (This, Lba, Buffer,BlockCount, OperationType);
+
+ if (EFI_ERROR(Status)) {
+ DEBUG ((EFI_D_ERROR, "TransferBlockData fails. %x\n", Status));
+ goto DoneRestoreTPL;
+ }
+
+ BytesRemainingToBeTransfered -= BytesToBeTranferedThisPass;
+ Lba += BlockCount;
+ Buffer = (UINT8 *)Buffer + (This->Media->BlockSize*BlockCount);
+ DEBUG ((EFI_D_INFO, "SdReadWrite::Buf:0x%x, ToBe:0x%x Rema:0x%x \n", BufferSize, BytesToBeTranferedThisPass, BytesRemainingToBeTransfered));
+ }
+ }
+ else
+ {
+ while (BytesRemainingToBeTransfered > 0) {
+ // Turn OFF DMA path until it is debugged
+ // BytesToBeTranferedThisPass = (BytesToBeTranferedThisPass >= MAX_SDHC_TRANSFER_SIZE) ? MAX_SDHC_TRANSFER_SIZE : BytesRemainingToBeTransfered;
+ BytesToBeTranferedThisPass = This->Media->BlockSize;
+
+ BlockCount = BytesToBeTranferedThisPass/This->Media->BlockSize;
+
+ if (BlockCount > 1) {
+ // Status = DmaBlocks (This, Lba, Buffer, BlockCount, OperationType);
+ } else {
+ //Transfer a block worth of data.
+ Status = TransferBlock (This, Lba, Buffer, BlockCount,OperationType);
+
+ }
+
+ if (EFI_ERROR(Status)) {
+ DEBUG ((EFI_D_ERROR, "TransferBlockData fails. %x\n", Status));
+ goto DoneRestoreTPL;
+ }
+
+ BytesRemainingToBeTransfered -= BytesToBeTranferedThisPass;
+ Lba += BlockCount;
+ Buffer = (UINT8 *)Buffer + This->Media->BlockSize;
+ }
+
+ }
+
+
+DoneRestoreTPL:
+
+ gBS->RestoreTPL (OldTpl);
+
+Done:
+ return Status;
+
+}
+
+
+/**
+
+ Reset the Block Device.
+
+
+
+ @param This Indicates a pointer to the calling context.
+
+ @param ExtendedVerification Driver may perform diagnostics on reset.
+
+
+
+ @retval EFI_SUCCESS The device was reset.
+
+ @retval EFI_DEVICE_ERROR The device is not functioning properly and could
+
+ not be reset.
+
+
+
+**/
+EFI_STATUS
+EFIAPI
+MSHCReset (
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ IN BOOLEAN ExtendedVerification
+ )
+{
+ DEBUG ((EFI_D_INFO, " MSHC::MSHCReset is called\n"));
+ MSHC_reset_all();
+ return EFI_SUCCESS;
+}
+
+
+/**
+
+ Read BufferSize bytes from Lba into Buffer.
+
+
+
+ @param This Indicates a pointer to the calling context.
+
+ @param MediaId Id of the media, changes every time the media is replaced.
+
+ @param Lba The starting Logical Block Address to read from
+
+ @param BufferSize Size of Buffer, must be a multiple of device block size.
+
+ @param Buffer A pointer to the destination buffer for the data. The caller is
+
+ responsible for either having implicit or explicit ownership of the buffer.
+
+
+
+ @retval EFI_SUCCESS The data was read correctly from the device.
+
+ @retval EFI_DEVICE_ERROR The device reported an error while performing the read.
+
+ @retval EFI_NO_MEDIA There is no media in the device.
+
+ @retval EFI_MEDIA_CHANGED The MediaId does not matched the current device.
+
+ @retval EFI_BAD_BUFFER_SIZE The Buffer was not a multiple of the block size of the device.
+
+ @retval EFI_INVALID_PARAMETER The read request contains LBAs that are not valid,
+
+ or the buffer is not on proper alignment.
+
+EFI_STATUS
+
+**/
+
+
+#define EMMC_TEST 0
+#if EMMC_TEST
+#define EMMC_TEST_SIZE (512*2)//(MAX_MSHC_TRANSFER_SIZE+1024)
+UINT32 bWrite[EMMC_TEST_SIZE];
+UINT32 bRead[EMMC_TEST_SIZE];
+//INTN EFIAPI CompareMem (IN CONST VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
+//two buffers are identical, then 0 is returned. Otherwise, the value returned is the first mismatched byte
+
+void MSHC_Test( IN EFI_BLOCK_IO_PROTOCOL *This)
+{
+ UINTN i=0;
+ UINTN Count;
+ INTN ret;
+ EFI_STATUS Status;
+ DEBUG ((EFI_D_INFO, "MSHC::Read Write test %dB\n", EMMC_TEST_SIZE));
+
+ for(i=0; i<EMMC_TEST_SIZE; i++)
+ {
+ bWrite[i]=i;
+ }
+
+//multi
+ for(Count=100000; Count<100002; Count++)
+ {
+ //Lba=n;
+ //DEBUG ((EFI_D_INFO, "MSHC::Read Write test : %d\n", Count));
+ ZeroMem (&bRead[0], sizeof(bRead));
+ DEBUG ((EFI_D_INFO, "ZR : 0x%x, 0x%x, 0x%x, 0x%x\n",
+ bRead[0], bRead[1], bRead[2], bRead[3]));
+
+ Status = SdReadWrite (This, (UINTN)Count, &bWrite[0], EMMC_TEST_SIZE, WRITE);
+ Status = SdReadWrite (This, (UINTN)Count, &bRead[0], EMMC_TEST_SIZE, READ);
+
+ DEBUG ((EFI_D_INFO, "W: 0x%x, 0x%x, 0x%x, 0x%x ",
+ bWrite[0], bWrite[1], bWrite[2], bWrite[3]));
+ DEBUG ((EFI_D_INFO, "R : 0x%x, 0x%x, 0x%x, 0x%x\n",
+ bRead[0], bRead[1], bRead[2], bRead[3]));
+
+ ret = CompareMem(&bRead[0],&bWrite[0],EMMC_TEST_SIZE);
+
+ if(ret==0)
+ DEBUG ((1, "SDHC::Read Write OK!!\n\n"));
+ else
+ DEBUG ((1, "SDHC::Read Write Failed bWrite[%d]=0x%x : bRead[%d]=0x%x\n", ret, bWrite[ret], ret, bRead[ret]));
+
+
+ }
+
+
+}
+#endif
+
+EFI_STATUS
+EFIAPI
+MSHCReadBlocks (
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ IN UINT32 MediaId,
+ IN EFI_LBA Lba,
+ IN UINTN BufferSize,
+ OUT VOID *Buffer
+ )
+{
+ EFI_STATUS Status=EFI_SUCCESS;
+ DEBUG ((EFI_D_INFO, "SDHC::MSHCReadBlocks : MediaId = %x, Lba = %d, BufferSize = %d, Buffer = 0x%x\n",
+ MediaId, (UINTN)Lba, BufferSize, Buffer));
+
+#if EMMC_TEST
+ MSHC_Test(This);
+#else
+ //Perform Read operation.
+ Status = SdReadWrite (This, (UINTN)Lba, Buffer, BufferSize, READ);
+#endif
+ return Status;
+
+}
+
+
+/**
+
+ Write BufferSize bytes from Lba into Buffer.
+
+
+
+ @param This Indicates a pointer to the calling context.
+
+ @param MediaId The media ID that the write request is for.
+
+ @param Lba The starting logical block address to be written. The caller is
+
+ responsible for writing to only legitimate locations.
+
+ @param BufferSize Size of Buffer, must be a multiple of device block size.
+
+ @param Buffer A pointer to the source buffer for the data.
+
+
+
+ @retval EFI_SUCCESS The data was written correctly to the device.
+
+ @retval EFI_WRITE_PROTECTED The device can not be written to.
+
+ @retval EFI_DEVICE_ERROR The device reported an error while performing the write.
+
+ @retval EFI_NO_MEDIA There is no media in the device.
+
+ @retval EFI_MEDIA_CHNAGED The MediaId does not matched the current device.
+
+ @retval EFI_BAD_BUFFER_SIZE The Buffer was not a multiple of the block size of the device.
+
+ @retval EFI_INVALID_PARAMETER The write request contains LBAs that are not valid,
+
+ or the buffer is not on proper alignment.
+
+
+
+**/
+
+
+EFI_STATUS
+EFIAPI
+MSHCWriteBlocks (
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ IN UINT32 MediaId,
+ IN EFI_LBA Lba,
+ IN UINTN BufferSize,
+ IN VOID *Buffer
+ )
+{
+ EFI_STATUS Status;
+#if EMMC_TEST
+ UINT32 Count=0;
+ UINT32 ret;
+#endif
+
+ DEBUG ((EFI_D_INFO, "SDHC::MSHCWriteBlocks : MediaId = 0x%x, Lba = %d, BufferSize = %d, Buffer = 0x%x\n",
+ MediaId, (UINTN)Lba, BufferSize, Buffer));
+
+ //Perform write operation.
+ Status = SdReadWrite (This, (UINTN)Lba, Buffer, BufferSize, WRITE);
+
+#if EMMC_TEST
+ Count = (BufferSize >= MAX_MSHC_TRANSFER_SIZE) ? MAX_MSHC_TRANSFER_SIZE : BufferSize;
+ DEBUG ((1, "\nMSHC::Read Write Test [0x%x] Start \n", Count));
+ ZeroMem (&bRead[0], sizeof(bRead));
+ CopyMem(&bWrite[0], (VOID *)Buffer, Count);
+ Status = SdReadWrite (This, (UINTN)Lba, &bRead[0], Count, READ);
+ DEBUG ((1, "W : 0x%x, 0x%x, 0x%x, 0x%x\n",
+ bWrite[7], bWrite[8], bWrite[9], bWrite[10]));
+
+ DEBUG ((1, "R : 0x%x, 0x%x, 0x%x, 0x%x\n",
+ bRead[7], bRead[8], bRead[9], bRead[10]));
+
+ ret = CompareMem(&bRead[0],&bWrite[0],Count);
+
+ if(ret==0)
+ DEBUG ((1, "SDHC::Read Write Test OK!!\n"));
+ else
+ DEBUG ((1, "SDHC::Read Write Test Failed -.- bRead[%d]=0x%x bWrite[%d]=0x%x \n", ret, bRead[ret], ret, bWrite[ret]));
+
+#endif
+
+ return Status;
+
+}
+
+
+/**
+
+ Flush the Block Device.
+
+
+
+ @param This Indicates a pointer to the calling context.
+
+
+
+ @retval EFI_SUCCESS All outstanding data was written to the device
+
+ @retval EFI_DEVICE_ERROR The device reported an error while writting back the data
+
+ @retval EFI_NO_MEDIA There is no media in the device.
+
+
+
+**/
+EFI_STATUS
+EFIAPI
+MSHCFlushBlocks (
+ IN EFI_BLOCK_IO_PROTOCOL *This
+ )
+{
+ DEBUG ((EFI_D_INFO, "SDHC::MSHCFlushBlocks is called\n"));
+ return EFI_SUCCESS;
+}
+
+
+EFI_BLOCK_IO_PROTOCOL gBlockIo = {
+ EFI_BLOCK_IO_INTERFACE_REVISION, // Revision
+ &gSDMMCMedia, // *Media
+ MSHCReset, // Reset
+ MSHCReadBlocks, // ReadBlocks
+ MSHCWriteBlocks, // WriteBlocks
+ MSHCFlushBlocks // FlushBlocks
+};
+
+/**
+
+ Timer callback to convert card present hardware into a boolean that indicates
+
+ a media change event has happened. If you just check the GPIO you could see
+
+ card 1 and then check again after card 1 was removed and card 2 was inserted
+
+ and you would still see media present. Thus you need the timer tick to catch
+
+ the toggle event.
+
+
+
+ @param Event Event whose notification function is being invoked.
+
+ @param Context The pointer to the notification function's context,
+
+ which is implementation-dependent. Not used.
+
+
+
+**/
+VOID
+EFIAPI
+TimerCallback (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ BOOLEAN Present;
+
+ //DEBUG ((EFI_D_ERROR, "SDHC::TimerCallBack is called\n"));
+ Present = CardPresent ();
+ if (gSDMMCMedia.MediaPresent) {
+ if (!Present && !gMediaChange) {
+ gMediaChange = TRUE;
+ }
+ } else {
+ if (Present && !gMediaChange) {
+ gMediaChange = TRUE;
+ }
+ }
+}
+
+EFI_HANDLE mHandle = NULL;
+EFI_EVENT mCommandProtocolRegistration=NULL;
+
+VOID
+EFIAPI
+CommandProtocolNotificationEvent (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ EFI_STATUS Status;
+
+ if(mHandle!=NULL){
+ return;
+ }
+
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &mHandle,
+ &gEfiBlockIoProtocolGuid, &gBlockIo,
+ &gEfiDevicePathProtocolGuid, &gMSHCDevicePath,
+ NULL
+ );
+ DEBUG((EFI_D_INFO, "SDHC::install protocol \n" ));
+ if(Status!=EFI_SUCCESS)
+ {
+ DEBUG((EFI_D_ERROR, "SDHC::install protocol fail %r\n", Status));
+ }
+}
+
+
+
+EFI_STATUS
+EFIAPI
+SDHCInitialize (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+
+ ZeroMem (&gCardInfo, sizeof (CARD_INFO));
+
+ Status = gBS->CreateEvent (EVT_TIMER | EVT_NOTIFY_SIGNAL, TPL_CALLBACK, TimerCallback, NULL, &gTimerEvent);
+ ASSERT_EFI_ERROR (Status);
+
+ Status = gBS->SetTimer (gTimerEvent, TimerPeriodic, 1000000);
+ ASSERT_EFI_ERROR (Status);
+
+ EfiCreateProtocolNotifyEvent (
+ &gEfiEblAddCommandProtocolGuid,
+ TPL_CALLBACK,
+ CommandProtocolNotificationEvent,
+ (VOID *)SystemTable,
+ &mCommandProtocolRegistration
+ );
+
+#if 0
+ //Publish BlockIO.
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &ImageHandle,
+ &gEfiBlockIoProtocolGuid, &gBlockIo,
+ &gEfiDevicePathProtocolGuid, &gMSHCDevicePath,
+ NULL
+ );
+#endif
+ return Status;
+}
diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/SDHCDxe_EVT1/SDHCDxe.h b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/SDHCDxe_EVT1/SDHCDxe.h
new file mode 100755
index 000000000..29f317b19
--- /dev/null
+++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/SDHCDxe_EVT1/SDHCDxe.h
@@ -0,0 +1,259 @@
+/** @file
+
+ Copyright (c) 2012, Samsung Electronics Co. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _MSHCDXE_H_
+#define _MSHCDXE_H_
+
+#include <Uefi.h>
+
+#include <Library/BaseLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/PcdLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Protocol/BlockIo.h>
+#include <Protocol/DevicePath.h>
+#include <Protocol/EblAddCommand.h>
+#include <Library/UefiLib.h>
+
+#include "SDHCDxe_5250.h"
+#include "SDHCDxe_CMD.h"
+
+
+#define MSHC_BOOT_SIZE 100 //100M
+#define MSHC_RPMB_SIZE 0
+
+#define MSHC_EMMC_OCR 0xC0FF8080
+
+#define BLEN_512BYTES (0x200)
+#define BLKSIZE_1 (0x1)
+
+
+#define MAX_RETRY_COUNT (100000)
+#define MMC_REFERENCE_CLK (96000000)
+#define MSHC_CLK_400 (400)
+#define MSHC_CLK_25M (25000)
+#define MSHC_CLK_50M (50000)
+
+#define OCR_BUSY 0x80000000
+#define OCR_HCS 0x40000000
+
+#define MMC_VDD_165_195 0x00000080 /* VDD voltage 1.65 - 1.95 */
+#define MMC_VDD_20_21 0x00000100 /* VDD voltage 2.0 ~ 2.1 */
+#define MMC_VDD_21_22 0x00000200 /* VDD voltage 2.1 ~ 2.2 */
+#define MMC_VDD_22_23 0x00000400 /* VDD voltage 2.2 ~ 2.3 */
+#define MMC_VDD_23_24 0x00000800 /* VDD voltage 2.3 ~ 2.4 */
+#define MMC_VDD_24_25 0x00001000 /* VDD voltage 2.4 ~ 2.5 */
+#define MMC_VDD_25_26 0x00002000 /* VDD voltage 2.5 ~ 2.6 */
+#define MMC_VDD_26_27 0x00004000 /* VDD voltage 2.6 ~ 2.7 */
+#define MMC_VDD_27_28 0x00008000 /* VDD voltage 2.7 ~ 2.8 */
+#define MMC_VDD_28_29 0x00010000 /* VDD voltage 2.8 ~ 2.9 */
+#define MMC_VDD_29_30 0x00020000 /* VDD voltage 2.9 ~ 3.0 */
+#define MMC_VDD_30_31 0x00040000 /* VDD voltage 3.0 ~ 3.1 */
+#define MMC_VDD_31_32 0x00080000 /* VDD voltage 3.1 ~ 3.2 */
+#define MMC_VDD_32_33 0x00100000 /* VDD voltage 3.2 ~ 3.3 */
+#define MMC_VDD_33_34 0x00200000 /* VDD voltage 3.3 ~ 3.4 */
+#define MMC_VDD_34_35 0x00400000 /* VDD voltage 3.4 ~ 3.5 */
+#define MMC_VDD_35_36 0x00800000 /* VDD voltage 3.5 ~ 3.6 */
+
+
+#define MMC_SWITCH_MODE_CMD_SET 0x00 /* Change the command set */
+#define MMC_SWITCH_MODE_SET_BITS 0x01 /* Set bits in EXT_CSD byte
+ addressed by index which are
+ 1 in value field */
+#define MMC_SWITCH_MODE_CLEAR_BITS 0x02 /* Clear bits in EXT_CSD byte
+ addressed by index, which are
+ 1 in value field */
+#define MMC_SWITCH_MODE_WRITE_BYTE 0x03 /* Set target byte to value */
+/*
+ * EXT_CSD fields
+ */
+
+#define EXT_CSD_BUS_WIDTH 183 /* R/W */
+#define EXT_CSD_HS_TIMING 185 /* R/W */
+#define EXT_CSD_CARD_TYPE 196 /* RO */
+#define EXT_CSD_REV 192 /* RO */
+#define EXT_CSD_SEC_CNT 212 /* RO, 4 bytes */
+#define BOOT_SIZE_MULTI 226 /* RO */
+
+/*
+ * EXT_CSD field definitions
+ */
+
+/* Card */
+#define EXT_CSD_CMD_SET_NORMAL (1<<0)
+#define EXT_CSD_CMD_SET_SECURE (1<<1)
+#define EXT_CSD_CMD_SET_CPSECURE (1<<2)
+
+#define EXT_CSD_CARD_TYPE_26 (1<<0) /* Card can run at 26MHz */
+#define EXT_CSD_CARD_TYPE_52 (1<<1) /* Card can run at 52MHz */
+#define EXT_CSD_CARD_TYPE_52_DDR_18_30 (1<<2) /* Card can run at 52MHz DDR 1.8V or 3V */
+#define EXT_CSD_CARD_TYPE_52_DDR_12 (1<<3) /* Card can run at 52MHz DDR 1.2V */
+
+#define EXT_CSD_BUS_WIDTH_1 0 /* Card is in 1 bit mode */
+#define EXT_CSD_BUS_WIDTH_4 1 /* Card is in 4 bit mode */
+#define EXT_CSD_BUS_WIDTH_8 2 /* Card is in 8 bit mode */
+#define EXT_CSD_BUS_WIDTH_4_DDR 5 /* Card is in 4 bit DDR mode */
+#define EXT_CSD_BUS_WIDTH_8_DDR 6 /* Card is in 8 bit DDR mode */
+
+
+typedef struct {
+ UINT32 hs_max_dtr;
+ UINT32 sectors;
+ UINT32 boot_size_multi;
+}mmc_ext_csd;
+
+
+typedef struct {
+ UINT32 Reserved0: 7; // 0
+ UINT32 V170_V195: 1; // 1.70V - 1.95V
+ UINT32 V200_V260: 7; // 2.00V - 2.60V
+ UINT32 V270_V360: 9; // 2.70V - 3.60V
+ UINT32 RESERVED_1: 5; // Reserved
+ UINT32 AccessMode: 2; // 00b (byte mode), 10b (sector mode)
+ UINT32 Busy: 1; // This bit is set to LOW if the card has not finished the power up routine
+}OCR;
+
+typedef struct {
+ UINT32 NOT_USED; // 1 [0:0]
+ UINT32 CRC; // CRC7 checksum [7:1]
+ UINT32 MDT; // Manufacturing date [19:8]
+ UINT32 RESERVED_1; // Reserved [23:20]
+ UINT32 PSN; // Product serial number [55:24]
+ UINT8 PRV; // Product revision [63:56]
+ UINT8 PNM[5]; // Product name [64:103]
+ UINT16 OID; // OEM/Application ID [119:104]
+ UINT8 MID; // Manufacturer ID [127:120]
+}CID;
+
+typedef struct {
+ UINT8 NOT_USED: 1; // Not used, always 1 [0:0]
+ UINT8 CRC: 7; // CRC [7:1]
+
+ UINT8 RESERVED_1: 2; // Reserved [9:8]
+ UINT8 FILE_FORMAT: 2; // File format [11:10]
+ UINT8 TMP_WRITE_PROTECT: 1; // Temporary write protection [12:12]
+ UINT8 PERM_WRITE_PROTECT: 1; // Permanent write protection [13:13]
+ UINT8 COPY: 1; // Copy flag (OTP) [14:14]
+ UINT8 FILE_FORMAT_GRP: 1; // File format group [15:15]
+
+ UINT16 RESERVED_2: 5; // Reserved [20:16]
+ UINT16 WRITE_BL_PARTIAL: 1; // Partial blocks for write allowed [21:21]
+ UINT16 WRITE_BL_LEN: 4; // Max. write data block length [25:22]
+ UINT16 R2W_FACTOR: 3; // Write speed factor [28:26]
+ UINT16 RESERVED_3: 2; // Reserved [30:29]
+ UINT16 WP_GRP_ENABLE: 1; // Write protect group enable [31:31]
+
+ UINT32 WP_GRP_SIZE: 7; // Write protect group size [38:32]
+ UINT32 SECTOR_SIZE: 7; // Erase sector size [45:39]
+ UINT32 ERASE_BLK_EN: 1; // Erase single block enable [46:46]
+ UINT32 C_SIZE_MULT: 3; // Device size multiplier [49:47]
+ UINT32 VDD_W_CURR_MAX: 3; // Max. write current @ VDD max [52:50]
+ UINT32 VDD_W_CURR_MIN: 3; // Max. write current @ VDD min [55:53]
+ UINT32 VDD_R_CURR_MAX: 3; // Max. read current @ VDD max [58:56]
+ UINT32 VDD_R_CURR_MIN: 3; // Max. read current @ VDD min [61:59]
+ UINT32 C_SIZELow2: 2; // Device size [63:62]
+
+ UINT32 C_SIZEHigh10: 10;// Device size [73:64]
+ UINT32 RESERVED_4: 2; // Reserved [75:74]
+ UINT32 DSR_IMP: 1; // DSR implemented [76:76]
+ UINT32 READ_BLK_MISALIGN: 1; // Read block misalignment [77:77]
+ UINT32 WRITE_BLK_MISALIGN: 1; // Write block misalignment [78:78]
+ UINT32 READ_BL_PARTIAL: 1; // Partial blocks for read allowed [79:79]
+ UINT32 READ_BL_LEN: 4; // Max. read data block length [83:80]
+ UINT32 CCC: 12;// Card command classes [95:84]
+
+ UINT8 TRAN_SPEED ; // Max. bus clock frequency [103:96]
+ UINT8 NSAC ; // Data read access-time 2 in CLK cycles (NSAC*100) [111:104]
+ UINT8 TAAC ; // Data read access-time 1 [119:112]
+
+ UINT8 RESERVED_5: 6; // Reserved [125:120]
+ UINT8 CSD_STRUCTURE: 2; // CSD structure [127:126]
+}CSD;
+
+
+
+typedef struct {
+ UINT8 NOT_USED: 1; // Not used, always 1 [0:0]
+ UINT8 CRC: 7; // CRC [7:1]
+ UINT8 RESERVED_1: 2; // Reserved [9:8]
+ UINT8 FILE_FORMAT: 2; // File format [11:10]
+ UINT8 TMP_WRITE_PROTECT: 1; // Temporary write protection [12:12]
+ UINT8 PERM_WRITE_PROTECT: 1; // Permanent write protection [13:13]
+ UINT8 COPY: 1; // Copy flag (OTP) [14:14]
+ UINT8 FILE_FORMAT_GRP: 1; // File format group [15:15]
+ UINT16 RESERVED_2: 5; // Reserved [20:16]
+ UINT16 WRITE_BL_PARTIAL: 1; // Partial blocks for write allowed [21:21]
+ UINT16 WRITE_BL_LEN: 4; // Max. write data block length [25:22]
+ UINT16 R2W_FACTOR: 3; // Write speed factor [28:26]
+ UINT16 RESERVED_3: 2; // Reserved [30:29]
+ UINT16 WP_GRP_ENABLE: 1; // Write protect group enable [31:31]
+ UINT16 WP_GRP_SIZE: 7; // Write protect group size [38:32]
+ UINT16 SECTOR_SIZE: 7; // Erase sector size [45:39]
+ UINT16 ERASE_BLK_EN: 1; // Erase single block enable [46:46]
+ UINT16 RESERVED_4: 1; // Reserved [47:47]
+ UINT32 C_SIZELow16: 16;// Device size [69:48]
+ UINT32 C_SIZEHigh6: 6; // Device size [69:48]
+ UINT32 RESERVED_5: 6; // Reserved [75:70]
+ UINT32 DSR_IMP: 1; // DSR implemented [76:76]
+ UINT32 READ_BLK_MISALIGN: 1; // Read block misalignment [77:77]
+ UINT32 WRITE_BLK_MISALIGN: 1; // Write block misalignment [78:78]
+ UINT32 READ_BL_PARTIAL: 1; // Partial blocks for read allowed [79:79]
+ UINT16 READ_BL_LEN: 4; // Max. read data block length [83:80]
+ UINT16 CCC: 12;// Card command classes [95:84]
+ UINT8 TRAN_SPEED ; // Max. bus clock frequency [103:96]
+ UINT8 NSAC ; // Data read access-time 2 in CLK cycles (NSAC*100) [111:104]
+ UINT8 TAAC ; // Data read access-time 1 [119:112]
+ UINT8 RESERVED_6: 6; // 0 [125:120]
+ UINT8 CSD_STRUCTURE: 2; // CSD structure [127:126]
+}CSD_SDV2;
+
+typedef enum {
+ UNKNOWN_CARD,
+ MMC_CARD, //MMC card
+ SD_CARD, //SD 1.1 card
+ SD_CARD_2, //SD 2.0 or above standard card
+ SD_CARD_2_HIGH, //SD 2.0 or above high capacity card
+ SD_CARD_MAX
+} CARD_TYPE;
+
+
+
+typedef enum {
+ MSHC_IDMA,
+ MSHC_FIFO
+}MSHC_OPERATION_MODE;
+
+typedef struct {
+ UINT16 RCA;
+ UINTN BlockSize;
+ UINTN NumBlocks;
+ UINTN ClockFrequencySelect;
+ CARD_TYPE CardType;
+ OCR OCRData;
+ CID CIDData;
+ CSD CSDData;
+} CARD_INFO;
+
+
+EFI_STATUS
+DetectCard (VOID);
+void mshci_reset_fifo(void);
+
+extern EFI_BLOCK_IO_PROTOCOL gBlockIo;
+
+#endif
+
diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/SDHCDxe_EVT1/SDHCDxe.inf b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/SDHCDxe_EVT1/SDHCDxe.inf
new file mode 100755
index 000000000..167eee6a4
--- /dev/null
+++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/SDHCDxe_EVT1/SDHCDxe.inf
@@ -0,0 +1,58 @@
+#/** @file
+#
+# Copyright (c) 2012, Samsung Electronics Co. All rights reserved.<BR>
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#**/
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = SDHCDxe
+ FILE_GUID = 7B857F59-CD4D-4403-A866-CFAD3A7C1381
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+
+ ENTRY_POINT = SDHCInitialize
+
+
+[Sources.common]
+ SDHCDxe.c
+ SDHCDxe_5250.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ SamsungPlatformPkg/ExynosPkg/Exynos5250/ExynosPkg.dec
+ SamsungPlatformPkg/SamsungPlatformPkg.dec
+ EmbeddedPkg/EmbeddedPkg.dec
+
+[LibraryClasses]
+ UefiDriverEntryPoint
+ IoLib
+ TimerLib
+ MemoryAllocationLib
+ UefiLib
+
+[Guids]
+
+[Protocols]
+ gEfiBlockIoProtocolGuid
+ gEfiDevicePathProtocolGuid
+ gSamsungPlatformGpioProtocolGuid ## GPIO Protocol
+ gEfiEblAddCommandProtocolGuid
+
+
+[Pcd]
+ gExynosPkgTokenSpaceGuid.PcdCmuBase
+ gExynosPkgTokenSpaceGuid.PcdSdMmcBase
+ gExynosPkgTokenSpaceGuid.PcdEmmcDMABufferBase
+
+[Depex]
+ TRUE
+
+
diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/SDHCDxe_EVT1/SDHCDxe_5250.c b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/SDHCDxe_EVT1/SDHCDxe_5250.c
new file mode 100755
index 000000000..5408360b0
--- /dev/null
+++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/SDHCDxe_EVT1/SDHCDxe_5250.c
@@ -0,0 +1,658 @@
+/** @file
+ MMC/SD Card driver for Secure Digital Host Controller
+
+ This driver always produces a BlockIo protocol but it starts off with no Media
+ present. A TimerCallBack detects when media is inserted or removed and after
+ a media change event a call to BlockIo ReadBlocks/WriteBlocks will cause the
+ media to be detected (or removed) and the BlockIo Media structure will get
+ updated. No MMC/SD Card harward registers are updated until the first BlockIo
+ ReadBlocks/WriteBlocks after media has been insterted (booting with a card
+ plugged in counts as an insertion event).
+
+ Copyright (c) 2012, Samsung Electronics Co. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+
+
+#include <Library/TimerLib.h>
+#include <Library/PcdLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Protocol/ExynosGpio.h>
+#include <Platform/ArmPlatform.h>
+#include <Platform/Exynos5250.h>
+#include <Platform/Arndale5250.h>
+
+
+#include "SDHCDxe.h"
+
+//#undef EFI_D_INFO
+//#define EFI_D_INFO 1
+
+
+
+void MSHC_reset_all(void)
+{
+ int count;
+ volatile int ctl_val=0;
+ UINT32 SdMmcBaseAddr;
+ SdMmcBaseAddr = PcdGet32(PcdSdMmcBase);
+
+ /* Wait max 100 ms */
+ count = 10000;
+
+ /* before reset ciu, it should check DATA0. if when DATA0 is low and
+ it resets ciu, it might make a problem */
+ while ((MmioRead32 ((SdMmcBaseAddr + MSHCI_STATUS)) & (1<<9))){
+ if (count == 0) {
+ DEBUG ((EFI_D_ERROR, "MMC controller never released. \n"));
+ return;
+ }
+ count--;
+ MicroSecondDelay(1);
+ }
+
+ // Reset CIU
+ ctl_val = MmioRead32((SdMmcBaseAddr + MSHCI_CTRL));
+ ctl_val |= CTRL_RESET;
+ MmioWrite32((SdMmcBaseAddr + MSHCI_CTRL), ctl_val);
+
+ //Reset FIFO
+ MSHC_reset_fifo();
+
+ //Reset DMA
+ ctl_val = MmioRead32((SdMmcBaseAddr + MSHCI_CTRL));
+ ctl_val |= DMA_RESET;
+ MmioWrite32((SdMmcBaseAddr + MSHCI_CTRL), ctl_val);
+
+ //Set auto stop CMD
+ ctl_val = MmioRead32((SdMmcBaseAddr + MSHCI_CTRL));
+ ctl_val |= SEND_AS_CCSD;
+ MmioWrite32((SdMmcBaseAddr + MSHCI_CTRL), ctl_val);
+
+}
+
+
+void MSHC_Set_DDR(int BusMode)
+{
+
+ UINT32 clkphase;
+ //clkphase = 0x03030002; //cmd response error at 50M RINT=0x46 error, RE and CD, RCRC
+ //clkphase = 0x03020001; //data read error at 50M SBE
+ UINT32 SdMmcBaseAddr;
+ SdMmcBaseAddr = PcdGet32(PcdSdMmcBase);
+
+ if(BusMode==BUSMODE_DDR)
+ {
+ DEBUG ((EFI_D_INFO, "MSHC DDR .\n"));
+ MmioWrite32((SdMmcBaseAddr + MSHCI_UHS_REG), UHS_DDR);
+ clkphase = 0x03020001;
+ }
+ else
+ {
+ DEBUG ((EFI_D_INFO, "MSHC Non DDR .\n"));
+ MmioWrite32((SdMmcBaseAddr + MSHCI_UHS_REG), UHS_NON_DDR);
+ clkphase = 0x03030002;
+ }
+ MmioWrite32((SdMmcBaseAddr + MSHCI_CLKSEL), clkphase);
+
+}
+
+
+void MSHC_5250_init(void)
+{
+ UINT32 SdMmcBaseAddr;
+ SdMmcBaseAddr = PcdGet32(PcdSdMmcBase);
+
+ /* Power Enable Register */
+ MmioWrite32((SdMmcBaseAddr + MSHCI_PWREN), POWER_ENABLE);
+ //MSHC_Set_DDR(BUSMODE_DDR);
+
+ MSHC_reset_all();
+
+ // Initialize FIFO
+ MmioWrite32((SdMmcBaseAddr + MSHCI_FIFOTH), (MSIZE_8 | TX_WMARK_DEFAULT | RX_WMARK_DEFAULT));
+
+ /* It clears all pending interrupts */
+ MmioWrite32((SdMmcBaseAddr + MSHCI_RINTSTS), INTMSK_ALL);
+ /* It dose not use Interrupt. Disable all */
+ MmioWrite32((SdMmcBaseAddr + MSHCI_INTMSK), 0);
+
+ //UpdateMSHCClkFrequency(MSHC_CLK_400);
+
+ /* Set auto stop command */
+ //MmioWrite32((SdMmcBaseAddr + MSHCI_CTRL), (1<<10));
+
+ /* set debounce filter value*/
+ MmioWrite32((SdMmcBaseAddr + MSHCI_DEBNCE), (0xfffff));
+
+ /* clear card type. set 1-bit mode */
+ MmioWrite32((SdMmcBaseAddr + MSHCI_CTYPE), 0x0);
+
+ /* set bus mode register for IDMAC */
+ MmioWrite32((SdMmcBaseAddr + MSHCI_BMOD), (BMOD_IDMAC_RESET));
+
+ /* disable all interrupt source of IDMAC */
+ MmioWrite32((SdMmcBaseAddr + MSHCI_IDINTEN), (0x0));
+
+ /* set max timeout */
+ MmioWrite32((SdMmcBaseAddr + MSHCI_TMOUT), (0xffffffff));
+
+ MmioWrite32((SdMmcBaseAddr + MSHCI_BLKSIZ), BLEN_512BYTES);
+ MmioWrite32((SdMmcBaseAddr + MSHCI_CLKSEL), 0x03030002);
+
+}
+
+EFI_STATUS
+InitializeMSHC (
+ VOID
+ )
+{
+
+ EFI_STATUS Status;
+ EXYNOS_GPIO *Gpio;
+ UINT32 CumBaseAddr;
+ //UINT32 SdMmcBaseAddr;
+ UINT32 i, clock;
+ volatile UINT32 ctl_val;
+
+
+ Status = gBS->LocateProtocol(&gSamsungPlatformGpioProtocolGuid, NULL, (VOID **)&Gpio);
+ ASSERT_EFI_ERROR(Status);
+
+ CumBaseAddr = PcdGet32(PcdCmuBase);
+ //SdMmcBaseAddr = PcdGet32(PcdSdMmcBase);
+
+ //MmioWrite32((SdMmcBaseAddr + SDHC_SWRST_OFFSET), SRA);
+
+ // Set Clock Source for using MPLL
+ ctl_val = MmioRead32((CumBaseAddr + CLK_SRC_FSYS_OFFSET));
+ ctl_val &= ~(0xf<<8);
+ ctl_val |= (0x6<<8);
+ MmioWrite32((CumBaseAddr + CLK_SRC_FSYS_OFFSET), ctl_val);
+ //MmioAndThenOr32 ((CumBaseAddr + CLK_SRC_FSYS_OFFSET), ~(0xF), (0x6));
+
+ // CLK mask
+ ctl_val = MmioRead32((CumBaseAddr + CLK_SRC_MASK_FSYS_OFFSET));
+ ctl_val |= (0x1<<8);
+ MmioWrite32((CumBaseAddr + CLK_SRC_MASK_FSYS_OFFSET), ctl_val);
+
+ // CLK gating
+ ctl_val = MmioRead32((CumBaseAddr + CLK_GATE_IP_FSYS_OFFSET));
+ ctl_val |= (0x1<<14);
+ MmioWrite32((CumBaseAddr + CLK_GATE_IP_FSYS_OFFSET), ctl_val);
+
+
+ /* MMC2 clock div */
+ clock = 800; //MPLL in MHz
+ for(i=0; i<= 0xf; i++)
+ {
+ if((clock / (i+1)) <= 90) {
+ MmioAndThenOr32 ((CumBaseAddr + CLK_DIV_FSYS2_OFFSET), ~(0xF << 0), (i << 0));
+ break;
+ }
+ }
+
+
+ // 2. GPIO setting
+ // Set GPIO for using SDMMC2
+ Gpio->Set(Gpio,SD_2_EVT1_CLK,GPIO_MODE_SPECIAL_FUNCTION_2);
+ Gpio->Set(Gpio,SD_2_EVT1_CMD,GPIO_MODE_SPECIAL_FUNCTION_2);
+ Gpio->Set(Gpio,SD_2_EVT1_CDn,GPIO_MODE_SPECIAL_FUNCTION_2);
+ Gpio->Set(Gpio,SD_2_EVT1_DATA0,GPIO_MODE_SPECIAL_FUNCTION_2);
+ Gpio->Set(Gpio,SD_2_EVT1_DATA1,GPIO_MODE_SPECIAL_FUNCTION_2);
+ Gpio->Set(Gpio,SD_2_EVT1_DATA2,GPIO_MODE_SPECIAL_FUNCTION_2);
+ Gpio->Set(Gpio,SD_2_EVT1_DATA3,GPIO_MODE_SPECIAL_FUNCTION_2);
+
+ Gpio->SetPull(Gpio,SD_2_EVT1_CLK,GPIO_PULL_NONE);
+ Gpio->SetPull(Gpio,SD_2_EVT1_CMD,GPIO_PULL_NONE);
+ Gpio->SetPull(Gpio,SD_2_EVT1_CDn,GPIO_PULL_UP);
+ Gpio->SetPull(Gpio,SD_2_EVT1_DATA0,GPIO_PULL_UP);
+ Gpio->SetPull(Gpio,SD_2_EVT1_DATA1,GPIO_PULL_UP);
+ Gpio->SetPull(Gpio,SD_2_EVT1_DATA2,GPIO_PULL_UP);
+ Gpio->SetPull(Gpio,SD_2_EVT1_DATA3,GPIO_PULL_UP);
+
+ Gpio->SetStrength(Gpio,SD_2_EVT1_CLK,GPIO_DRV_4X);
+ Gpio->SetStrength(Gpio,SD_2_EVT1_CMD,GPIO_DRV_4X);
+ Gpio->SetStrength(Gpio,SD_2_EVT1_CDn,GPIO_DRV_4X);
+ Gpio->SetStrength(Gpio,SD_2_EVT1_DATA0,GPIO_DRV_4X);
+ Gpio->SetStrength(Gpio,SD_2_EVT1_DATA1,GPIO_DRV_4X);
+ Gpio->SetStrength(Gpio,SD_2_EVT1_DATA2,GPIO_DRV_4X);
+ Gpio->SetStrength(Gpio,SD_2_EVT1_DATA3,GPIO_DRV_4X);
+
+ MSHC_5250_init();
+ return EFI_SUCCESS;
+}
+
+void MSHC_reset_fifo(void)
+{
+ volatile int ctl_val=0;
+ UINT32 SdMmcBaseAddr;
+ SdMmcBaseAddr = PcdGet32(PcdSdMmcBase);
+ //Reset FIFO
+ ctl_val = MmioRead32((SdMmcBaseAddr + MSHCI_CTRL));
+ ctl_val |= FIFO_RESET;
+ MmioWrite32((SdMmcBaseAddr + MSHCI_CTRL), ctl_val);
+
+}
+
+
+VOID MSHC_clock_onoff (int value)
+{
+ volatile UINT32 loop_count = 0x100000;
+ UINT32 SdMmcBaseAddr;
+
+ SdMmcBaseAddr = PcdGet32(PcdSdMmcBase);
+
+ if(value==CLK_ENABLE)
+ {
+ MmioWrite32 ((SdMmcBaseAddr + MSHCI_CLKENA), (0x1<<0));
+ MmioWrite32 ((SdMmcBaseAddr + MSHCI_CMD), 0);
+ MmioWrite32 ((SdMmcBaseAddr + MSHCI_CMD), CMD_ONLY_CLK);
+ do {
+ if((MmioRead32 (SdMmcBaseAddr + MSHCI_CMD) & CMD_STRT_BIT)==0)
+ break;
+ loop_count--;
+ } while (loop_count);
+ }
+ else
+ {
+ MmioWrite32 ((SdMmcBaseAddr + MSHCI_CLKENA), (0x0<<0));
+ MmioWrite32 ((SdMmcBaseAddr + MSHCI_CMD), 0);
+ MmioWrite32 ((SdMmcBaseAddr + MSHCI_CMD), CMD_ONLY_CLK);
+ do {
+ if((MmioRead32 (SdMmcBaseAddr + MSHCI_CMD) & CMD_STRT_BIT)==0)
+ break;
+ loop_count--;
+ } while (loop_count);
+ }
+
+ if (loop_count == 0) {
+ DEBUG ((EFI_D_ERROR, "MSHC::clockonoff : Clk = %d\n", value));
+ }
+
+}
+
+
+VOID
+UpdateMSHCClkFrequency (
+ UINTN NewCLK
+ )
+{
+ UINT32 CumBaseAddr;
+ UINT32 SdMmcBaseAddr;
+
+ SdMmcBaseAddr = PcdGet32(PcdSdMmcBase);
+ CumBaseAddr = PcdGet32(PcdCmuBase);
+
+ // Disable all clocks to not provide the clock to the card
+//(CONFIG_CPU_EXYNOS5250_EVT1)
+ MSHC_clock_onoff(CLK_DISABLE);
+ //MmioAnd32 ((SdMmcBaseAddr + CLKCON_OFFSET), ~(0xF));
+
+ //Set new clock frequency.
+ if (NewCLK == MSHC_CLK_400)
+ {
+ DEBUG ((EFI_D_INFO, "MSHC::CLK=400.\n"));
+ // MPLL=800, cclk_in=100, 100M/250=400k
+ //MmioAndThenOr32 ((CumBaseAddr + CLK_DIV_FSYS1_OFFSET), ~(0xFFFF), 0xE008);
+ MmioAndThenOr32 ((CumBaseAddr + CLK_DIV_FSYS2_OFFSET), ~(0xFFFF), 0x1);
+ MmioWrite32 ((SdMmcBaseAddr + MSHCI_CLKDIV), 125);
+ }
+ else if (NewCLK == MSHC_CLK_25M)
+ {
+ DEBUG ((EFI_D_INFO, "MSHC::CLK=25M.\n"));
+ // DDR mode use CLKDIV MPLL = 800, SCLK = 400, cclk_in=100M
+ //MmioAndThenOr32 ((CumBaseAddr + CLK_DIV_FSYS2_OFFSET), ~(0xFFFF), 0x1);
+ //MmioWrite32 ((SdMmcBaseAddr + MSHCI_CLKDIV), 2);
+ MmioAndThenOr32 ((CumBaseAddr + CLK_DIV_FSYS2_OFFSET), ~(0xFFFF), 0x1);
+ MmioWrite32 ((SdMmcBaseAddr + MSHCI_CLKDIV), 2);
+ }
+ else if(NewCLK == MSHC_CLK_50M)
+ {
+ DEBUG ((EFI_D_INFO, "MSHC::CLK=50M.\n"));
+ // DDR mode use CLKDIV MPLL = 800, SCLK = 400, cclk_in=100M
+ MmioAndThenOr32 ((CumBaseAddr + CLK_DIV_FSYS2_OFFSET), ~(0xFFFF), 0x1);
+ MmioWrite32 ((SdMmcBaseAddr + MSHCI_CLKDIV), 1);
+
+ MSHC_Set_DDR(BUSMODE_DDR);
+ //MmioWrite32 ((SdMmcBaseAddr + MSHCI_CMD), CMD_ONLY_CLK);
+ }
+
+//#if defined(CONFIG_CPU_EXYNOS5250_EVT1)
+ MSHC_clock_onoff(CLK_ENABLE);
+ //MmioOr32 ((SdMmcBaseAddr + CLKCON_OFFSET), ICE);
+
+ //Poll till Internal Clock Stable
+ //while ((MmioRead32 ((SdMmcBaseAddr + CLKCON_OFFSET)) & ICS) != ICS);
+
+ //Set Clock enable to 0x1 to provide the clock to the card
+ //MmioOr32 ((SdMmcBaseAddr + CLKCON_OFFSET), CCE);
+
+}
+
+extern MSHC_OPERATION_MODE MSHC_operation_mode;
+void mshci_set_mdma_desc(UINT8 *desc_vir, UINT8 *desc_phy,
+ UINT32 des0, UINT32 des1, UINT32 des2)
+{
+ ((struct mshci_idmac *)(desc_vir))->des0 = des0;
+ ((struct mshci_idmac *)(desc_vir))->des1 = des1;
+ ((struct mshci_idmac *)(desc_vir))->des2 = des2;
+ ((struct mshci_idmac *)(desc_vir))->des3 = (UINT32)desc_phy +
+ sizeof(struct mshci_idmac);
+}
+
+
+VOID
+PrepareTransfer (
+IN OUT VOID *Buffer, UINTN BlockCount, IN OPERATION_TYPE OperationType
+ )
+{
+ UINT32 SdMmcBaseAddr;
+ UINT32 EmmcDMABufferBase;
+ volatile UINT32 MshcRegValue;
+ struct mshci_idmac *pdesc_dmac;
+ UINT32 des_flag;
+ UINTN i=0;
+ UINT32 ByteCnt=0;
+ UINT32 BlockCnt=BlockCount;
+// UINT32 MSH_uDES_A_0, MSH_uDES_A_1, MSH_uDES_A_2, MSH_uDES_A_3;
+
+ SdMmcBaseAddr = PcdGet32(PcdSdMmcBase);
+ EmmcDMABufferBase = PcdGet32(PcdEmmcDMABufferBase);
+ EmmcDMABufferBase += PHY_CH2_OFFSET;
+ DEBUG ((EFI_D_INFO, "EmmcDMABufferBase:0x%x \n", EmmcDMABufferBase));
+ pdesc_dmac = (struct mshci_idmac *)EmmcDMABufferBase;
+
+ if(MSHC_operation_mode==MSHC_FIFO)
+ {
+ MSHC_reset_fifo();
+
+ // 1. enable interrupt mode
+ MshcRegValue = MmioRead32(SdMmcBaseAddr + MSHCI_CTRL);
+ MshcRegValue |= INT_ENABLE;
+ MmioWrite32 ((SdMmcBaseAddr + MSHCI_CTRL), MshcRegValue);
+
+ // 2. DDR mode
+
+ // 3. set BLKSIZE
+ MmioWrite32 ((SdMmcBaseAddr + MSHCI_BLKSIZ), BLEN_512BYTES);
+ //MmioWrite32 ((SdMmcBaseAddr + MSHCI_BLKSIZ), BLKSIZE_1);
+
+ // 4. set BYTCNT
+ MmioWrite32 ((SdMmcBaseAddr + MSHCI_BYTCNT), BLEN_512BYTES);
+
+ //Setting Data timeout counter value to max value.
+ MmioWrite32((SdMmcBaseAddr + MSHCI_TMOUT), (0xffffffff));
+
+ }
+ else if(MSHC_operation_mode==MSHC_IDMA)
+ {
+ ZeroMem ((VOID *)EmmcDMABufferBase, PHY_BUF_OFFSET);//20120608
+ if(OperationType==WRITE)
+ {
+ CopyMem((VOID *)(EmmcDMABufferBase+PHY_BUF_OFFSET), (VOID *)Buffer, BlockCount*BLEN_512BYTES);
+ //DEBUG ((EFI_D_INFO, "MSHC_DMA prepare WRITE:%d Block \n", BlockCount));
+ }
+ else
+ {
+ //DEBUG ((EFI_D_INFO, "MSHC_DMA prepare READ:%d Block \n", BlockCount));
+ }
+
+ MSHC_reset_fifo();
+
+ //IDMA reset
+ MshcRegValue = MmioRead32(SdMmcBaseAddr + MSHCI_BMOD);
+ MshcRegValue |= (BMOD_IDMAC_RESET);
+ MmioWrite32 ((SdMmcBaseAddr + MSHCI_BMOD), MshcRegValue);
+
+
+ // 1. enable IDMA at CTRL
+ MshcRegValue = MmioRead32(SdMmcBaseAddr + MSHCI_CTRL);
+ MshcRegValue &= ~(INT_ENABLE);
+ MshcRegValue |= (ENABLE_IDMAC);
+ MmioWrite32 ((SdMmcBaseAddr + MSHCI_CTRL), MshcRegValue);
+
+
+ // 2. enable IDMA at BMODE
+ //Set Block Size and Block count.
+ MshcRegValue = MmioRead32(SdMmcBaseAddr + MSHCI_BMOD);
+ MshcRegValue |= (BMOD_IDMAC_ENABLE | BMOD_IDMAC_FB);
+ MmioWrite32 ((SdMmcBaseAddr + MSHCI_BMOD), MshcRegValue);
+
+ // interrupt enable
+ MmioWrite32((SdMmcBaseAddr + MSHCI_IDINTEN), (0x337));
+
+ for(i=0; ; i++)
+ {
+ // set descriptor multichain
+ des_flag = (MSHCI_IDMAC_OWN|MSHCI_IDMAC_CH);
+ des_flag |= (i==0) ? MSHCI_IDMAC_FS:0;
+ if(BlockCnt<=8)
+ {
+ //DEBUG ((EFI_D_INFO, "DESC LD\n"));
+ des_flag |= (MSHCI_IDMAC_LD);
+ mshci_set_mdma_desc((UINT8 *)pdesc_dmac,
+ //(UINT8 *)pdesc_dmac,
+ (UINT8 *)(EmmcDMABufferBase-sizeof(struct mshci_idmac)),
+ des_flag, BlockCnt*BLEN_512BYTES,
+ ((UINT32)((EmmcDMABufferBase + PHY_BUF_OFFSET)+(UINT32)(i*PHY_BUF_SIZE))));
+ break;
+
+ }
+ //DEBUG ((EFI_D_INFO, "DESC FS\n"));
+ mshci_set_mdma_desc((UINT8 *)pdesc_dmac,
+ (UINT8 *)pdesc_dmac,
+ des_flag, BLEN_512BYTES*8,
+ ((UINT32)((EmmcDMABufferBase + PHY_BUF_OFFSET)+(UINT32)(i*PHY_BUF_SIZE))));
+
+ BlockCnt -=8;
+ pdesc_dmac++;
+
+ }
+
+ MmioWrite32 ((SdMmcBaseAddr + MSHCI_DBADDR), (UINT32)EmmcDMABufferBase);
+
+ // 3. set BLKSIZE
+ MmioWrite32 ((SdMmcBaseAddr + MSHCI_BLKSIZ), BLEN_512BYTES);
+
+ // 4. set BYTCNT
+ ByteCnt = (BlockCount*BLEN_512BYTES);
+ MmioWrite32 ((SdMmcBaseAddr + MSHCI_BYTCNT), ByteCnt);
+
+ //Setting Data timeout counter value to max value.
+ MmioWrite32((SdMmcBaseAddr + MSHCI_TMOUT), (0xffffffff));
+ DEBUG ((EFI_D_INFO, "Block:%d BYTCNT:0x%x ByteCnt:0x%x\n", BlockCount,MmioRead32(SdMmcBaseAddr + MSHCI_BYTCNT), ByteCnt));
+
+ }
+
+}
+
+EFI_STATUS MSHC_ReadFIFO(IN UINTN Size32, OUT VOID *Buffer)
+{
+ EFI_STATUS Status;
+ UINT32 SdMmcBaseAddr;
+ UINTN *DataBuffer = Buffer;
+ UINTN BufSize=Size32;
+ UINTN FifoCount=0;
+ UINTN Count=0;
+
+ SdMmcBaseAddr = PcdGet32(PcdSdMmcBase);
+ //Check controller status to make sure there is no error.
+
+ while (BufSize)
+ {
+ if((MmioRead32 (SdMmcBaseAddr + MSHCI_RINTSTS)) & INTMSK_RXDR)
+ {
+
+ //Read block worth of data.
+ FifoCount = GET_FIFO_COUNT(MmioRead32 (SdMmcBaseAddr + MSHCI_STATUS));
+ DEBUG ((EFI_D_INFO, "MSHC::ReadBlock DTO FIFO:%d\n", FifoCount));
+ for (Count = 0; Count < FifoCount; Count++)
+ {
+ *DataBuffer++ = MmioRead32 (SdMmcBaseAddr + MSHCI_FIFO);
+ }
+ MmioWrite32((SdMmcBaseAddr + MSHCI_RINTSTS), INTMSK_RXDR);
+ BufSize -= FifoCount;
+ }
+
+ else if((MmioRead32 (SdMmcBaseAddr + MSHCI_RINTSTS)) & INTMSK_DTO)
+ {
+
+ //Read block worth of data.
+ FifoCount = GET_FIFO_COUNT(MmioRead32 (SdMmcBaseAddr + MSHCI_STATUS));
+ DEBUG ((EFI_D_INFO, "MSHC::ReadBlock DTO FIFO:%d\n", FifoCount));
+ for (Count = 0; Count < FifoCount; Count++)
+ {
+ *DataBuffer++ = MmioRead32 (SdMmcBaseAddr + MSHCI_FIFO);
+ }
+ MmioWrite32((SdMmcBaseAddr + MSHCI_RINTSTS), INTMSK_DTO);
+ BufSize -= FifoCount;
+ }
+
+ else if((MmioRead32 (SdMmcBaseAddr + MSHCI_RINTSTS)) & (INTMSK_DCRC|INTMSK_DRTO|INTMSK_HTO|INTMSK_FRUN))
+ {
+ DEBUG ((EFI_D_INFO, "MSHC::ReadBlock Error RINT:0x%x\n", MmioRead32 (SdMmcBaseAddr + MSHCI_RINTSTS)));
+ return EFI_DEVICE_ERROR;
+ }
+
+ }
+
+ if(BufSize==0)
+ {
+ Status = EFI_SUCCESS;
+ }
+ else
+ {
+ Status = EFI_BAD_BUFFER_SIZE;
+ }
+ return Status;
+}
+
+EFI_STATUS MSHC_WriteFIFO(IN UINTN Size32, IN VOID *Buffer)
+{
+ UINT32 SdMmcBaseAddr;
+ UINTN *DataBuffer = Buffer;
+ UINTN BufSize=Size32;
+ UINTN Count=0;
+
+ SdMmcBaseAddr = PcdGet32(PcdSdMmcBase);
+
+ if(BufSize>FIFO_SIZE)
+ {
+ DEBUG ((EFI_D_INFO, "MSHC::Error MSHC_WriteFIFO Bad buffer size\n"));
+ return EFI_BAD_BUFFER_SIZE;
+ }
+
+ //Write block worth of data.
+ for (Count = 0; Count < BufSize; Count++)
+ {
+ MmioWrite32 ((SdMmcBaseAddr + MSHCI_FIFO), *DataBuffer++);
+ }
+ return EFI_SUCCESS;
+
+}
+
+/*typedef
+VOID
+CopyMem (
+ IN VOID *Destination,
+ IN VOID *Source,
+ IN UINTN Length
+ );*/
+
+EFI_STATUS MSHC_ReadDMA(OUT VOID *Buffer, IN UINTN BlockCount)
+{
+ EFI_STATUS Status;
+ UINT32 SdMmcBaseAddr, EmmcDMABufferBase;
+ UINTN Count=MAX_RETRY_COUNT;
+ //UINT32 MshcRegValue;
+ //UINT32 TransferSize=0;
+
+ SdMmcBaseAddr = PcdGet32(PcdSdMmcBase);
+ EmmcDMABufferBase = PcdGet32(PcdEmmcDMABufferBase);
+ EmmcDMABufferBase += PHY_CH2_OFFSET;
+ //Check controller status to make sure there is no error.
+
+ while (Count)
+ {
+ if((MmioRead32 (SdMmcBaseAddr + MSHCI_RINTSTS)) & INTMSK_DTO)
+ {
+ //TransferSize = MmioRead32 (SdMmcBaseAddr + MSHCI_TBBCNT);
+ CopyMem((VOID *)Buffer, (VOID *)(EmmcDMABufferBase+PHY_BUF_OFFSET), BlockCount*BLEN_512BYTES);
+ DEBUG ((EFI_D_INFO, "MSHC_ReadDMA Over %d Blocks\n", BlockCount));
+ break;
+ }
+ else if((MmioRead32 (SdMmcBaseAddr + MSHCI_RINTSTS)) & (DATA_ERR|DATA_TOUT))
+ {
+ DEBUG ((EFI_D_ERROR, "MSHC_ReadDMA Err RINT:0x%x\n", MmioRead32 (SdMmcBaseAddr + MSHCI_RINTSTS)));
+ }
+
+ else
+ {
+ Count--;
+ MicroSecondDelay(1);
+ DEBUG ((EFI_D_INFO, ".\n"));
+ }
+
+ }
+
+ if(Count!=0)
+ {
+ Status = EFI_SUCCESS;
+ }
+ else
+ {
+ DEBUG ((EFI_D_ERROR, "MSHC_ReadDMA bad buffer size RINT:0x%x\n", MmioRead32 (SdMmcBaseAddr + MSHCI_RINTSTS)));
+ Status = EFI_BAD_BUFFER_SIZE;
+ MmioWrite32 ((SdMmcBaseAddr + MSHCI_PLDMND), 7);
+
+ }
+ return Status;
+}
+
+EFI_STATUS MSHC_WriteDMA(IN VOID *Buffer, IN UINTN BlockCount)
+{
+ EFI_STATUS Status;
+ UINT32 SdMmcBaseAddr;
+ UINTN Count=MAX_RETRY_COUNT;
+
+ SdMmcBaseAddr = PcdGet32(PcdSdMmcBase);
+ //Check controller status to make sure there is no error.
+
+ while (Count)
+ {
+ if((MmioRead32 (SdMmcBaseAddr + MSHCI_RINTSTS)) & INTMSK_DTO)
+ {
+ DEBUG ((EFI_D_INFO, "MSHC_writeDMA Over %d blocks\n", BlockCount));
+ break;
+ }
+ else
+ {
+ MicroSecondDelay(1);
+ Count--;
+ }
+
+ }
+
+ if(Count!=0)
+ {
+ Status = EFI_SUCCESS;
+ }
+ else
+ {
+ Status = EFI_BAD_BUFFER_SIZE;
+ MmioWrite32 ((SdMmcBaseAddr + MSHCI_PLDMND), 7);
+ DEBUG ((EFI_D_ERROR, "MSHC_writeDMA bad buffer size RINT:0x%x \n", MmioRead32 (SdMmcBaseAddr + MSHCI_RINTSTS)));
+ }
+ return Status;
+}
diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/SDHCDxe_EVT1/SDHCDxe_5250.h b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/SDHCDxe_EVT1/SDHCDxe_5250.h
new file mode 100755
index 000000000..7dbf590e1
--- /dev/null
+++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/SDHCDxe_EVT1/SDHCDxe_5250.h
@@ -0,0 +1,323 @@
+/** @file
+
+ Copyright (c) 2012, Samsung Electronics Co. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _MSHCDXE_5250_H_
+#define _MSHCDXE_5250_H_
+
+
+/*
+ * Controller registers
+ */
+/*****************************************************/
+/* MSHC Internal Registers */
+/*****************************************************/
+
+#define MSHCI_CTRL 0x00 /* Control */
+#define MSHCI_PWREN 0x04 /* Power-enable */
+#define MSHCI_CLKDIV 0x08 /* Clock divider */
+#define MSHCI_CLKSRC 0x0C /* Clock source */
+#define MSHCI_CLKENA 0x10 /* Clock enable */
+#define MSHCI_TMOUT 0x14 /* Timeout */
+#define MSHCI_CTYPE 0x18 /* Card type */
+#define MSHCI_BLKSIZ 0x1C /* Block Size */
+#define MSHCI_BYTCNT 0x20 /* Byte count */
+#define MSHCI_INTMSK 0x24 /* Interrupt Mask */
+#define MSHCI_CMDARG 0x28 /* Command Argument */
+#define MSHCI_CMD 0x2C /* Command */
+#define MSHCI_RESP0 0x30 /* Response 0 */
+#define MSHCI_RESP1 0x34 /* Response 1 */
+#define MSHCI_RESP2 0x38 /* Response 2 */
+#define MSHCI_RESP3 0x3C /* Response 3 */
+#define MSHCI_MINTSTS 0x40 /* Masked interrupt status */
+#define MSHCI_RINTSTS 0x44 /* Raw interrupt status */
+#define MSHCI_STATUS 0x48 /* Status */
+#define MSHCI_FIFOTH 0x4C /* FIFO threshold */
+#define MSHCI_CDETECT 0x50 /* Card detect */
+#define MSHCI_WRTPRT 0x54 /* Write protect */
+#define MSHCI_GPIO 0x58 /* General Purpose IO */
+#define MSHCI_TCBCNT 0x5C /* Transferred CIU byte count */
+#define MSHCI_TBBCNT 0x60 /* Transferred host/DMA to/from byte count */
+#define MSHCI_DEBNCE 0x64 /* Card detect debounce */
+#define MSHCI_USRID 0x68 /* User ID */
+#define MSHCI_VERID 0x6C /* Version ID */
+#define MSHCI_HCON 0x70 /* Hardware Configuration */
+#define MSHCI_UHS_REG 0x74 /* UHS and DDR setting */
+#define MSHCI_BMOD 0x80 /* Bus mode register */
+#define MSHCI_PLDMND 0x84 /* Poll demand */
+#define MSHCI_DBADDR 0x88 /* Descriptor list base address */
+#define MSHCI_IDSTS 0x8C /* Internal DMAC status */
+#define MSHCI_IDINTEN 0x90 /* Internal DMAC interrupt enable */
+#define MSHCI_DSCADDR 0x94 /* Current host descriptor address */
+#define MSHCI_BUFADDR 0x98 /* Current host buffer address */
+#define MSHCI_CLKSEL 0x9C /* Drv/sample clock selection register */
+#define MSHCI_WAKEUPCON 0xA0 /* Wakeup control register */
+#define MSHCI_CLOCKCON 0xA4 /* Clock (delay) control register */
+#define MSHCI_FIFO 0x200
+#define MSHCI_FIFODAT(x) (x) /* FIFO data read write */
+
+
+/*****************************************************
+ * Control Register Register
+ * MSHCI_CTRL - offset 0x00
+ *****************************************************/
+
+#define CTRL_RESET (0x1<<0) /* Reset DWC_mobile_storage controller */
+#define FIFO_RESET (0x1<<1) /* Reset FIFO */
+#define DMA_RESET (0x1<<2) /* Reset DMA interface */
+#define INT_ENABLE (0x1<<4) /* Global interrupt enable/disable bit */
+#define DMA_ENABLE (0x1<<5) /* DMA transfer mode enable/disable bit */
+#define READ_WAIT (0x1<<6) /* For sending read-wait to SDIO cards */
+#define SEND_IRQ_RESP (0x1<<7) /* Send auto IRQ response */
+#define ABRT_READ_DATA (0x1<<8)
+#define SEND_CCSD (0x1<<9)
+#define SEND_AS_CCSD (0x1<<10)
+#define CEATA_INTSTAT (0x1<<11)
+#define CARD_VOLA (0xF<<16)
+#define CARD_VOLB (0xF<<20)
+#define ENABLE_OD_PULLUP (0x1<<24)
+#define ENABLE_IDMAC (0x1<<25)
+#define MSHCI_RESET_ALL (0x1)
+
+/*****************************************************
+ * Power Enable Register
+ * MSHCI_PWREN - offset 0x04
+ *****************************************************/
+#define POWER_ENABLE (0x1<<0)
+
+/*****************************************************
+* Clock Enable Register
+* MSHCI_CLKENA - offset 0x10
+*****************************************************/
+#define CLK_SDMMC_MAX (48000000) /* 96Mhz. it SHOULDBE optimized */
+#define CLK_ENABLE (0x1<<0)
+#define CLK_DISABLE (0x0<<0)
+
+
+/*****************************************************
+ * Interrupt Mask Register
+ * MSHCI_INTMSK - offset 0x24
+ *****************************************************/
+#define INT_MASK (0xFFFF<<0)
+#define SDIO_INT_MASK (0xFFFF<<16)
+#define SDIO_INT_ENABLE (0x1<<16)
+
+/* interrupt bits */
+#define INTMSK_ALL 0xFFFFFFFF
+#define INTMSK_CDETECT (0x1<<0)
+#define INTMSK_RE (0x1<<1)
+#define INTMSK_CDONE (0x1<<2)
+#define INTMSK_DTO (0x1<<3)
+#define INTMSK_TXDR (0x1<<4)
+#define INTMSK_RXDR (0x1<<5)
+#define INTMSK_RCRC (0x1<<6)
+#define INTMSK_DCRC (0x1<<7)
+#define INTMSK_RTO (0x1<<8)
+#define INTMSK_DRTO (0x1<<9)
+#define INTMSK_HTO (0x1<<10)
+#define INTMSK_FRUN (0x1<<11)
+#define INTMSK_HLE (0x1<<12)
+#define INTMSK_SBE (0x1<<13)
+#define INTMSK_ACD (0x1<<14)
+#define INTMSK_EBE (0x1<<15)
+#define INTMSK_DMA (INTMSK_ACD|INTMSK_RXDR|INTMSK_TXDR)
+
+#define INT_SRC_IDMAC (0x0)
+#define INT_SRC_MINT (0x1)
+
+
+/*****************************************************
+ * Command Register
+ * MSHCI_CMD - offset 0x2C
+ *****************************************************/
+
+#define CMD_RESP_EXP_BIT (0x1<<6)
+#define CMD_RESP_LENGTH_BIT (0x1<<7)
+#define CMD_CHECK_CRC_BIT (0x1<<8)
+#define CMD_DATA_EXP_BIT (0x1<<9)
+#define CMD_RW_BIT (0x1<<10)
+#define CMD_TRANSMODE_BIT (0x1<<11)
+#define CMD_SENT_AUTO_STOP_BIT (0x1<<12)
+#define CMD_WAIT_PRV_DAT_BIT (0x1<<13)
+#define CMD_ABRT_CMD_BIT (0x1<<14)
+#define CMD_SEND_INIT_BIT (0x1<<15)
+#define CMD_CARD_NUM_BITS (0x1F<<16)
+#define CMD_SEND_CLK_ONLY (0x1<<21)
+#define CMD_READ_CEATA (0x1<<22)
+#define CMD_CCS_EXPECTED (0x1<<23)
+#define CMD_USE_HOLD_REG (0x1<<29)
+#define CMD_STRT_BIT (0x1<<31)
+#define CMD_ONLY_CLK (CMD_STRT_BIT | CMD_SEND_CLK_ONLY | \
+ CMD_WAIT_PRV_DAT_BIT)
+
+/*****************************************************
+ * Raw Interrupt Register
+ * MSHCI_RINTSTS - offset 0x44
+ *****************************************************/
+#define INT_STATUS (0xFFFF<<0)
+#define SDIO_INTR (0xFFFF<<16)
+#define DATA_ERR (INTMSK_EBE|INTMSK_SBE|INTMSK_HLE|INTMSK_FRUN |\
+ INTMSK_EBE |INTMSK_DCRC)
+#define DATA_TOUT (INTMSK_HTO|INTMSK_DRTO)
+#define DATA_STATUS (DATA_ERR|DATA_TOUT|INTMSK_RXDR|INTMSK_TXDR|INTMSK_DTO)
+#define CMD_STATUS (INTMSK_RTO|INTMSK_RCRC|INTMSK_CDONE|INTMSK_RE)
+#define CMD_ERROR (INTMSK_RCRC|INTMSK_RTO|INTMSK_RE)
+
+
+/*****************************************************
+ * Status Register
+ * MSHCI_STATUS - offset 0x48
+ *****************************************************/
+#define FIFO_RXWTRMARK (0x1<<0)
+#define FIFO_TXWTRMARK (0x1<<1)
+#define FIFO_EMPTY (0x1<<2)
+#define FIFO_FULL (0x1<<3)
+#define CMD_FSMSTAT (0xF<<4)
+#define DATA_3STATUS (0x1<<8)
+#define DATA_BUSY (0x1<<9)
+#define DATA_MCBUSY (0x1<<10)
+#define RSP_INDEX (0x3F<<11)
+#define FIFO_COUNT (0x1FFF<<17)
+#define DMA_ACK (0x1<<30)
+#define DMA_REQ (0x1<<31)
+#define FIFO_WIDTH (0x4)
+#define FIFO_DEPTH (0x20)
+#define FIFO_SIZE (0x80)
+#define GET_FIFO_COUNT(x) (((x)&0x3ffe0000)>>17)
+
+
+
+/*****************************************************
+ * FIFO Threshold Watermark Register
+ * MSHCI_FIFOTH - offset 0x4C
+ *****************************************************/
+#define TX_WMARK (0xFFF<<0)
+#define RX_WMARK (0xFFF<<16)
+#define MSIZE_MASK (0x7<<28)
+
+/* DW DMA Mutiple Transaction Size */
+#define MSIZE_1 (0<<28)
+#define MSIZE_4 (1<<28)
+#define MSIZE_8 (2<<28)
+#define MSIZE_16 (3<<28)
+#define MSIZE_32 (4<<28)
+#define MSIZE_64 (5<<28)
+#define MSIZE_128 (6<<28)
+#define MSIZE_256 (7<<28)
+
+#define TX_WMARK_DEFAULT (0x10<<0)
+#define RX_WMARK_DEFAULT (0x10<<16)
+
+//#define TX_WMARK_DEFAULT (0x40<<0)
+//#define RX_WMARK_DEFAULT (0x3F<<16)
+
+
+/*****************************************************
+ * Bus Mode Register
+ * MSHCI_UHS_REG - offset 0x74
+ *****************************************************/
+#define UHS_DDR (0x1<<16)
+#define UHS_NON_DDR (0x0<<16)
+#define BUSMODE_DDR 1
+#define BUSMODE_NON_DDR 0
+
+/*****************************************************
+ * Bus Mode Register
+ * MSHCI_BMOD - offset 0x80
+ *****************************************************/
+#define BMOD_IDMAC_RESET (0x1<<0)
+#define BMOD_IDMAC_FB (0x1<<1)
+#define BMOD_IDMAC_ENABLE (0x1<<7)
+
+/*****************************************************
+ * Hardware Configuration Register
+ * MSHCI_IDSTS - offset 0x8c
+ *****************************************************/
+#define IDSTS_FSM (0xf<<13)
+#define IDSTS_EB (0x7<<10)
+#define IDSTS_AIS (0x1<<9)
+#define IDSTS_NIS (0x1<<8)
+#define IDSTS_CES (0x1<<5)
+#define IDSTS_DU (0x1<<4)
+#define IDSTS_FBE (0x1<<2)
+#define IDSTS_RI (0x1<<1)
+#define IDSTS_TI (0x1<<0)
+
+
+/*****************************************************
+ * Card Type Register
+ * MSHCI_CTYPE - offset 0x18
+ *****************************************************/
+#define CARD_WIDTH14 (0xFFFF<<0)
+#define CARD_WIDTH8 (0xFFFF<<16)
+
+struct mshci_idmac {
+ UINT32 des0;
+ UINT32 des1;
+ UINT32 des2;
+ UINT32 des3;
+#define MSHCI_IDMAC_OWN (1<<31)
+#define MSHCI_IDMAC_ER (1<<5)
+#define MSHCI_IDMAC_CH (1<<4)
+#define MSHCI_IDMAC_FS (1<<3)
+#define MSHCI_IDMAC_LD (1<<2)
+#define MSHCI_IDMAC_DIC (1<<1)
+#define INTMSK_IDMAC_ALL (0x337)
+#define INTMSK_IDMAC_ERROR (0x214)
+};
+
+typedef enum {
+ READ,
+ WRITE
+} OPERATION_TYPE;
+
+
+/*****************************************************
+ * DMA Buffer structure
+ *
+ * CH0 for eMMC 0x40300000--0x40380000
+ * CH2 for SD Card 0x40380000--0x40400000
+ *****************************************************/
+#define EMMC_DMA_PHYSICAL_BUFFER_BASE 0x40300000
+#define EMMC_DMA_PHYSICAL_BUFFER_SIZE 0x00100000 //1MB
+#define PHY_CH2_OFFSET 0x80000
+#define PHY_BUF_OFFSET 0x1000 //4K
+#define PHY_BUF_SIZE 0x1000 //4K
+
+//#define MAX_MSHC_TRANSFER_SIZE 0x4000 //16K
+#define MAX_MSHC_TRANSFER_SIZE 0x40000 //512blocks, 256KB
+
+
+
+
+/*****************************************************
+ * External Functions
+ *****************************************************/
+
+
+EFI_STATUS InitializeMSHC (VOID);
+VOID UpdateMSHCClkFrequency (UINTN NewCLK);
+void MSHC_reset_fifo(void);
+extern void MSHC_reset_all(void);
+extern VOID PrepareTransfer (IN OUT VOID *Buffer, UINTN ByteCount, IN OPERATION_TYPE OperationType);
+extern EFI_STATUS MSHC_ReadFIFO(IN UINTN Size32, OUT VOID *Buffer);
+extern EFI_STATUS MSHC_WriteFIFO(IN UINTN Size32, IN VOID *Buffer);
+void mshci_set_mdma_desc(UINT8 *desc_vir, UINT8 *desc_phy,
+ UINT32 des0, UINT32 des1, UINT32 des2);
+EFI_STATUS MSHC_ReadDMA(OUT VOID *Buffer, IN UINTN BlockCount);
+EFI_STATUS MSHC_WriteDMA(IN VOID *Buffer, IN UINTN BlockCount);
+
+
+
+#endif
+
diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/SDHCDxe_EVT1/SDHCDxe_CMD.h b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/SDHCDxe_EVT1/SDHCDxe_CMD.h
new file mode 100755
index 000000000..cbaa7b935
--- /dev/null
+++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/SDHCDxe_EVT1/SDHCDxe_CMD.h
@@ -0,0 +1,165 @@
+/** @file
+
+ Copyright (c) 2011, Samsung Electronics Co. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _MSHCDXE_CMD_H_
+#define _MSHCDXE_CMD_H_
+
+
+
+#define HosttoCard 0x1
+#define CardtoHost 0x0
+
+#define ENDMA BIT0
+#define ENBLKCNT BIT1
+#define RD1WT0 BIT4
+#define MUL1SIN0 BIT5
+#define RSPTYP136 (0x1 << 16)
+#define RSPTYP48 (0x2 << 16)
+#define RSPTYP48B (0x3 << 16)
+#define ENCMDCRC BIT19
+#define ENCMDIDX BIT20
+#define DATAPRNT BIT21
+
+
+#define CMDCOMP BIT0
+#define TRNSCOMP BIT1
+#define RDYFORWT BIT4
+#define RDYFORRD BIT5
+#define CARDINSERT BIT6
+#define CARDREMOVE BIT7
+#define ERRINT BIT15
+#define CMDTOUTERR BIT16
+#define CMDCRCERR BIT17
+#define CMDEBITERR BIT18
+#define CMDIDXERR BIT19
+#define DATATOUTERR BIT20
+#define DATACRCERR BIT21
+#define DATAEBITERR BIT22
+
+#define HCS BIT30 //Host capacity support/1 = Supporting high capacity
+
+
+
+/* Command Definitions */
+#define INDX(CMD_INDX) (CMD_INDX & 0x3F)
+
+#define CMD0 INDX(0)
+#define CMD0_INT_EN (CMDCOMP | CMDEBITERR)
+
+#define CMD1 (INDX(1) | RSPTYP48)
+#define CMD1_INT_EN (CMDCOMP | CMDEBITERR | CMDTOUTERR)
+
+#define CMD2 (INDX(2) | ENCMDCRC | RSPTYP136)
+#define CMD2_INT_EN (CMDIDXERR | CMDCRCERR | CMDCOMP | CMDEBITERR | CMDTOUTERR)
+
+#define CMD3 (INDX(3) | ENCMDIDX | ENCMDCRC | RSPTYP48)
+#define CMD3_INT_EN (CMDIDXERR | CMDCRCERR | CMDCOMP | CMDEBITERR | CMDTOUTERR)
+
+#define CMD5 (INDX(5) | RSPTYP48)
+#define CMD5_INT_EN (CMDCOMP | CMDEBITERR | CMDTOUTERR)
+
+#define CMD7 (INDX(7) | ENCMDIDX | ENCMDCRC | RSPTYP48)
+#define CMD7_INT_EN (CMDIDXERR | CMDCRCERR | CMDCOMP | CMDEBITERR | CMDTOUTERR)
+
+//#define CMD8 (INDX(8) | ENCMDIDX | ENCMDCRC | RSPTYP48)
+#define CMD8 (INDX(8) | ENCMDIDX | RSPTYP48)
+#define CMD8_INT_EN (CMDIDXERR | CMDCRCERR | CMDCOMP | CMDEBITERR | CMDTOUTERR)
+//Reserved(0)[12:31], Supply voltage(1)[11:8], check pattern(0xCE)[7:0] = 0x1CE
+//#define CMD8_ARG (0x0UL << 12 | BIT8 | 0xCEUL << 0)
+#define CMD8_ARG (0x0UL << 12 | BIT8 | 0xAAUL << 0)
+
+#define CMD9 (INDX(9) | ENCMDCRC | RSPTYP136)
+#define CMD9_INT_EN (CMDCRCERR | CMDCOMP | CMDEBITERR | CMDTOUTERR)
+
+#define CMD13 (INDX(13) | RSPTYP48)
+#define CMD13_INT_EN (CMDCOMP | CMDEBITERR | CMDTOUTERR)
+
+
+//#define CMD16 (INDX(16) | ENCMDIDX | ENCMDCRC | RSPTYP48)
+#define CMD16 (INDX(16) | ENCMDIDX | RSPTYP48)
+#define CMD16_INT_EN (CMDIDXERR | CMDCRCERR | CMDCOMP | CMDEBITERR | CMDTOUTERR)
+
+#define CMD17 (INDX(17) | DATAPRNT | ENCMDIDX | ENCMDCRC | RSPTYP48 | RD1WT0)
+#define CMD17_INT_EN (CMDIDXERR | CMDCRCERR | CMDCOMP | TRNSCOMP | RDYFORRD | CMDTOUTERR | DATATOUTERR | DATACRCERR | DATAEBITERR | CMDEBITERR)
+
+//#define CMD18 (INDX(18) | DATAPRNT | ENCMDIDX | ENCMDCRC | RSPTYP48 | MUL1SIN0 | RD1WT0 | ENBLKCNT | ENDMA)
+#define CMD18 (INDX(18) | DATAPRNT | ENCMDIDX | ENCMDCRC | RSPTYP48 )
+#define CMD18_INT_EN (CMDIDXERR | CMDCRCERR | CMDCOMP | TRNSCOMP | RDYFORRD | CMDTOUTERR | DATATOUTERR | DATACRCERR | DATAEBITERR | CMDEBITERR)
+
+#define CMD23 (INDX(23) | ENCMDIDX | ENCMDCRC | RSPTYP48)
+#define CMD23_INT_EN (CMDIDXERR | CMDCRCERR | CMDCOMP | CMDEBITERR | CMDTOUTERR)
+
+#define CMD24 (INDX(24) | DATAPRNT | ENCMDIDX | ENCMDCRC | RSPTYP48)
+#define CMD24_INT_EN (CMDIDXERR | CMDCRCERR | CMDCOMP | TRNSCOMP | RDYFORWT | CMDTOUTERR | DATATOUTERR | DATACRCERR | DATAEBITERR | CMDEBITERR)
+
+//#define CMD25 (INDX(25) | DATAPRNT | ENCMDIDX | ENCMDCRC | RSPTYP48 | MUL1SIN0 | ENBLKCNT | ENDMA)
+#define CMD25 (INDX(25) | DATAPRNT | ENCMDIDX | ENCMDCRC | RSPTYP48)
+#define CMD25_INT_EN (CMDIDXERR | CMDCRCERR | CMDCOMP | TRNSCOMP | RDYFORWT | CMDTOUTERR | DATATOUTERR | DATACRCERR | DATAEBITERR | CMDEBITERR)
+
+//#define CMD55 (INDX(55) | ENCMDIDX | ENCMDCRC | RSPTYP48)
+#define CMD55 (INDX(55) | ENCMDIDX | RSPTYP48)
+#define CMD55_INT_EN (CMDIDXERR | CMDCRCERR | CMDCOMP | CMDEBITERR | CMDTOUTERR)
+
+#define ACMD41 (INDX(41) | RSPTYP48)
+#define ACMD41_INT_EN (CMDIDXERR | CMDCRCERR | CMDCOMP | CMDEBITERR | CMDTOUTERR)
+
+#define ACMD6 (INDX(6) | RSPTYP48)
+#define ACMD6_INT_EN (CMDIDXERR | CMDCRCERR | CMDCOMP | CMDEBITERR | CMDTOUTERR)
+
+#define CMD62 (INDX(62) | RSPTYP48)
+#define CMD62_INT_EN (CMDIDXERR | CMDCRCERR | CMDCOMP | CMDEBITERR | CMDTOUTERR)
+
+
+
+/*
+EFI_STATUS
+EFI_SUCCESS 0
+
+EFI_LOAD_ERROR 1
+EFI_INVALID_PARAMETER 2
+EFI_UNSUPPORTED 3
+EFI_BAD_BUFFER_SIZE 4
+EFI_BUFFER_TOO_SMALL 5
+EFI_NOT_READY 6
+EFI_DEVICE_ERROR 7
+EFI_WRITE_PROTECTED 8
+EFI_OUT_OF_RESOURCES 9
+EFI_VOLUME_CORRUPTED 10
+EFI_VOLUME_FULL 11
+EFI_NO_MEDIA 12
+EFI_MEDIA_CHANGED 13
+EFI_NOT_FOUND 14
+EFI_ACCESS_DENIED 15
+EFI_NO_RESPONSE 16
+EFI_NO_MAPPING 17
+EFI_TIMEOUT 18
+EFI_NOT_STARTED 19
+EFI_ALREADY_STARTED 20
+EFI_ABORTED 21
+EFI_ICMO_ERROR 22
+EFI_TFTP_ERROR 23
+EFI_PROTOCOL_ERROR 24
+EFI_INCOMPATIBLE_VERSION 25
+EFI_SECURITY_VIOLATION 26
+EFI_CRC_ERROR 27
+EFI_END_OF_MEDIA 28
+EFI_END_OF_FILE 31
+EFI_INVALID_LANGUAGE 32
+EFI_COMPROMISED_DATA 33
+
+
+*/
+
+#endif
+
diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/TimerDxe/TimerDxe.c b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/TimerDxe/TimerDxe.c
new file mode 100644
index 000000000..4eab280e6
--- /dev/null
+++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/TimerDxe/TimerDxe.c
@@ -0,0 +1,469 @@
+/** @file
+ Template for Timer Architecture Protocol driver of the ARM flavor
+
+ Copyright (c) 2012, Samsung Electronics Co. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+
+#include <PiDxe.h>
+
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiLib.h>
+#include <Library/PcdLib.h>
+#include <Library/IoLib.h>
+
+#include <Protocol/Timer.h>
+#include <Protocol/HardwareInterrupt.h>
+
+#include <Library/ExynosTimerLib.h>
+#include <Platform/ArmPlatform.h>
+
+// The notification function to call on every timer interrupt.
+volatile EFI_TIMER_NOTIFY mTimerNotifyFunction = (EFI_TIMER_NOTIFY)NULL;
+EFI_EVENT EfiExitBootServicesEvent = (EFI_EVENT)NULL;
+
+// The current period of the timer interrupt
+volatile UINT64 mTimerPeriod = 0;
+
+// Cached copy of the Hardware Interrupt protocol instance
+EFI_HARDWARE_INTERRUPT_PROTOCOL *gInterrupt = NULL;
+
+// Cached interrupt vector
+UINTN gVector;
+
+UINT32 mLastTickCount;
+
+/**
+
+ C Interrupt Handler called in the interrupt context when Source interrupt is active.
+
+
+ @param Source Source of the interrupt. Hardware routing off a specific platform defines
+ what source means.
+
+ @param SystemContext Pointer to system register context. Mostly used by debuggers and will
+ update the system context after the return from the interrupt if
+ modified. Don't change these values unless you know what you are doing
+
+**/
+VOID
+EFIAPI
+TimerInterruptHandler (
+ IN HARDWARE_INTERRUPT_SOURCE Source,
+ IN EFI_SYSTEM_CONTEXT SystemContext
+ )
+{
+ EFI_TPL OriginalTPL;
+ UINT32 Tmp;
+ UINT32 PWMTimerBase;
+
+
+ PWMTimerBase=PcdGet32(PcdPWMTimerBase);
+ //DEBUG ((EFI_D_ERROR, "PWM Timer INT Occur\n"));
+ //
+ // DXE core uses this callback for the EFI timer tick. The DXE core uses locks
+ // that raise to TPL_HIGH and then restore back to current level. Thus we need
+ // to make sure TPL level is set to TPL_HIGH while we are handling the timer tick.
+ //
+ OriginalTPL = gBS->RaiseTPL (TPL_HIGH_LEVEL);
+
+ // clear the periodic interrupt
+ Tmp = MmioRead32 (PWMTimerBase + PWM_TINT_CSTAT_OFFSET);
+ MmioWrite32 ((PWMTimerBase + PWM_TINT_CSTAT_OFFSET), Tmp);
+
+ // signal end of interrupt early to help avoid losing subsequent ticks from long duration handlers
+ gInterrupt->EndOfInterrupt (gInterrupt, Source);
+
+ if (mTimerNotifyFunction) {
+ mTimerNotifyFunction (mTimerPeriod);
+ }
+
+ gBS->RestoreTPL (OriginalTPL);
+}
+
+/**
+ This function registers the handler NotifyFunction so it is called every time
+ the timer interrupt fires. It also passes the amount of time since the last
+ handler call to the NotifyFunction. If NotifyFunction is NULL, then the
+ handler is unregistered. If the handler is registered, then EFI_SUCCESS is
+ returned. If the CPU does not support registering a timer interrupt handler,
+ then EFI_UNSUPPORTED is returned. If an attempt is made to register a handler
+ when a handler is already registered, then EFI_ALREADY_STARTED is returned.
+ If an attempt is made to unregister a handler when a handler is not registered,
+ then EFI_INVALID_PARAMETER is returned. If an error occurs attempting to
+ register the NotifyFunction with the timer interrupt, then EFI_DEVICE_ERROR
+ is returned.
+
+ @param This The EFI_TIMER_ARCH_PROTOCOL instance.
+ @param NotifyFunction The function to call when a timer interrupt fires. This
+ function executes at TPL_HIGH_LEVEL. The DXE Core will
+ register a handler for the timer interrupt, so it can know
+ how much time has passed. This information is used to
+ signal timer based events. NULL will unregister the handler.
+ @retval EFI_SUCCESS The timer handler was registered.
+ @retval EFI_UNSUPPORTED The platform does not support timer interrupts.
+ @retval EFI_ALREADY_STARTED NotifyFunction is not NULL, and a handler is already
+ registered.
+ @retval EFI_INVALID_PARAMETER NotifyFunction is NULL, and a handler was not
+ previously registered.
+ @retval EFI_DEVICE_ERROR The timer handler could not be registered.
+
+**/
+EFI_STATUS
+EFIAPI
+TimerDriverRegisterHandler (
+ IN EFI_TIMER_ARCH_PROTOCOL *This,
+ IN EFI_TIMER_NOTIFY NotifyFunction
+ )
+{
+ if ((NotifyFunction == NULL) && (mTimerNotifyFunction == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if ((NotifyFunction != NULL) && (mTimerNotifyFunction != NULL)) {
+ return EFI_ALREADY_STARTED;
+ }
+
+ DEBUG ((EFI_D_ERROR, "++TimerDriverRegisterHandler\n"));
+ mTimerNotifyFunction = NotifyFunction;
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Make sure all ArrmVe Timers are disabled
+**/
+VOID
+EFIAPI
+ExitBootServicesEvent (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ UINT32 PWMTimerBase;
+
+ PWMTimerBase=PcdGet32(PcdPWMTimerBase);
+ // All PWM timer is off
+ MmioWrite32 ((PWMTimerBase + PWM_TCON_OFFSET), 0);
+}
+
+/**
+
+ This function adjusts the period of timer interrupts to the value specified
+ by TimerPeriod. If the timer period is updated, then the selected timer
+ period is stored in EFI_TIMER.TimerPeriod, and EFI_SUCCESS is returned. If
+ the timer hardware is not programmable, then EFI_UNSUPPORTED is returned.
+ If an error occurs while attempting to update the timer period, then the
+ timer hardware will be put back in its state prior to this call, and
+ EFI_DEVICE_ERROR is returned. If TimerPeriod is 0, then the timer interrupt
+ is disabled. This is not the same as disabling the CPU's interrupts.
+ Instead, it must either turn off the timer hardware, or it must adjust the
+ interrupt controller so that a CPU interrupt is not generated when the timer
+ interrupt fires.
+
+ @param This The EFI_TIMER_ARCH_PROTOCOL instance.
+ @param TimerPeriod The rate to program the timer interrupt in 100 nS units. If
+ the timer hardware is not programmable, then EFI_UNSUPPORTED is
+ returned. If the timer is programmable, then the timer period
+ will be rounded up to the nearest timer period that is supported
+ by the timer hardware. If TimerPeriod is set to 0, then the
+ timer interrupts will be disabled.
+
+
+ @retval EFI_SUCCESS The timer period was changed.
+ @retval EFI_UNSUPPORTED The platform cannot change the period of the timer interrupt.
+ @retval EFI_DEVICE_ERROR The timer period could not be changed due to a device error.
+
+**/
+EFI_STATUS
+EFIAPI
+TimerDriverSetTimerPeriod (
+ IN EFI_TIMER_ARCH_PROTOCOL *This,
+ IN UINT64 TimerPeriod
+ )
+{
+ EFI_STATUS Status;
+ UINT64 TimerTicks;
+ UINT32 Tmp;
+ UINT32 PWMTimerBase;
+
+ PWMTimerBase=PcdGet32(PcdPWMTimerBase);
+ // Stop PWM timer 0
+ Tmp = MmioRead32 (PWMTimerBase + PWM_TCON_OFFSET);
+ Tmp &= ~(0x1F << 0);
+ MmioWrite32 ((PWMTimerBase + PWM_TCON_OFFSET) ,Tmp);
+
+ if (TimerPeriod == 0) {
+ // leave timer disabled from above, and...
+ Tmp = MmioRead32 (PWMTimerBase + PWM_TINT_CSTAT_OFFSET);
+ Tmp &= ~(1 << 0);
+ MmioWrite32 ((PWMTimerBase + PWM_TINT_CSTAT_OFFSET), Tmp);
+ // disable timer 0/1 interrupt for a TimerPeriod of 0
+ Status = gInterrupt->DisableInterruptSource (gInterrupt, gVector);
+ } else {
+ // Convert TimerPeriod into 1MHz clock counts (us units = 100ns units / 10)
+ TimerTicks = DivU64x32 (TimerPeriod, 10);
+ // if it's larger than 32-bits, pin to highest value
+ if (TimerTicks > 0xffffffff) {
+ TimerTicks = 0xffffffff;
+ }
+
+ // PWM Timer 0 used by Period counter with Auto re-load mode
+ MmioWrite32 ((PWMTimerBase + PWM_TCNTB0_OFFSET), TimerTicks);
+ // Set and Clear PWM Manually update for Timer 0
+ Tmp = MmioRead32 (PWMTimerBase + PWM_TCON_OFFSET);
+ Tmp |= (0x2 << 0);
+ MmioWrite32 ((PWMTimerBase + PWM_TCON_OFFSET), Tmp);
+ Tmp &= ~(0x2 << 0);
+ MmioWrite32 ((PWMTimerBase + PWM_TCON_OFFSET), Tmp);
+ // Set Auto re-load and start Timer
+ Tmp |= (0x9 << 0);
+ MmioWrite32 ((PWMTimerBase + PWM_TCON_OFFSET), Tmp);
+
+ // enable PWM Timer 0 interrupts
+ Tmp = MmioRead32 (PWMTimerBase + PWM_TINT_CSTAT_OFFSET);
+ Tmp |= (1 << 0);
+ MmioWrite32 ((PWMTimerBase + PWM_TINT_CSTAT_OFFSET), Tmp);
+
+ Status = gInterrupt->EnableInterruptSource (gInterrupt, gVector);
+ }
+
+ // Save the new timer period
+ mTimerPeriod = TimerPeriod;
+ return Status;
+}
+
+/**
+ This function retrieves the period of timer interrupts in 100 ns units,
+ returns that value in TimerPeriod, and returns EFI_SUCCESS. If TimerPeriod
+ is NULL, then EFI_INVALID_PARAMETER is returned. If a TimerPeriod of 0 is
+ returned, then the timer is currently disabled.
+
+ @param This The EFI_TIMER_ARCH_PROTOCOL instance.
+ @param TimerPeriod A pointer to the timer period to retrieve in 100 ns units. If
+ 0 is returned, then the timer is currently disabled.
+
+
+ @retval EFI_SUCCESS The timer period was returned in TimerPeriod.
+ @retval EFI_INVALID_PARAMETER TimerPeriod is NULL.
+
+**/
+EFI_STATUS
+EFIAPI
+TimerDriverGetTimerPeriod (
+ IN EFI_TIMER_ARCH_PROTOCOL *This,
+ OUT UINT64 *TimerPeriod
+ )
+{
+ if (TimerPeriod == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ *TimerPeriod = mTimerPeriod;
+ return EFI_SUCCESS;
+}
+
+/**
+ This function generates a soft timer interrupt. If the platform does not support soft
+ timer interrupts, then EFI_UNSUPPORTED is returned. Otherwise, EFI_SUCCESS is returned.
+ If a handler has been registered through the EFI_TIMER_ARCH_PROTOCOL.RegisterHandler()
+ service, then a soft timer interrupt will be generated. If the timer interrupt is
+ enabled when this service is called, then the registered handler will be invoked. The
+ registered handler should not be able to distinguish a hardware-generated timer
+ interrupt from a software-generated timer interrupt.
+
+ @param This The EFI_TIMER_ARCH_PROTOCOL instance.
+
+ @retval EFI_SUCCESS The soft timer interrupt was generated.
+ @retval EFI_UNSUPPORTED The platform does not support the generation of soft timer interrupts.
+
+**/
+EFI_STATUS
+EFIAPI
+TimerDriverGenerateSoftInterrupt (
+ IN EFI_TIMER_ARCH_PROTOCOL *This
+ )
+{
+ return EFI_UNSUPPORTED;
+}
+
+/**
+ Interface structure for the Timer Architectural Protocol.
+
+ @par Protocol Description:
+ This protocol provides the services to initialize a periodic timer
+ interrupt, and to register a handler that is called each time the timer
+ interrupt fires. It may also provide a service to adjust the rate of the
+ periodic timer interrupt. When a timer interrupt occurs, the handler is
+ passed the amount of time that has passed since the previous timer
+ interrupt.
+
+ @param RegisterHandler
+ Registers a handler that will be called each time the
+ timer interrupt fires. TimerPeriod defines the minimum
+ time between timer interrupts, so TimerPeriod will also
+ be the minimum time between calls to the registered
+ handler.
+
+ @param SetTimerPeriod
+ Sets the period of the timer interrupt in 100 nS units.
+ This function is optional, and may return EFI_UNSUPPORTED.
+ If this function is supported, then the timer period will
+ be rounded up to the nearest supported timer period.
+
+
+ @param GetTimerPeriod
+ Retrieves the period of the timer interrupt in 100 nS units.
+
+ @param GenerateSoftInterrupt
+ Generates a soft timer interrupt that simulates the firing of
+ the timer interrupt. This service can be used to invoke the registered handler if the timer interrupt has been masked for
+ a period of time.
+
+**/
+EFI_TIMER_ARCH_PROTOCOL gTimer = {
+ TimerDriverRegisterHandler,
+ TimerDriverSetTimerPeriod,
+ TimerDriverGetTimerPeriod,
+ TimerDriverGenerateSoftInterrupt
+};
+
+
+/**
+ Initialize the state information for the Timer Architectural Protocol and
+ the Timer Debug support protocol that allows the debugger to break into a
+ running program.
+
+ @param ImageHandle of the loaded driver
+ @param SystemTable Pointer to the System Table
+
+ @retval EFI_SUCCESS Protocol registered
+ @retval EFI_OUT_OF_RESOURCES Cannot allocate protocol data structure
+ @retval EFI_DEVICE_ERROR Hardware problems
+
+**/
+EFI_STATUS
+EFIAPI
+TimerInitialize (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_HANDLE Handle = NULL;
+ EFI_STATUS Status;
+
+ UINT32 Tmp;
+ UINT32 PWMTimerBase;
+
+ PWMTimerBase=PcdGet32(PcdPWMTimerBase);
+ // Find the interrupt controller protocol. ASSERT if not found.
+ Status = gBS->LocateProtocol (&gHardwareInterruptProtocolGuid, NULL, (VOID **)&gInterrupt);
+ ASSERT_EFI_ERROR (Status);
+
+ // Timer Source : SCLK_MPLL(800Mhz)
+ Tmp = MmioRead32(0x10020250);
+ Tmp &= ~(0xF << 24);
+ Tmp |= (0x6 << 24);
+ MmioWrite32(0x10020250, Tmp);
+ // Timer 0,1,2 prescale:0x02(/(0x02+1)) => 266666666hz (at least 0x01+1)
+ Tmp = MmioRead32(PWMTimerBase + PWM_TCFG0_OFFSET);
+ Tmp &= ~((0xFF << 8) + (0xFF << 0));
+ Tmp |= (0x02 << 8) + (0x02 << 0);
+ MmioWrite32 ((PWMTimerBase + PWM_TCFG0_OFFSET), Tmp);
+ // Timer 0,1,2 divider:0x2(/4) => 66666666hz
+ MmioWrite32 ((PWMTimerBase + PWM_TCFG1_OFFSET), (0x2 << 2) + (0x2 << 1) + (0x2 << 0));
+/*
+ // PWM Input source clock is 100Mhz and Configure 1Mhz for PWM Timer
+ Tmp = MmioRead32 (PWMTimerBase + PWM_TCFG0_OFFSET);
+ Tmp &= ~(0xFF << 0);
+ Tmp |= (0x63 << 0);
+ MmioWrite32 ((PWMTimerBase + PWM_TCFG0_OFFSET), Tmp);
+ MmioWrite32 ((PWMTimerBase + PWM_TCFG1_OFFSET), 0x0);
+*/
+ //Timer 1 INT disable
+ Tmp = MmioRead32 (PWMTimerBase + PWM_TINT_CSTAT_OFFSET);
+ Tmp &= ~(1 << 1);
+ MmioWrite32 ((PWMTimerBase + PWM_TINT_CSTAT_OFFSET), Tmp);
+
+ // configure timer 1 Stop
+ Tmp = MmioRead32 (PWMTimerBase + PWM_TCON_OFFSET);
+ Tmp &= ~(0xF << 8);
+ MmioWrite32 ((PWMTimerBase + PWM_TCON_OFFSET), Tmp);
+
+ // PWM Timer 1 used by Free running counter with Auto re-load mode
+ MmioWrite32 ((PWMTimerBase + PWM_TCNTB1_OFFSET), 0xFFFFFFFF);
+ // Set and Clear PWM Manually update for Timer 1
+ Tmp = MmioRead32 (PWMTimerBase + PWM_TCON_OFFSET);
+ Tmp |= (0x2 << 8);
+ MmioWrite32 ((PWMTimerBase + PWM_TCON_OFFSET), Tmp);
+ Tmp &= ~(0x2 << 8);
+ MmioWrite32 ((PWMTimerBase + PWM_TCON_OFFSET), Tmp);
+ // Set Auto re-load and start Timer
+ Tmp |= (0x9 << 8);
+ MmioWrite32 ((PWMTimerBase + PWM_TCON_OFFSET), Tmp);
+
+ // Install interrupt handler
+ gVector = PWM_TIMER0_INTERRUPT_NUM;
+ Status = gInterrupt->RegisterInterruptSource (gInterrupt, gVector, TimerInterruptHandler);
+ ASSERT_EFI_ERROR (Status);
+
+ // Disable the timer
+ Status = TimerDriverSetTimerPeriod (&gTimer, 0);
+ ASSERT_EFI_ERROR (Status);
+
+ // PWM Timer 0 make to stop
+ Tmp = MmioRead32 (PWMTimerBase + PWM_TCON_OFFSET);
+ Tmp &= ~(0x1F << 0);
+ MmioWrite32 ((PWMTimerBase + PWM_TCON_OFFSET), Tmp);
+
+ // PWM Timer 0 INT disable
+ Tmp = MmioRead32 (PWMTimerBase + PWM_TINT_CSTAT_OFFSET);
+ Tmp &= ~(1 << 0);
+ MmioWrite32 ((PWMTimerBase + PWM_TINT_CSTAT_OFFSET), Tmp);
+
+ // PWM Timer 0 used by Period counter with Auto re-load mode
+ MmioWrite32 ((PWMTimerBase + PWM_TCNTB0_OFFSET), FixedPcdGet32(PcdTimerPeriod));
+ Status = TimerDriverSetTimerPeriod (&gTimer, FixedPcdGet32(PcdTimerPeriod));
+ ASSERT_EFI_ERROR (Status);
+
+ // Set and Clear PWM Manually update for Timer 0
+ Tmp = MmioRead32 (PWMTimerBase + PWM_TCON_OFFSET);
+ Tmp |= (0x2 << 0);
+ MmioWrite32 ((PWMTimerBase + PWM_TCON_OFFSET), Tmp);
+ Tmp &= ~(0x2 << 0);
+ MmioWrite32 ((PWMTimerBase + PWM_TCON_OFFSET), Tmp);
+ // Set Auto re-load and start Timer
+ Tmp |= (0x9 << 0);
+ MmioWrite32 ((PWMTimerBase + PWM_TCON_OFFSET), Tmp);
+
+ //PWM Timer0 INT enable
+ Tmp = MmioRead32 (PWMTimerBase + PWM_TINT_CSTAT_OFFSET);
+ Tmp |= (1 << 0);
+ MmioWrite32 ((PWMTimerBase + PWM_TINT_CSTAT_OFFSET), Tmp);
+
+ // Install the Timer Architectural Protocol onto a new handle
+ Status = gBS->InstallMultipleProtocolInterfaces(
+ &Handle,
+ &gEfiTimerArchProtocolGuid, &gTimer,
+ NULL
+ );
+ ASSERT_EFI_ERROR(Status);
+
+ // Register for an ExitBootServicesEvent
+ Status = gBS->CreateEvent (EVT_SIGNAL_EXIT_BOOT_SERVICES, TPL_NOTIFY, ExitBootServicesEvent, NULL, &EfiExitBootServicesEvent);
+ ASSERT_EFI_ERROR (Status);
+
+ return Status;
+}
diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/TimerDxe/TimerDxe.inf b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/TimerDxe/TimerDxe.inf
new file mode 100644
index 000000000..019d84477
--- /dev/null
+++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/TimerDxe/TimerDxe.inf
@@ -0,0 +1,54 @@
+#/** @file
+#
+# Component discription file for Timer module
+#
+# Copyright (c) 2012, Samsung Electronics Co. All rights reserved.<BR>
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#**/
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = TimerDxe
+ FILE_GUID = 494ffd22-3228-4b7e-ad40-7e780fa88301
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+
+ ENTRY_POINT = TimerInitialize
+
+[Sources.common]
+ TimerDxe.c
+
+[Packages]
+ SamsungPlatformPkg/ExynosPkg/Exynos5250/ExynosPkg.dec
+ MdePkg/MdePkg.dec
+ EmbeddedPkg/EmbeddedPkg.dec
+ ArmPkg/ArmPkg.dec
+ ArmPlatformPkg/ArmPlatformPkg.dec
+
+
+[LibraryClasses]
+ BaseLib
+ IoLib
+ UefiBootServicesTableLib
+ UefiDriverEntryPoint
+ TimerLib
+
+[Guids]
+
+[Protocols]
+ gEfiTimerArchProtocolGuid
+ gHardwareInterruptProtocolGuid
+
+
+[Pcd.common]
+ gEmbeddedTokenSpaceGuid.PcdTimerPeriod
+ gExynosPkgTokenSpaceGuid.PcdPWMTimerBase
+[Depex]
+ gHardwareInterruptProtocolGuid
diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/eMMCDxe/eMMCDxe.c b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/eMMCDxe/eMMCDxe.c
new file mode 100755
index 000000000..87f937924
--- /dev/null
+++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/eMMCDxe/eMMCDxe.c
@@ -0,0 +1,1378 @@
+/** @file
+ MMC/SD Card driver for Secure Digital Host Controller
+
+ This driver always produces a BlockIo protocol but it starts off with no Media
+ present. A TimerCallBack detects when media is inserted or removed and after
+ a media change event a call to BlockIo ReadBlocks/WriteBlocks will cause the
+ media to be detected (or removed) and the BlockIo Media structure will get
+ updated. No MMC/SD Card harward registers are updated until the first BlockIo
+ ReadBlocks/WriteBlocks after media has been insterted (booting with a card
+ plugged in counts as an insertion event).
+
+ Copyright (c) 2012, Samsung Electronics Co. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+
+#include <Library/TimerLib.h>
+#include <Library/PcdLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Protocol/ExynosGpio.h>
+#include <Platform/ArmPlatform.h>
+#include <Platform/Exynos5250.h>
+#include <Platform/Arndale5250.h>
+
+#include "eMMCDxe.h"
+
+
+
+#define DateInformation "20120723_007"
+
+
+MSHC_OPERATION_MODE MSHC_operation_mode=MSHC_FIFO;
+//MSHC_OPERATION_MODE MSHC_operation_mode=MSHC_IDMA;
+
+
+//#undef EFI_D_INFO
+//#define EFI_D_INFO 1
+
+
+
+CARD_INFO gCardInfo;
+BOOLEAN gMediaChange = TRUE;
+BOOLEAN gCardInit = FALSE;
+
+
+EFI_BLOCK_IO_MEDIA gSDMMCMedia = {
+ SIGNATURE_32('e','m','m','c'), // MediaId
+ FALSE, // RemovableMedia
+ TRUE, // MediaPresent
+ FALSE, // LogicalPartition
+ FALSE, // ReadOnly
+ FALSE, // WriteCaching
+ 512, // BlockSize
+ 4, // IoAlign
+ 0, // Pad
+ 0 // LastBlock
+};
+
+typedef struct {
+ VENDOR_DEVICE_PATH Mmc;
+ EFI_DEVICE_PATH End;
+} MSHC_DEVICE_PATH;
+
+MSHC_DEVICE_PATH gMSHCDevicePath = {
+ {
+ HARDWARE_DEVICE_PATH,
+ HW_VENDOR_DP,
+ (UINT8)(sizeof(VENDOR_DEVICE_PATH)),
+ (UINT8)((sizeof(VENDOR_DEVICE_PATH)) >> 8),
+ 0xb615f1f5, 0x5088, 0x43cd, 0x80, 0x9c, 0xa1, 0x6e, 0x52, 0x48, 0x7d, 0x00
+ },
+ {
+ END_DEVICE_PATH_TYPE,
+ END_ENTIRE_DEVICE_PATH_SUBTYPE,
+ sizeof (EFI_DEVICE_PATH_PROTOCOL),
+ 0
+ }
+};
+
+
+
+//
+// Internal Functions
+//
+
+
+
+
+VOID
+ParseCardCIDData (
+ UINT32 Response0,
+ UINT32 Response1,
+ UINT32 Response2,
+ UINT32 Response3
+ )
+{
+ gCardInfo.CIDData.MDT = ((Response0 >> 8) & 0xFFF);
+ gCardInfo.CIDData.PSN = (((Response0 >> 24) & 0xFF) | ((Response1 & 0xFFFFFF) << 8));
+ gCardInfo.CIDData.PRV = ((Response1 >> 24) & 0xFF);
+ gCardInfo.CIDData.PNM[4] = ((Response2) & 0xFF);
+ gCardInfo.CIDData.PNM[3] = ((Response2 >> 8) & 0xFF);
+ gCardInfo.CIDData.PNM[2] = ((Response2 >> 16) & 0xFF);
+ gCardInfo.CIDData.PNM[1] = ((Response2 >> 24) & 0xFF);
+ gCardInfo.CIDData.PNM[0] = ((Response3) & 0xFF);
+ gCardInfo.CIDData.OID = ((Response3 >> 8) & 0xFFFF);
+ gCardInfo.CIDData.MID = ((Response3 >> 24) & 0xFF);
+}
+
+
+EFI_STATUS
+MSHC_SendCmd (
+ UINTN Cmd,
+ UINTN CmdInterruptEnableVal,
+ UINTN CmdArgument
+ )
+{
+ UINTN MmcStatus = 0;
+ volatile UINTN RetryCount = 0;
+ int cmd_flags = 0;
+ int timeout=0;
+ UINT32 SdMmcBaseAddr;
+ //UINT32 MSHCRintStatus=0;
+
+ DEBUG ((EFI_D_INFO, "CMD = %d\n", (Cmd&0x3F)));
+
+ timeout = MAX_RETRY_COUNT;
+ SdMmcBaseAddr = PcdGet32(PcdSdMmcCH0Base);
+
+ //1. Check if Data busy or not
+ while(MmioRead32(SdMmcBaseAddr + MSHCI_STATUS) & (DATA_BUSY))
+ {
+ if (timeout == 0)
+ {
+ DEBUG ((EFI_D_ERROR, "MSHC::MSHC_SendCmd timeout : CMD = %d\n", Cmd));
+ return EFI_DEVICE_ERROR;
+ }
+ timeout--;
+ MicroSecondDelay(1);
+ }
+
+ // 2. Check if Raw interrupt is command done
+ /*MSHCRintStatus = MmioRead32(SdMmcBaseAddr + MSHCI_RINTSTS);
+ if ((MSHCRintStatus & (INTMSK_CDONE|INTMSK_ACD)) == 0)
+ {
+ DEBUG ((EFI_D_ERROR, "MSHC::MSHC_SendCmd interrupt error : INT = %x\n", MmioRead32(SdMmcBaseAddr + MSHCI_RINTSTS)));
+ } */
+
+ // 3. Clear Raw interrupt
+ MmioWrite32 ((SdMmcBaseAddr + MSHCI_RINTSTS), INTMSK_ALL);
+
+ // 4. prepare data
+ //mshci_reset_fifo();
+
+ //5. Set command argument register
+ MmioWrite32 ((SdMmcBaseAddr + MSHCI_CMDARG), CmdArgument);
+
+ // 6. transfer data
+
+ //Enable interrupt enable events to occur
+ // EVT1 do not need interrupt mask, use Raw interrupt
+ //MmioWrite32 ((SdMmcBaseAddr + MSHCI_INTMSK), CmdInterruptEnableVal);
+
+ // 7. trasfer data
+
+ //8. Send a command
+ cmd_flags = (Cmd & 0x3F);
+ if(Cmd & (RSPTYP48 | RSPTYP48B | RSPTYP136))
+ {
+ cmd_flags |= CMD_RESP_EXP_BIT;
+ if(Cmd & RSPTYP136)
+ cmd_flags |= CMD_RESP_LENGTH_BIT;
+ }
+
+ if((Cmd==CMD17)|(Cmd==CMD18)|(Cmd==CMD8))
+ {
+ cmd_flags |= CMD_DATA_EXP_BIT;
+ //DEBUG ((EFI_D_ERROR, "MSHC::MSHC_SendCmd Read\n"));
+ }
+
+ if((Cmd==CMD24)|(Cmd==CMD25))
+ {
+ cmd_flags |= CMD_DATA_EXP_BIT | CMD_RW_BIT;
+ //DEBUG ((EFI_D_ERROR, "MSHC::MSHC_SendCmd Write\n"));
+
+ }
+
+ if (Cmd & ENCMDCRC)
+ {
+ cmd_flags |= CMD_CHECK_CRC_BIT;
+ }
+ cmd_flags |= (CMD_STRT_BIT | CMD_USE_HOLD_REG | CMD_WAIT_PRV_DAT_BIT|CMD_SENT_AUTO_STOP_BIT);
+ //cmd_flags |= (CMD_STRT_BIT | CMD_USE_HOLD_REG | CMD_WAIT_PRV_DAT_BIT);
+ DEBUG ((EFI_D_INFO, "CMD flag = 0x%x\n", cmd_flags));
+ MmioWrite32 ((SdMmcBaseAddr + MSHCI_CMD), cmd_flags);
+ MicroSecondDelay(1);
+
+ //9. Check for the Raw interrupt
+ //wait for command complete by busy waiting.
+ for (RetryCount; RetryCount<MAX_RETRY_COUNT; RetryCount++)
+ {
+ MmcStatus = MmioRead32(SdMmcBaseAddr + MSHCI_RINTSTS);
+ if (MmcStatus & INTMSK_CDONE)
+ {
+ break;
+ }
+ }
+
+ if (RetryCount == MAX_RETRY_COUNT)
+ {
+ DEBUG ((EFI_D_ERROR, "MSHC::MSHC_SendCmd timeout CMD:%d RINT:0x%x\n",(Cmd&0x3F) ,MmcStatus));
+ return EFI_TIMEOUT;
+ }
+
+ if(MmcStatus & INTMSK_RTO)
+ {
+ DEBUG ((EFI_D_ERROR, "MSHC::MSHC_SendCmd Response timeout CMD:%d RINT:0x%x\n", (Cmd & 0x3F),MmcStatus));
+ return EFI_TIMEOUT;
+
+ }
+ else if (MmcStatus & INTMSK_RE)
+ {
+ DEBUG ((EFI_D_ERROR, "MSHC::MSHC_SendCmd Response Error RINT:0x%x\n", MmcStatus));
+ return EFI_TIMEOUT;
+ }
+ else if(MmcStatus & INTMSK_RCRC)
+ DEBUG ((EFI_D_ERROR, "MSHC::MSHC_SendCmd Response CRC Err RINT:0x%x\n", MmcStatus));
+ else if(MmcStatus & INTMSK_DCRC)
+ DEBUG ((EFI_D_ERROR, "MSHC::MSHC_SendCmd Data CRC Err RINT:0x%x\n", MmcStatus));
+ else if(MmcStatus & INTMSK_HLE)
+ DEBUG ((EFI_D_ERROR, "MSHC::MSHC_SendCmd HLE Err RINT:0x%x\n", MmcStatus));
+ else if(MmcStatus & INTMSK_SBE)
+ DEBUG ((EFI_D_ERROR, "MSHC::MSHC_SendCmd SBE Err RINT:0x%x\n", MmcStatus));
+ else if(MmcStatus & INTMSK_EBE)
+ DEBUG ((EFI_D_ERROR, "MSHC::MSHC_SendCmd EBE Err RINT:0x%x\n", MmcStatus));
+
+ return EFI_SUCCESS;
+}
+
+/**
+Super block size : 4MB (16GB density)
+Argument (Boot Size) =(Number of Super Block for boot partition) / 2
+
+**/
+EFI_STATUS MSHC_BOOT_Partition(UINT32 bootsize, UINT32 rpmbsize)
+{
+ UINTN CmdArgument;
+ EFI_STATUS Status = RETURN_SUCCESS;
+ UINT32 BootSize, RPMBSize;
+
+ /* Only use this command for raw eMMC moviNAND */
+ /* Enter backdoor mode */
+ CmdArgument = 0xefac62ec;
+ Status = MSHC_SendCmd (CMD62, CMD62_INT_EN, CmdArgument);
+
+ /* Boot partition changing mode */
+ CmdArgument = 0xcbaea7;
+ Status = MSHC_SendCmd (CMD62, CMD62_INT_EN, CmdArgument);
+
+ //BootSize = ((bootsize*1024)/128);
+ BootSize = (bootsize*2);
+
+ /* Arg: boot partition size */
+ CmdArgument = BootSize;
+ Status = MSHC_SendCmd (CMD62, CMD62_INT_EN, CmdArgument);
+
+ //RPMBSize = ((rpmbsize*1024)/128);
+ RPMBSize = (rpmbsize*2);
+
+ /* Arg: RPMB partition size */
+ CmdArgument = RPMBSize;
+ Status = MSHC_SendCmd (CMD62, CMD62_INT_EN, CmdArgument);
+
+ return Status;
+
+}
+
+EFI_STATUS MSHC_EMMC_Boot_Open()
+{
+ UINTN CmdArgument;
+ EFI_STATUS Status = RETURN_SUCCESS;
+
+ DEBUG ((EFI_D_INFO, "emmc open\n" ));
+ /* Boot ack enable, boot partition enable , boot partition access */
+ CmdArgument = ((3<<24)|(179<<16)|(((1<<6)|(1<<3)|(1<<0))<<8));
+ Status = MSHC_SendCmd (ACMD6, ACMD6_INT_EN, CmdArgument);
+ if (!EFI_ERROR(Status))
+ {
+ /* 4bit transfer mode at booting time. */
+ CmdArgument = ((3<<24)|(177<<16)|((1<<0)<<8));
+ Status = MSHC_SendCmd (ACMD6, ACMD6_INT_EN, CmdArgument);
+ if (EFI_ERROR(Status))
+ {
+ DEBUG ((EFI_D_ERROR, "emmc open fail 2nd CMD6\n" ));
+ }
+ }
+ else
+ {
+ DEBUG ((EFI_D_ERROR, "emmc open fail first CMD6\n" ));
+ }
+
+ return Status;
+}
+
+EFI_STATUS MSHC_EMMC_Boot_Close()
+{
+ UINTN CmdArgument;
+ EFI_STATUS Status = RETURN_SUCCESS;
+
+ DEBUG ((EFI_D_INFO, "emmc close\n" ));
+ CmdArgument = ((3<<24)|(179<<16)|(((1<<6)|(1<<3)|(0<<0))<<8));
+ Status = MSHC_SendCmd (ACMD6, ACMD6_INT_EN, CmdArgument);
+ if (EFI_ERROR(Status))
+ {
+ DEBUG ((EFI_D_ERROR, "emmc close fail \n" ));
+ }
+ return Status;
+}
+
+
+void PrintCardInfo()
+{
+ DEBUG ((EFI_D_INFO, "MSHC::READ_BL_LEN %d\n", gCardInfo.CSDData.READ_BL_LEN));
+ DEBUG ((EFI_D_INFO, "MSHC::CSize %d\n", gCardInfo.CSDData.C_SIZELow2 | (gCardInfo.CSDData.C_SIZEHigh10 << 2)));
+ DEBUG ((EFI_D_INFO, "MSHC::MULTI %d\n", gCardInfo.CSDData.C_SIZE_MULT));
+
+}
+
+
+#define EXT_CSD_SIZE 128
+UINT32 Ext_csd[EXT_CSD_SIZE];
+VOID GetEXTCSD()
+{
+ gCardInfo.NumBlocks = 0;
+ gCardInfo.TotalNumBlocks = 30801920;
+
+ UINTN cmdarg = 0;
+ EFI_STATUS Status = EFI_SUCCESS;
+
+ cmdarg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) |
+ (EXT_CSD_HS_TIMING << 16) |
+ (0 << 8);
+ Status = MSHC_SendCmd (ACMD6, ACMD6_INT_EN, cmdarg);
+
+ cmdarg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) |
+ (EXT_CSD_BUS_WIDTH << 16) |
+ (EXT_CSD_BUS_WIDTH_1 << 8);
+ Status = MSHC_SendCmd (ACMD6, ACMD6_INT_EN, cmdarg);
+
+ cmdarg = 0;
+ Status = MSHC_SendCmd (CMD8, CMD8_INT_EN, cmdarg);
+
+ gCardInfo.BlockSize = BLEN_512BYTES;
+
+ if (!EFI_ERROR(Status))
+ {
+ DEBUG ((EFI_D_INFO, "MSHC::EXT CSD \n"));
+ //PrepareTransfer(&Ext_csd[0], 1, READ);
+ //MSHC_ReadDMA(&Ext_csd[0], 1);
+ MSHC_ReadFIFO(EXT_CSD_SIZE, &Ext_csd[0]);
+ gCardInfo.NumBlocks = Ext_csd[EXT_CSD_SEC_CNT/4];
+ gCardInfo.Extcsd.boot_size_multi = Ext_csd[BOOT_SIZE_MULTI/4];
+ gCardInfo.Extcsd.boot_size_multi = (gCardInfo.Extcsd.boot_size_multi>>16)&0xff;
+ //MicroSecondDelay(5000);
+
+ DEBUG ((EFI_D_INFO, "MSHC::num blocks %d\n", gCardInfo.NumBlocks));
+ DEBUG ((1, "MSHC::eMMC Size:%dMB\n", (gCardInfo.NumBlocks/2048)));
+ DEBUG ((1, "MSHC::Boot partition Size:%dMB\n", ((gCardInfo.TotalNumBlocks-gCardInfo.NumBlocks)/2048)));
+ DEBUG ((EFI_D_INFO, "MSHC::Ext CSD boot block %d\n", (gCardInfo.Extcsd.boot_size_multi)));
+
+ }
+ else
+ {
+ gCardInfo.NumBlocks = 0x1D4C000;
+ DEBUG ((EFI_D_ERROR, "MSHC:: default block number : 0x1D4C000"));
+ }
+
+}
+
+
+EFI_STATUS
+PerformCardIdenfication (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ UINTN CmdArgument = 0;
+ //UINTN Response = 0;
+ //UINTN RetryCount = 0;
+ UINTN TempRes0,TempRes1,TempRes2,TempRes3;
+ //BOOLEAN SDCmd8Supported = FALSE;
+ UINT32 SdMmcBaseAddr;
+ int timeout = MAX_RETRY_COUNT;
+
+ SdMmcBaseAddr = PcdGet32(PcdSdMmcCH0Base);
+ gCardInfo.CardType = MMC_CARD;
+
+ //1. Send CMD0 command. go to IDLE
+ Status = MSHC_SendCmd (CMD0, CMD0_INT_EN, CmdArgument);
+
+ // 2. Send CMD1 while OCR is not busy and get OCR register
+ do {
+ CmdArgument = OCR_HCS | MMC_VDD_32_33 | MMC_VDD_33_34;
+ Status = MSHC_SendCmd (CMD1, CMD1_INT_EN, CmdArgument);
+
+ if (EFI_ERROR(Status))
+ {
+ DEBUG ((EFI_D_ERROR, "MSHC::CMD1 fails.\n"));
+ }
+
+ MicroSecondDelay(100);
+ } while (!(MmioRead32 (SdMmcBaseAddr + MSHCI_RESP0)& OCR_BUSY) && timeout--);
+
+ if (timeout <= 0)
+ {
+ DEBUG ((EFI_D_ERROR, "MSHC::CMD1 OCR busy timeout.\n"));
+ return EFI_DEVICE_ERROR;
+ }
+ DEBUG ((EFI_D_INFO, "MSHC::CMD1 OCR 0x%x\n", MmioRead32(SdMmcBaseAddr + MSHCI_RESP0)));
+
+ ((UINT32 *) &(gCardInfo.OCRData))[0] = MmioRead32 ((SdMmcBaseAddr + MSHCI_RESP0));
+
+ //3. send CMD2 to get CID register
+ CmdArgument = 0;
+ Status = MSHC_SendCmd (CMD2, CMD2_INT_EN, CmdArgument);
+ if (EFI_ERROR(Status)) {
+ DEBUG ((EFI_D_ERROR, "CMD2 fails. Status: %x\n", Status));
+ return Status;
+ }
+
+ DEBUG ((EFI_D_INFO, "CMD2 response: %x %x %x %x\n", MmioRead32 ((SdMmcBaseAddr + MSHCI_RESP0)), \
+ MmioRead32 ((SdMmcBaseAddr + MSHCI_RESP1)), \
+ MmioRead32 ((SdMmcBaseAddr + MSHCI_RESP2)), \
+ MmioRead32 ((SdMmcBaseAddr + MSHCI_RESP3))));
+
+ TempRes0 = MmioRead32 ((SdMmcBaseAddr + MSHCI_RESP0));
+ TempRes1 = MmioRead32 ((SdMmcBaseAddr + MSHCI_RESP1));
+ TempRes2 = MmioRead32 ((SdMmcBaseAddr + MSHCI_RESP2));
+ TempRes3 = MmioRead32 ((SdMmcBaseAddr + MSHCI_RESP3));
+
+ //Parse CID register data.
+ ParseCardCIDData(TempRes0 << 8, (TempRes1 << 8) | (TempRes0 >> 24),
+ (TempRes2 << 8) | (TempRes1 >> 24), (TempRes3 << 8) | (TempRes2 >> 24));
+
+ //4. send CMD3 to get RCA register
+ CmdArgument = 0;
+ Status = MSHC_SendCmd (CMD3, CMD3_INT_EN, CmdArgument);
+ if (EFI_ERROR(Status)) {
+ DEBUG ((EFI_D_ERROR, "CMD3 fails. Status: %x\n", Status));
+ return Status;
+ }
+
+ //Set RCA for the detected card. RCA is CMD3 response.
+ DEBUG ((EFI_D_INFO, "MSHC::CMD3 RCA 0x%x\n", MmioRead32(SdMmcBaseAddr + MSHCI_RESP0)));
+ gCardInfo.RCA = (MmioRead32 ((SdMmcBaseAddr + MSHCI_RESP0)) >> 16);
+ DEBUG ((EFI_D_INFO, "CMD3 response: RCA %x\n", gCardInfo.RCA));
+
+ gBS->Stall(1000); //Need Debug by wprkfgur
+
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+GetCardSpecificData (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ UINTN CmdArgument;
+ UINTN TempRes[4],i;
+ UINT32 SdMmcBaseAddr;
+
+ SdMmcBaseAddr = PcdGet32(PcdSdMmcCH0Base);
+
+ //Send CMD9 to retrieve CSD.
+ CmdArgument = gCardInfo.RCA << 16;
+ Status = MSHC_SendCmd (CMD9, CMD9_INT_EN, CmdArgument);
+ if (EFI_ERROR(Status)) {
+ DEBUG ((EFI_D_ERROR, "CMD9 fails. Status: %x\n", Status));
+ return Status;
+ }
+
+ TempRes[0] = MmioRead32 ((SdMmcBaseAddr + MSHCI_RESP0));
+ TempRes[1] = MmioRead32 ((SdMmcBaseAddr + MSHCI_RESP1));
+ TempRes[2] = MmioRead32 ((SdMmcBaseAddr + MSHCI_RESP2));
+ TempRes[3] = MmioRead32 ((SdMmcBaseAddr + MSHCI_RESP3));
+
+ //Populate 128-bit CSD register data.
+ for (i = 0 ; i < 4; i++) {
+ ((UINT32 *)&(gCardInfo.CSDData))[i] = TempRes[i];
+ }
+
+ DEBUG ((EFI_D_INFO, "CMD9 response: %x %x %x %x\n", ((UINT32 *)&(gCardInfo.CSDData))[0], ((UINT32 *)&(gCardInfo.CSDData))[1], ((UINT32 *)&(gCardInfo.CSDData))[2], ((UINT32 *)&(gCardInfo.CSDData))[3]));
+ return Status;
+}
+
+EFI_STATUS
+PerformCardConfiguration (
+ VOID
+ )
+{
+ UINTN CmdArgument = 0;
+ EFI_STATUS Status;
+ UINT32 SdMmcBaseAddr;
+ //UINTN FifoCount = 0;
+ //UINTN Count=0;
+ UINT32 OMval;
+
+ SdMmcBaseAddr = PcdGet32(PcdSdMmcCH0Base);
+ OMval = MmioRead32(0x10040000);
+ DEBUG ((EFI_D_INFO, "MSHC::OM read 0x%x \n", OMval));
+
+ //Send CMD7
+ CmdArgument = gCardInfo.RCA << 16;
+ Status = MSHC_SendCmd (CMD7, CMD7_INT_EN, CmdArgument);
+ if (EFI_ERROR(Status)) {
+ DEBUG ((EFI_D_ERROR, "CMD7 fails. Status: %x\n", Status));
+ return Status;
+ }
+
+ //Send CMD16 to set the block length
+ //CmdArgument = gCardInfo.BlockSize;
+ CmdArgument = BLEN_512BYTES;
+ Status = MSHC_SendCmd (CMD16, CMD16_INT_EN, CmdArgument);
+ if (EFI_ERROR(Status)) {
+ DEBUG ((EFI_D_ERROR, "CMD16 fails. Status: %x\n", Status));
+ return Status;
+ }
+
+ if(OMval!=OM_EMMC)
+ {
+ GetEXTCSD();
+ if(gCardInfo.Extcsd.boot_size_multi!= MSHC_BOOT_SIZE_MULTI)
+ {
+ MSHC_BOOT_Partition(MSHC_BOOT_SIZE, MSHC_RPMB_SIZE);
+ DEBUG ((EFI_D_INFO, "MSHC::Doing Boot partition \n"));
+ }
+ else
+ {
+ DEBUG ((EFI_D_INFO, "MSHC::Alread boot partition \n", Status));
+ }
+ }
+ else
+ {
+ DEBUG ((1, "MSHC::eMMC booting \n"));
+ gCardInfo.TotalNumBlocks = 30801920;
+ gCardInfo.NumBlocks = 30588928;
+ }
+
+ // set device into 4-bit data bus mode
+ //Status = MSHC_SendCmd (ACMD6, ACMD6_INT_EN, 0x2);
+ // set device into 8-bit data bus mode
+ CmdArgument = (MMC_SWITCH_MODE_WRITE_BYTE << 24) |
+ (EXT_CSD_BUS_WIDTH <<16) |
+ (EXT_CSD_BUS_WIDTH_8_DDR <<8);
+ Status = MSHC_SendCmd (ACMD6, ACMD6_INT_EN, CmdArgument);
+ if (!EFI_ERROR (Status)) {
+ // Set host controler into 8-bit mode
+ MmioOr32 ((SdMmcBaseAddr + MSHCI_CTYPE), CARD_WIDTH8);
+ //MmioOr32 ((SdMmcBaseAddr + MSHCI_CTYPE), CARD_WIDTH14);
+ DEBUG ((EFI_D_INFO, "8-bit mode\n"));
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+ReadBlockData (
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ OUT VOID *Buffer,
+ IN UINTN BlockCount
+ )
+{
+ EFI_STATUS Status = EFI_INVALID_PARAMETER;
+ UINTN DataSize = This->Media->BlockSize/4;
+
+ DEBUG ((EFI_D_INFO, "MSHC::ReadBlockData start \n"));
+
+ if(MSHC_operation_mode == MSHC_FIFO)
+ {
+ Status = MSHC_ReadFIFO(DataSize, Buffer);
+ }
+
+ else if(MSHC_operation_mode == MSHC_IDMA)
+ {
+ Status = MSHC_ReadDMA(Buffer, BlockCount);
+ }
+
+ return Status;
+}
+
+
+EFI_STATUS
+WriteBlockData (
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ OUT VOID *Buffer,
+ IN UINTN BlockCount
+ )
+{
+ EFI_STATUS Status = EFI_INVALID_PARAMETER;
+ UINTN DataSize = This->Media->BlockSize/4;
+
+ if(MSHC_operation_mode == MSHC_FIFO)
+ {
+ Status = MSHC_WriteFIFO(DataSize, Buffer);
+ }
+ else if(MSHC_operation_mode == MSHC_IDMA)
+ {
+ Status = MSHC_WriteDMA(Buffer, BlockCount);
+ }
+
+ return Status;
+}
+
+EFI_STATUS
+EraseBlockData (
+ IN UINT32 Partition,
+ IN UINTN StartBlock,
+ IN UINTN NumBlock
+ )
+{
+ UINTN cmdarg = 0;
+ EFI_STATUS status = EFI_SUCCESS;
+
+ if(Partition!=MSHC_BOOT_PARTITION)
+ {
+ DEBUG ((EFI_D_ERROR, "EraseBlockData failed \n"));
+ status = EFI_UNSUPPORTED;
+ goto Exit;
+ }
+
+ /* MMC High Capacity erase minimum size is 512KB */
+ if (NumBlock < 1024) {
+ if (NumBlock < 512)
+ NumBlock = 1;
+ else
+ NumBlock = 2;
+ } else {
+ if (0 == (NumBlock%1024)) {
+ NumBlock = (NumBlock / 1024);
+ } else {
+ NumBlock = (NumBlock / 1024) + 1;
+ }
+ }
+ DEBUG ((EFI_D_INFO, "EraseBlockData start:%d, Numblock:%d\n", StartBlock, NumBlock));
+
+ cmdarg = StartBlock;
+ status = MSHC_SendCmd (CMD35, 0, cmdarg);
+ if(status!=EFI_SUCCESS)
+ {
+ DEBUG ((EFI_D_ERROR, "EraseBlockData CMD35 failed \n"));
+ status = EFI_DEVICE_ERROR;
+ goto Exit;
+ }
+
+ cmdarg = StartBlock + NumBlock;
+ status = MSHC_SendCmd (CMD36, 0, cmdarg);
+ if(status!=EFI_SUCCESS)
+ {
+ DEBUG ((EFI_D_ERROR, "EraseBlockData CMD36 failed \n"));
+ status = EFI_DEVICE_ERROR;
+ goto Exit;
+ }
+
+ cmdarg = 0;
+ status = MSHC_SendCmd (CMD38, 0, cmdarg);
+ if(status!=EFI_SUCCESS)
+ {
+ DEBUG ((EFI_D_ERROR, "EraseBlockData CMD38 failed \n"));
+ status = EFI_DEVICE_ERROR;
+ goto Exit;
+ }
+
+ Exit:
+
+ return status;
+}
+
+
+EFI_STATUS
+TransferBlock (
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ IN UINTN Lba,
+ IN OUT VOID *Buffer,
+ IN UINTN BlockCount,
+ IN OPERATION_TYPE OperationType
+ )
+{
+ EFI_STATUS Status;
+ UINTN Cmd = 0;
+ UINTN CmdInterruptEnable = 0;
+ UINTN CmdArgument = 0;
+
+ // 1. FIFO reset
+ // MSHC_SendCmd do the fifo reset
+
+ // 2. prepare transfer
+
+ DEBUG ((EFI_D_INFO, "SDHC::TransferBlock : Lba = %d, Buffer = 0x%x, Type = %d\n", Lba, Buffer, OperationType));
+ //Populate the command information based on the operation type.
+ if (OperationType == READ)
+ {
+ if(BlockCount>1)
+ {
+ Cmd = CMD18; //multi block read
+ CmdInterruptEnable = CMD18_INT_EN;
+ }
+ else
+ {
+ Cmd = CMD17; //Single block read
+ CmdInterruptEnable = CMD17_INT_EN;
+ }
+
+ }
+ else if (OperationType == WRITE)
+ {
+ if(BlockCount>1)
+ {
+ Cmd = CMD25; //multi block write
+ CmdInterruptEnable = CMD25_INT_EN;
+ }
+ else
+ {
+ Cmd = CMD24; //Single block write
+ CmdInterruptEnable = CMD24_INT_EN;
+ }
+ }
+ PrepareTransfer(Buffer, BlockCount, OperationType);
+
+ //Set command argument based on the card access mode (Byte mode or Block mode)
+ if (gCardInfo.OCRData.AccessMode & BIT1) {
+ CmdArgument = Lba;
+ } else {
+ CmdArgument = Lba * This->Media->BlockSize;
+ }
+
+ //Send Command.
+ Status = MSHC_SendCmd (Cmd, CmdInterruptEnable, CmdArgument);
+ if (EFI_ERROR(Status)) {
+ DEBUG ((EFI_D_ERROR, "CMD%d fails. Status: %x\n", (Cmd&0x3F), Status));
+ return Status;
+ }
+
+ DEBUG ((EFI_D_INFO, "CMD%d succeed! \n", (Cmd&0x3F)));
+
+ //Read or Write data.
+ if (OperationType == READ) {
+ Status = ReadBlockData (This, Buffer, BlockCount);
+ if (EFI_ERROR(Status)) {
+ DEBUG((EFI_D_ERROR, "ReadBlockData fails.\n"));
+ return Status;
+ }
+ } else if (OperationType == WRITE) {
+ Status = WriteBlockData (This, Buffer, BlockCount);
+ if (EFI_ERROR(Status)) {
+ DEBUG((EFI_D_ERROR, "WriteBlockData fails.\n"));
+ return Status;
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+BOOLEAN
+CardPresent (
+ VOID
+ )
+{
+ return TRUE;
+}
+
+EFI_STATUS
+DetectCard (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ //UINT32 SdMmcBaseAddr;
+
+ //DEBUG ((EFI_D_INFO, "===================================\n"));
+ DEBUG ((EFI_D_INFO, "===MSHC: Version %a ===\n", DateInformation));
+ //DEBUG ((EFI_D_INFO, "===================================\n"));
+
+ //SdMmcBaseAddr = PcdGet32(PcdSdMmcCH0Base);
+
+ if (!CardPresent ()) {
+ return EFI_NO_MEDIA;
+ }
+
+ //Initialize MMC host controller clocks.
+ Status = InitializeMSHC ();
+ if (EFI_ERROR(Status)) {
+ DEBUG ((EFI_D_ERROR, "Initialize MMC host controller fails. Status: %x\n", Status));
+ return Status;
+ }
+
+ // EVT1 InitializeSDHC do the SW Reset
+ //Soft reset for all.
+ //MmioWrite32((SdMmcBaseAddr + SDHC_SWRST_OFFSET), SRA);
+ //gBS->Stall(1000);
+ //while ((MmioRead32 ((SdMmcBaseAddr + SDHC_SWRST_OFFSET)) & SRA) != 0x0);
+
+ //Set the clock frequency to 400KHz.
+ UpdateMSHCClkFrequency (MSHC_CLK_400);
+
+ //Card idenfication
+ Status = PerformCardIdenfication ();
+ if (EFI_ERROR(Status)) {
+ DEBUG ((EFI_D_ERROR, "No MMC/SD card detected.\n"));
+ return Status;
+ }
+
+ //Get CSD (Card specific data) for the detected card.
+ Status = GetCardSpecificData();
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ //Configure the card in data transfer mode.
+ Status = PerformCardConfiguration();
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ //Patch the Media structure.
+ gSDMMCMedia.LastBlock = (gCardInfo.NumBlocks - 1);
+ //gSDMMCMedia.BlockSize = gCardInfo.BlockSize;
+ gSDMMCMedia.BlockSize = 512;
+ gSDMMCMedia.ReadOnly = 0;
+ gSDMMCMedia.MediaPresent = TRUE;
+ gSDMMCMedia.MediaId++;
+
+ UpdateMSHCClkFrequency(MSHC_CLK_50M);
+ DEBUG ((EFI_D_INFO, "SD Card Media Change on Handle 0x%08x\n", gImageHandle));
+
+ return Status;
+}
+
+
+EFI_STATUS
+SdReadWrite (
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ IN UINTN Lba,
+ OUT VOID *Buffer,
+ IN UINTN BufferSize,
+ IN OPERATION_TYPE OperationType
+ )
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ UINTN RetryCount = 0;
+ UINTN BlockCount;
+ UINTN BytesToBeTranferedThisPass = 0;
+ UINTN BytesRemainingToBeTransfered=0;
+ EFI_TPL OldTpl;
+ //BOOLEAN Update;
+ UINT32 SdMmcBaseAddr;
+
+ SdMmcBaseAddr = PcdGet32(PcdSdMmcCH0Base);
+
+ if(gMediaChange==TRUE)
+ {
+ Status = DetectCard();
+ gMediaChange = FALSE;
+ gCardInit = TRUE;
+ }
+ if (EFI_ERROR(Status)) {
+ DEBUG ((EFI_D_ERROR, "MSHC::Card initialization fail .\n"));
+ gCardInit = FALSE;
+ goto Done;
+ }
+
+if(gCardInit)
+{
+ DEBUG ((EFI_D_INFO, "MSHC::SdReadWrite is called Buffersize:%d \n", BufferSize));
+
+ if (Buffer == NULL) {
+ Status = EFI_INVALID_PARAMETER;
+ goto Done;
+ }
+
+ if (Lba > This->Media->LastBlock) {
+ Status = EFI_INVALID_PARAMETER;
+ DEBUG ((EFI_D_ERROR, "MSHC::SdReadWrite EFI_INVALID_PARAMETER\n"));
+ goto Done;
+ }
+
+ if ((BufferSize % This->Media->BlockSize) != 0) {
+ Status = EFI_BAD_BUFFER_SIZE;
+ DEBUG ((EFI_D_ERROR, "MSHC::SdReadWrite EFI_BAD_BUFFER_SIZE\n"));
+ goto Done;
+ }
+
+ //Check if the data lines are not in use.
+ while ((RetryCount++ < MAX_RETRY_COUNT) && (MmioRead32 ((SdMmcBaseAddr + MSHCI_STATUS)) & DATA_BUSY));
+ if (RetryCount == MAX_RETRY_COUNT) {
+ Status = EFI_TIMEOUT;
+ DEBUG ((EFI_D_ERROR, "MSHC::SdReadWrite EFI_TIMEOUT\n"));
+ goto Done;
+ }
+
+ OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
+
+ BytesRemainingToBeTransfered = BufferSize;
+
+ if(MSHC_operation_mode == MSHC_IDMA)
+ {
+ while (BytesRemainingToBeTransfered > 0) {
+ // Turn OFF DMA path until it is debugged
+ BytesToBeTranferedThisPass = (BytesRemainingToBeTransfered >= MAX_MSHC_TRANSFER_SIZE) ? MAX_MSHC_TRANSFER_SIZE : BytesRemainingToBeTransfered;
+ //BytesToBeTranferedThisPass = This->Media->BlockSize;
+
+ BlockCount = BytesToBeTranferedThisPass/This->Media->BlockSize;
+ Status = TransferBlock (This, Lba, Buffer,BlockCount, OperationType);
+
+ if (EFI_ERROR(Status)) {
+ DEBUG ((EFI_D_ERROR, "TransferBlockData fails. %x\n", Status));
+ goto DoneRestoreTPL;
+ }
+
+ BytesRemainingToBeTransfered -= BytesToBeTranferedThisPass;
+ Lba += BlockCount;
+ Buffer = (UINT8 *)Buffer + (This->Media->BlockSize*BlockCount);
+ DEBUG ((EFI_D_INFO, "SdReadWrite::Buf:0x%x, ToBe:0x%x Rema:0x%x \n", BufferSize, BytesToBeTranferedThisPass, BytesRemainingToBeTransfered));
+
+ }
+ }
+ else
+ {
+ while (BytesRemainingToBeTransfered > 0) {
+ // Turn OFF DMA path until it is debugged
+ // BytesToBeTranferedThisPass = (BytesToBeTranferedThisPass >= MAX_SDHC_TRANSFER_SIZE) ? MAX_SDHC_TRANSFER_SIZE : BytesRemainingToBeTransfered;
+ BytesToBeTranferedThisPass = This->Media->BlockSize;
+
+ BlockCount = BytesToBeTranferedThisPass/This->Media->BlockSize;
+
+ if (BlockCount > 1) {
+ // Status = DmaBlocks (This, Lba, Buffer, BlockCount, OperationType);
+ } else {
+ //Transfer a block worth of data.
+ Status = TransferBlock (This, Lba, Buffer, BlockCount,OperationType);
+
+ }
+
+ if (EFI_ERROR(Status)) {
+ DEBUG ((EFI_D_ERROR, "TransferBlockData fails. %x\n", Status));
+ goto DoneRestoreTPL;
+ }
+
+ BytesRemainingToBeTransfered -= BytesToBeTranferedThisPass;
+ Lba += BlockCount;
+ Buffer = (UINT8 *)Buffer + This->Media->BlockSize;
+ }
+
+ }
+
+
+DoneRestoreTPL:
+
+ gBS->RestoreTPL (OldTpl);
+
+Done:
+
+ return Status;
+}
+else
+ return EFI_TIMEOUT;
+
+
+}
+
+
+/**
+
+ Reset the Block Device.
+
+
+
+ @param This Indicates a pointer to the calling context.
+
+ @param ExtendedVerification Driver may perform diagnostics on reset.
+
+
+
+ @retval EFI_SUCCESS The device was reset.
+
+ @retval EFI_DEVICE_ERROR The device is not functioning properly and could
+
+ not be reset.
+
+
+
+**/
+EFI_STATUS
+EFIAPI
+MSHCReset (
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ IN BOOLEAN ExtendedVerification
+ )
+{
+ DEBUG ((EFI_D_INFO, " MSHC::MSHCReset is called\n"));
+ MSHC_reset_all();
+ return EFI_SUCCESS;
+}
+
+
+/**
+
+ Read BufferSize bytes from Lba into Buffer.
+
+
+
+ @param This Indicates a pointer to the calling context.
+
+ @param MediaId Id of the media, changes every time the media is replaced.
+
+ @param Lba The starting Logical Block Address to read from
+
+ @param BufferSize Size of Buffer, must be a multiple of device block size.
+
+ @param Buffer A pointer to the destination buffer for the data. The caller is
+
+ responsible for either having implicit or explicit ownership of the buffer.
+
+
+
+ @retval EFI_SUCCESS The data was read correctly from the device.
+
+ @retval EFI_DEVICE_ERROR The device reported an error while performing the read.
+
+ @retval EFI_NO_MEDIA There is no media in the device.
+
+ @retval EFI_MEDIA_CHANGED The MediaId does not matched the current device.
+
+ @retval EFI_BAD_BUFFER_SIZE The Buffer was not a multiple of the block size of the device.
+
+ @retval EFI_INVALID_PARAMETER The read request contains LBAs that are not valid,
+
+ or the buffer is not on proper alignment.
+
+EFI_STATUS
+
+**/
+
+
+#define EMMC_TEST 0
+#if EMMC_TEST
+#define EMMC_TEST_SIZE (MAX_MSHC_TRANSFER_SIZE+1024)
+UINT32 bWrite[EMMC_TEST_SIZE];
+UINT32 bRead[EMMC_TEST_SIZE];
+//INTN EFIAPI CompareMem (IN CONST VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
+//two buffers are identical, then 0 is returned. Otherwise, the value returned is the first mismatched byte
+
+void MSHC_Test( IN EFI_BLOCK_IO_PROTOCOL *This)
+{
+ UINTN i=0;
+ UINTN Count;
+ INTN ret;
+ EFI_STATUS Status;
+ DEBUG ((EFI_D_INFO, "MSHC::Read Write test %dB\n", EMMC_TEST_SIZE));
+
+ for(i=0; i<EMMC_TEST_SIZE; i++)
+ {
+ bWrite[i]=i;
+ }
+
+//multi
+ for(Count=100; Count<102; Count++)
+ {
+ //Lba=n;
+ //DEBUG ((EFI_D_INFO, "MSHC::Read Write test : %d\n", Count));
+ ZeroMem (&bRead[0], sizeof(bRead));
+ DEBUG ((EFI_D_INFO, "ZR : 0x%x, 0x%x, 0x%x, 0x%x\n",
+ bRead[0], bRead[1], bRead[2], bRead[3]));
+
+ Status = SdReadWrite (This, (UINTN)Count, &bWrite[0], EMMC_TEST_SIZE, WRITE);
+ Status = SdReadWrite (This, (UINTN)Count, &bRead[0], EMMC_TEST_SIZE, READ);
+
+ DEBUG ((EFI_D_INFO, "W: 0x%x, 0x%x, 0x%x, 0x%x ",
+ bWrite[0], bWrite[1], bWrite[2], bWrite[3]));
+ DEBUG ((EFI_D_INFO, "R : 0x%x, 0x%x, 0x%x, 0x%x\n",
+ bRead[0], bRead[1], bRead[2], bRead[3]));
+
+ ret = CompareMem(&bRead[0],&bWrite[0],EMMC_TEST_SIZE);
+
+ if(ret==0)
+ DEBUG ((1, "MSHC::Read Write OK!!\n"));
+ else
+ DEBUG ((1, "MSHC::Read Write Failed bWrite[%d]=0x%x : bRead[%d]=0x%x\n", ret, bWrite[ret], ret, bRead[ret]));
+
+
+ }
+
+
+}
+#endif
+
+
+#define FVB_TEST 0
+
+#if FVB_TEST
+#define FVB_TEST_SIZE 1336//(64)
+#define FVB_Offset 64 //0
+UINT32 FVB_Read[512*3];
+UINT32 FVB_Write[512*3];
+UINT32 Temp[512*3];
+void FVB_Test(IN EFI_BLOCK_IO_PROTOCOL *This)
+{
+ EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *Fvbhandle;
+ EFI_STATUS status = EFI_SUCCESS;
+ EFI_LBA Lba = 10;
+ UINTN NumBytes=FVB_TEST_SIZE;
+ UINT32 i;
+ INTN ret;
+ UINTN Offset=FVB_Offset;
+ //EFI_FVB_ATTRIBUTES_2 *Attribute=NULL;
+ UINTN blocksize=0, numofblocks=0;
+ UINTN EraseStartBlock=10, EraseNumBlocks=5;
+ EFI_PHYSICAL_ADDRESS *Address=NULL;
+
+
+ Fvbhandle = (EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *)This;
+ DEBUG ((1, "FVB_Test Start \n"));
+
+ status = SdReadWrite (This, 0, &Temp[0], 512, READ);
+ if(status!=EFI_SUCCESS)
+ {
+ DEBUG ((1, "FVB_Test Card Init Failed !!\n"));
+ goto Exit;
+ }
+
+ for(i=0; i<512; i++)
+ {
+ FVB_Write[i]=i;
+ }
+ ZeroMem (&FVB_Read[0], 512);
+
+ //DEBUG ((1, "FVB_Test FvbGetAttributes \n"));
+ //FvbGetAttributes(Fvbhandle, Attribute);
+ FvbGetPhysicalAddress(Fvbhandle, Address);
+ FvbGetBlockSize(Fvbhandle, 0, &blocksize, &numofblocks);
+ DEBUG ((1, "FVB_Test erase\n"));
+ FvbEraseBlocks(Fvbhandle, EraseStartBlock, EraseNumBlocks, EFI_LBA_LIST_TERMINATOR);
+
+ DEBUG ((1, "FVB_Test Offset : %d Num : %d\n", Offset, NumBytes));
+ status = FvbWrite(Fvbhandle, Lba, Offset, &NumBytes, (UINT8 *)&FVB_Write[Offset]);
+ if(status!=EFI_SUCCESS)
+ {
+ DEBUG ((1, "FVB_Test write fail !!\n"));
+ goto Exit;
+ }
+
+ status = FvbRead(Fvbhandle, Lba, Offset, &NumBytes, (UINT8 *)&FVB_Read[0]);
+ if(status!=EFI_SUCCESS)
+ {
+ DEBUG ((1, "FVB_Test read fail !!\n"));
+ goto Exit;
+ }
+
+ DEBUG ((1, "FVB W: 0x%x, 0x%x, 0x%x, 0x%x ",
+ FVB_Write[Offset], FVB_Write[Offset+1], FVB_Write[Offset+2], FVB_Write[Offset+3]));
+ DEBUG ((1, "FVB R : 0x%x, 0x%x, 0x%x, 0x%x\n",
+ FVB_Read[0], FVB_Read[1], FVB_Read[2], FVB_Read[3]));
+
+ ret = CompareMem(&FVB_Write[Offset], &FVB_Read[0], FVB_TEST_SIZE);
+
+ if(ret==0)
+ DEBUG ((1, "MSHC::FVB_Test OK!!\n"));
+ else
+ DEBUG ((1, "MSHC::ERROR !!! FVB_Test Failed bWrite[%d]=0x%x : bRead[%d]=0x%x\n", ret, FVB_Write[ret], ret, FVB_Read[ret]));
+
+ Exit:
+ if(status!=EFI_SUCCESS)
+ DEBUG ((1, "FVB_Test fail !!\n"));
+
+}
+
+#endif
+
+
+
+EFI_STATUS
+EFIAPI
+MSHCReadBlocks (
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ IN UINT32 MediaId,
+ IN EFI_LBA Lba,
+ IN UINTN BufferSize,
+ OUT VOID *Buffer
+ )
+{
+ EFI_STATUS Status=EFI_SUCCESS;
+ DEBUG ((EFI_D_INFO, "MSHC::MSHCReadBlocks : MediaId = %x, Lba = %d, BufferSize = %d, Buffer = 0x%x\n",
+ MediaId, (UINTN)Lba, BufferSize, Buffer));
+
+ Status = SdReadWrite (This, (UINTN)Lba, Buffer, BufferSize, READ);
+
+#if 0
+#if FVB_TEST
+ FVB_Test(This);
+#else
+#if EMMC_TEST
+ MSHC_Test(This);
+#else
+ //Perform Read operation.
+ Status = SdReadWrite (This, (UINTN)Lba, Buffer, BufferSize, READ);
+#endif
+#endif //#if FVB_TEST
+#endif
+
+ return Status;
+
+}
+
+
+/**
+
+ Write BufferSize bytes from Lba into Buffer.
+
+
+
+ @param This Indicates a pointer to the calling context.
+
+ @param MediaId The media ID that the write request is for.
+
+ @param Lba The starting logical block address to be written. The caller is
+
+ responsible for writing to only legitimate locations.
+
+ @param BufferSize Size of Buffer, must be a multiple of device block size.
+
+ @param Buffer A pointer to the source buffer for the data.
+
+
+
+ @retval EFI_SUCCESS The data was written correctly to the device.
+
+ @retval EFI_WRITE_PROTECTED The device can not be written to.
+
+ @retval EFI_DEVICE_ERROR The device reported an error while performing the write.
+
+ @retval EFI_NO_MEDIA There is no media in the device.
+
+ @retval EFI_MEDIA_CHNAGED The MediaId does not matched the current device.
+
+ @retval EFI_BAD_BUFFER_SIZE The Buffer was not a multiple of the block size of the device.
+
+ @retval EFI_INVALID_PARAMETER The write request contains LBAs that are not valid,
+
+ or the buffer is not on proper alignment.
+
+
+
+**/
+
+
+EFI_STATUS
+EFIAPI
+MSHCWriteBlocks (
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ IN UINT32 MediaId,
+ IN EFI_LBA Lba,
+ IN UINTN BufferSize,
+ IN VOID *Buffer
+ )
+{
+ EFI_STATUS Status;
+#if EMMC_TEST
+ UINT32 Count=0;
+ UINT32 ret;
+#endif
+
+ DEBUG ((EFI_D_INFO, "MSHC::MSHCWriteBlocks : MediaId = 0x%x, Lba = %d, BufferSize = %d, Buffer = 0x%x\n",
+ MediaId, (UINTN)Lba, BufferSize, Buffer));
+
+ //Perform write operation.
+ Status = SdReadWrite (This, (UINTN)Lba, Buffer, BufferSize, WRITE);
+
+
+#if 0
+#if EMMC_TEST
+ Count = (BufferSize >= MAX_MSHC_TRANSFER_SIZE) ? MAX_MSHC_TRANSFER_SIZE : BufferSize;
+ DEBUG ((1, "\nMSHC::Read Write Test [0x%x] Start \n", Count));
+ ZeroMem (&bRead[0], sizeof(bRead));
+ CopyMem(&bWrite[0], (VOID *)Buffer, Count);
+ Status = SdReadWrite (This, (UINTN)Lba, &bRead[0], Count, READ);
+ DEBUG ((1, "W : 0x%x, 0x%x, 0x%x, 0x%x\n",
+ bWrite[7], bWrite[8], bWrite[9], bWrite[10]));
+
+ DEBUG ((1, "R : 0x%x, 0x%x, 0x%x, 0x%x\n",
+ bRead[7], bRead[8], bRead[9], bRead[10]));
+
+ ret = CompareMem(&bRead[0],&bWrite[0],Count);
+
+ if(ret==0)
+ DEBUG ((1, "MSHC::Read Write Test OK!!\n"));
+ else
+ DEBUG ((1, "MSHC::Read Write Test Failed -.- bRead[%d]=0x%x bWrite[%d]=0x%x \n", ret, bRead[ret], ret, bWrite[ret]));
+
+#endif
+#endif
+
+
+ return Status;
+
+}
+
+
+/**
+
+ Flush the Block Device.
+
+
+
+ @param This Indicates a pointer to the calling context.
+
+
+
+ @retval EFI_SUCCESS All outstanding data was written to the device
+
+ @retval EFI_DEVICE_ERROR The device reported an error while writting back the data
+
+ @retval EFI_NO_MEDIA There is no media in the device.
+
+
+
+**/
+EFI_STATUS
+EFIAPI
+MSHCFlushBlocks (
+ IN EFI_BLOCK_IO_PROTOCOL *This
+ )
+{
+ DEBUG ((EFI_D_INFO, "MSHC::MSHCFlushBlocks is called\n"));
+ return EFI_SUCCESS;
+}
+
+
+EFI_BLOCK_IO_PROTOCOL gBlockIo = {
+ EFI_BLOCK_IO_INTERFACE_REVISION, // Revision
+ &gSDMMCMedia, // *Media
+ MSHCReset, // Reset
+ MSHCReadBlocks, // ReadBlocks
+ MSHCWriteBlocks, // WriteBlocks
+ MSHCFlushBlocks // FlushBlocks
+};
+
+
+EFI_STATUS
+EFIAPI
+MSHCInitialize (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+
+ ZeroMem (&gCardInfo, sizeof (CARD_INFO));
+
+//Publish BlockIO.
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &ImageHandle,
+ &gEfiBlockIoProtocolGuid, &gBlockIo,
+ &gEfiDevicePathProtocolGuid, &gMSHCDevicePath,
+ NULL
+ );
+
+ DEBUG ((EFI_D_INFO, "MSHC::MSHCInitialize:0x%x\n", Status));
+ return Status;
+}
diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/eMMCDxe/eMMCDxe.h b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/eMMCDxe/eMMCDxe.h
new file mode 100755
index 000000000..e410d669e
--- /dev/null
+++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/eMMCDxe/eMMCDxe.h
@@ -0,0 +1,308 @@
+/** @file
+
+ Copyright (c) 2011, Samsung Electronics Co. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _MSHCDXE_H_
+#define _MSHCDXE_H_
+
+#include <Uefi.h>
+
+#include <Library/BaseLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/PcdLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Protocol/BlockIo.h>
+#include <Protocol/DevicePath.h>
+#include <Protocol/FirmwareVolumeBlock.h>
+
+#include "eMMCDxe_5250.h"
+#include "eMMCDxe_CMD.h"
+
+/**
+eMMC partition Gaia EVT1
+
+boot partition-1 : 100M store BL1, BL2, UEFI, TZSW
+boot partition-2 : 100M not used
+RPMB : 16M for secure team
+General purpose-1 : not used
+General purpose-2 : not used
+General purpose-3 : not used
+General purpose-4 : not used
+
+boot partition-1 start offset
+BL1: 0
+BL2: 16
+UEFI : 32
+TZSW : 2592~3104
+NV data area : 3200
+NV data for security team : 3200
+NV data for general purpose : 3400
+**/
+
+#define MSHC_BOOT_SIZE 100
+#define MSHC_RPMB_SIZE 0
+#define MSHC_BOOT_SIZE_MULTI (MSHC_BOOT_SIZE*2)
+#define MSHC_BOOT_SECURE_OFFSET 3200
+#define MSHC_BOOT_SECURE_SIZE 512 // 256k
+
+#define MSHC_BOOT_PARTITION 0
+#define MSHC_RPMB_PARTITION 1
+#define MSHC_USER_PARTITION 2
+
+#define BLEN_512BYTES (0x200)
+#define BLKSIZE_1 (0x1)
+
+#define OM_EMMC 0x8
+
+#define MAX_RETRY_COUNT (100000)
+#define MMC_REFERENCE_CLK (96000000)
+#define MSHC_CLK_400 (400)
+#define MSHC_CLK_25M (25000)
+#define MSHC_CLK_50M (50000)
+
+#define OCR_BUSY 0x80000000
+#define OCR_HCS 0x40000000
+
+#define MMC_VDD_165_195 0x00000080 /* VDD voltage 1.65 - 1.95 */
+#define MMC_VDD_20_21 0x00000100 /* VDD voltage 2.0 ~ 2.1 */
+#define MMC_VDD_21_22 0x00000200 /* VDD voltage 2.1 ~ 2.2 */
+#define MMC_VDD_22_23 0x00000400 /* VDD voltage 2.2 ~ 2.3 */
+#define MMC_VDD_23_24 0x00000800 /* VDD voltage 2.3 ~ 2.4 */
+#define MMC_VDD_24_25 0x00001000 /* VDD voltage 2.4 ~ 2.5 */
+#define MMC_VDD_25_26 0x00002000 /* VDD voltage 2.5 ~ 2.6 */
+#define MMC_VDD_26_27 0x00004000 /* VDD voltage 2.6 ~ 2.7 */
+#define MMC_VDD_27_28 0x00008000 /* VDD voltage 2.7 ~ 2.8 */
+#define MMC_VDD_28_29 0x00010000 /* VDD voltage 2.8 ~ 2.9 */
+#define MMC_VDD_29_30 0x00020000 /* VDD voltage 2.9 ~ 3.0 */
+#define MMC_VDD_30_31 0x00040000 /* VDD voltage 3.0 ~ 3.1 */
+#define MMC_VDD_31_32 0x00080000 /* VDD voltage 3.1 ~ 3.2 */
+#define MMC_VDD_32_33 0x00100000 /* VDD voltage 3.2 ~ 3.3 */
+#define MMC_VDD_33_34 0x00200000 /* VDD voltage 3.3 ~ 3.4 */
+#define MMC_VDD_34_35 0x00400000 /* VDD voltage 3.4 ~ 3.5 */
+#define MMC_VDD_35_36 0x00800000 /* VDD voltage 3.5 ~ 3.6 */
+
+
+#define MMC_SWITCH_MODE_CMD_SET 0x00 /* Change the command set */
+#define MMC_SWITCH_MODE_SET_BITS 0x01 /* Set bits in EXT_CSD byte
+ addressed by index which are
+ 1 in value field */
+#define MMC_SWITCH_MODE_CLEAR_BITS 0x02 /* Clear bits in EXT_CSD byte
+ addressed by index, which are
+ 1 in value field */
+#define MMC_SWITCH_MODE_WRITE_BYTE 0x03 /* Set target byte to value */
+/*
+ * EXT_CSD fields
+ */
+
+#define EXT_CSD_BUS_WIDTH 183 /* R/W */
+#define EXT_CSD_HS_TIMING 185 /* R/W */
+#define EXT_CSD_CARD_TYPE 196 /* RO */
+#define EXT_CSD_REV 192 /* RO */
+#define EXT_CSD_SEC_CNT 212 /* RO, 4 bytes */
+#define BOOT_SIZE_MULTI 226 /* RO */
+#define PARTITIONING_SUPPORT 160 /* RO */
+
+/*
+ * EXT_CSD field definitions
+ */
+
+/* Card */
+#define EXT_CSD_CMD_SET_NORMAL (1<<0)
+#define EXT_CSD_CMD_SET_SECURE (1<<1)
+#define EXT_CSD_CMD_SET_CPSECURE (1<<2)
+
+#define EXT_CSD_CARD_TYPE_26 (1<<0) /* Card can run at 26MHz */
+#define EXT_CSD_CARD_TYPE_52 (1<<1) /* Card can run at 52MHz */
+#define EXT_CSD_CARD_TYPE_52_DDR_18_30 (1<<2) /* Card can run at 52MHz DDR 1.8V or 3V */
+#define EXT_CSD_CARD_TYPE_52_DDR_12 (1<<3) /* Card can run at 52MHz DDR 1.2V */
+
+#define EXT_CSD_BUS_WIDTH_1 0 /* Card is in 1 bit mode */
+#define EXT_CSD_BUS_WIDTH_4 1 /* Card is in 4 bit mode */
+#define EXT_CSD_BUS_WIDTH_8 2 /* Card is in 8 bit mode */
+#define EXT_CSD_BUS_WIDTH_4_DDR 5 /* Card is in 4 bit DDR mode */
+#define EXT_CSD_BUS_WIDTH_8_DDR 6 /* Card is in 8 bit DDR mode */
+
+
+typedef struct {
+ UINT32 hs_max_dtr;
+ UINT32 sectors;
+ UINT32 boot_size_multi; //226
+ UINT32 Partitioning_Support; //160
+}mmc_ext_csd;
+
+
+typedef struct {
+ UINT32 Reserved0: 7; // 0
+ UINT32 V170_V195: 1; // 1.70V - 1.95V
+ UINT32 V200_V260: 7; // 2.00V - 2.60V
+ UINT32 V270_V360: 9; // 2.70V - 3.60V
+ UINT32 RESERVED_1: 5; // Reserved
+ UINT32 AccessMode: 2; // 00b (byte mode), 10b (sector mode)
+ UINT32 Busy: 1; // This bit is set to LOW if the card has not finished the power up routine
+}OCR;
+
+typedef struct {
+ UINT32 NOT_USED; // 1 [0:0]
+ UINT32 CRC; // CRC7 checksum [7:1]
+ UINT32 MDT; // Manufacturing date [19:8]
+ UINT32 RESERVED_1; // Reserved [23:20]
+ UINT32 PSN; // Product serial number [55:24]
+ UINT8 PRV; // Product revision [63:56]
+ UINT8 PNM[5]; // Product name [64:103]
+ UINT16 OID; // OEM/Application ID [119:104]
+ UINT8 MID; // Manufacturer ID [127:120]
+}CID;
+
+typedef struct {
+ UINT8 NOT_USED: 1; // Not used, always 1 [0:0]
+ UINT8 CRC: 7; // CRC [7:1]
+
+ UINT8 RESERVED_1: 2; // Reserved [9:8]
+ UINT8 FILE_FORMAT: 2; // File format [11:10]
+ UINT8 TMP_WRITE_PROTECT: 1; // Temporary write protection [12:12]
+ UINT8 PERM_WRITE_PROTECT: 1; // Permanent write protection [13:13]
+ UINT8 COPY: 1; // Copy flag (OTP) [14:14]
+ UINT8 FILE_FORMAT_GRP: 1; // File format group [15:15]
+
+ UINT16 RESERVED_2: 5; // Reserved [20:16]
+ UINT16 WRITE_BL_PARTIAL: 1; // Partial blocks for write allowed [21:21]
+ UINT16 WRITE_BL_LEN: 4; // Max. write data block length [25:22]
+ UINT16 R2W_FACTOR: 3; // Write speed factor [28:26]
+ UINT16 RESERVED_3: 2; // Reserved [30:29]
+ UINT16 WP_GRP_ENABLE: 1; // Write protect group enable [31:31]
+
+ UINT32 WP_GRP_SIZE: 7; // Write protect group size [38:32]
+ UINT32 SECTOR_SIZE: 7; // Erase sector size [45:39]
+ UINT32 ERASE_BLK_EN: 1; // Erase single block enable [46:46]
+ UINT32 C_SIZE_MULT: 3; // Device size multiplier [49:47]
+ UINT32 VDD_W_CURR_MAX: 3; // Max. write current @ VDD max [52:50]
+ UINT32 VDD_W_CURR_MIN: 3; // Max. write current @ VDD min [55:53]
+ UINT32 VDD_R_CURR_MAX: 3; // Max. read current @ VDD max [58:56]
+ UINT32 VDD_R_CURR_MIN: 3; // Max. read current @ VDD min [61:59]
+ UINT32 C_SIZELow2: 2; // Device size [63:62]
+
+ UINT32 C_SIZEHigh10: 10;// Device size [73:64]
+ UINT32 RESERVED_4: 2; // Reserved [75:74]
+ UINT32 DSR_IMP: 1; // DSR implemented [76:76]
+ UINT32 READ_BLK_MISALIGN: 1; // Read block misalignment [77:77]
+ UINT32 WRITE_BLK_MISALIGN: 1; // Write block misalignment [78:78]
+ UINT32 READ_BL_PARTIAL: 1; // Partial blocks for read allowed [79:79]
+ UINT32 READ_BL_LEN: 4; // Max. read data block length [83:80]
+ UINT32 CCC: 12;// Card command classes [95:84]
+
+ UINT8 TRAN_SPEED ; // Max. bus clock frequency [103:96]
+ UINT8 NSAC ; // Data read access-time 2 in CLK cycles (NSAC*100) [111:104]
+ UINT8 TAAC ; // Data read access-time 1 [119:112]
+
+ UINT8 RESERVED_5: 6; // Reserved [125:120]
+ UINT8 CSD_STRUCTURE: 2; // CSD structure [127:126]
+}CSD;
+
+
+
+typedef struct {
+ UINT8 NOT_USED: 1; // Not used, always 1 [0:0]
+ UINT8 CRC: 7; // CRC [7:1]
+ UINT8 RESERVED_1: 2; // Reserved [9:8]
+ UINT8 FILE_FORMAT: 2; // File format [11:10]
+ UINT8 TMP_WRITE_PROTECT: 1; // Temporary write protection [12:12]
+ UINT8 PERM_WRITE_PROTECT: 1; // Permanent write protection [13:13]
+ UINT8 COPY: 1; // Copy flag (OTP) [14:14]
+ UINT8 FILE_FORMAT_GRP: 1; // File format group [15:15]
+ UINT16 RESERVED_2: 5; // Reserved [20:16]
+ UINT16 WRITE_BL_PARTIAL: 1; // Partial blocks for write allowed [21:21]
+ UINT16 WRITE_BL_LEN: 4; // Max. write data block length [25:22]
+ UINT16 R2W_FACTOR: 3; // Write speed factor [28:26]
+ UINT16 RESERVED_3: 2; // Reserved [30:29]
+ UINT16 WP_GRP_ENABLE: 1; // Write protect group enable [31:31]
+ UINT16 WP_GRP_SIZE: 7; // Write protect group size [38:32]
+ UINT16 SECTOR_SIZE: 7; // Erase sector size [45:39]
+ UINT16 ERASE_BLK_EN: 1; // Erase single block enable [46:46]
+ UINT16 RESERVED_4: 1; // Reserved [47:47]
+ UINT32 C_SIZELow16: 16;// Device size [69:48]
+ UINT32 C_SIZEHigh6: 6; // Device size [69:48]
+ UINT32 RESERVED_5: 6; // Reserved [75:70]
+ UINT32 DSR_IMP: 1; // DSR implemented [76:76]
+ UINT32 READ_BLK_MISALIGN: 1; // Read block misalignment [77:77]
+ UINT32 WRITE_BLK_MISALIGN: 1; // Write block misalignment [78:78]
+ UINT32 READ_BL_PARTIAL: 1; // Partial blocks for read allowed [79:79]
+ UINT16 READ_BL_LEN: 4; // Max. read data block length [83:80]
+ UINT16 CCC: 12;// Card command classes [95:84]
+ UINT8 TRAN_SPEED ; // Max. bus clock frequency [103:96]
+ UINT8 NSAC ; // Data read access-time 2 in CLK cycles (NSAC*100) [111:104]
+ UINT8 TAAC ; // Data read access-time 1 [119:112]
+ UINT8 RESERVED_6: 6; // 0 [125:120]
+ UINT8 CSD_STRUCTURE: 2; // CSD structure [127:126]
+}CSD_SDV2;
+
+typedef enum {
+ UNKNOWN_CARD,
+ MMC_CARD, //MMC card
+ SD_CARD, //SD 1.1 card
+ SD_CARD_2, //SD 2.0 or above standard card
+ SD_CARD_2_HIGH, //SD 2.0 or above high capacity card
+ SD_CARD_MAX
+} CARD_TYPE;
+
+
+
+typedef enum {
+ MSHC_IDMA,
+ MSHC_FIFO
+}MSHC_OPERATION_MODE;
+
+typedef struct {
+ UINT16 RCA;
+ UINTN BlockSize;
+ UINTN NumBlocks;
+ UINTN TotalNumBlocks;
+ UINTN ClockFrequencySelect;
+ CARD_TYPE CardType;
+ OCR OCRData;
+ CID CIDData;
+ CSD CSDData;
+ mmc_ext_csd Extcsd;
+} CARD_INFO;
+
+
+EFI_STATUS
+DetectCard (VOID);
+void mshci_reset_fifo(void);
+
+extern EFI_BLOCK_IO_PROTOCOL gBlockIo;
+extern EFI_BLOCK_IO_MEDIA gSDMMCMedia;
+extern CARD_INFO gCardInfo;
+extern BOOLEAN gCardInit;
+
+extern EFI_STATUS
+SdReadWrite (
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ IN UINTN Lba,
+ OUT VOID *Buffer,
+ IN UINTN BufferSize,
+ IN OPERATION_TYPE OperationType
+ );
+EFI_STATUS
+EraseBlockData (
+ IN UINT32 Partition,
+ IN UINTN StartBlock,
+ IN UINTN NumBlock
+ );
+
+
+
+#endif
+
diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/eMMCDxe/eMMCDxe.inf b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/eMMCDxe/eMMCDxe.inf
new file mode 100755
index 000000000..45e9ed1a4
--- /dev/null
+++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/eMMCDxe/eMMCDxe.inf
@@ -0,0 +1,64 @@
+#/** @file
+#
+# Copyright (c) 2012, Samsung Electronics Co. All rights reserved.<BR>
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#**/
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = eMMCDxe
+ FILE_GUID = 39ad4d3f-dee8-4708-ac4e-46c8335c48a6
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+
+ ENTRY_POINT = MSHCInitialize
+
+
+[Sources.common]
+ eMMCDxe.c
+ eMMCDxe_5250.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ SamsungPlatformPkg/ExynosPkg/Exynos5250/ExynosPkg.dec
+ SamsungPlatformPkg/SamsungPlatformPkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ EmbeddedPkg/EmbeddedPkg.dec
+ SamsungPlatformPkg/ArndaleBoardPkg/ArndaleBoardPkg.dec
+ ArmPkg/ArmPkg.dec
+
+[LibraryClasses]
+ UefiDriverEntryPoint
+ IoLib
+ TimerLib
+ MemoryAllocationLib
+ UncachedMemoryAllocationLib
+
+[Guids]
+
+[Protocols]
+ gEfiBlockIoProtocolGuid
+ gEfiDevicePathProtocolGuid
+ gSamsungPlatformGpioProtocolGuid ## GPIO Protocol
+ gEfiFirmwareVolumeBlockProtocolGuid
+
+[Pcd]
+ gExynosPkgTokenSpaceGuid.PcdCmuBase
+ gExynosPkgTokenSpaceGuid.PcdSdMmcCH0Base
+ gExynosPkgTokenSpaceGuid.PcdEmmcDMABufferBase
+
+[FixedPcd.common]
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase
+
+[Depex]
+ TRUE
+
+
diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/eMMCDxe/eMMCDxe_5250.c b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/eMMCDxe/eMMCDxe_5250.c
new file mode 100755
index 000000000..511b079d4
--- /dev/null
+++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/eMMCDxe/eMMCDxe_5250.c
@@ -0,0 +1,721 @@
+/** @file
+ MMC/SD Card driver for Secure Digital Host Controller
+
+ This driver always produces a BlockIo protocol but it starts off with no Media
+ present. A TimerCallBack detects when media is inserted or removed and after
+ a media change event a call to BlockIo ReadBlocks/WriteBlocks will cause the
+ media to be detected (or removed) and the BlockIo Media structure will get
+ updated. No MMC/SD Card harward registers are updated until the first BlockIo
+ ReadBlocks/WriteBlocks after media has been insterted (booting with a card
+ plugged in counts as an insertion event).
+
+ Copyright (c) 2012, Samsung Electronics Co. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+
+
+#include <Library/TimerLib.h>
+#include <Library/PcdLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/UncachedMemoryAllocationLib.h>
+#include <Protocol/ExynosGpio.h>
+#include <Platform/ArmPlatform.h>
+#include <Platform/Exynos5250.h>
+#include <Platform/Arndale5250.h>
+
+
+#include "eMMCDxe.h"
+
+//#undef EFI_D_INFO
+//#define EFI_D_INFO 1
+
+#define DMA_UNCACHE_ALLOC 0
+#if DMA_UNCACHE_ALLOC
+UINT32 *DMABuffer;
+#endif
+void MSHC_reset_all(void)
+{
+ int count;
+ volatile int ctl_val=0;
+ UINT32 SdMmcBaseAddr;
+ SdMmcBaseAddr = PcdGet32(PcdSdMmcCH0Base);
+
+ /* Wait max 100 ms */
+ count = 10000;
+
+ /* before reset ciu, it should check DATA0. if when DATA0 is low and
+ it resets ciu, it might make a problem */
+ while ((MmioRead32 ((SdMmcBaseAddr + MSHCI_STATUS)) & (1<<9))){
+ if (count == 0) {
+ DEBUG ((EFI_D_ERROR, "MMC controller never released. \n"));
+ return;
+ }
+ count--;
+ MicroSecondDelay(1);
+ }
+
+ // Reset CIU
+ ctl_val = MmioRead32((SdMmcBaseAddr + MSHCI_CTRL));
+ ctl_val |= CTRL_RESET;
+ MmioWrite32((SdMmcBaseAddr + MSHCI_CTRL), ctl_val);
+
+ //Reset FIFO
+ MSHC_reset_fifo();
+
+ //Reset DMA
+ ctl_val = MmioRead32((SdMmcBaseAddr + MSHCI_CTRL));
+ ctl_val |= DMA_RESET;
+ MmioWrite32((SdMmcBaseAddr + MSHCI_CTRL), ctl_val);
+
+ //Set auto stop CMD
+ ctl_val = MmioRead32((SdMmcBaseAddr + MSHCI_CTRL));
+ ctl_val |= SEND_AS_CCSD;
+ MmioWrite32((SdMmcBaseAddr + MSHCI_CTRL), ctl_val);
+
+}
+
+
+void MSHC_Set_DDR(int BusMode)
+{
+
+ UINT32 clkphase;
+ //clkphase = 0x03030002; //cmd response error at 50M RINT=0x46 error, RE and CD, RCRC
+ //clkphase = 0x03020001; //data read error at 50M SBE
+ UINT32 SdMmcBaseAddr;
+ SdMmcBaseAddr = PcdGet32(PcdSdMmcCH0Base);
+
+ if(BusMode==BUSMODE_DDR)
+ {
+ DEBUG ((EFI_D_INFO, "MSHC DDR .\n"));
+ MmioWrite32((SdMmcBaseAddr + MSHCI_UHS_REG), UHS_DDR);
+ clkphase = 0x03020001;
+ }
+ else
+ {
+ DEBUG ((EFI_D_INFO, "MSHC Non DDR .\n"));
+ MmioWrite32((SdMmcBaseAddr + MSHCI_UHS_REG), UHS_NON_DDR);
+ clkphase = 0x03030002;
+ }
+ MmioWrite32((SdMmcBaseAddr + MSHCI_CLKSEL), clkphase);
+
+}
+
+
+void MSHC_5250_init(void)
+{
+ UINT32 SdMmcBaseAddr;
+ SdMmcBaseAddr = PcdGet32(PcdSdMmcCH0Base);
+
+ /* Power Enable Register */
+ MmioWrite32((SdMmcBaseAddr + MSHCI_PWREN), POWER_ENABLE);
+ //MSHC_Set_DDR(BUSMODE_DDR);
+
+ MSHC_reset_all();
+
+ // Initialize FIFO
+ MmioWrite32((SdMmcBaseAddr + MSHCI_FIFOTH), (MSIZE_8 | TX_WMARK_DEFAULT | RX_WMARK_DEFAULT));
+
+ /* It clears all pending interrupts */
+ MmioWrite32((SdMmcBaseAddr + MSHCI_RINTSTS), INTMSK_ALL);
+ /* It dose not use Interrupt. Disable all */
+ MmioWrite32((SdMmcBaseAddr + MSHCI_INTMSK), 0);
+
+ //UpdateMSHCClkFrequency(MSHC_CLK_400);
+
+ /* Set auto stop command */
+ //MmioWrite32((SdMmcBaseAddr + MSHCI_CTRL), (1<<10));
+
+ /* set debounce filter value*/
+ MmioWrite32((SdMmcBaseAddr + MSHCI_DEBNCE), (0xfffff));
+
+ /* clear card type. set 1-bit mode */
+ MmioWrite32((SdMmcBaseAddr + MSHCI_CTYPE), 0x0);
+
+ /* set bus mode register for IDMAC */
+ MmioWrite32((SdMmcBaseAddr + MSHCI_BMOD), (BMOD_IDMAC_RESET));
+
+ /* disable all interrupt source of IDMAC */
+ MmioWrite32((SdMmcBaseAddr + MSHCI_IDINTEN), (0x0));
+
+ /* set max timeout */
+ MmioWrite32((SdMmcBaseAddr + MSHCI_TMOUT), (0xffffffff));
+
+ MmioWrite32((SdMmcBaseAddr + MSHCI_BLKSIZ), BLEN_512BYTES);
+ MmioWrite32((SdMmcBaseAddr + MSHCI_CLKSEL), 0x03030002);
+
+}
+
+EFI_STATUS
+InitializeMSHC (
+ VOID
+ )
+{
+
+ EFI_STATUS Status;
+ EXYNOS_GPIO *Gpio;
+ UINT32 CumBaseAddr;
+ //UINT32 SdMmcBaseAddr;
+ UINT32 i, clock;
+ volatile UINT32 ctl_val;
+
+
+ Status = gBS->LocateProtocol(&gSamsungPlatformGpioProtocolGuid, NULL, (VOID **)&Gpio);
+ ASSERT_EFI_ERROR(Status);
+
+ CumBaseAddr = PcdGet32(PcdCmuBase);
+ //SdMmcBaseAddr = PcdGet32(PcdSdMmcCH0Base);
+
+ //MmioWrite32((SdMmcBaseAddr + SDHC_SWRST_OFFSET), SRA);
+
+ // Set Clock Source for using MPLL
+ ctl_val = MmioRead32((CumBaseAddr + CLK_SRC_FSYS_OFFSET));
+ ctl_val &= ~(0xf);
+ ctl_val |= (0x6);
+ MmioWrite32((CumBaseAddr + CLK_SRC_FSYS_OFFSET), ctl_val);
+ //MmioAndThenOr32 ((CumBaseAddr + CLK_SRC_FSYS_OFFSET), ~(0xF), (0x6));
+
+ // CLK mask
+ ctl_val = MmioRead32((CumBaseAddr + CLK_SRC_MASK_FSYS_OFFSET));
+ ctl_val |= (0x1);
+ MmioWrite32((CumBaseAddr + CLK_SRC_MASK_FSYS_OFFSET), ctl_val);
+
+ // CLK gating
+ ctl_val = MmioRead32((CumBaseAddr + CLK_GATE_IP_FSYS_OFFSET));
+ ctl_val |= (0x1<<12);
+ MmioWrite32((CumBaseAddr + CLK_GATE_IP_FSYS_OFFSET), ctl_val);
+
+
+ /* MMC2 clock div */
+ clock = 800; //MPLL in MHz
+ for(i=0; i<= 0xf; i++)
+ {
+ if((clock / (i+1)) <= 90) {
+ MmioAndThenOr32 ((CumBaseAddr + CLK_DIV_FSYS1_OFFSET), ~(0xF << 0), (i << 0));
+ break;
+ }
+ }
+
+
+ // 2. GPIO setting
+ // Set GPIO for using SD/MMC CH0 for eMMC
+ Gpio->Set(Gpio,SD_0_CLK,GPIO_MODE_SPECIAL_FUNCTION_2);
+ Gpio->Set(Gpio,SD_0_CMD,GPIO_MODE_SPECIAL_FUNCTION_2);
+ //Gpio->Set(Gpio,SD_0_CDn,GPIO_MODE_SPECIAL_FUNCTION_2);
+
+ //Set CDn as HIGH
+ Gpio->Set(Gpio,SD_0_CDn, GPIO_MODE_OUTPUT_1);
+
+
+ Gpio->Set(Gpio,SD_0_DATA0,GPIO_MODE_SPECIAL_FUNCTION_2);
+ Gpio->Set(Gpio,SD_0_DATA1,GPIO_MODE_SPECIAL_FUNCTION_2);
+ Gpio->Set(Gpio,SD_0_DATA2,GPIO_MODE_SPECIAL_FUNCTION_2);
+ Gpio->Set(Gpio,SD_0_DATA3,GPIO_MODE_SPECIAL_FUNCTION_2);
+ Gpio->Set(Gpio,SD_0_DATA4,GPIO_MODE_SPECIAL_FUNCTION_2);
+ Gpio->Set(Gpio,SD_0_DATA5,GPIO_MODE_SPECIAL_FUNCTION_2);
+ Gpio->Set(Gpio,SD_0_DATA6,GPIO_MODE_SPECIAL_FUNCTION_2);
+ Gpio->Set(Gpio,SD_0_DATA7,GPIO_MODE_SPECIAL_FUNCTION_2);
+
+ Gpio->SetPull(Gpio,SD_0_CLK,GPIO_PULL_NONE);
+ Gpio->SetPull(Gpio,SD_0_CMD,GPIO_PULL_NONE);
+ Gpio->SetPull(Gpio,SD_0_CDn,GPIO_PULL_UP);
+ Gpio->SetPull(Gpio,SD_0_DATA0,GPIO_PULL_UP);
+ Gpio->SetPull(Gpio,SD_0_DATA1,GPIO_PULL_UP);
+ Gpio->SetPull(Gpio,SD_0_DATA2,GPIO_PULL_UP);
+ Gpio->SetPull(Gpio,SD_0_DATA3,GPIO_PULL_UP);
+ Gpio->SetPull(Gpio,SD_0_DATA4,GPIO_PULL_UP);
+ Gpio->SetPull(Gpio,SD_0_DATA5,GPIO_PULL_UP);
+ Gpio->SetPull(Gpio,SD_0_DATA6,GPIO_PULL_UP);
+ Gpio->SetPull(Gpio,SD_0_DATA7,GPIO_PULL_UP);
+
+Gpio->SetStrength(Gpio,SD_0_CLK,GPIO_DRV_3X);
+Gpio->SetStrength(Gpio,SD_0_CMD,GPIO_DRV_3X);
+Gpio->SetStrength(Gpio,SD_0_CDn,GPIO_DRV_3X);
+Gpio->SetStrength(Gpio,SD_0_DATA0,GPIO_DRV_3X);
+Gpio->SetStrength(Gpio,SD_0_DATA1,GPIO_DRV_3X);
+Gpio->SetStrength(Gpio,SD_0_DATA2,GPIO_DRV_3X);
+Gpio->SetStrength(Gpio,SD_0_DATA3,GPIO_DRV_3X);
+Gpio->SetStrength(Gpio,SD_0_DATA4,GPIO_DRV_3X);
+Gpio->SetStrength(Gpio,SD_0_DATA5,GPIO_DRV_3X);
+Gpio->SetStrength(Gpio,SD_0_DATA6,GPIO_DRV_3X);
+Gpio->SetStrength(Gpio,SD_0_DATA7,GPIO_DRV_3X);
+
+ MSHC_5250_init();
+#if DMA_UNCACHE_ALLOC
+ DMABuffer = (UINT32 *)UncachedAllocatePool(EMMC_DMA_PHYSICAL_BUFFER_SIZE/2);
+ if(DMABuffer==NULL)
+ {
+ DEBUG ((EFI_D_ERROR, "MSHC::DMA alloc failed \n"));
+ }
+#endif
+ return EFI_SUCCESS;
+
+}
+
+void MSHC_reset_fifo(void)
+{
+ volatile int ctl_val=0;
+ UINT32 SdMmcBaseAddr;
+ SdMmcBaseAddr = PcdGet32(PcdSdMmcCH0Base);
+ //Reset FIFO
+ ctl_val = MmioRead32((SdMmcBaseAddr + MSHCI_CTRL));
+ ctl_val |= FIFO_RESET;
+ MmioWrite32((SdMmcBaseAddr + MSHCI_CTRL), ctl_val);
+
+}
+
+
+VOID MSHC_clock_onoff (int value)
+{
+ volatile UINT32 loop_count = 0x100000;
+ UINT32 SdMmcBaseAddr;
+
+ SdMmcBaseAddr = PcdGet32(PcdSdMmcCH0Base);
+
+ if(value==CLK_ENABLE)
+ {
+ MmioWrite32 ((SdMmcBaseAddr + MSHCI_CLKENA), (0x1<<0));
+ MmioWrite32 ((SdMmcBaseAddr + MSHCI_CMD), 0);
+ MmioWrite32 ((SdMmcBaseAddr + MSHCI_CMD), CMD_ONLY_CLK);
+ do {
+ if((MmioRead32 (SdMmcBaseAddr + MSHCI_CMD) & CMD_STRT_BIT)==0)
+ break;
+ loop_count--;
+ } while (loop_count);
+ }
+ else
+ {
+ MmioWrite32 ((SdMmcBaseAddr + MSHCI_CLKENA), (0x0<<0));
+ MmioWrite32 ((SdMmcBaseAddr + MSHCI_CMD), 0);
+ MmioWrite32 ((SdMmcBaseAddr + MSHCI_CMD), CMD_ONLY_CLK);
+ do {
+ if((MmioRead32 (SdMmcBaseAddr + MSHCI_CMD) & CMD_STRT_BIT)==0)
+ break;
+ loop_count--;
+ } while (loop_count);
+ }
+
+ if (loop_count == 0) {
+ DEBUG ((EFI_D_ERROR, "MSHC::clockonoff : Clk = %d\n", value));
+ }
+
+}
+
+
+VOID
+UpdateMSHCClkFrequency (
+ UINTN NewCLK
+ )
+{
+ UINT32 CumBaseAddr;
+ UINT32 SdMmcBaseAddr;
+
+ SdMmcBaseAddr = PcdGet32(PcdSdMmcCH0Base);
+ CumBaseAddr = PcdGet32(PcdCmuBase);
+
+ // Disable all clocks to not provide the clock to the card
+//(CONFIG_CPU_EXYNOS5250_EVT1)
+ MSHC_clock_onoff(CLK_DISABLE);
+ //MmioAnd32 ((SdMmcBaseAddr + CLKCON_OFFSET), ~(0xF));
+
+ //Set new clock frequency.
+ if (NewCLK == MSHC_CLK_400)
+ {
+ DEBUG ((EFI_D_INFO, "MSHC::CLK=400.\n"));
+ // MPLL=800, cclk_in=100, 100M/250=400k
+ //MmioAndThenOr32 ((CumBaseAddr + CLK_DIV_FSYS1_OFFSET), ~(0xFFFF), 0xE008);
+ MmioAndThenOr32 ((CumBaseAddr + CLK_DIV_FSYS1_OFFSET), ~(0xFFFF), 0x1);
+ MmioWrite32 ((SdMmcBaseAddr + MSHCI_CLKDIV), 125);
+ }
+ else if (NewCLK == MSHC_CLK_25M)
+ {
+ DEBUG ((EFI_D_INFO, "MSHC::CLK=25M.\n"));
+ // DDR mode use CLKDIV MPLL = 800, SCLK = 400, cclk_in=100M
+ MmioAndThenOr32 ((CumBaseAddr + CLK_DIV_FSYS1_OFFSET), ~(0xFFFF), 0x1);
+ MmioWrite32 ((SdMmcBaseAddr + MSHCI_CLKDIV), 2);
+ }
+ else if(NewCLK == MSHC_CLK_50M)
+ {
+ DEBUG ((EFI_D_INFO, "MSHC::CLK=50M.\n"));
+ // DDR mode use CLKDIV MPLL = 800, SCLK = 400, cclk_in=100M
+ MmioAndThenOr32 ((CumBaseAddr + CLK_DIV_FSYS1_OFFSET), ~(0xFFFF), 0x1);
+ MmioWrite32 ((SdMmcBaseAddr + MSHCI_CLKDIV), 1);
+
+ MSHC_Set_DDR(BUSMODE_DDR);
+ //MmioWrite32 ((SdMmcBaseAddr + MSHCI_CMD), CMD_ONLY_CLK);
+ }
+
+//#if defined(CONFIG_CPU_EXYNOS5250_EVT1)
+ MSHC_clock_onoff(CLK_ENABLE);
+ //MmioOr32 ((SdMmcBaseAddr + CLKCON_OFFSET), ICE);
+
+ //Poll till Internal Clock Stable
+ //while ((MmioRead32 ((SdMmcBaseAddr + CLKCON_OFFSET)) & ICS) != ICS);
+
+ //Set Clock enable to 0x1 to provide the clock to the card
+ //MmioOr32 ((SdMmcBaseAddr + CLKCON_OFFSET), CCE);
+
+}
+
+extern MSHC_OPERATION_MODE MSHC_operation_mode;
+void mshci_set_mdma_desc(UINT8 *desc_vir, UINT8 *desc_phy,
+ UINT32 des0, UINT32 des1, UINT32 des2)
+{
+ ((struct mshci_idmac *)(desc_vir))->des0 = des0;
+ ((struct mshci_idmac *)(desc_vir))->des1 = des1;
+ ((struct mshci_idmac *)(desc_vir))->des2 = des2;
+ ((struct mshci_idmac *)(desc_vir))->des3 = (UINT32)desc_phy +
+ sizeof(struct mshci_idmac);
+}
+
+
+VOID
+PrepareTransfer (
+IN OUT VOID *Buffer, UINTN BlockCount, IN OPERATION_TYPE OperationType
+ )
+{
+ UINT32 SdMmcBaseAddr;
+ UINT32 EmmcDMABufferBase;
+ volatile UINT32 MshcRegValue;
+ struct mshci_idmac *pdesc_dmac;
+ UINT32 des_flag;
+ UINTN i=0;
+ UINT32 ByteCnt=0;
+ UINT32 BlockCnt=BlockCount;
+// UINT32 MSH_uDES_A_0, MSH_uDES_A_1, MSH_uDES_A_2, MSH_uDES_A_3;
+
+ SdMmcBaseAddr = PcdGet32(PcdSdMmcCH0Base);
+#if DMA_UNCACHE_ALLOC
+ EmmcDMABufferBase = (UINT32)DMABuffer;
+#else
+ EmmcDMABufferBase = PcdGet32(PcdEmmcDMABufferBase);
+#endif
+ //pdesc_dmac = idmac_desc;
+ pdesc_dmac = (struct mshci_idmac *)EmmcDMABufferBase;
+
+ if(MSHC_operation_mode==MSHC_FIFO)
+ {
+ MSHC_reset_fifo();
+
+ // 1. enable interrupt mode
+ MshcRegValue = MmioRead32(SdMmcBaseAddr + MSHCI_CTRL);
+ MshcRegValue |= INT_ENABLE;
+ MmioWrite32 ((SdMmcBaseAddr + MSHCI_CTRL), MshcRegValue);
+
+ // 2. DDR mode
+
+ // 3. set BLKSIZE
+ MmioWrite32 ((SdMmcBaseAddr + MSHCI_BLKSIZ), BLEN_512BYTES);
+ //MmioWrite32 ((SdMmcBaseAddr + MSHCI_BLKSIZ), BLKSIZE_1);
+
+ // 4. set BYTCNT
+ MmioWrite32 ((SdMmcBaseAddr + MSHCI_BYTCNT), BLEN_512BYTES);
+
+ //Setting Data timeout counter value to max value.
+ MmioWrite32((SdMmcBaseAddr + MSHCI_TMOUT), (0xffffffff));
+
+ }
+ else if(MSHC_operation_mode==MSHC_IDMA)
+ {
+ ZeroMem ((VOID *)EmmcDMABufferBase, PHY_BUF_OFFSET);//20120608
+ if(OperationType==WRITE)
+ {
+ CopyMem((VOID *)(EmmcDMABufferBase+PHY_BUF_OFFSET), (VOID *)Buffer, BlockCount*BLEN_512BYTES);
+ //DEBUG ((EFI_D_INFO, "MSHC_DMA prepare WRITE:%d Block \n", BlockCount));
+ }
+ else
+ {
+ //DEBUG ((EFI_D_INFO, "MSHC_DMA prepare READ:%d Block \n", BlockCount));
+ }
+
+ MSHC_reset_fifo();
+
+ //IDMA reset
+ MshcRegValue = MmioRead32(SdMmcBaseAddr + MSHCI_BMOD);
+ MshcRegValue |= (BMOD_IDMAC_RESET);
+ MmioWrite32 ((SdMmcBaseAddr + MSHCI_BMOD), MshcRegValue);
+
+
+ // 1. enable IDMA at CTRL
+ MshcRegValue = MmioRead32(SdMmcBaseAddr + MSHCI_CTRL);
+ MshcRegValue &= ~(INT_ENABLE);
+ MshcRegValue |= (ENABLE_IDMAC);
+ MmioWrite32 ((SdMmcBaseAddr + MSHCI_CTRL), MshcRegValue);
+
+
+ // 2. enable IDMA at BMODE
+ //Set Block Size and Block count.
+ MshcRegValue = MmioRead32(SdMmcBaseAddr + MSHCI_BMOD);
+ MshcRegValue |= (BMOD_IDMAC_ENABLE | BMOD_IDMAC_FB);
+ MmioWrite32 ((SdMmcBaseAddr + MSHCI_BMOD), MshcRegValue);
+
+ // interrupt enable
+ MmioWrite32((SdMmcBaseAddr + MSHCI_IDINTEN), (0x337));
+
+#if 0
+#if 0
+ // set descriptor singlechain
+ des_flag = 0x8000000E;
+ MSH_uDES_A_0 = (EmmcDMABufferBase+0x02F000);
+ MSH_uDES_A_1 = (EmmcDMABufferBase+0x02F004);
+ MSH_uDES_A_2 = (EmmcDMABufferBase+0x02F008);
+ MSH_uDES_A_3 = (EmmcDMABufferBase+0x02F00C);
+ MmioWrite32(MSH_uDES_A_0, 0x8000000E);
+ MmioWrite32(MSH_uDES_A_1, (ByteCount));
+ MmioWrite32(MSH_uDES_A_2, (EmmcDMABufferBase+PHY_BUF_OFFSET));
+ MmioWrite32(MSH_uDES_A_3, MSH_uDES_A_0);
+#endif
+
+
+
+ des_flag = (MSHCI_IDMAC_OWN | MSHCI_IDMAC_FS | MSHCI_IDMAC_DIC | MSHCI_IDMAC_LD);
+ mshci_set_mdma_desc((UINT8 *)pdesc_dmac,
+ (UINT8 *)pdesc_dmac,
+ des_flag, ByteCount,
+ ((UINT32)(EmmcDMABufferBase + PHY_BUF0_OFFSET)));
+
+ MmioWrite32 ((SdMmcBaseAddr + MSHCI_DBADDR), (UINT32)pdesc_dmac);
+
+
+
+#else
+
+ for(i=0; ; i++)
+ {
+ // set descriptor multichain
+ des_flag = (MSHCI_IDMAC_OWN|MSHCI_IDMAC_CH);
+ des_flag |= (i==0) ? MSHCI_IDMAC_FS:0;
+ if(BlockCnt<=8)
+ {
+ //DEBUG ((EFI_D_INFO, "DESC LD\n"));
+ des_flag |= (MSHCI_IDMAC_LD);
+ mshci_set_mdma_desc((UINT8 *)pdesc_dmac,
+ //(UINT8 *)pdesc_dmac,
+ (UINT8 *)(EmmcDMABufferBase-sizeof(struct mshci_idmac)),
+ des_flag, BlockCnt*BLEN_512BYTES,
+ ((UINT32)((EmmcDMABufferBase + PHY_BUF_OFFSET)+(UINT32)(i*PHY_BUF_SIZE))));
+ break;
+
+ }
+ //DEBUG ((EFI_D_INFO, "DESC FS\n"));
+ mshci_set_mdma_desc((UINT8 *)pdesc_dmac,
+ (UINT8 *)pdesc_dmac,
+ des_flag, BLEN_512BYTES*8,
+ ((UINT32)((EmmcDMABufferBase + PHY_BUF_OFFSET)+(UINT32)(i*PHY_BUF_SIZE))));
+
+ BlockCnt -=8;
+ pdesc_dmac++;
+
+ }
+
+ MmioWrite32 ((SdMmcBaseAddr + MSHCI_DBADDR), (UINT32)EmmcDMABufferBase);
+
+#endif
+
+ // 3. set BLKSIZE
+ MmioWrite32 ((SdMmcBaseAddr + MSHCI_BLKSIZ), BLEN_512BYTES);
+
+ // 4. set BYTCNT
+ ByteCnt = (BlockCount*BLEN_512BYTES);
+ MmioWrite32 ((SdMmcBaseAddr + MSHCI_BYTCNT), ByteCnt);
+
+ //Setting Data timeout counter value to max value.
+ MmioWrite32((SdMmcBaseAddr + MSHCI_TMOUT), (0xffffffff));
+ DEBUG ((EFI_D_INFO, "Block:%d BYTCNT:0x%x ByteCnt:0x%x\n", BlockCount,MmioRead32(SdMmcBaseAddr + MSHCI_BYTCNT), ByteCnt));
+
+ }
+
+}
+
+EFI_STATUS MSHC_ReadFIFO(IN UINTN Size32, OUT VOID *Buffer)
+{
+ EFI_STATUS Status;
+ UINT32 SdMmcBaseAddr;
+ UINTN *DataBuffer = Buffer;
+ UINTN BufSize=Size32;
+ UINTN FifoCount=0;
+ UINTN Count=0;
+
+ SdMmcBaseAddr = PcdGet32(PcdSdMmcCH0Base);
+ //Check controller status to make sure there is no error.
+
+ while (BufSize)
+ {
+ if((MmioRead32 (SdMmcBaseAddr + MSHCI_RINTSTS)) & INTMSK_RXDR)
+ {
+
+ //Read block worth of data.
+ FifoCount = GET_FIFO_COUNT(MmioRead32 (SdMmcBaseAddr + MSHCI_STATUS));
+ DEBUG ((EFI_D_INFO, "MSHC::ReadBlock DTO FIFO:%d\n", FifoCount));
+ for (Count = 0; Count < FifoCount; Count++)
+ {
+ *DataBuffer++ = MmioRead32 (SdMmcBaseAddr + MSHCI_FIFO);
+ }
+ MmioWrite32((SdMmcBaseAddr + MSHCI_RINTSTS), INTMSK_RXDR);
+ BufSize -= FifoCount;
+ }
+
+ else if((MmioRead32 (SdMmcBaseAddr + MSHCI_RINTSTS)) & INTMSK_DTO)
+ {
+
+ //Read block worth of data.
+ FifoCount = GET_FIFO_COUNT(MmioRead32 (SdMmcBaseAddr + MSHCI_STATUS));
+ DEBUG ((EFI_D_INFO, "MSHC::ReadBlock DTO FIFO:%d\n", FifoCount));
+ for (Count = 0; Count < FifoCount; Count++)
+ {
+ *DataBuffer++ = MmioRead32 (SdMmcBaseAddr + MSHCI_FIFO);
+ }
+ MmioWrite32((SdMmcBaseAddr + MSHCI_RINTSTS), INTMSK_DTO);
+ BufSize -= FifoCount;
+ }
+
+ else if((MmioRead32 (SdMmcBaseAddr + MSHCI_RINTSTS)) & (INTMSK_DCRC|INTMSK_DRTO|INTMSK_HTO|INTMSK_FRUN))
+ {
+ DEBUG ((EFI_D_INFO, "MSHC::ReadBlock Error RINT:0x%x\n", MmioRead32 (SdMmcBaseAddr + MSHCI_RINTSTS)));
+ return EFI_DEVICE_ERROR;
+ }
+
+ }
+
+ if(BufSize==0)
+ {
+ Status = EFI_SUCCESS;
+ }
+ else
+ {
+ Status = EFI_BAD_BUFFER_SIZE;
+ }
+ return Status;
+}
+
+EFI_STATUS MSHC_WriteFIFO(IN UINTN Size32, IN VOID *Buffer)
+{
+ UINT32 SdMmcBaseAddr;
+ UINTN *DataBuffer = Buffer;
+ UINTN BufSize=Size32;
+ UINTN Count=0;
+
+ SdMmcBaseAddr = PcdGet32(PcdSdMmcCH0Base);
+
+ if(BufSize>FIFO_SIZE)
+ {
+ DEBUG ((EFI_D_INFO, "MSHC::Error MSHC_WriteFIFO Bad buffer size\n"));
+ return EFI_BAD_BUFFER_SIZE;
+ }
+
+ //Write block worth of data.
+ for (Count = 0; Count < BufSize; Count++)
+ {
+ MmioWrite32 ((SdMmcBaseAddr + MSHCI_FIFO), *DataBuffer++);
+ }
+ return EFI_SUCCESS;
+
+}
+
+/*typedef
+VOID
+CopyMem (
+ IN VOID *Destination,
+ IN VOID *Source,
+ IN UINTN Length
+ );*/
+
+EFI_STATUS MSHC_ReadDMA(OUT VOID *Buffer, IN UINTN BlockCount)
+{
+ EFI_STATUS Status;
+ UINT32 SdMmcBaseAddr;
+ UINT32 EmmcDMABufferBase;
+ UINTN Count=MAX_RETRY_COUNT;
+ //UINT32 MshcRegValue;
+ //UINT32 TransferSize=0;
+
+ SdMmcBaseAddr = PcdGet32(PcdSdMmcCH0Base);
+#if DMA_UNCACHE_ALLOC
+ EmmcDMABufferBase = (UINT32)DMABuffer;
+#else
+ EmmcDMABufferBase = PcdGet32(PcdEmmcDMABufferBase);
+#endif
+ //Check controller status to make sure there is no error.
+
+ while (Count)
+ {
+ if((MmioRead32 (SdMmcBaseAddr + MSHCI_RINTSTS)) & INTMSK_DTO)
+ {
+ //TransferSize = MmioRead32 (SdMmcBaseAddr + MSHCI_TBBCNT);
+ CopyMem((VOID *)Buffer, (VOID *)(EmmcDMABufferBase+PHY_BUF_OFFSET), BlockCount*BLEN_512BYTES);
+ DEBUG ((EFI_D_INFO, "MSHC_ReadDMA Over %d Blocks\n", BlockCount));
+ break;
+ }
+ else if((MmioRead32 (SdMmcBaseAddr + MSHCI_RINTSTS)) & (DATA_ERR|DATA_TOUT))
+ {
+ DEBUG ((EFI_D_ERROR, "MSHC_ReadDMA Err RINT:0x%x\n", MmioRead32 (SdMmcBaseAddr + MSHCI_RINTSTS)));
+ }
+
+ else
+ {
+ Count--;
+ MicroSecondDelay(1);
+ DEBUG ((EFI_D_INFO, ".\n"));
+ }
+
+ }
+
+ if(Count!=0)
+ {
+ Status = EFI_SUCCESS;
+ }
+ else
+ {
+ DEBUG ((EFI_D_ERROR, "MSHC_ReadDMA bad buffer size RINT:0x%x\n", MmioRead32 (SdMmcBaseAddr + MSHCI_RINTSTS)));
+ Status = EFI_BAD_BUFFER_SIZE;
+ MmioWrite32 ((SdMmcBaseAddr + MSHCI_PLDMND), 7);
+
+ }
+ return Status;
+}
+
+EFI_STATUS MSHC_WriteDMA(IN VOID *Buffer, IN UINTN BlockCount)
+{
+ EFI_STATUS Status;
+ UINT32 SdMmcBaseAddr;
+ UINTN Count=MAX_RETRY_COUNT;
+
+ SdMmcBaseAddr = PcdGet32(PcdSdMmcCH0Base);
+ //Check controller status to make sure there is no error.
+
+ while (Count)
+ {
+ if((MmioRead32 (SdMmcBaseAddr + MSHCI_RINTSTS)) & INTMSK_DTO)
+ {
+ DEBUG ((EFI_D_INFO, "MSHC_writeDMA Over %d blocks\n", BlockCount));
+ break;
+ }
+ else
+ {
+ MicroSecondDelay(1);
+ Count--;
+ }
+
+ }
+
+ if(Count!=0)
+ {
+ Status = EFI_SUCCESS;
+ }
+ else
+ {
+ Status = EFI_BAD_BUFFER_SIZE;
+ MmioWrite32 ((SdMmcBaseAddr + MSHCI_PLDMND), 7);
+ DEBUG ((EFI_D_ERROR, "MSHC_writeDMA bad buffer size RINT:0x%x \n", MmioRead32 (SdMmcBaseAddr + MSHCI_RINTSTS)));
+ }
+ return Status;
+}
diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/eMMCDxe/eMMCDxe_5250.h b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/eMMCDxe/eMMCDxe_5250.h
new file mode 100755
index 000000000..56638ba44
--- /dev/null
+++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/eMMCDxe/eMMCDxe_5250.h
@@ -0,0 +1,322 @@
+/** @file
+
+ Copyright (c) 2012, Samsung Electronics Co. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _MSHCDXE_5250_H_
+#define _MSHCDXE_5250_H_
+
+
+/*
+ * Controller registers
+ */
+/*****************************************************/
+/* MSHC Internal Registers */
+/*****************************************************/
+
+#define MSHCI_CTRL 0x00 /* Control */
+#define MSHCI_PWREN 0x04 /* Power-enable */
+#define MSHCI_CLKDIV 0x08 /* Clock divider */
+#define MSHCI_CLKSRC 0x0C /* Clock source */
+#define MSHCI_CLKENA 0x10 /* Clock enable */
+#define MSHCI_TMOUT 0x14 /* Timeout */
+#define MSHCI_CTYPE 0x18 /* Card type */
+#define MSHCI_BLKSIZ 0x1C /* Block Size */
+#define MSHCI_BYTCNT 0x20 /* Byte count */
+#define MSHCI_INTMSK 0x24 /* Interrupt Mask */
+#define MSHCI_CMDARG 0x28 /* Command Argument */
+#define MSHCI_CMD 0x2C /* Command */
+#define MSHCI_RESP0 0x30 /* Response 0 */
+#define MSHCI_RESP1 0x34 /* Response 1 */
+#define MSHCI_RESP2 0x38 /* Response 2 */
+#define MSHCI_RESP3 0x3C /* Response 3 */
+#define MSHCI_MINTSTS 0x40 /* Masked interrupt status */
+#define MSHCI_RINTSTS 0x44 /* Raw interrupt status */
+#define MSHCI_STATUS 0x48 /* Status */
+#define MSHCI_FIFOTH 0x4C /* FIFO threshold */
+#define MSHCI_CDETECT 0x50 /* Card detect */
+#define MSHCI_WRTPRT 0x54 /* Write protect */
+#define MSHCI_GPIO 0x58 /* General Purpose IO */
+#define MSHCI_TCBCNT 0x5C /* Transferred CIU byte count */
+#define MSHCI_TBBCNT 0x60 /* Transferred host/DMA to/from byte count */
+#define MSHCI_DEBNCE 0x64 /* Card detect debounce */
+#define MSHCI_USRID 0x68 /* User ID */
+#define MSHCI_VERID 0x6C /* Version ID */
+#define MSHCI_HCON 0x70 /* Hardware Configuration */
+#define MSHCI_UHS_REG 0x74 /* UHS and DDR setting */
+#define MSHCI_BMOD 0x80 /* Bus mode register */
+#define MSHCI_PLDMND 0x84 /* Poll demand */
+#define MSHCI_DBADDR 0x88 /* Descriptor list base address */
+#define MSHCI_IDSTS 0x8C /* Internal DMAC status */
+#define MSHCI_IDINTEN 0x90 /* Internal DMAC interrupt enable */
+#define MSHCI_DSCADDR 0x94 /* Current host descriptor address */
+#define MSHCI_BUFADDR 0x98 /* Current host buffer address */
+#define MSHCI_CLKSEL 0x9C /* Drv/sample clock selection register */
+#define MSHCI_WAKEUPCON 0xA0 /* Wakeup control register */
+#define MSHCI_CLOCKCON 0xA4 /* Clock (delay) control register */
+#define MSHCI_FIFO 0x200
+#define MSHCI_FIFODAT(x) (x) /* FIFO data read write */
+
+
+/*****************************************************
+ * Control Register Register
+ * MSHCI_CTRL - offset 0x00
+ *****************************************************/
+
+#define CTRL_RESET (0x1<<0) /* Reset DWC_mobile_storage controller */
+#define FIFO_RESET (0x1<<1) /* Reset FIFO */
+#define DMA_RESET (0x1<<2) /* Reset DMA interface */
+#define INT_ENABLE (0x1<<4) /* Global interrupt enable/disable bit */
+#define DMA_ENABLE (0x1<<5) /* DMA transfer mode enable/disable bit */
+#define READ_WAIT (0x1<<6) /* For sending read-wait to SDIO cards */
+#define SEND_IRQ_RESP (0x1<<7) /* Send auto IRQ response */
+#define ABRT_READ_DATA (0x1<<8)
+#define SEND_CCSD (0x1<<9)
+#define SEND_AS_CCSD (0x1<<10)
+#define CEATA_INTSTAT (0x1<<11)
+#define CARD_VOLA (0xF<<16)
+#define CARD_VOLB (0xF<<20)
+#define ENABLE_OD_PULLUP (0x1<<24)
+#define ENABLE_IDMAC (0x1<<25)
+#define MSHCI_RESET_ALL (0x1)
+
+/*****************************************************
+ * Power Enable Register
+ * MSHCI_PWREN - offset 0x04
+ *****************************************************/
+#define POWER_ENABLE (0x1<<0)
+
+/*****************************************************
+* Clock Enable Register
+* MSHCI_CLKENA - offset 0x10
+*****************************************************/
+#define CLK_SDMMC_MAX (48000000) /* 96Mhz. it SHOULDBE optimized */
+#define CLK_ENABLE (0x1<<0)
+#define CLK_DISABLE (0x0<<0)
+
+
+/*****************************************************
+ * Interrupt Mask Register
+ * MSHCI_INTMSK - offset 0x24
+ *****************************************************/
+#define INT_MASK (0xFFFF<<0)
+#define SDIO_INT_MASK (0xFFFF<<16)
+#define SDIO_INT_ENABLE (0x1<<16)
+
+/* interrupt bits */
+#define INTMSK_ALL 0xFFFFFFFF
+#define INTMSK_CDETECT (0x1<<0)
+#define INTMSK_RE (0x1<<1)
+#define INTMSK_CDONE (0x1<<2)
+#define INTMSK_DTO (0x1<<3)
+#define INTMSK_TXDR (0x1<<4)
+#define INTMSK_RXDR (0x1<<5)
+#define INTMSK_RCRC (0x1<<6)
+#define INTMSK_DCRC (0x1<<7)
+#define INTMSK_RTO (0x1<<8)
+#define INTMSK_DRTO (0x1<<9)
+#define INTMSK_HTO (0x1<<10)
+#define INTMSK_FRUN (0x1<<11)
+#define INTMSK_HLE (0x1<<12)
+#define INTMSK_SBE (0x1<<13)
+#define INTMSK_ACD (0x1<<14)
+#define INTMSK_EBE (0x1<<15)
+#define INTMSK_DMA (INTMSK_ACD|INTMSK_RXDR|INTMSK_TXDR)
+
+#define INT_SRC_IDMAC (0x0)
+#define INT_SRC_MINT (0x1)
+
+
+/*****************************************************
+ * Command Register
+ * MSHCI_CMD - offset 0x2C
+ *****************************************************/
+
+#define CMD_RESP_EXP_BIT (0x1<<6)
+#define CMD_RESP_LENGTH_BIT (0x1<<7)
+#define CMD_CHECK_CRC_BIT (0x1<<8)
+#define CMD_DATA_EXP_BIT (0x1<<9)
+#define CMD_RW_BIT (0x1<<10)
+#define CMD_TRANSMODE_BIT (0x1<<11)
+#define CMD_SENT_AUTO_STOP_BIT (0x1<<12)
+#define CMD_WAIT_PRV_DAT_BIT (0x1<<13)
+#define CMD_ABRT_CMD_BIT (0x1<<14)
+#define CMD_SEND_INIT_BIT (0x1<<15)
+#define CMD_CARD_NUM_BITS (0x1F<<16)
+#define CMD_SEND_CLK_ONLY (0x1<<21)
+#define CMD_READ_CEATA (0x1<<22)
+#define CMD_CCS_EXPECTED (0x1<<23)
+#define CMD_USE_HOLD_REG (0x1<<29)
+#define CMD_STRT_BIT (0x1<<31)
+#define CMD_ONLY_CLK (CMD_STRT_BIT | CMD_SEND_CLK_ONLY | \
+ CMD_WAIT_PRV_DAT_BIT)
+
+/*****************************************************
+ * Raw Interrupt Register
+ * MSHCI_RINTSTS - offset 0x44
+ *****************************************************/
+#define INT_STATUS (0xFFFF<<0)
+#define SDIO_INTR (0xFFFF<<16)
+#define DATA_ERR (INTMSK_EBE|INTMSK_SBE|INTMSK_HLE|INTMSK_FRUN |\
+ INTMSK_EBE |INTMSK_DCRC)
+#define DATA_TOUT (INTMSK_HTO|INTMSK_DRTO)
+#define DATA_STATUS (DATA_ERR|DATA_TOUT|INTMSK_RXDR|INTMSK_TXDR|INTMSK_DTO)
+#define CMD_STATUS (INTMSK_RTO|INTMSK_RCRC|INTMSK_CDONE|INTMSK_RE)
+#define CMD_ERROR (INTMSK_RCRC|INTMSK_RTO|INTMSK_RE)
+
+
+/*****************************************************
+ * Status Register
+ * MSHCI_STATUS - offset 0x48
+ *****************************************************/
+#define FIFO_RXWTRMARK (0x1<<0)
+#define FIFO_TXWTRMARK (0x1<<1)
+#define FIFO_EMPTY (0x1<<2)
+#define FIFO_FULL (0x1<<3)
+#define CMD_FSMSTAT (0xF<<4)
+#define DATA_3STATUS (0x1<<8)
+#define DATA_BUSY (0x1<<9)
+#define DATA_MCBUSY (0x1<<10)
+#define RSP_INDEX (0x3F<<11)
+#define FIFO_COUNT (0x1FFF<<17)
+#define DMA_ACK (0x1<<30)
+#define DMA_REQ (0x1<<31)
+#define FIFO_WIDTH (0x4)
+#define FIFO_DEPTH (0x20)
+#define FIFO_SIZE (0x80)
+#define GET_FIFO_COUNT(x) (((x)&0x3ffe0000)>>17)
+
+
+
+/*****************************************************
+ * FIFO Threshold Watermark Register
+ * MSHCI_FIFOTH - offset 0x4C
+ *****************************************************/
+#define TX_WMARK (0xFFF<<0)
+#define RX_WMARK (0xFFF<<16)
+#define MSIZE_MASK (0x7<<28)
+
+/* DW DMA Mutiple Transaction Size */
+#define MSIZE_1 (0<<28)
+#define MSIZE_4 (1<<28)
+#define MSIZE_8 (2<<28)
+#define MSIZE_16 (3<<28)
+#define MSIZE_32 (4<<28)
+#define MSIZE_64 (5<<28)
+#define MSIZE_128 (6<<28)
+#define MSIZE_256 (7<<28)
+
+#define TX_WMARK_DEFAULT (0x10<<0)
+#define RX_WMARK_DEFAULT (0x10<<16)
+
+//#define TX_WMARK_DEFAULT (0x40<<0)
+//#define RX_WMARK_DEFAULT (0x3F<<16)
+
+
+/*****************************************************
+ * Bus Mode Register
+ * MSHCI_UHS_REG - offset 0x74
+ *****************************************************/
+#define UHS_DDR (0x1<<16)
+#define UHS_NON_DDR (0x0<<16)
+#define BUSMODE_DDR 1
+#define BUSMODE_NON_DDR 0
+
+/*****************************************************
+ * Bus Mode Register
+ * MSHCI_BMOD - offset 0x80
+ *****************************************************/
+#define BMOD_IDMAC_RESET (0x1<<0)
+#define BMOD_IDMAC_FB (0x1<<1)
+#define BMOD_IDMAC_ENABLE (0x1<<7)
+
+/*****************************************************
+ * Hardware Configuration Register
+ * MSHCI_IDSTS - offset 0x8c
+ *****************************************************/
+#define IDSTS_FSM (0xf<<13)
+#define IDSTS_EB (0x7<<10)
+#define IDSTS_AIS (0x1<<9)
+#define IDSTS_NIS (0x1<<8)
+#define IDSTS_CES (0x1<<5)
+#define IDSTS_DU (0x1<<4)
+#define IDSTS_FBE (0x1<<2)
+#define IDSTS_RI (0x1<<1)
+#define IDSTS_TI (0x1<<0)
+
+
+/*****************************************************
+ * Card Type Register
+ * MSHCI_CTYPE - offset 0x18
+ *****************************************************/
+#define CARD_WIDTH14 (0xFFFF<<0)
+#define CARD_WIDTH8 (0xFFFF<<16)
+
+struct mshci_idmac {
+ UINT32 des0;
+ UINT32 des1;
+ UINT32 des2;
+ UINT32 des3;
+#define MSHCI_IDMAC_OWN (1<<31)
+#define MSHCI_IDMAC_ER (1<<5)
+#define MSHCI_IDMAC_CH (1<<4)
+#define MSHCI_IDMAC_FS (1<<3)
+#define MSHCI_IDMAC_LD (1<<2)
+#define MSHCI_IDMAC_DIC (1<<1)
+#define INTMSK_IDMAC_ALL (0x337)
+#define INTMSK_IDMAC_ERROR (0x214)
+};
+
+typedef enum {
+ READ,
+ WRITE
+} OPERATION_TYPE;
+
+
+/*****************************************************
+ * DMA Buffer structure
+ *
+ * CH0 for eMMC 0x40300000--0x40380000
+ * CH2 for SD Card 0x40380000--0x40400000
+
+
+ *****************************************************/
+#define EMMC_DMA_PHYSICAL_BUFFER_BASE 0x40300000
+#define EMMC_DMA_PHYSICAL_BUFFER_SIZE 0x00100000 //1MB
+#define PHY_BUF_OFFSET 0x1000 //4K
+#define PHY_BUF_SIZE 0x1000 //4K
+
+#define MAX_MSHC_TRANSFER_SIZE 0x40000 //512blocks, 256KB
+
+
+
+/*****************************************************
+ * External Functions
+ *****************************************************/
+
+
+EFI_STATUS InitializeMSHC (VOID);
+VOID UpdateMSHCClkFrequency (UINTN NewCLK);
+void MSHC_reset_fifo(void);
+extern void MSHC_reset_all(void);
+extern VOID PrepareTransfer (IN OUT VOID *Buffer, UINTN ByteCount, IN OPERATION_TYPE OperationType);
+extern EFI_STATUS MSHC_ReadFIFO(IN UINTN Size32, OUT VOID *Buffer);
+extern EFI_STATUS MSHC_WriteFIFO(IN UINTN Size32, IN VOID *Buffer);
+void mshci_set_mdma_desc(UINT8 *desc_vir, UINT8 *desc_phy,
+ UINT32 des0, UINT32 des1, UINT32 des2);
+EFI_STATUS MSHC_ReadDMA(OUT VOID *Buffer, IN UINTN BlockCount);
+EFI_STATUS MSHC_WriteDMA(IN VOID *Buffer, IN UINTN BlockCount);
+
+
+
+#endif
+
diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/eMMCDxe/eMMCDxe_CMD.h b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/eMMCDxe/eMMCDxe_CMD.h
new file mode 100755
index 000000000..615da0799
--- /dev/null
+++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/eMMCDxe/eMMCDxe_CMD.h
@@ -0,0 +1,165 @@
+/** @file
+
+ Copyright (c) 2012, Samsung Electronics Co. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _MSHCDXE_CMD_H_
+#define _MSHCDXE_CMD_H_
+
+
+
+#define HosttoCard 0x1
+#define CardtoHost 0x0
+
+#define ENDMA BIT0
+#define ENBLKCNT BIT1
+#define RD1WT0 BIT4
+#define MUL1SIN0 BIT5
+#define RSPTYP136 (0x1 << 16)
+#define RSPTYP48 (0x2 << 16)
+#define RSPTYP48B (0x3 << 16)
+#define ENCMDCRC BIT19
+#define ENCMDIDX BIT20
+#define DATAPRNT BIT21
+
+
+#define CMDCOMP BIT0
+#define TRNSCOMP BIT1
+#define RDYFORWT BIT4
+#define RDYFORRD BIT5
+#define CARDINSERT BIT6
+#define CARDREMOVE BIT7
+#define ERRINT BIT15
+#define CMDTOUTERR BIT16
+#define CMDCRCERR BIT17
+#define CMDEBITERR BIT18
+#define CMDIDXERR BIT19
+#define DATATOUTERR BIT20
+#define DATACRCERR BIT21
+#define DATAEBITERR BIT22
+
+
+
+
+/* Command Definitions */
+#define INDX(CMD_INDX) (CMD_INDX & 0x3F)
+
+#define CMD0 INDX(0)
+#define CMD0_INT_EN (CMDCOMP | CMDEBITERR)
+
+#define CMD1 (INDX(1) | RSPTYP48)
+#define CMD1_INT_EN (CMDCOMP | CMDEBITERR | CMDTOUTERR)
+
+#define CMD2 (INDX(2) | ENCMDCRC | RSPTYP136)
+#define CMD2_INT_EN (CMDIDXERR | CMDCRCERR | CMDCOMP | CMDEBITERR | CMDTOUTERR)
+
+#define CMD3 (INDX(3) | ENCMDIDX | ENCMDCRC | RSPTYP48)
+#define CMD3_INT_EN (CMDIDXERR | CMDCRCERR | CMDCOMP | CMDEBITERR | CMDTOUTERR)
+
+#define CMD5 (INDX(5) | RSPTYP48)
+#define CMD5_INT_EN (CMDCOMP | CMDEBITERR | CMDTOUTERR)
+
+#define CMD7 (INDX(7) | ENCMDIDX | ENCMDCRC | RSPTYP48)
+#define CMD7_INT_EN (CMDIDXERR | CMDCRCERR | CMDCOMP | CMDEBITERR | CMDTOUTERR)
+
+#define CMD8 (INDX(8) | ENCMDIDX | ENCMDCRC | RSPTYP48)
+#define CMD8_INT_EN (CMDIDXERR | CMDCRCERR | CMDCOMP | CMDEBITERR | CMDTOUTERR)
+//Reserved(0)[12:31], Supply voltage(1)[11:8], check pattern(0xCE)[7:0] = 0x1CE
+#define CMD8_ARG (0x0UL << 12 | BIT8 | 0xCEUL << 0)
+
+#define CMD9 (INDX(9) | ENCMDCRC | RSPTYP136)
+#define CMD9_INT_EN (CMDCRCERR | CMDCOMP | CMDEBITERR | CMDTOUTERR)
+
+#define CMD13 (INDX(13) | RSPTYP48)
+#define CMD13_INT_EN (CMDCOMP | CMDEBITERR | CMDTOUTERR)
+
+
+//#define CMD16 (INDX(16) | ENCMDIDX | ENCMDCRC | RSPTYP48)
+#define CMD16 (INDX(16) | ENCMDIDX | RSPTYP48)
+#define CMD16_INT_EN (CMDIDXERR | CMDCRCERR | CMDCOMP | CMDEBITERR | CMDTOUTERR)
+
+#define CMD17 (INDX(17) | DATAPRNT | ENCMDIDX | ENCMDCRC | RSPTYP48 | RD1WT0)
+#define CMD17_INT_EN (CMDIDXERR | CMDCRCERR | CMDCOMP | TRNSCOMP | RDYFORRD | CMDTOUTERR | DATATOUTERR | DATACRCERR | DATAEBITERR | CMDEBITERR)
+
+//#define CMD18 (INDX(18) | DATAPRNT | ENCMDIDX | ENCMDCRC | RSPTYP48 | MUL1SIN0 | RD1WT0 | ENBLKCNT | ENDMA)
+#define CMD18 (INDX(18) | DATAPRNT | ENCMDIDX | ENCMDCRC | RSPTYP48 )
+#define CMD18_INT_EN (CMDIDXERR | CMDCRCERR | CMDCOMP | TRNSCOMP | RDYFORRD | CMDTOUTERR | DATATOUTERR | DATACRCERR | DATAEBITERR | CMDEBITERR)
+
+#define CMD23 (INDX(23) | ENCMDIDX | ENCMDCRC | RSPTYP48)
+#define CMD23_INT_EN (CMDIDXERR | CMDCRCERR | CMDCOMP | CMDEBITERR | CMDTOUTERR)
+
+#define CMD24 (INDX(24) | DATAPRNT | ENCMDIDX | ENCMDCRC | RSPTYP48)
+#define CMD24_INT_EN (CMDIDXERR | CMDCRCERR | CMDCOMP | TRNSCOMP | RDYFORWT | CMDTOUTERR | DATATOUTERR | DATACRCERR | DATAEBITERR | CMDEBITERR)
+
+//#define CMD25 (INDX(25) | DATAPRNT | ENCMDIDX | ENCMDCRC | RSPTYP48 | MUL1SIN0 | ENBLKCNT | ENDMA)
+#define CMD25 (INDX(25) | DATAPRNT | ENCMDIDX | ENCMDCRC | RSPTYP48)
+#define CMD25_INT_EN (CMDIDXERR | CMDCRCERR | CMDCOMP | TRNSCOMP | RDYFORWT | CMDTOUTERR | DATATOUTERR | DATACRCERR | DATAEBITERR | CMDEBITERR)
+
+#define CMD35 (INDX(35) | ENCMDCRC | RSPTYP48)
+#define CMD36 (INDX(36) | ENCMDCRC | RSPTYP48)
+#define CMD38 (INDX(38) |RSPTYP48)
+
+#define CMD55 (INDX(55) | ENCMDIDX | ENCMDCRC | RSPTYP48)
+#define CMD55_INT_EN (CMDIDXERR | CMDCRCERR | CMDCOMP | CMDEBITERR | CMDTOUTERR)
+
+#define ACMD41 (INDX(41) | RSPTYP48)
+#define ACMD41_INT_EN (CMDIDXERR | CMDCRCERR | CMDCOMP | CMDEBITERR | CMDTOUTERR)
+
+#define ACMD6 (INDX(6) | RSPTYP48)
+#define ACMD6_INT_EN (CMDIDXERR | CMDCRCERR | CMDCOMP | CMDEBITERR | CMDTOUTERR)
+
+#define CMD62 (INDX(62) | RSPTYP48)
+#define CMD62_INT_EN (CMDIDXERR | CMDCRCERR | CMDCOMP | CMDEBITERR | CMDTOUTERR)
+
+
+
+/*
+EFI_STATUS
+EFI_SUCCESS 0
+
+EFI_LOAD_ERROR 1
+EFI_INVALID_PARAMETER 2
+EFI_UNSUPPORTED 3
+EFI_BAD_BUFFER_SIZE 4
+EFI_BUFFER_TOO_SMALL 5
+EFI_NOT_READY 6
+EFI_DEVICE_ERROR 7
+EFI_WRITE_PROTECTED 8
+EFI_OUT_OF_RESOURCES 9
+EFI_VOLUME_CORRUPTED 10
+EFI_VOLUME_FULL 11
+EFI_NO_MEDIA 12
+EFI_MEDIA_CHANGED 13
+EFI_NOT_FOUND 14
+EFI_ACCESS_DENIED 15
+EFI_NO_RESPONSE 16
+EFI_NO_MAPPING 17
+EFI_TIMEOUT 18
+EFI_NOT_STARTED 19
+EFI_ALREADY_STARTED 20
+EFI_ABORTED 21
+EFI_ICMO_ERROR 22
+EFI_TFTP_ERROR 23
+EFI_PROTOCOL_ERROR 24
+EFI_INCOMPATIBLE_VERSION 25
+EFI_SECURITY_VIOLATION 26
+EFI_CRC_ERROR 27
+EFI_END_OF_MEDIA 28
+EFI_END_OF_FILE 31
+EFI_INVALID_LANGUAGE 32
+EFI_COMPROMISED_DATA 33
+
+
+*/
+
+#endif
+
diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/eMMCDxe/eMMC_Fvb.c b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/eMMCDxe/eMMC_Fvb.c
new file mode 100755
index 000000000..ee8d1c902
--- /dev/null
+++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/eMMCDxe/eMMC_Fvb.c
@@ -0,0 +1,587 @@
+/** @file
+ eMMC firmware volume block protocol driver
+ Copyright (c) 2012, Samsung Electronics Co. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <PiDxe.h>
+
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiLib.h>
+#include <Library/PcdLib.h>
+#include <Library/UncachedMemoryAllocationLib.h>
+
+#include <Protocol/FirmwareVolumeBlock.h>
+#include "eMMCDxe.h"
+
+
+//#undef EFI_D_INFO
+//#define EFI_D_INFO 1
+
+
+EFI_FVB_ATTRIBUTES_2 gAttribute = (EFI_FVB2_READ_STATUS|EFI_FVB2_WRITE_STATUS|EFI_FVB2_ALIGNMENT_32);
+UINT32 *FVBMemAddr;
+
+/**
+ The GetAttributes() function retrieves the attributes and
+ current settings of the block.
+
+ @param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance.
+
+ @param Attributes Pointer to EFI_FVB_ATTRIBUTES_2 in which the
+ attributes and current settings are
+ returned. Type EFI_FVB_ATTRIBUTES_2 is defined
+ in EFI_FIRMWARE_VOLUME_HEADER.
+
+ @retval EFI_SUCCESS The firmware volume attributes were
+ returned.
+
+**/
+
+EFI_STATUS
+EFIAPI
+FvbGetAttributes (
+ IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This,
+ OUT EFI_FVB_ATTRIBUTES_2 *Attributes
+ )
+{
+ *Attributes = gAttribute;
+ DEBUG ((EFI_D_INFO, "FvbGetAttributes 0x%x\n", gAttribute));
+ return EFI_SUCCESS;
+}
+
+
+/**
+ The SetAttributes() function sets configurable firmware volume
+ attributes and returns the new settings of the firmware volume.
+
+
+ @param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance.
+
+ @param Attributes On input, Attributes is a pointer to
+ EFI_FVB_ATTRIBUTES_2 that contains the
+ desired firmware volume settings. On
+ successful return, it contains the new
+ settings of the firmware volume. Type
+ EFI_FVB_ATTRIBUTES_2 is defined in
+ EFI_FIRMWARE_VOLUME_HEADER.
+
+ @retval EFI_SUCCESS The firmware volume attributes were returned.
+
+ @retval EFI_INVALID_PARAMETER The attributes requested are in
+ conflict with the capabilities
+ as declared in the firmware
+ volume header.
+
+**/
+EFI_STATUS
+EFIAPI
+FvbSetAttributes (
+ IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This,
+ IN OUT EFI_FVB_ATTRIBUTES_2 *Attributes
+ )
+{
+ gAttribute |= *Attributes;
+ *Attributes = gAttribute;
+ DEBUG ((EFI_D_INFO, "FvbSetAttributes 0x%x\n", gAttribute));
+ return EFI_SUCCESS;
+}
+
+
+/**
+ The GetPhysicalAddress() function retrieves the base address of
+ a memory-mapped firmware volume. This function should be called
+ only for memory-mapped firmware volumes.
+
+ @param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance.
+
+ @param Address Pointer to a caller-allocated
+ EFI_PHYSICAL_ADDRESS that, on successful
+ return from GetPhysicalAddress(), contains the
+ base address of the firmware volume.
+
+ @retval EFI_SUCCESS The firmware volume base address was returned.
+
+ @retval EFI_NOT_SUPPORTED The firmware volume is not memory mapped.
+
+**/
+EFI_STATUS
+EFIAPI
+FvbGetPhysicalAddress (
+ IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This,
+ OUT EFI_PHYSICAL_ADDRESS *Address
+ )
+{
+ UINT32 NVBase = PcdGet32(PcdFlashNvStorageVariableBase);
+ UINT32 NVSize = PcdGet32(PcdFlashNvStorageVariableSize);
+
+ DEBUG ((EFI_D_INFO, "FvbGetPhysicalAddress Base:0x%x, Size:0x%x\n", NVBase, NVSize));
+
+ if(FVBMemAddr==NULL)
+ {
+ FVBMemAddr = (UINT32 *)UncachedAllocatePool(NVSize);
+ DEBUG ((EFI_D_INFO, "FvbGetPhysicalAddress MEM Alloc 0x%x\n", FVBMemAddr));
+
+ if(FVBMemAddr==NULL)
+ {
+ DEBUG ((EFI_D_ERROR, "FvbGetPhysicalAddress Alloc failed \n"));
+ return EFI_UNSUPPORTED;
+ }
+ }
+ else
+ {
+ DEBUG ((EFI_D_INFO, "FvbGetPhysicalAddress already Allocated 0x%x \n", FVBMemAddr));
+ }
+
+ CopyMem((VOID *)FVBMemAddr, (VOID *)NVBase, NVSize);
+ Address = (EFI_PHYSICAL_ADDRESS *)FVBMemAddr;
+ DEBUG ((EFI_D_INFO, "FvbGetPhysicalAddress Addr:0x%x\n", Address));
+ return EFI_SUCCESS;
+}
+
+
+/**
+ The GetBlockSize() function retrieves the size of the requested
+ block. It also returns the number of additional blocks with
+ the identical size. The GetBlockSize() function is used to
+ retrieve the block map (see EFI_FIRMWARE_VOLUME_HEADER).
+
+
+ @param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance.
+
+ @param Lba Indicates the block for which to return the size.
+
+ @param BlockSize Pointer to a caller-allocated UINTN in which
+ the size of the block is returned.
+
+ @param NumberOfBlocks Pointer to a caller-allocated UINTN in
+ which the number of consecutive blocks,
+ starting with Lba, is returned. All
+ blocks in this range have a size of
+ BlockSize.
+
+
+ @retval EFI_SUCCESS The firmware volume base address was returned.
+
+ @retval EFI_INVALID_PARAMETER The requested LBA is out of range.
+
+**/
+EFI_STATUS
+EFIAPI
+FvbGetBlockSize (
+ IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This,
+ IN EFI_LBA Lba,
+ OUT UINTN *BlockSize,
+ OUT UINTN *NumberOfBlocks
+ )
+{
+ EFI_STATUS status = EFI_SUCCESS;
+ *BlockSize = gSDMMCMedia.BlockSize;
+ *NumberOfBlocks = 512;
+ DEBUG ((EFI_D_INFO, "FvbGetBlockSize numblocks:%d\n", *NumberOfBlocks));
+ return status;
+}
+
+
+
+/**
+ Reads the specified number of bytes into a buffer from the specified block.
+
+ The Read() function reads the requested number of bytes from the
+ requested block and stores them in the provided buffer.
+ Implementations should be mindful that the firmware volume
+ might be in the ReadDisabled state. If it is in this state,
+ the Read() function must return the status code
+ EFI_ACCESS_DENIED without modifying the contents of the
+ buffer. The Read() function must also prevent spanning block
+ boundaries. If a read is requested that would span a block
+ boundary, the read must read up to the boundary but not
+ beyond. The output parameter NumBytes must be set to correctly
+ indicate the number of bytes actually read. The caller must be
+ aware that a read may be partially completed.
+
+ @param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance.
+
+ @param Lba The starting logical block index
+ from which to read.
+
+ @param Offset Offset into the block at which to begin reading.
+
+ @param NumBytes Pointer to a UINTN. At entry, *NumBytes
+ contains the total size of the buffer. At
+ exit, *NumBytes contains the total number of
+ bytes read.
+
+ @param Buffer Pointer to a caller-allocated buffer that will
+ be used to hold the data that is read.
+
+ @retval EFI_SUCCESS The firmware volume was read successfully,
+ and contents are in Buffer.
+
+ @retval EFI_BAD_BUFFER_SIZE Read attempted across an LBA
+ boundary. On output, NumBytes
+ contains the total number of bytes
+ returned in Buffer.
+
+ @retval EFI_ACCESS_DENIED The firmware volume is in the
+ ReadDisabled state.
+
+ @retval EFI_DEVICE_ERROR The block device is not
+ functioning correctly and could
+ not be read.
+
+**/
+EFI_STATUS
+EFIAPI
+FvbRead (
+ IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This,
+ IN EFI_LBA Lba,
+ IN UINTN Offset,
+ IN OUT UINTN *NumBytes,
+ IN OUT UINT8 *Buffer
+ )
+{
+ EFI_BLOCK_IO_PROTOCOL *EFIBlockIO = (EFI_BLOCK_IO_PROTOCOL *)This;
+ EFI_STATUS status = EFI_SUCCESS;
+ VOID *TempBuf = NULL;
+ UINT32 NumBlock;
+ UINT32 AllocSize=0;
+ Lba += MSHC_BOOT_SECURE_OFFSET;
+
+ DEBUG ((EFI_D_INFO, "FvbRead Offset : %d, Numbytes : %d\n", Offset, *NumBytes));
+
+ if(gCardInit==TRUE)
+ {
+ if (0 == (*NumBytes%gSDMMCMedia.BlockSize))
+ {
+ NumBlock = (*NumBytes/gSDMMCMedia.BlockSize);
+ }
+ else
+ {
+ NumBlock = (*NumBytes/gSDMMCMedia.BlockSize) + 1;
+ }
+ //DEBUG ((EFI_D_INFO, "FvbRead numblock : %d, BlockSize : %d\n", NumBlock, gSDMMCMedia.BlockSize));
+
+ AllocSize = NumBlock*gSDMMCMedia.BlockSize;
+ TempBuf = AllocatePool(AllocSize);
+ //ZeroMem (TempBuf, NumBlock*gSDMMCMedia.BlockSize);
+ if(TempBuf==NULL)
+ {
+ DEBUG ((EFI_D_ERROR, "FvbRead AllocatePool Failed!!\n"));
+ status = EFI_DEVICE_ERROR;
+ goto Exit;
+ }
+
+ status = SdReadWrite(EFIBlockIO, Lba, TempBuf, AllocSize, READ);
+ if(status!=EFI_SUCCESS)
+ {
+ DEBUG ((EFI_D_ERROR, "FvbRead Failed 0x%x\n", status));
+ status = EFI_ACCESS_DENIED;
+ goto Exit;
+ }
+
+ CopyMem((VOID *)Buffer, (VOID *)(TempBuf+Offset), *NumBytes);
+ }
+
+ Exit:
+
+ if (TempBuf != NULL)
+ {
+ FreePool(TempBuf);
+ }
+
+ return status;
+}
+
+
+/**
+ Writes the specified number of bytes from the input buffer to the block.
+
+ The Write() function writes the specified number of bytes from
+ the provided buffer to the specified block and offset. If the
+ firmware volume is sticky write, the caller must ensure that
+ all the bits of the specified range to write are in the
+ EFI_FVB_ERASE_POLARITY state before calling the Write()
+ function, or else the result will be unpredictable. This
+ unpredictability arises because, for a sticky-write firmware
+ volume, a write may negate a bit in the EFI_FVB_ERASE_POLARITY
+ state but cannot flip it back again. Before calling the
+ Write() function, it is recommended for the caller to first call
+ the EraseBlocks() function to erase the specified block to
+ write. A block erase cycle will transition bits from the
+ (NOT)EFI_FVB_ERASE_POLARITY state back to the
+ EFI_FVB_ERASE_POLARITY state. Implementations should be
+ mindful that the firmware volume might be in the WriteDisabled
+ state. If it is in this state, the Write() function must
+ return the status code EFI_ACCESS_DENIED without modifying the
+ contents of the firmware volume. The Write() function must
+ also prevent spanning block boundaries. If a write is
+ requested that spans a block boundary, the write must store up
+ to the boundary but not beyond. The output parameter NumBytes
+ must be set to correctly indicate the number of bytes actually
+ written. The caller must be aware that a write may be
+ partially completed. All writes, partial or otherwise, must be
+ fully flushed to the hardware before the Write() service
+ returns.
+
+ @param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance.
+
+ @param Lba The starting logical block index to write to.
+
+ @param Offset Offset into the block at which to begin writing.
+
+ @param NumBytes The pointer to a UINTN. At entry, *NumBytes
+ contains the total size of the buffer. At
+ exit, *NumBytes contains the total number of
+ bytes actually written.
+
+ @param Buffer The pointer to a caller-allocated buffer that
+ contains the source for the write.
+
+ @retval EFI_SUCCESS The firmware volume was written successfully.
+
+ @retval EFI_BAD_BUFFER_SIZE The write was attempted across an
+ LBA boundary. On output, NumBytes
+ contains the total number of bytes
+ actually written.
+
+ @retval EFI_ACCESS_DENIED The firmware volume is in the
+ WriteDisabled state.
+
+ @retval EFI_DEVICE_ERROR The block device is malfunctioning
+ and could not be written.
+
+
+**/
+EFI_STATUS
+EFIAPI
+FvbWrite (
+ IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This,
+ IN EFI_LBA Lba,
+ IN UINTN Offset,
+ IN OUT UINTN *NumBytes,
+ IN UINT8 *Buffer
+ )
+{
+ EFI_BLOCK_IO_PROTOCOL *EFIBlockIO = (EFI_BLOCK_IO_PROTOCOL *)This;
+ EFI_STATUS status = EFI_SUCCESS;
+ VOID *TempBuf = NULL;
+ UINT32 NumBlock;
+ UINT32 AllocSize=0;
+ Lba += MSHC_BOOT_SECURE_OFFSET;
+
+ DEBUG ((EFI_D_INFO, "FvbWrite Offset : %d, Numbyte : %d\n", Offset, *NumBytes));
+
+ if(gCardInit==TRUE)
+ {
+ if (0 == (*NumBytes%gSDMMCMedia.BlockSize))
+ {
+ NumBlock = (*NumBytes/gSDMMCMedia.BlockSize);
+ }
+ else
+ {
+ NumBlock = (*NumBytes/gSDMMCMedia.BlockSize) + 1;
+ }
+ //DEBUG ((EFI_D_INFO, "FvbWrite numblock : %d, BlockSize : %d\n", NumBlock, gSDMMCMedia.BlockSize));
+
+ AllocSize = (NumBlock*gSDMMCMedia.BlockSize);
+ TempBuf = AllocatePool(AllocSize);
+ //ZeroMem (TempBuf, NumBlock*gSDMMCMedia.BlockSize);
+ if(TempBuf==NULL)
+ {
+ DEBUG ((EFI_D_ERROR, "FvbWrite AllocatePool Failed!!\n"));
+ status = EFI_DEVICE_ERROR;
+ goto Exit;
+ }
+
+ status = SdReadWrite(EFIBlockIO, Lba, TempBuf, AllocSize, READ);
+ if(status!=EFI_SUCCESS)
+ {
+ DEBUG ((EFI_D_ERROR, "FvbWrite Read Failed 0x%x\n", status));
+ status = EFI_DEVICE_ERROR;
+ goto Exit;
+ }
+
+ CopyMem((VOID *)(TempBuf+Offset), (VOID *)Buffer, *NumBytes);
+
+ status = SdReadWrite(EFIBlockIO, Lba, TempBuf, AllocSize, WRITE);
+ if(status!=EFI_SUCCESS)
+ {
+ DEBUG ((EFI_D_ERROR, "FvbWrite Write Failed 0x%x\n", status));
+ status = EFI_ACCESS_DENIED;
+ goto Exit;
+ }
+ }
+ else
+ {
+ DEBUG ((EFI_D_ERROR, "FvbWrite Error eMMC is not ready\n"));
+ }
+
+ Exit:
+
+ if (TempBuf != NULL)
+ {
+ FreePool(TempBuf);
+ }
+
+ return status;
+}
+
+
+/**
+ Erases and initializes a firmware volume block.
+
+ The EraseBlocks() function erases one or more blocks as denoted
+ by the variable argument list. The entire parameter list of
+ blocks must be verified before erasing any blocks. If a block is
+ requested that does not exist within the associated firmware
+ volume (it has a larger index than the last block of the
+ firmware volume), the EraseBlocks() function must return the
+ status code EFI_INVALID_PARAMETER without modifying the contents
+ of the firmware volume. Implementations should be mindful that
+ the firmware volume might be in the WriteDisabled state. If it
+ is in this state, the EraseBlocks() function must return the
+ status code EFI_ACCESS_DENIED without modifying the contents of
+ the firmware volume. All calls to EraseBlocks() must be fully
+ flushed to the hardware before the EraseBlocks() service
+ returns.
+
+ @param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL
+ instance.
+
+ @param ... The variable argument list is a list of tuples.
+ Each tuple describes a range of LBAs to erase
+ and consists of the following:
+ - An EFI_LBA that indicates the starting LBA
+ - A UINTN that indicates the number of blocks to
+ erase.
+
+ The list is terminated with an
+ EFI_LBA_LIST_TERMINATOR. For example, the
+ following indicates that two ranges of blocks
+ (5-7 and 10-11) are to be erased: EraseBlocks
+ (This, 5, 3, 10, 2, EFI_LBA_LIST_TERMINATOR);
+
+ @retval EFI_SUCCESS The erase request successfully
+ completed.
+
+ @retval EFI_ACCESS_DENIED The firmware volume is in the
+ WriteDisabled state.
+ @retval EFI_DEVICE_ERROR The block device is not functioning
+ correctly and could not be written.
+ The firmware device may have been
+ partially erased.
+ @retval EFI_INVALID_PARAMETER One or more of the LBAs listed
+ in the variable argument list do
+ not exist in the firmware volume.
+
+**/
+EFI_STATUS
+EFIAPI
+FvbEraseBlocks (
+ IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This,
+ ...
+ )
+{
+ EFI_STATUS status = EFI_SUCCESS;
+ UINTN StartBlock, NumBlock;
+ UINTN Index;
+ VA_LIST Marker;
+
+ VA_START (Marker, This);
+
+ for (Index = 0, status = EFI_SUCCESS; !EFI_ERROR (status); Index++)
+ {
+ StartBlock = VA_ARG (Marker, UINTN);
+ NumBlock = VA_ARG (Marker, UINTN);
+ DEBUG ((EFI_D_INFO, "FvbEraseBlocks start:%d numblock:%d\n", StartBlock, NumBlock));
+
+ if(StartBlock==0xFFFFFFFF)
+ {
+ break;
+ }
+
+ StartBlock += MSHC_BOOT_SECURE_OFFSET;
+ /* MMC High Capacity erase minimum size is 512KB */
+ status = EraseBlockData(MSHC_BOOT_PARTITION, StartBlock, NumBlock);
+ }
+
+ VA_END (Marker);
+ return status;
+}
+
+
+//
+// Making this global saves a few bytes in image size
+//
+EFI_HANDLE gFvbHandle = NULL;
+
+
+///
+/// The Firmware Volume Block Protocol is the low-level interface
+/// to a firmware volume. File-level access to a firmware volume
+/// should not be done using the Firmware Volume Block Protocol.
+/// Normal access to a firmware volume must use the Firmware
+/// Volume Protocol. Typically, only the file system driver that
+/// produces the Firmware Volume Protocol will bind to the
+/// Firmware Volume Block Protocol.
+///
+EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL gFvbProtocol = {
+ FvbGetAttributes,
+ FvbSetAttributes,
+ FvbGetPhysicalAddress,
+ FvbGetBlockSize,
+ FvbRead,
+ FvbWrite,
+ FvbEraseBlocks,
+ ///
+ /// The handle of the parent firmware volume.
+ ///
+ NULL
+};
+
+
+#if 0
+/**
+ Initialize the state information for the CPU Architectural Protocol
+
+ @param ImageHandle of the loaded driver
+ @param SystemTable Pointer to the System Table
+
+ @retval EFI_SUCCESS Protocol registered
+ @retval EFI_OUT_OF_RESOURCES Cannot allocate protocol data structure
+ @retval EFI_DEVICE_ERROR Hardware problems
+
+**/
+EFI_STATUS
+EFIAPI
+FvbDxeInitialize ()
+{
+ EFI_STATUS Status;
+
+
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &gFvbHandle,
+ &gEfiFirmwareVolumeBlockProtocolGuid, &gFvbProtocol,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ // SetVertAddressEvent ()
+
+ // GCD Map NAND as RT
+
+ return Status;
+}
+#endif
diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/ExynosPkg.dec b/SamsungPlatformPkg/ExynosPkg/Exynos5250/ExynosPkg.dec
new file mode 100755
index 000000000..d4863ced4
--- /dev/null
+++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/ExynosPkg.dec
@@ -0,0 +1,101 @@
+#/** @file
+# Arm RealView EB package.
+#
+# Copyright (c) 2012, Samsung Electronics Co. All rights reserved.<BR>
+#
+# This program and the accompanying materials are licensed and made available under
+# the terms and conditions of the BSD License which accompanies this distribution.
+# The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#**/
+
+[Defines]
+ DEC_SPECIFICATION = 0x00010005
+ PACKAGE_NAME = ExynosPkg
+ PACKAGE_GUID = ec1a4982-4a00-47e7-8df5-69c8ce895427
+ PACKAGE_VERSION = 0.1
+
+################################################################################
+#
+# Include Section - list of Include Paths that are provided by this package.
+# Comments are used for Keywords and Module Types.
+#
+# Supported Module Types:
+# BASE SEC PEI_CORE PEIM DXE_CORE DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SMM_DRIVER DXE_SAL_DRIVER UEFI_DRIVER UEFI_APPLICATION
+#
+################################################################################
+[Includes.common]
+ Include # Root include for the package
+
+[Guids.common]
+ gExynosPkgTokenSpaceGuid = { 0x70b6655a, 0x7a03, 0x11e0, { 0xbe, 0x19, 0x00, 0x26, 0xb9, 0x73, 0x3e, 0x2c} }
+
+[PcdsFeatureFlag.common]
+
+[PcdsFixedAtBuild.common]
+
+ #
+ # Samsung
+ #
+ # Framebuffer Base Address and size
+ gExynosPkgTokenSpaceGuid.PcdFrameBufferBase|0|UINT32|0x4E000000
+ gExynosPkgTokenSpaceGuid.PcdFrameBufferSize|0|UINT32|0x00400000
+
+ # Memory Partition : Shared memory 1MB (0x4000_0000 -- 0x4010_0000)
+ gExynosPkgTokenSpaceGuid.PcdSmemBaseAddress|0|UINT32|0x40000000
+ gExynosPkgTokenSpaceGuid.PcdSmemSize|0|UINT32|0x00100000
+
+ # Memory Partition : EMMC DMA buffer Address and Size 1MB (0x4030_0000 -- 0x4040_0000)
+ gExynosPkgTokenSpaceGuid.PcdEmmcDMABufferBase|0|UINT32|0x40300000
+# gExynosPkgTokenSpaceGuid.PcdEmmcDMABufferSize|0|UINT32|0x00100000
+
+ ## iRam Base Address and size.
+ gExynosPkgTokenSpaceGuid.PcdiRamBootBase|0|UINT32|0x00020000
+ gExynosPkgTokenSpaceGuid.PcdiRamBootSize|0|UINT32|0x00020001
+
+ gExynosPkgTokenSpaceGuid.PcdiRamStackBase|0|UINT32|0x00020002
+ gExynosPkgTokenSpaceGuid.PcdiRamStackSize|0|UINT32|0x00020003
+
+ gExynosPkgTokenSpaceGuid.PcdMpSharedArgsBase|0x8ff00000|UINT32|0x00000020
+ gExynosPkgTokenSpaceGuid.PcdMpSharedArgsSize|0x00100000|UINT32|0x00000021
+
+ gExynosPkgTokenSpaceGuid.PcdPeiServicePtrAddr|0|UINT32|0x00000003
+ gExynosPkgTokenSpaceGuid.PcdConsoleUartBase|0|UINT32|0x00000004
+ gExynosPkgTokenSpaceGuid.PcdWinDebugUartBase|0|UINT32|0x00000005
+ gExynosPkgTokenSpaceGuid.PcdCmuBase|0|UINT32|0x00000006
+ gExynosPkgTokenSpaceGuid.PcdPWMTimerBase|0|UINT32|0x00000007
+ gExynosPkgTokenSpaceGuid.PcdPmuBase|0|UINT32|0x00000008
+ gExynosPkgTokenSpaceGuid.PcdGdbUartBase|0|UINT32|0x00000009
+ gExynosPkgTokenSpaceGuid.PcdGpioPart1Base|0|UINT32|0x0000000A
+ gExynosPkgTokenSpaceGuid.PcdGpioPart2Base|0|UINT32|0x0000000B
+ gExynosPkgTokenSpaceGuid.PcdGpioPart3Base|0|UINT32|0x0000000C
+ gExynosPkgTokenSpaceGuid.PcdGpioPart4Base|0|UINT32|0x0000000D
+ gExynosPkgTokenSpaceGuid.PcdSdMmcBase|0|UINT32|0x0000000E
+ gExynosPkgTokenSpaceGuid.PcdSysBase|0|UINT32|0x0000000F
+ gExynosPkgTokenSpaceGuid.PcdFIMD1Base|0|UINT32|0x00000010
+ gExynosPkgTokenSpaceGuid.PcdGICBase|0|UINT32|0x00000011
+ gExynosPkgTokenSpaceGuid.PcdTZPCBase|0|UINT32|0x00000012
+ gExynosPkgTokenSpaceGuid.PcdDSIM1Base|0|UINT32|0x00000013
+ gExynosPkgTokenSpaceGuid.PcdSMC911XBase|0|UINT32|0x00000014
+ gExynosPkgTokenSpaceGuid.PcdRtcBase|0|UINT32|0x00000015
+ gExynosPkgTokenSpaceGuid.PcdExynos5250Evt1|FALSE|BOOLEAN|0x00000016
+ gExynosPkgTokenSpaceGuid.PcdSdMmcCH0Base|0|UINT32|0x00000017
+ gExynosPkgTokenSpaceGuid.PcdCryptoBase|0|UINT32|0x00000018
+
+
+ #
+ # SMBIOS related
+ #
+ gExynosPkgTokenSpaceGuid.PcdProcessorInfoSockInfoStr|"Samsung Exynos5250"|VOID*|0x00000A00
+ # Following can be changed by OEM's as it suits their products
+ gExynosPkgTokenSpaceGuid.PcdSystemMfrStr|"Samsung's OEM"|VOID*|0x00000A01
+ gExynosPkgTokenSpaceGuid.PcdSystemProductNameStr|"Exynos5250 Product"|VOID*|0x00000A02
+ gExynosPkgTokenSpaceGuid.PcdSystemProductFamilyStr|"Exynos5250 Product Family"|VOID*|0x00000A03
+
+
+# Samsung specific GUID = be26dd4f-9d02-413c-aa4f-dcd4aa334122
+[Protocols.common]
diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Include/Library/ExynosLib.h b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Include/Library/ExynosLib.h
new file mode 100644
index 000000000..8cd9fad2e
--- /dev/null
+++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Include/Library/ExynosLib.h
@@ -0,0 +1,42 @@
+/** @file
+
+ Copyright (c) 2012, Samsung Electronics Co. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef __EXYNOSLIB_H__
+#define __EXYNOSLIB_H__
+
+/*===========================================================================
+ MACRO DECLARATIONS
+===========================================================================*/
+/**
+ gExynosPkgTokenSpaceGuid GUID definition.
+*/
+#define EXYNOSPKG_TOKEN_SPACE_GUID \
+ { 0x70b6655a, 0x7a03, 0x11e0, { 0xbe, 0x19, 0x00, 0x26, 0xb9, 0x73, 0x3e, 0x2c } }
+
+/*===========================================================================
+ EXTERNAL VARIABLES
+===========================================================================*/
+/**
+ External reference to the gExynosPkgTokenSpaceGuid GUID.
+*/
+extern EFI_GUID gExynosPkgTokenSpaceGuid;
+
+
+UINT32
+EFIAPI
+GpioBase (
+ IN UINTN Port
+ );
+
+#endif // __EXYNOSLIB_H__
diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Include/Library/ExynosTimerLib.h b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Include/Library/ExynosTimerLib.h
new file mode 100644
index 000000000..783dd6d5f
--- /dev/null
+++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Include/Library/ExynosTimerLib.h
@@ -0,0 +1,56 @@
+/** @file
+*
+* Copyright (c) 2012, Samsung Electronics Co. All rights reserved.
+*
+* This program and the accompanying materials
+* are licensed and made available under the terms and conditions of the BSD License
+* which accompanies this distribution. The full text of the license may be found at
+* http://opensource.org/licenses/bsd-license.php
+*
+* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+
+#ifndef _EXYNOSTIMERLIB_H__
+#define _EXYNOSTIMERLIB_H__
+
+#define PWM_TCFG0_OFFSET (0x0000)
+#define PWM_TCFG1_OFFSET (0x0004)
+#define PWM_TCON_OFFSET (0x0008)
+#define PWM_TCNTB0_OFFSET (0x000C)
+#define PWM_TCMPB0_OFFSET (0x0010)
+#define PWM_TCNTO0_OFFSET (0x0014)
+#define PWM_TCNTB1_OFFSET (0x0018)
+#define PWM_TCMPB1_OFFSET (0x001C)
+#define PWM_TCNTO1_OFFSET (0x0020)
+#define PWM_TCNTB2_OFFSET (0x0024)
+#define PWM_TCMPB2_OFFSET (0x0028)
+#define PWM_TCNTO2_OFFSET (0x002C)
+#define PWM_TCNTB3_OFFSET (0x0030)
+#define PWM_TCMPB3_OFFSET (0x0034)
+#define PWM_TCNTO3_OFFSET (0x0038)
+#define PWM_TINT_CSTAT_OFFSET (0x0044)
+
+// Exynos4210 Timer constants
+#define Exynos4210_TIMER_LOAD_REG 0x00
+#define Exynos4210_TIMER_CURRENT_REG 0x04
+#define Exynos4210_TIMER_CONTROL_REG 0x08
+#define Exynos4210_TIMER_INT_CLR_REG 0x0C
+#define Exynos4210_TIMER_RAW_INT_STS_REG 0x10
+#define Exynos4210_TIMER_MSK_INT_STS_REG 0x14
+#define Exynos4210_TIMER_BG_LOAD_REG 0x18
+
+// Timer control register bit definitions
+#define Exynos4210_TIMER_CTRL_ONESHOT BIT0
+#define Exynos4210_TIMER_CTRL_32BIT BIT1
+#define Exynos4210_TIMER_CTRL_PRESCALE_MASK (BIT3|BIT2)
+#define Exynos4210_PRESCALE_DIV_1 0
+#define Exynos4210_PRESCALE_DIV_16 BIT2
+#define Exynos4210_PRESCALE_DIV_256 BIT3
+#define Exynos4210_TIMER_CTRL_INT_ENABLE BIT5
+#define Exynos4210_TIMER_CTRL_PERIODIC BIT6
+#define Exynos4210_TIMER_CTRL_ENABLE BIT7
+
+#endif
diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Include/Library/MpParkLib.h b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Include/Library/MpParkLib.h
new file mode 100644
index 000000000..688051b42
--- /dev/null
+++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Include/Library/MpParkLib.h
@@ -0,0 +1,51 @@
+/** @file
+ Template for Timer Architecture Protocol driver of the ARM flavor
+
+ Copyright (c) 2012, Samsung Electronics Co. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+
+#ifndef __MPPARKLIB_H_
+#define __MPPARKLIB_H_
+
+/*===========================================================================
+
+ INCLUDE FILES FOR MODULE
+
+===========================================================================*/
+
+/*===========================================================================
+
+ Defines and Structs
+
+===========================================================================*/
+extern UINT32 MpParkGPT0CntAddr;
+extern UINT32 MpParkGPT0MatchAddr;
+extern UINT32 MpParkGPT0EnableAddr;
+extern UINT32 MpParkMPMCountAddr;
+
+/*===========================================================================
+
+ Public Functions
+
+===========================================================================*/
+void CPU1_Start(void);
+
+
+/*===========================================================================
+
+ Private Functions
+
+===========================================================================*/
+
+#endif // __MPPARKLIB_H_
+
diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Include/Library/com_dtypes.h b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Include/Library/com_dtypes.h
new file mode 100644
index 000000000..02e113c31
--- /dev/null
+++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Include/Library/com_dtypes.h
@@ -0,0 +1,186 @@
+#ifndef COM_DTYPES_H
+#define COM_DTYPES_H
+/** @file
+ Template for Timer Architecture Protocol driver of the ARM flavor
+
+ Copyright (c) 2012, Samsung Electronics Co. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+
+/*===========================================================================
+
+ Data Declarations
+
+===========================================================================*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* For NT apps we want to use the Win32 definitions and/or those
+** supplied by the Win32 compiler for things like NULL, MAX, MIN
+** abs, labs, etc.
+*/
+#ifdef T_WINNT
+ #ifndef WIN32
+ #define WIN32
+ #endif
+ #include <stdlib.h>
+#endif
+
+/* ------------------------------------------------------------------------
+** Constants
+** ------------------------------------------------------------------------ */
+
+#ifdef TRUE
+#undef TRUE
+#endif
+
+#ifdef FALSE
+#undef FALSE
+#endif
+
+#define TRUE 1 /* Boolean true value. */
+#define FALSE 0 /* Boolean false value. */
+
+#define ON 1 /* On value. */
+#define OFF 0 /* Off value. */
+
+#ifndef NULL
+ #define NULL 0
+#endif
+
+/* -----------------------------------------------------------------------
+** Standard Types
+** ----------------------------------------------------------------------- */
+
+/* The following definitions are the same accross platforms. This first
+** group are the sanctioned types.
+*/
+#ifndef _ARM_ASM_
+#ifndef _BOOLEAN_DEFINED
+typedef unsigned char boolean; /* Boolean value type. */
+#define _BOOLEAN_DEFINED
+#endif
+
+
+#if defined(DALSTDDEF_H) /* guards against a known re-definer */
+#define _BOOLEAN_DEFINED
+#define _UINT32_DEFINED
+#define _UINT16_DEFINED
+#define _UINT8_DEFINED
+#define _INT32_DEFINED
+#define _INT16_DEFINED
+#define _INT8_DEFINED
+#define _UINT64_DEFINED
+#define _INT64_DEFINED
+#define _BYTE_DEFINED
+#endif /* #if !defined(DALSTDDEF_H) */
+
+#ifndef _UINT32_DEFINED
+typedef unsigned long int uint32; /* Unsigned 32 bit value */
+#define _UINT32_DEFINED
+#endif
+
+#ifndef _UINT16_DEFINED
+typedef unsigned short uint16; /* Unsigned 16 bit value */
+#define _UINT16_DEFINED
+#endif
+
+#ifndef _UINT8_DEFINED
+typedef unsigned char uint8; /* Unsigned 8 bit value */
+#define _UINT8_DEFINED
+#endif
+
+#ifndef _INT32_DEFINED
+typedef signed long int int32; /* Signed 32 bit value */
+#define _INT32_DEFINED
+#endif
+
+#ifndef _INT16_DEFINED
+typedef signed short int16; /* Signed 16 bit value */
+#define _INT16_DEFINED
+#endif
+
+#ifndef _INT8_DEFINED
+typedef signed char int8; /* Signed 8 bit value */
+#define _INT8_DEFINED
+#endif
+
+/* This group are the deprecated types. Their use should be
+** discontinued and new code should use the types above
+*/
+#ifndef _BYTE_DEFINED
+typedef unsigned char byte; /* Unsigned 8 bit value type. */
+#define _BYTE_DEFINED
+#endif
+
+typedef unsigned short word; /* Unsinged 16 bit value type. */
+typedef unsigned long dword; /* Unsigned 32 bit value type. */
+
+typedef unsigned char uint1; /* Unsigned 8 bit value type. */
+typedef unsigned short uint2; /* Unsigned 16 bit value type. */
+typedef unsigned long uint4; /* Unsigned 32 bit value type. */
+
+typedef signed char int1; /* Signed 8 bit value type. */
+typedef signed short int2; /* Signed 16 bit value type. */
+typedef long int int4; /* Signed 32 bit value type. */
+
+typedef signed long sint31; /* Signed 32 bit value */
+typedef signed short sint15; /* Signed 16 bit value */
+typedef signed char sint7; /* Signed 8 bit value */
+
+typedef uint16 UWord16 ;
+typedef uint32 UWord32 ;
+typedef int32 Word32 ;
+typedef int16 Word16 ;
+typedef uint8 UWord8 ;
+typedef int8 Word8 ;
+typedef int32 Vect32 ;
+
+#if (! defined T_WINNT) && (! defined __GNUC__)
+ /* Non WinNT Targets */
+ #ifndef _INT64_DEFINED
+ typedef long long int64; /* Signed 64 bit value */
+ #define _INT64_DEFINED
+ #endif
+ #ifndef _UINT64_DEFINED
+ typedef unsigned long long uint64; /* Unsigned 64 bit value */
+ #define _UINT64_DEFINED
+ #endif
+#else /* T_WINNT || TARGET_OS_SOLARIS || __GNUC__ */
+ /* WINNT or SOLARIS based targets */
+ #if (defined __GNUC__)
+ #ifndef _INT64_DEFINED
+ typedef long long int64;
+ #define _INT64_DEFINED
+ #endif
+ #ifndef _UINT64_DEFINED
+ typedef unsigned long long uint64;
+ #define _UINT64_DEFINED
+ #endif
+ #else
+ typedef __int64 int64; /* Signed 64 bit value */
+ #ifndef _UINT64_DEFINED
+ typedef unsigned __int64 uint64; /* Unsigned 64 bit value */
+ #define _UINT64_DEFINED
+ #endif
+ #endif
+#endif /* T_WINNT */
+
+#endif /* _ARM_ASM_ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* COM_DTYPES_H */
diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Include/Platform/ArmPlatform.h b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Include/Platform/ArmPlatform.h
new file mode 100755
index 000000000..4d5f7d86f
--- /dev/null
+++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Include/Platform/ArmPlatform.h
@@ -0,0 +1,692 @@
+/** @file
+* Header defining RealView EB constants (Base addresses, sizes, flags)
+*
+* Copyright (c) 2012, Samsung Electronics Co. All rights reserved.
+*
+* This program and the accompanying materials
+* are licensed and made available under the terms and conditions of the BSD License
+* which accompanies this distribution. The full text of the license may be found at
+* http://opensource.org/licenses/bsd-license.php
+*
+* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#ifndef __ARMPLATFORM_H__
+#define __ARMPLATFORM_H__
+
+/*******************************************
+// Platform Memory Map
+*******************************************/
+
+/*******************************************
+// Motherboard peripherals
+*******************************************/
+//PMU DOMAIN offsets
+#define SWRESET_OFFSET (0x400)
+#define PMU_DISP1_CONFIGURATION_OFFSET (0x40A0)
+#define PMU_DISP1_STATUS_OFFSET (0x40A4)
+
+#define LOCAL_PWR_ENABLE (0x07)
+
+#define PMU_MIPI_PHY1_CONTROL_OFFSET (0x0714)
+
+// SYSTRCL Register
+#define ARM_EB_SYSCTRL 0x10001000
+
+#define PL011_CONSOLE_UART_SPEED 115200
+
+// IRAM & RAM Base Address
+#define CONFIG_PHY_SDRAM_BASE (0x40000000)
+#define CONFIG_PHY_IRAM_BASE (0x02020000)
+#define CONFIG_PHY_UEFI_BASE (CONFIG_PHY_SDRAM_BASE)
+#define CONFIG_SECURE_CONTEXT_BASE (CONFIG_PHY_IRAM_BASE + 0x4c00)
+#define CONFIG_PHY_TZSW_BASE (CONFIG_PHY_IRAM_BASE + 0x8000)
+#define CONFIG_PHY_IRAM_NS_BASE (CONFIG_PHY_IRAM_BASE + 0x2F000)
+#define CONFIG_IMAGE_INFO_BASE (CONFIG_PHY_IRAM_NS_BASE + 0x11000)
+
+// Exynos5250 DMC Base Address : Not used it.
+#define Exynos5250_DMC_DELAY 0x3000
+#define Exynos5250_DMC_0_BASE 0x10C00000
+#define Exynos5250_DMC_1_BASE 0x10C10000
+
+
+// Exynos5250 DMC Base Address
+#define DMC_CTRL_BASE 0x10DD0000
+
+#define DMC_CONCONTROL 0x00
+#define DMC_MEMCONTROL 0x04
+#define DMC_MEMCONFIG0 0x08
+#define DMC_MEMCONFIG1 0x0C
+#define DMC_DIRECTCMD 0x10
+#define DMC_PRECHCONFIG 0x14
+#define DMC_PHYCONTROL0 0x18
+#define DMC_PWRDNCONFIG 0x28
+#define DMC_TIMINGPZQ 0x2C
+#define DMC_TIMINGAREF 0x30
+#define DMC_TIMINGROW 0x34
+#define DMC_TIMINGDATA 0x38
+#define DMC_TIMINGPOWER 0x3C
+#define DMC_PHYSTATUS 0x40
+#define DMC_CHIPSTATUS_CH0 0x48
+#define DMC_CHIPSTATUS_CH1 0x4C
+#define DMC_MRSTATUS 0x54
+#define DMC_QOSCONTROL0 0x60
+#define DMC_QOSCONTROL1 0x68
+#define DMC_QOSCONTROL2 0x70
+#define DMC_QOSCONTROL3 0x78
+#define DMC_QOSCONTROL4 0x80
+#define DMC_QOSCONTROL5 0x88
+#define DMC_QOSCONTROL6 0x90
+#define DMC_QOSCONTROL7 0x98
+#define DMC_QOSCONTROL8 0xA0
+#define DMC_QOSCONTROL9 0xA8
+#define DMC_QOSCONTROL10 0xB0
+#define DMC_QOSCONTROL11 0xB8
+#define DMC_QOSCONTROL12 0xC0
+#define DMC_QOSCONTROL13 0xC8
+#define DMC_QOSCONTROL14 0xD0
+#define DMC_QOSCONTROL15 0xD8
+#define DMC_IVCONTROL 0xF0
+#define DMC_WRTRA_CONFIG 0x00F4
+#define DMC_RDLVL_CONFIG 0x00F8
+#define DMC_BRBRSVCONTROL 0x0100
+#define DMC_BRBRSVCONFIG 0x0104
+#define DMC_BRBQOSCONFIG 0x0108
+#define DMC_MEMBASECONFIG0 0x010C
+#define DMC_MEMBASECONFIG1 0x0110
+#define DMC_WRLVL_CONFIG 0x0120
+#define DMC_PMNC_PPC 0xE000
+#define DMC_CNTENS_PPC 0xE010
+#define DMC_CNTENC_PPC 0xE020
+#define DMC_INTENS_PPC 0xE030
+#define DMC_INTENC_PPC 0xE040
+#define DMC_FLAG_PPC 0xE050
+#define DMC_CCNT_PPC 0xE100
+#define DMC_PMCNT0_PPC 0xE110
+#define DMC_PMCNT1_PPC 0xE120
+#define DMC_PMCNT2_PPC 0xE130
+#define DMC_PMCNT3_PPC 0xE140
+
+/* PHY Control Register */
+#define PHY0_CTRL_BASE 0x10C00000
+#define PHY1_CTRL_BASE 0x10C10000
+
+#define DMC_PHY_CON0 0x00
+#define DMC_PHY_CON1 0x04
+#define DMC_PHY_CON2 0x08
+#define DMC_PHY_CON3 0x0C
+#define DMC_PHY_CON4 0x10
+#define DMC_PHY_CON6 0x18
+#define DMC_PHY_CON8 0x20
+#define DMC_PHY_CON10 0x28
+#define DMC_PHY_CON11 0x2C
+#define DMC_PHY_CON12 0x30
+#define DMC_PHY_CON13 0x34
+#define DMC_PHY_CON14 0x38
+#define DMC_PHY_CON15 0x3C
+#define DMC_PHY_CON16 0x40
+#define DMC_PHY_CON17 0x48
+#define DMC_PHY_CON18 0x4C
+#define DMC_PHY_CON19 0x50
+#define DMC_PHY_CON20 0x54
+#define DMC_PHY_CON21 0x58
+#define DMC_PHY_CON22 0x5C
+#define DMC_PHY_CON23 0x60
+#define DMC_PHY_CON24 0x64
+#define DMC_PHY_CON25 0x68
+#define DMC_PHY_CON26 0x6C
+#define DMC_PHY_CON27 0x70
+#define DMC_PHY_CON28 0x74
+#define DMC_PHY_CON29 0x78
+#define DMC_PHY_CON30 0x7C
+#define DMC_PHY_CON31 0x80
+#define DMC_PHY_CON32 0x84
+#define DMC_PHY_CON33 0x88
+#define DMC_PHY_CON34 0x8C
+#define DMC_PHY_CON35 0x90
+#define DMC_PHY_CON36 0x94
+#define DMC_PHY_CON37 0x98
+#define DMC_PHY_CON38 0x9C
+#define DMC_PHY_CON39 0xA0
+#define DMC_PHY_CON40 0xA4
+#define DMC_PHY_CON41 0xA8
+#define DMC_PHY_CON42 0xAC
+
+
+
+
+
+
+// Exynos5250 UART Register
+#define Exynos5250_UART_BASE 0x12C10000
+
+#define ULCON_OFFSET 0x00
+#define UCON_OFFSET 0x04
+#define UFCON_OFFSET 0x08
+#define UMCON_OFFSET 0x0C
+#define UTRSTAT_OFFSET 0x10
+#define UERSTAT_OFFSET 0x14
+#define UFSTAT_OFFSET 0x18
+#define UMSTAT_OFFSET 0x1C
+#define UTXH_OFFSET 0x20
+#define URXH_OFFSET 0x24
+#define UBRDIV_OFFSET 0x28
+#define UDIVSLOT_OFFSET 0x2C
+#define UINTP_OFFSET 0x30
+#define UINTSP_OFFSET 0x34
+#define UINTM_OFFSET 0x38
+
+
+#define UARTLCR_H ULCON_OFFSET
+#define UARTECR UFCON_OFFSET
+#define UARTCR UCON_OFFSET
+#define UARTIBRD UBRDIV_OFFSET
+#define UARTFBRD UDIVSLOT_OFFSET
+
+#define UART_TX_EMPTY_FLAG_MASK (0x02)
+#define UART_RX_EMPTY_FLAG_MASK (0x01)
+// Exynos5250 TZPC Register
+#define Exynos5250_TZPC0_BASE 0x10100000
+#define Exynos5250_TZPC1_BASE 0x10110000
+#define Exynos5250_TZPC2_BASE 0x10120000
+#define Exynos5250_TZPC3_BASE 0x10130000
+#define Exynos5250_TZPC4_BASE 0x10140000
+#define Exynos5250_TZPC5_BASE 0x10150000
+#define Exynos5250_TZPC6_BASE 0x10160000
+#define Exynos5250_TZPC7_BASE 0x10170000
+#define Exynos5250_TZPC8_BASE 0x10180000
+#define Exynos5250_TZPC9_BASE 0x10190000
+
+
+#define TZPC0_OFFSET 0x00000
+#define TZPC1_OFFSET 0x10000
+#define TZPC2_OFFSET 0x20000
+#define TZPC3_OFFSET 0x30000
+#define TZPC4_OFFSET 0x40000
+#define TZPC5_OFFSET 0x50000
+#define TZPC6_OFFSET 0x60000
+#define TZPC7_OFFSET 0x70000
+#define TZPC8_OFFSET 0x80000
+#define TZPC9_OFFSET 0x90000
+
+#define TZPC_DECPROT0SET_OFFSET 0x804
+#define TZPC_DECPROT1SET_OFFSET 0x810
+#define TZPC_DECPROT2SET_OFFSET 0x81C
+#define TZPC_DECPROT3SET_OFFSET 0x828
+
+
+// Exynos5250 CMU Base Address
+#define Exynos5250_CMU_DELAY 0x2000
+#define Exynos5250_CMU_BASE 0x10010000
+#define Exynos5250_CMU_DIV_DMC0 0x10500
+
+#define APLL_AFC_ENB 0x1
+#define APLL_AFC 0xC
+
+/* MPLL_CON1 */
+#define MPLL_AFC_ENB 0x0
+#if defined(CONFIG_CLK_800_330_165) || defined(CONFIG_CLK_1000_330_165)
+#define MPLL_AFC 0xD
+#elif defined(CONFIG_CLK_1000_400_200) || defined(CONFIG_CLK_1000_200_200) || defined(CONFIG_CLK_800_400_200)
+#define MPLL_AFC 0x1C
+#endif
+
+#define EPLL_PDIV 0x3
+#define EPLL_K 0x0
+#define VPLL_PDIV 0x3
+#define VPLL_SDIV 0x2
+
+#define VPLL_SSCG_EN 0x0
+#define VPLL_SEL_PF 0x0
+#define VPLL_MRR 0x11
+#define VPLL_MFR 0x0
+#define VPLL_K 0x400
+/********************************************************/
+
+/* Set PLL */
+#define set_pll(mdiv, pdiv, sdiv) (1<<31 | mdiv<<16 | pdiv<<8 | sdiv)
+
+/* CLK_SRC_CPU */
+/* 0 = MOUTAPLL, 1 = SCLKMPLL */
+#define MUX_HPM_SEL_MOUTAPLL 0
+#define MUX_HPM_SEL_SCLKMPLL 1
+#define MUX_CORE_SEL_MOUTAPLL 0
+#define MUX_CORE_SEL_SCLKMPLL 1
+
+/* 0 = FILPLL, 1 = MOUT */
+#define MUX_MPLL_SEL_FILPLL 0
+#define MUX_MPLL_SEL_MOUTMPLLFOUT 1
+
+#define MUX_APLL_SEL_FILPLL 0
+#define MUX_APLL_SEL_MOUTMPLLFOUT 1
+
+#define CLK_SRC_CPU_VAL_FINPLL ((MUX_HPM_SEL_MOUTAPLL << 20) \
+ | (MUX_CORE_SEL_MOUTAPLL <<16) \
+ | (MUX_MPLL_SEL_FILPLL << 8) \
+ | (MUX_APLL_SEL_FILPLL <<0))
+
+#define CLK_SRC_CPU_VAL_MOUTMPLLFOUT ((MUX_HPM_SEL_MOUTAPLL << 20) \
+ | (MUX_CORE_SEL_MOUTAPLL <<16) \
+ | (MUX_MPLL_SEL_MOUTMPLLFOUT << 8) \
+ | (MUX_APLL_SEL_MOUTMPLLFOUT <<0))
+
+/* CLK_DIV_CPU0 */
+#define APLL_RATIO 0x1
+#define PCLK_DBG_RATIO 0x1
+#define ATB_RATIO 0x3
+#define COREM1_RATIO 0x7
+#define COREM0_RATIO 0x3
+#define CORE_RATIO 0x0
+
+/* CLK_DIV_CPU1 */
+#define HPM_RATIO 0x0
+#define COPY_RATIO 0x3
+#define CLK_DIV_CPU1_VAL ((HPM_RATIO << 4) | (COPY_RATIO))
+
+/* CLK_SRC_DMC */
+#define MUX_PWI_SEL 0x0
+#define MUX_CORE_TIMERS_SEL 0x0
+#define MUX_DPHY_SEL 0x0
+#define MUX_DMC_BUS_SEL 0x0
+#define CLK_SRC_DMC_VAL ((MUX_PWI_SEL << 16) \
+ | (MUX_CORE_TIMERS_SEL << 12) \
+ | (MUX_DPHY_SEL << 8) \
+ | (MUX_DMC_BUS_SEL << 4))
+
+/* CLK_DIV_DMC0 */
+#if defined(CONFIG_CLK_1000_200_200)
+#define CORE_TIMERS_RATIO 0x1
+#define COPY2_RATIO 0x3
+#define DMCP_RATIO 0x1
+#define DMCD_RATIO 0x0
+#define DMC_RATIO 0x3
+#define DPHY_RATIO 0x1
+#define ACP_PCLK_RATIO 0x1
+#define ACP_RATIO 0x3
+#else
+#define CORE_TIMERS_RATIO 0x1
+#define COPY2_RATIO 0x3
+#define DMCP_RATIO 0x1
+#define DMCD_RATIO 0x1
+#define DMC_RATIO 0x1
+#define DPHY_RATIO 0x1
+#define ACP_PCLK_RATIO 0x1
+#endif
+#define CLK_DIV_DMC0_VAL ((CORE_TIMERS_RATIO << 28) \
+ | (COPY2_RATIO << 24) \
+ | (DMCP_RATIO << 20) \
+ | (DMCD_RATIO << 16) \
+ | (DMC_RATIO << 12) \
+ | (DPHY_RATIO << 8) \
+ | (ACP_PCLK_RATIO << 4) \
+ | (ACP_RATIO))
+
+/* CLK_DIV_DMC1 */
+#define DPM_RATIO 0x1
+#define DVSEM_RATIO 0x1
+#define PWI_RATIO 0x1
+#define CLK_DIV_DMC1_VAL ((DPM_RATIO << 24) \
+ | (DVSEM_RATIO << 16) \
+ | (PWI_RATIO << 8))
+
+/* CLK_SRC_TOP0 */
+#define MUX_ONENAND_SEL 0x0 /* 0 = DOUT133, 1 = DOUT166 */
+#define MUX_ACLK_133_SEL 0x0 /* 0 = SCLKMPLL, 1 = SCLKAPLL */
+#define MUX_ACLK_160_SEL 0x0
+#define MUX_ACLK_100_SEL 0x0
+#define MUX_ACLK_200_SEL 0x0
+#define MUX_VPLL_SEL 0x0
+#define MUX_EPLL_SEL 0x0
+
+/* CLK_SRC_TOP1 */
+#define VPLLSRC_SEL 0x0 /* 0 = FINPLL, 1 = SCLKHDMI27M */
+
+/* CLK_DIV_TOP */
+#define ONENAND_RATIO 0x0
+#define ACLK_160_RATIO 0x4
+#define ACLK_100_RATIO 0x7
+#define ACLK_200_RATIO 0x3
+#define CLK_DIV_TOP_VAL ((ONENAND_RATIO << 16) \
+ | (ACLK_133_RATIO << 12) \
+ | (ACLK_160_RATIO << 8) \
+ | (ACLK_100_RATIO << 4) \
+ | (ACLK_200_RATIO))
+
+/* CLK_SRC_LEFTBUS */
+#define MUX_GDL_SEL 0x0
+#define CLK_SRC_LEFTBUS_VAL (MUX_GDL_SEL)
+
+/* CLK_DIV_LEFRBUS */
+#define GPL_RATIO 0x1
+#define GDL_RATIO 0x3
+#define CLK_DIV_LEFRBUS_VAL ((GPL_RATIO << 4) \
+ | (GDL_RATIO))
+
+/* CLK_SRC_RIGHTBUS */
+#define MUX_GDR_SEL 0x0
+#define CLK_SRC_RIGHTBUS_VAL (MUX_GDR_SEL)
+
+/* CLK_DIV_RIGHTBUS */
+#define GPR_RATIO 0x1
+#define GDR_RATIO 0x3
+#define CLK_DIV_RIGHTBUS_VAL ((GPR_RATIO << 4) \
+ | (GDR_RATIO))
+
+#define PLL_LOCKTIME 0x1C20
+
+/* CLK_SRC_PERIL0 */
+#define PWM_SEL 0
+#define UART5_SEL 6
+#define UART4_SEL 6
+#define UART3_SEL 6
+#define UART2_SEL 6
+#define UART1_SEL 6
+#define UART0_SEL 6
+#define CLK_SRC_PERIL0_VAL ((PWM_SEL << 24)\
+ | (UART5_SEL << 20) \
+ | (UART4_SEL << 16) \
+ | (UART3_SEL << 12) \
+ | (UART2_SEL<< 8) \
+ | (UART1_SEL << 4) \
+ | (UART0_SEL))
+
+/* CLK_DIV_PERIL0 */
+#if defined(CONFIG_CLK_800_330_165) || defined(CONFIG_CLK_1000_330_165)
+#define UART5_RATIO 7
+#define UART4_RATIO 7
+#define UART3_RATIO 7
+#define UART2_RATIO 7
+#define UART1_RATIO 7
+#define UART0_RATIO 7
+#elif defined(CONFIG_CLK_1000_400_200) || defined(CONFIG_CLK_1000_200_200) || defined(CONFIG_CLK_800_400_200)
+#define UART5_RATIO 8
+#define UART4_RATIO 8
+#define UART3_RATIO 8
+#define UART2_RATIO 8
+#define UART1_RATIO 8
+#define UART0_RATIO 8
+#endif
+#define CLK_DIV_PERIL0_VAL ((UART5_RATIO << 20) \
+ | (UART4_RATIO << 16) \
+ | (UART3_RATIO << 12) \
+ | (UART2_RATIO << 8) \
+ | (UART1_RATIO << 4) \
+ | (UART0_RATIO))
+
+#define MPLL_DEC (MPLL_MDIV * MPLL_MDIV / (MPLL_PDIV * 2^(MPLL_SDIV-1)))
+
+#if defined(CONFIG_CLK_800_330_165) || defined(CONFIG_CLK_1000_330_165)
+#define UART_UBRDIV_VAL 0x2B/* (SCLK_UART/(115200*16) -1) */
+#define UART_UDIVSLOT_VAL 0xC /*((((SCLK_UART*10/(115200*16) -10))%10)*16/10)*/
+#elif defined(CONFIG_CLK_1000_400_200) || defined(CONFIG_CLK_1000_200_200) || defined(CONFIG_CLK_800_400_200)
+#define UART_UBRDIV_VAL 0x2F /* (SCLK_UART/(115200*16) -1) */
+#define UART_UDIVSLOT_VAL 0x3 /*((((SCLK_UART*10/(115200*16) -10))%10)*16/10)*/
+#endif
+
+#define UART_115200_IDIV UART_UBRDIV_VAL
+#define UART_115200_FDIV UART_UDIVSLOT_VAL
+
+#define UART_38400_IDIV UART_UBRDIV_VAL
+#define UART_38400_FDIV UART_UDIVSLOT_VAL
+
+#define UART_19200_IDIV UART_UBRDIV_VAL
+#define UART_19200_FDIV UART_UDIVSLOT_VAL
+
+#define UART_LCON_VAL 0x03
+#define UART_ECR_VAL 0x111
+#define UART_CR_VAL 0x3C5
+
+// System Configuration Controller register Base addresses
+#define SYS_DISP1BLK_CFG_OFFSET (0x0214)
+#define FIMDBYPASS_DISP1 (0x01 << 15)
+
+//FIMD register offsets
+#define VIDCON0_OFFSET (0x00)
+#define VIDCON1_OFFSET (0x20004)/* Video control 1 */
+#define VIDCON2_OFFSET (0x0008) /* Video control 2 */
+#define VIDTCON0_OFFSET (0x20010) /* Video time control 0 */
+#define VIDTCON1_OFFSET (0x20014) /* Video time control 1 */
+#define VIDTCON2_OFFSET (0x20018) /* Video time control 2 */
+#define SHADOWCON_OFFSET (0x0034) /* Window Shadow control */
+#define WINCON_OFFSET(x) (0x0020 + (x * 0x04))
+#define VIDOSD_A_OFFSET(x) (0x0040 + (x * 0x10))
+#define VIDOSD_B_OFFSET(x) (0x0044 + (x * 0x10))
+#define VIDOSD_C_OFFSET(x) (0x0048 + (x * 0x10))
+#define VIDADDR_START0_OFFSET(x)(0x00A0 + (x * 0x08))
+#define VIDADDR_END0_OFFSET(x) (0x00D0 + (x * 0x08))
+#define VIDADDR_SIZE_OFFSET(x) (0x0100 + (x * 0x04))
+
+// MIPI-DSIM register offsets
+#define DSIM_STATUS (0x00)
+#define DSIM_SWRST (0x04)
+#define DSIM_CLKCTRL (0x08)
+#define DSIM_TIMEOUT (0x0C)
+#define DSIM_CONFIG (0x10)
+#define DSIM_ESCMODE (0x14)
+#define DSIM_MDRESOL (0x18)
+#define DSIM_MVPORCH (0x1C)
+#define DSIM_MHPORCH (0x20)
+#define DSIM_MSYNC (0x24)
+#define DSIM_SDRESOL (0x28)
+#define DSIM_INTSRC (0x2C)
+#define DSIM_INTMSK (0x30)
+#define DSIM_PKTHDR (0x34)
+#define DSIM_PAYLOAD (0x38)
+#define DSIM_RXFIFO (0x3C)
+#define DSIM_FIFOTHLD (0x40)
+#define DSIM_FIFOCTRL (0x44)
+#define DSIM_MEMACCHR (0x48)
+#define DSIM_PLLCTRL (0x4C)
+#define DSIM_PLLTMR (0x50)
+#define DSIM_PHYACCHR (0x54)
+#define DSIM_PHYACCHR1 (0x58)
+
+// RTC register offset
+#define EXYNOS_RTCREG(x) (x)
+#define EXYNOS_INTP EXYNOS_RTCREG(0x30)
+#define EXYNOS_INTP_ALM (1 << 1)
+#define EXYNOS_INTP_TIC (1 << 0)
+
+#define EXYNOS_RTCCON EXYNOS_RTCREG(0x40)
+#define EXYNOS_RTCCON_RTCEN (1<<0)
+#define EXYNOS_RTCCON_CLKSEL (1<<1)
+#define EXYNOS_RTCCON_CNTSEL (1<<2)
+#define EXYNOS_RTCCON_CLKRST (1<<3)
+#define EXYNOS_RTCCON_TICEN (1<<8)
+
+#define EXYNOS_RTCCON_TICMSK (0xF<<7)
+#define EXYNOS_RTCCON_TICSHT (7)
+
+#define EXYNOS_TICNT EXYNOS_RTCREG(0x44)
+#define EXYNOS_TICNT_ENABLE (1<<7)
+
+#define EXYNOS_RTCALM EXYNOS_RTCREG(0x50)
+#define EXYNOS_RTCALM_ALMEN (1<<6)
+#define EXYNOS_RTCALM_YEAREN (1<<5)
+#define EXYNOS_RTCALM_MONEN (1<<4)
+#define EXYNOS_RTCALM_DAYEN (1<<3)
+#define EXYNOS_RTCALM_HOUREN (1<<2)
+#define EXYNOS_RTCALM_MINEN (1<<1)
+#define EXYNOS_RTCALM_SECEN (1<<0)
+
+#define EXYNOS_RTCALM_ALL \
+ EXYNOS_RTCALM_ALMEN | EXYNOS_RTCALM_YEAREN | EXYNOS_RTCALM_MONEN |\
+ EXYNOS_RTCALM_DAYEN | EXYNOS_RTCALM_HOUREN | EXYNOS_RTCALM_MINEN |\
+ EXYNOS_RTCALM_SECEN
+
+
+#define EXYNOS_ALMSEC EXYNOS_RTCREG(0x54)
+#define EXYNOS_ALMMIN EXYNOS_RTCREG(0x58)
+#define EXYNOS_ALMHOUR EXYNOS_RTCREG(0x5c)
+
+#define EXYNOS_ALMDAY EXYNOS_RTCREG(0x60)
+#define EXYNOS_ALMMON EXYNOS_RTCREG(0x64)
+#define EXYNOS_ALMYEAR EXYNOS_RTCREG(0x68)
+
+//#define EXYNOS_RTCRST EXYNOS_RTCREG(0x6c)
+
+#define EXYNOS_BCDSEC EXYNOS_RTCREG(0x70)
+#define EXYNOS_BCDMIN EXYNOS_RTCREG(0x74)
+#define EXYNOS_BCDHOUR EXYNOS_RTCREG(0x78)
+#define EXYNOS_BCDDAY EXYNOS_RTCREG(0x7c)
+#define EXYNOS_BCDDAYWEEK EXYNOS_RTCREG(0x80)
+#define EXYNOS_BCDMON EXYNOS_RTCREG(0x84)
+#define EXYNOS_BCDYEAR EXYNOS_RTCREG(0x88)
+
+// Kimoon add RTC clock gate
+#define CLK_GATE_IP_PERIR (0xC960)
+#define CLK_RTC_OFFSET (0x1 << 15)
+#define CLK_RTC_MASK (0x0 << 15)
+#define CLK_RTC_UNMASK (0x1 << 15)
+
+//#define CLK_DIV_FSYS2 (CLK_BASE + 0xC548)
+//#define CLK_DIV_FSYS3 (CLK_BASE + 0xC54C)
+
+
+/*******************************************
+* Interrupt Map
+*******************************************/
+
+// Timer Interrupts
+#define Exynos5250_INT_NUM(x) ((x) + 32)
+
+#define PWM_TIMER0_INTERRUPT_NUM Exynos5250_INT_NUM(36)
+#define PWM_TIMER1_INTERRUPT_NUM Exynos5250_INT_NUM(37)
+#define PWM_TIMER2_INTERRUPT_NUM Exynos5250_INT_NUM(38)
+#define PWM_TIMER3_INTERRUPT_NUM Exynos5250_INT_NUM(39)
+#define PWM_TIMER4_INTERRUPT_NUM Exynos5250_INT_NUM(40)
+
+/*******************************************
+* EFI Memory Map in Permanent Memory (DRAM)
+*******************************************/
+
+//gpio definitions as required by the Embedded gpio module
+#define DISTANCE_BTWN_PORTS (0x20)
+
+#define GPIO_CON (0x00)
+#define GPIO_DATAIN (0x04)
+#define GPIO_PUD (0x08)
+#define GPIO_DRV (0x0C)
+
+#define GPIO_DATAIN_MASK(x) (1UL << (x))
+#define GPIO_PUD_MASK(x) (3UL << (x*2))
+#define GPIO_DRV_MASK(x) (3UL << (x*2))
+#define GPIO_SFN_MASK(x) (15UL <<(x*4))
+
+#define GPIO_SFN_EN(x) (2UL << (x*4))
+#define GPIO_OP_EN(x) (1UL << (x*4))
+
+#define GPIO_PUD_DIS(x) (0UL << (x*2))
+#define GPIO_PDN_EN(x) (1UL << (x*2))
+#define GPIO_PUP_EN(x) (3UL << (x*2))
+#define GPIO_DATA_HIGH(x) (1UL << (x))
+#define GPIO_DATA_LOW(x) (0UL << (x))
+
+#define GPIO_DRV_SET(strength,pin) (strength << (pin*2))
+
+#define PIN0 (0x00)
+#define PIN1 (0x01)
+#define PIN2 (0x02)
+#define PIN3 (0x03)
+#define PIN4 (0x04)
+#define PIN5 (0x05)
+#define PIN6 (0x06)
+#define PIN7 (0x07)
+
+// 0x1140_0000
+#define GPA0 (0x00)
+#define GPA1 (0x01)
+#define GPA2 (0x02)
+#define GPB0 (0x03)
+#define GPB1 (0x04)
+#define GPB2 (0x05)
+#define GPB3 (0x06)
+#define GPC0 (0x07)
+#define GPC1 (0x08)
+#define GPC2 (0x09)
+#define GPC3 (0x0A)
+#define GPD0 (0x0B)
+#define GPD1 (0x0C)
+#define GPY0 (0x0D)
+#define GPY1 (0x0E)
+#define GPY2 (0x0F)
+#define GPY3 (0x10)
+#define GPY4 (0x11)
+#define GPY5 (0x12)
+#define GPY6 (0x13)
+#define GPX0 (0x60)
+#define GPX1 (0x61)
+#define GPX2 (0x62)
+#define GPX3 (0x63)
+
+// 0x1340_0000
+#define GPE0 (0x70)
+#define GPE1 (0x71)
+#define GPF0 (0x72)
+#define GPF1 (0x73)
+#define GPG0 (0x74)
+#define GPG1 (0x75)
+#define GPG2 (0x76)
+#define GPH0 (0x77)
+#define GPH1 (0x78)
+
+// 0x10D1_0000
+#define GPV0 (0x80)
+#define GPV1 (0x81)
+// ETC5PUD
+#define GPV2 (0x83)
+#define GPV3 (0x84)
+// ETC8PUD
+#define GPV4 (0x86)
+
+// 0x0386_0000
+#define GPZ (0x90)
+
+#define LCD_BACKLIGHT GPIO(GPB2,PIN0)
+#define LCD_RESET GPIO(GPX1,PIN5)
+#define LCD_POWER GPIO(GPX3,PIN0)
+
+/* SDHC GPIO Pin Configuration for GAIA */
+#define SD_2_EVT1_CLK GPIO(GPC3,PIN0)
+#define SD_2_EVT1_CMD GPIO(GPC3,PIN1)
+#define SD_2_EVT1_CDn GPIO(GPC3,PIN2)
+#define SD_2_EVT1_DATA0 GPIO(GPC3,PIN3)
+#define SD_2_EVT1_DATA1 GPIO(GPC3,PIN4)
+#define SD_2_EVT1_DATA2 GPIO(GPC3,PIN5)
+#define SD_2_EVT1_DATA3 GPIO(GPC3,PIN6)
+
+#define SD_2_CLK GPIO(GPC2,PIN0)
+#define SD_2_CMD GPIO(GPC2,PIN1)
+#define SD_2_CDn GPIO(GPC2,PIN2)
+#define SD_2_DATA0 GPIO(GPC2,PIN3)
+#define SD_2_DATA1 GPIO(GPC2,PIN4)
+#define SD_2_DATA2 GPIO(GPC2,PIN5)
+#define SD_2_DATA3 GPIO(GPC2,PIN6)
+#define SD_2_DATA4 GPIO(GPC3,PIN3)
+#define SD_2_DATA5 GPIO(GPC3,PIN4)
+#define SD_2_DATA6 GPIO(GPC3,PIN5)
+#define SD_2_DATA7 GPIO(GPC3,PIN6)
+
+/* USB 2.0 GPIO Pin Configuration for GAIA Evt1 */
+#define USB_2_EVT1 GPIO(GPX2,PIN6)
+
+/* SDHC CH0 GPIO Pin Configuration for GAIA */
+#define SD_0_CLK GPIO(GPC0,PIN0)
+#define SD_0_CMD GPIO(GPC0,PIN1)
+#define SD_0_CDn GPIO(GPC0,PIN2)
+#define SD_0_DATA0 GPIO(GPC0,PIN3)
+#define SD_0_DATA1 GPIO(GPC0,PIN4)
+#define SD_0_DATA2 GPIO(GPC0,PIN5)
+#define SD_0_DATA3 GPIO(GPC0,PIN6)
+#define SD_0_DATA4 GPIO(GPC1,PIN0)
+#define SD_0_DATA5 GPIO(GPC1,PIN1)
+#define SD_0_DATA6 GPIO(GPC1,PIN2)
+#define SD_0_DATA7 GPIO(GPC1,PIN3)
+
+
+#define CLK_DIV_FSYS1_OFFSET 0x1054C
+#define CLK_DIV_FSYS2_OFFSET 0x10550
+
+#endif
diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Include/Platform/Arndale5250.h b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Include/Platform/Arndale5250.h
new file mode 100644
index 000000000..0762b8aeb
--- /dev/null
+++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Include/Platform/Arndale5250.h
@@ -0,0 +1,337 @@
+/*
+ * (C) Copyright 2009 Samsung Electronics
+ * Minkyu Kang <mk7.kang@samsung.com>
+ * HeungJun Kim <riverful.kim@samsung.com>
+ * Inki Dae <inki.dae@samsung.com>
+ *
+ * Configuation settings for the SAMSUNG ARNDALE board.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+/*
+ * High Level Configuration Options
+ * (easy to change)
+ */
+#define CONFIG_ARMV7 1 /* This is an ARM V7 CPU core */
+#define CONFIG_SAMSUNG 1 /* in a SAMSUNG core */
+#define CONFIG_S5P 1 /* which is in a S5P Family */
+#define CONFIG_ARCH_EXYNOS 1 /* which is in a Exynos Family */
+#define CONFIG_ARCH_EXYNOS5 1 /* which is in a Exynos5 Family */
+#define CONFIG_CPU_EXYNOS5250 1 /* which is in a Exynos5250 */
+#define CONFIG_MACH_SMDK5250 1 /* which is in a ARNDALE */
+#define CONFIG_EVT1 1 /* EVT1 */
+//#define CONFIG_CORTEXA5_ENABLE 1 /* enable coretex-A5(IOP) Booting */
+
+#define CONFIG_SECURE_BL1_ONLY
+//#define CONFIG_SECURE_BOOT
+#ifdef CONFIG_SECURE_BOOT
+#define CONFIG_S5PC210S
+#define CONFIG_SECURE_ROOTFS
+#define CONFIG_SECURE_KERNEL_BASE 0xc0008000
+#define CONFIG_SECURE_KERNEL_SIZE 0x200000
+#define CONFIG_SECURE_ROOTFS_BASE 0xc1000000
+#define CONFIG_SECURE_ROOTFS_SIZE 0x5c2000
+#endif
+
+//#include <asm/arch/cpu.h> /* get chip and board defs */
+
+#define CONFIG_CLK_ARM_1000_APLL_1000
+
+#define MCLK_CDREX_533 1
+#define RD_LVL 1
+
+/* (Memory Interleaving Size = 1 << IV_SIZE) */
+#define CONFIG_IV_SIZE 0x07
+
+#define CONFIG_L2_OFF
+
+//#define CONFIG_ARCH_CPU_INIT
+
+#define CONFIG_DISPLAY_CPUINFO
+//#define CONFIG_DISPLAY_BOARDINFO
+#define BOARD_LATE_INIT
+
+/* input clock of PLL: ARNDALE has 24MHz input clock */
+#define CONFIG_SYS_CLK_FREQ 24000000
+
+/* DRAM Base */
+#define CONFIG_SYS_SDRAM_BASE 0x40000000
+
+#define CONFIG_SETUP_MEMORY_TAGS
+#define CONFIG_CMDLINE_TAG
+#define CONFIG_INITRD_TAG
+#define CONFIG_CMDLINE_EDITING
+
+/* Power Management is enabled */
+//#define CONFIG_PM
+//#define CONFIG_INVERSE_PMIC_I2C 1
+#define CONFIG_PM_VDD_ARM 1.1
+#define CONFIG_PM_VDD_INT 1.0
+#define CONFIG_PM_VDD_G3D 1.1
+#define CONFIG_PM_VDD_MIF 1.1
+#define CONFIG_PM_VDD_LDO14 1.8
+
+/*
+ * Size of malloc() pool
+ * 1MB = 0x100000, 0x100000 = 1024 * 1024
+ */
+#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + (1 << 20))
+ /* initial data */
+/*
+ * select serial console configuration
+ */
+#define CONFIG_SERIAL1 1
+#define CONFIG_SERIAL_MULTI 1
+
+#define CONFIG_USB_OHCI
+#undef CONFIG_USB_STORAGE
+//#define CONFIG_S3C_USBD
+#define CONFIG_EXYNOS_USBD3
+
+#define USBD_DOWN_ADDR 0xc0000000
+
+/* allow to overwrite serial and ethaddr */
+#define CONFIG_ENV_OVERWRITE
+#define CONFIG_BAUDRATE 115200
+
+/***********************************************************
+ * Command definition
+ ***********************************************************/
+
+#define CONFIG_CMD_PING
+
+#define CONFIG_CMD_USB
+
+#define CONFIG_CMD_MOVINAND
+
+#undef CONFIG_CMD_FLASH
+#undef CONFIG_CMD_IMLS
+#undef CONFIG_CMD_NAND
+
+#define CONFIG_CMD_CACHE
+#define CONFIG_CMD_REGINFO
+#define CONFIG_CMD_MMC
+#define CONFIG_CMD_MOVI
+#define CONFIG_CMD_ELF
+#define CONFIG_CMD_FAT
+#define CONFIG_CMD_MTDPARTS
+#define CONFIG_MTD_DEVICE
+
+#define CONFIG_CMD_EXT2
+#define CONFIG_CMD_FAT
+
+#define CONFIG_SYS_NAND_QUIET_TEST
+#define CONFIG_SYS_ONENAND_QUIET_TEST
+
+#define CONFIG_MMC
+#define CONFIG_GENERIC_MMC
+#define CONFIG_S3C_HSMMC
+
+/* The macro for MMC channel 0 is defined by default and can't be undefined */
+
+/* Notice for MSHC[Using of MMC CH4] */
+/*
+ * If you want MSHC at MMC CH4.
+ */
+
+#define MMC_MAX_CHANNEL 5
+
+#define USE_MMC2
+#define USE_MMC4
+
+/*
+ * BOOTP options
+ */
+#define CONFIG_BOOTP_SUBNETMASK
+#define CONFIG_BOOTP_GATEWAY
+#define CONFIG_BOOTP_HOSTNAME
+#define CONFIG_BOOTP_BOOTPATH
+
+#define CONFIG_ETHADDR 00:40:5c:26:0a:5b
+#define CONFIG_NETMASK 255.255.255.0
+#define CONFIG_IPADDR 192.168.0.20
+#define CONFIG_SERVERIP 192.168.0.10
+#define CONFIG_GATEWAYIP 192.168.0.1
+
+#define CONFIG_BOOTDELAY 3
+/* Default boot commands for Android booting. */
+#define CONFIG_BOOTCOMMAND "movi read kernel 0 40008000;movi read rootfs 0 41000000 100000;bootm 40008000 41000000"
+#define CONFIG_BOOTARGS ""
+
+#define CONFIG_BOOTCOMMAND2 \
+ "mmc erase user 0 1072 1;" \
+ "movi r f 1 40000000;emmc open 0;movi w z f 0 40000000;emmc close 0;" \
+ "movi r u 1 40000000;emmc open 0;movi w z u 0 40000000;emmc close 0;" \
+ "movi r k 1 40000000;movi w k 0 40000000;" \
+ "movi r r 1 40000000 100000;movi w r 0 40000000 100000;" \
+ "fdisk -c 0;" \
+ "movi init 0;" \
+ "fatformat mmc 0:1;" \
+ "mmc read 1 48000000 20000 a0000;" \
+ "fastboot flash system 48000000;" \
+ "mmc read 1 48000000 c0000 a0000;" \
+ "fastboot flash userdata 48000000;" \
+ "mmc read 1 48000000 160000 a0000;" \
+ "fastboot flash cache 48000000;" \
+ "reset"
+
+/*
+ * Miscellaneous configurable options
+ */
+#define CONFIG_SYS_LONGHELP /* undef to save memory */
+#define CONFIG_SYS_HUSH_PARSER /* use "hush" command parser */
+#define CONFIG_SYS_PROMPT_HUSH_PS2 "> "
+#define CONFIG_SYS_PROMPT "ARNDALE# "
+#define CONFIG_SYS_CBSIZE 256 /* Console I/O Buffer Size */
+#define CONFIG_SYS_PBSIZE 384 /* Print Buffer Size */
+#define CONFIG_SYS_MAXARGS 16 /* max number of command args */
+/* Boot Argument Buffer Size */
+#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE
+/* memtest works on */
+#define CONFIG_SYS_MEMTEST_START CONFIG_SYS_SDRAM_BASE
+#define CONFIG_SYS_MEMTEST_END (CONFIG_SYS_SDRAM_BASE + 0x5e00000)
+
+#define CONFIG_SYS_HZ 1000
+
+/* valid baudrates */
+#define CONFIG_SYS_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 }
+
+/*-----------------------------------------------------------------------
+ * Stack sizes
+ *
+ * The stack sizes are set up in start.S using the settings below
+ */
+#define CONFIG_STACKSIZE (256 << 10) /* 256 KiB */
+
+#define CONFIG_NR_DRAM_BANKS 4
+#define SDRAM_BANK_SIZE 0x10000000 /* 256 MB */
+#define PHYS_SDRAM_1 CONFIG_SYS_SDRAM_BASE /* SDRAM Bank #1 */
+#define PHYS_SDRAM_1_SIZE SDRAM_BANK_SIZE
+#define PHYS_SDRAM_2 (CONFIG_SYS_SDRAM_BASE + SDRAM_BANK_SIZE) /* SDRAM Bank #2 */
+#define PHYS_SDRAM_2_SIZE SDRAM_BANK_SIZE
+#define PHYS_SDRAM_3 (CONFIG_SYS_SDRAM_BASE + 2 * SDRAM_BANK_SIZE) /* SDRAM Bank #3 */
+#define PHYS_SDRAM_3_SIZE SDRAM_BANK_SIZE
+#define PHYS_SDRAM_4 (CONFIG_SYS_SDRAM_BASE + 3 * SDRAM_BANK_SIZE) /* SDRAM Bank #4 */
+#define PHYS_SDRAM_4_SIZE SDRAM_BANK_SIZE
+#define PHYS_SDRAM_5 (CONFIG_SYS_SDRAM_BASE + 4 * SDRAM_BANK_SIZE) /* SDRAM Bank #5 */
+#define PHYS_SDRAM_5_SIZE SDRAM_BANK_SIZE
+#define PHYS_SDRAM_6 (CONFIG_SYS_SDRAM_BASE + 5 * SDRAM_BANK_SIZE) /* SDRAM Bank #6 */
+#define PHYS_SDRAM_6_SIZE SDRAM_BANK_SIZE
+#define PHYS_SDRAM_7 (CONFIG_SYS_SDRAM_BASE + 6 * SDRAM_BANK_SIZE) /* SDRAM Bank #7 */
+#define PHYS_SDRAM_7_SIZE SDRAM_BANK_SIZE
+#define PHYS_SDRAM_8 (CONFIG_SYS_SDRAM_BASE + 7 * SDRAM_BANK_SIZE) /* SDRAM Bank #8 */
+#define PHYS_SDRAM_8_SIZE SDRAM_BANK_SIZE
+
+#define CONFIG_SYS_MONITOR_BASE 0x00000000
+
+/*-----------------------------------------------------------------------
+ * FLASH and environment organization
+ */
+#define CONFIG_SYS_NO_FLASH 1
+
+#define CONFIG_SYS_MONITOR_LEN (256 << 10) /* 256 KiB */
+#define CONFIG_IDENT_STRING " for ARNDALE"
+
+#define CONFIG_ENABLE_MMU
+
+#ifdef CONFIG_ENABLE_MMU
+#define CONFIG_SYS_MAPPED_RAM_BASE 0xc0000000
+#define virt_to_phys(x) virt_to_phy_exynos5250(x)
+#else
+#define CONFIG_SYS_MAPPED_RAM_BASE CONFIG_SYS_SDRAM_BASE
+#define virt_to_phys(x) (x)
+#endif
+
+#define CONFIG_SYS_LOAD_ADDR CONFIG_SYS_MAPPED_RAM_BASE + 0x3e00000
+#define CONFIG_PHY_UBOOT_BASE CONFIG_SYS_SDRAM_BASE + 0x3e00000
+
+/*
+ * Fast Boot
+*/
+/* Fastboot variables */
+#define CFG_FASTBOOT_TRANSFER_BUFFER (0x48000000)
+#define CFG_FASTBOOT_TRANSFER_BUFFER_SIZE (0x10000000) /* 256MB */
+#define CFG_FASTBOOT_ADDR_KERNEL (0x40008000)
+#define CFG_FASTBOOT_ADDR_RAMDISK (0x40800000)
+#define CFG_FASTBOOT_PAGESIZE (2048) // Page size of booting device
+#define CFG_FASTBOOT_SDMMC_BLOCKSIZE (512) // Block size of sdmmc
+#define CFG_PARTITION_START (0x4000000)
+
+/* Just one BSP type should be defined. */
+#if defined(CONFIG_CMD_MOVINAND)
+#define CONFIG_FASTBOOT
+#endif
+
+#if defined(CONFIG_CMD_MOVINAND)
+#define CFG_FASTBOOT_SDMMCBSP
+#endif
+
+/*
+ * machine type
+ */
+
+#define MACH_TYPE 3774 /* ARNDALE machine ID */
+
+#define CONFIG_ENV_OFFSET 0x0007C000
+
+/*-----------------------------------------------------------------------
+ * Boot configuration
+ */
+#define BOOT_ONENAND 0x1
+#define BOOT_NAND 0x40000
+#define BOOT_MMCSD 0x3
+#define BOOT_NOR 0x4
+#define BOOT_SEC_DEV 0x5
+#define BOOT_EMMC 0x6
+#define BOOT_EMMC_4_4 0x7
+
+#define CONFIG_ZIMAGE_BOOT
+
+#define CONFIG_ENV_IS_IN_AUTO 1
+#define CONFIG_ENV_SIZE 0x4000
+
+#define CONFIG_DOS_PARTITION 1
+
+//#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_LOAD_ADDR - 0x1000000)
+#define CONFIG_SYS_INIT_SP_ADDR (0x43e00000 - 0x1000000)
+
+/*
+ * Ethernet Contoller driver
+ */
+#define CONFIG_CMD_NET 1
+#ifdef CONFIG_CMD_NET
+#define CONFIG_NET_MULTI
+#define CONFIG_SMC911X
+#define CONFIG_SMC911X_BASE 0x5000000
+#define CONFIG_SMC911X_16_BIT
+#endif /* CONFIG_CMD_NET */
+
+/* GPIO */
+#define GPIO_BASE 0x11400000
+
+#define CFG_PHY_UBOOT_BASE MEMORY_BASE_ADDRESS + 0x3e00000
+#define CFG_PHY_KERNEL_BASE MEMORY_BASE_ADDRESS + 0x8000
+
+#define MEMORY_BASE_ADDRESS 0x40000000
+
+#endif /* __CONFIG_H */
diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Include/Platform/Arndale5250_Val.h b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Include/Platform/Arndale5250_Val.h
new file mode 100755
index 000000000..d6cdd1d9d
--- /dev/null
+++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Include/Platform/Arndale5250_Val.h
@@ -0,0 +1,402 @@
+/*
+ * (C) Copyright 2012 Samsung Electronics Co. Ltd
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#ifndef _VAL_ARNDALE5250_H
+#define _VAL_ARNDALE5250_H
+
+#if defined(CONFIG_CLK_ARM_800_APLL_800)
+
+#define APLL_MDIV 0x64
+#define APLL_PDIV 0x3
+#define APLL_SDIV 0x0
+
+#elif defined(CONFIG_CLK_ARM_1000_APLL_1000)
+
+#define APLL_MDIV 0x7D
+#define APLL_PDIV 0x3
+#define APLL_SDIV 0x0
+
+#elif defined(CONFIG_CLK_ARM_1200_APLL_1200)
+
+#define APLL_MDIV 0x96
+#define APLL_PDIV 0x3
+#define APLL_SDIV 0x0
+
+#elif defined(CONFIG_CLK_ARM_1400_APLL_1400)
+
+#define APLL_MDIV 0xAF
+#define APLL_PDIV 0x3
+#define APLL_SDIV 0x0
+
+#elif defined(CONFIG_CLK_ARM_1700_APLL_1700)
+
+#define APLL_MDIV 0xAF
+#define APLL_PDIV 0x3
+#define APLL_SDIV 0x0
+#endif
+
+#define MPLL_MDIV 0x64
+#define MPLL_PDIV 0x3
+#define MPLL_SDIV 0x0
+
+#define CPLL_MDIV 0xDE
+#define CPLL_PDIV 0x4
+#define CPLL_SDIV 0x2
+
+#define GPLL_MDIV 0x215
+#define GPLL_PDIV 0xC
+#define GPLL_SDIV 0x1
+
+/* APLL_CON1 */
+#define APLL_CON1_VAL (0x00203800)
+
+/* MPLL_CON1 */
+#define MPLL_CON1_VAL (0x00203800)
+
+/* CPLL_CON1 */
+#define CPLL_CON1_VAL (0x00203800)
+
+/* GPLL_CON1 */
+#define GPLL_CON1_VAL (0x00203800)
+
+#define EPLL_MDIV 0x60
+#define EPLL_PDIV 0x3
+#define EPLL_SDIV 0x3
+
+#define EPLL_CON1_VAL 0x00000000
+#define EPLL_CON2_VAL 0x00000080
+
+#define VPLL_MDIV 0x96
+#define VPLL_PDIV 0x3
+#define VPLL_SDIV 0x2
+
+/* VPLL_CON1, CON2 */
+#define VPLL_CON1_VAL 0x00000000
+#define VPLL_CON2_VAL 0x00000080
+
+#define BPLL_MDIV 0x64
+#define BPLL_PDIV 0x3
+#define BPLL_SDIV 0x0
+
+/* BPLL_CON1 */
+#define BPLL_CON1_VAL 0x00203800
+
+/* Set PLL */
+#define set_pll(mdiv, pdiv, sdiv) (1<<31 | mdiv<<16 | pdiv<<8 | sdiv)
+
+#define APLL_CON0_VAL set_pll(APLL_MDIV, APLL_PDIV, APLL_SDIV)
+#define MPLL_CON0_VAL set_pll(MPLL_MDIV, MPLL_PDIV, MPLL_SDIV)
+#define CPLL_CON0_VAL set_pll(CPLL_MDIV, CPLL_PDIV, CPLL_SDIV)
+#define GPLL_CON0_VAL set_pll(GPLL_MDIV, GPLL_PDIV, GPLL_SDIV)
+#define EPLL_CON0_VAL set_pll(EPLL_MDIV, EPLL_PDIV, EPLL_SDIV)
+#define VPLL_CON0_VAL set_pll(VPLL_MDIV, VPLL_PDIV, VPLL_SDIV)
+#define BPLL_CON0_VAL set_pll(BPLL_MDIV, BPLL_PDIV, BPLL_SDIV)
+
+/* CLK_SRC_CPU */
+/* 0 = MOUTAPLL, 1 = SCLKMPLL */
+#define MUX_HPM_SEL 0
+#define MUX_CPU_SEL 0
+#define MUX_APLL_SEL 1
+
+#define CLK_SRC_CPU_VAL ((MUX_HPM_SEL << 20) \
+ | (MUX_CPU_SEL << 16) \
+ | (MUX_APLL_SEL))
+
+/* CLK_DIV_CPU0 */
+#if defined(CONFIG_CLK_ARM_600_APLL_600)
+#define ARM2_RATIO 0x0
+#define APLL_RATIO 0x1
+#define PCLK_DBG_RATIO 0x1
+#define ATB_RATIO 0x2
+#define PERIPH_RATIO 0x7
+#define ACP_RATIO 0x7
+#define CPUD_RATIO 0x1
+#define ARM_RATIO 0x0
+
+#elif defined(CONFIG_CLK_ARM_800_APLL_800)
+
+#define ARM2_RATIO 0x0
+#define APLL_RATIO 0x1
+#define PCLK_DBG_RATIO 0x1
+#define ATB_RATIO 0x3
+#define PERIPH_RATIO 0x7
+#define ACP_RATIO 0x7
+#define CPUD_RATIO 0x2
+#define ARM_RATIO 0x0
+
+#elif defined(CONFIG_CLK_ARM_1000_APLL_1000)
+
+#define ARM2_RATIO 0x0
+#define APLL_RATIO 0x1
+#define PCLK_DBG_RATIO 0x1
+#define ATB_RATIO 0x4
+#define PERIPH_RATIO 0x7
+#define ACP_RATIO 0x7
+#define CPUD_RATIO 0x2
+#define ARM_RATIO 0x0
+
+#elif defined(CONFIG_CLK_ARM_1200_APLL_1200)
+
+#define ARM2_RATIO 0x0
+#define APLL_RATIO 0x3
+#define PCLK_DBG_RATIO 0x1
+#define ATB_RATIO 0x5
+#define PERIPH_RATIO 0x7
+#define ACP_RATIO 0x7
+#define CPUD_RATIO 0x3
+#define ARM_RATIO 0x0
+
+#elif defined(CONFIG_CLK_ARM_1400_APLL_1400)
+
+#define ARM2_RATIO 0x0
+#define APLL_RATIO 0x3
+#define PCLK_DBG_RATIO 0x1
+#define ATB_RATIO 0x6
+#define PERIPH_RATIO 0x7
+#define ACP_RATIO 0x7
+#define CPUD_RATIO 0x3
+#define ARM_RATIO 0x0
+
+#elif defined(CONFIG_CLK_ARM_1700_APLL_1700)
+
+#define ARM2_RATIO 0x0
+#define APLL_RATIO 0x3
+#define PCLK_DBG_RATIO 0x1
+#define ATB_RATIO 0x6
+#define PERIPH_RATIO 0x7
+#define ACP_RATIO 0x7
+#define CPUD_RATIO 0x3
+#define ARM_RATIO 0x0
+#endif
+
+/* CLK_DIV_CPU0_VAL */
+#define CLK_DIV_CPU0_VAL ((ARM2_RATIO << 28) \
+ | (APLL_RATIO << 24) \
+ | (PCLK_DBG_RATIO << 20) \
+ | (ATB_RATIO << 16) \
+ | (PERIPH_RATIO << 12) \
+ | (ACP_RATIO << 8) \
+ | (CPUD_RATIO << 4) \
+ | (ARM_RATIO))
+
+/* CLK_DIV_CPU1 */
+#define HPM_RATIO 0x2
+#define COPY_RATIO 0x0
+
+/* CLK_DIV_CPU1 = 0x00000003 */
+#define CLK_DIV_CPU1_VAL ((HPM_RATIO << 4) \
+ | (COPY_RATIO))
+
+/* CLK_SRC_CORE0 */
+#define CLK_SRC_CORE0_VAL 0x00000000
+
+/* CLK_SRC_CORE1 */
+#define CLK_SRC_CORE1_VAL 0x100
+
+/* CLK_DIV_CORE0 */
+#define CLK_DIV_CORE0_VAL 0x00120000
+
+/* CLK_DIV_CORE1 */
+#define CLK_DIV_CORE1_VAL 0x07070700
+
+/* CLK_DIV_SYSRGT */
+#define CLK_DIV_SYSRGT_VAL 0x00000111
+
+/* CLK_DIV_ACP */
+#define CLK_DIV_ACP_VAL 0x12
+
+/* CLK_DIV_SYSLFT */
+#define CLK_DIV_SYSLFT_VAL 0x00000311
+
+/* CLK_SRC_CDREX */
+#define CLK_SRC_CDREX_VAL 0x1
+
+/* CLK_DIV_CDREX */
+#define MCLK_DPHY_RATIO 0x1
+#define MCLK_CDREX_RATIO 0x1
+#define ACLK_C2C_200_RATIO 0x1
+#define C2C_CLK_400_RATIO 0x1
+#define PCLK_CDREX_RATIO 0x1
+#define ACLK_CDREX_RATIO 0x1
+
+#define CLK_DIV_CDREX_VAL ((MCLK_DPHY_RATIO << 20) \
+ | (MCLK_CDREX_RATIO << 16) \
+ | (ACLK_C2C_200_RATIO << 12) \
+ | (C2C_CLK_400_RATIO << 8) \
+ | (PCLK_CDREX_RATIO << 4) \
+ | (ACLK_CDREX_RATIO)) \
+/* CLK_SRC_TOP0 */
+#define MUX_ACLK_300_GSCL_SEL 0x0
+#define MUX_ACLK_300_GSCL_MID_SEL 0x0
+#define MUX_ACLK_400_G3D_MID_SEL 0x0
+#define MUX_ACLK_333_SEL 0x0
+#define MUX_ACLK_300_DISP1_SEL 0x0
+#define MUX_ACLK_300_DISP1_MID_SEL 0x0
+#define MUX_ACLK_200_SEL 0x0
+#define MUX_ACLK_166_SEL 0x0
+#define CLK_SRC_TOP0_VAL ((MUX_ACLK_300_GSCL_SEL << 25) \
+ | (MUX_ACLK_300_GSCL_MID_SEL << 24) \
+ | (MUX_ACLK_400_G3D_MID_SEL << 20) \
+ | (MUX_ACLK_333_SEL << 16) \
+ | (MUX_ACLK_300_DISP1_SEL << 15) \
+ | (MUX_ACLK_300_DISP1_MID_SEL << 14) \
+ | (MUX_ACLK_200_SEL << 12) \
+ | (MUX_ACLK_166_SEL << 8))
+
+/* CLK_SRC_TOP1 */
+#define MUX_ACLK_400_G3D_SEL 0x1
+#define MUX_ACLK_400_ISP_SEL 0x0
+#define MUX_ACLK_400_IOP_SEL 0x0
+#define MUX_ACLK_MIPI_HSI_TXBASE_SEL 0x0
+#define MUX_ACLK_300_GSCL_MID1_SEL 0x0
+#define MUX_ACLK_300_DISP1_MID1_SEL 0x0
+#define CLK_SRC_TOP1_VAL ((MUX_ACLK_400_G3D_SEL << 28) \
+ |(MUX_ACLK_400_ISP_SEL << 24) \
+ |(MUX_ACLK_400_IOP_SEL << 20) \
+ |(MUX_ACLK_MIPI_HSI_TXBASE_SEL << 16) \
+ |(MUX_ACLK_300_GSCL_MID1_SEL << 12) \
+ |(MUX_ACLK_300_DISP1_MID1_SEL << 8))
+
+/* CLK_SRC_TOP2 */
+#define MUX_GPLL_SEL 0x1
+#define MUX_BPLL_USER_SEL 0x0
+#define MUX_MPLL_USER_SEL 0x0
+#define MUX_VPLL_SEL 0x1
+#define MUX_EPLL_SEL 0x1
+#define MUX_CPLL_SEL 0x1
+#define VPLLSRC_SEL 0x0
+#define CLK_SRC_TOP2_VAL ((MUX_GPLL_SEL << 28) \
+ | (MUX_BPLL_USER_SEL << 24) \
+ | (MUX_MPLL_USER_SEL << 20) \
+ | (MUX_VPLL_SEL << 16) \
+ | (MUX_EPLL_SEL << 12) \
+ | (MUX_CPLL_SEL << 8) \
+ | (VPLLSRC_SEL))
+/* CLK_SRC_TOP3 */
+#define MUX_ACLK_333_SUB_SEL 0x1
+#define MUX_ACLK_400_SUB_SEL 0x1
+#define MUX_ACLK_266_ISP_SUB_SEL 0x1
+#define MUX_ACLK_266_GPS_SUB_SEL 0x0
+#define MUX_ACLK_300_GSCL_SUB_SEL 0x1
+#define MUX_ACLK_266_GSCL_SUB_SEL 0x1
+#define MUX_ACLK_300_DISP1_SUB_SEL 0x1
+#define MUX_ACLK_200_DISP1_SUB_SEL 0x1
+#define CLK_SRC_TOP3_VAL ((MUX_ACLK_333_SUB_SEL << 24) \
+ | (MUX_ACLK_400_SUB_SEL << 20) \
+ | (MUX_ACLK_266_ISP_SUB_SEL << 16) \
+ | (MUX_ACLK_266_GPS_SUB_SEL << 12) \
+ | (MUX_ACLK_300_GSCL_SUB_SEL << 10) \
+ | (MUX_ACLK_266_GSCL_SUB_SEL << 8) \
+ | (MUX_ACLK_300_DISP1_SUB_SEL << 6) \
+ | (MUX_ACLK_200_DISP1_SUB_SEL << 4))
+
+/* CLK_DIV_TOP0 */
+#define ACLK_300_DISP1_RATIO 0x2
+#define ACLK_400_G3D_RATIO 0x0
+#define ACLK_333_RATIO 0x0
+#define ACLK_266_RATIO 0x2
+#define ACLK_200_RATIO 0x3
+#define ACLK_166_RATIO 0x1
+#define ACLK_133_RATIO 0x1
+#define ACLK_66_RATIO 0x5
+
+#define CLK_DIV_TOP0_VAL ((ACLK_300_DISP1_RATIO << 28) \
+ | (ACLK_400_G3D_RATIO << 24) \
+ | (ACLK_333_RATIO << 20) \
+ | (ACLK_266_RATIO << 16) \
+ | (ACLK_200_RATIO << 12) \
+ | (ACLK_166_RATIO << 8) \
+ | (ACLK_133_RATIO << 4) \
+ | (ACLK_66_RATIO))
+
+/* CLK_DIV_TOP1 */
+#define ACLK_MIPI_HSI_TX_BASE_RATIO 0x3
+#define ACLK_66_PRE_RATIO 0x1
+#define ACLK_400_ISP_RATIO 0x1
+#define ACLK_400_IOP_RATIO 0x1
+#define ACLK_300_GSCL_RATIO 0x2
+
+#define CLK_DIV_TOP1_VAL ((ACLK_MIPI_HSI_TX_BASE_RATIO << 28) \
+ | (ACLK_66_PRE_RATIO << 24) \
+ | (ACLK_400_ISP_RATIO << 20) \
+ | (ACLK_400_IOP_RATIO << 16) \
+ | (ACLK_300_GSCL_RATIO << 12))
+
+/* APLL_LOCK */
+#define APLL_LOCK_VAL (0x546)
+/* MPLL_LOCK */
+#define MPLL_LOCK_VAL (0x546)
+/* CPLL_LOCK */
+#define CPLL_LOCK_VAL (0x546)
+/* GPLL_LOCK */
+#define GPLL_LOCK_VAL (0x546)
+/* EPLL_LOCK */
+#define EPLL_LOCK_VAL (0x3A98)
+/* VPLL_LOCK */
+#define VPLL_LOCK_VAL (0x3A98)
+/* BPLL_LOCK */
+#define BPLL_LOCK_VAL (0x546)
+
+/* CLK_SRC_PERIC0 */
+#define PWM_SEL 0
+#define UART3_SEL 6
+#define UART2_SEL 6
+#define UART1_SEL 6
+#define UART0_SEL 6
+/* SRC_CLOCK = SCLK_MPLL */
+#define CLK_SRC_PERIC0_VAL ((PWM_SEL << 24) \
+ | (UART3_SEL << 12) \
+ | (UART2_SEL<< 8) \
+ | (UART1_SEL << 4) \
+ | (UART0_SEL))
+
+/* CLK_DIV_PERIL0 */
+#define UART5_RATIO 7
+#define UART4_RATIO 7
+#define UART3_RATIO 7
+#define UART2_RATIO 7
+#define UART1_RATIO 7
+#define UART0_RATIO 7
+
+#define CLK_DIV_PERIC0_VAL ((UART3_RATIO << 12) \
+ | (UART2_RATIO << 8) \
+ | (UART1_RATIO << 4) \
+ | (UART0_RATIO))
+/* CLK_SRC_LEX */
+#define CLK_SRC_LEX_VAL 0x0
+
+/* CLK_DIV_LEX */
+#define CLK_DIV_LEX_VAL 0x10
+
+/* CLK_DIV_R0X */
+#define CLK_DIV_R0X_VAL 0x10
+
+/* CLK_DIV_L0X */
+#define CLK_DIV_R1X_VAL 0x10
+
+/* CLK_DIV_ISP0 */
+#define CLK_DIV_ISP0_VAL 0x31
+
+/* CLK_DIV_ISP1 */
+#define CLK_DIV_ISP1_VAL 0x0
+
+/* CLK_DIV_ISP2 */
+#define CLK_DIV_ISP2_VAL 0x1
+
+#define MPLL_DEC (MPLL_MDIV * MPLL_MDIV / (MPLL_PDIV * 2^(MPLL_SDIV-1)))
+
+#define SCLK_UART MPLL_DEC / (UART1_RATIO+1)
+
+#define UART_UBRDIV_VAL 0x35 /* (SCLK_UART/(115200*16) -1) */
+#define UART_UDIVSLOT_VAL 0x4 /*((((SCLK_UART*10/(115200*16) -10))%10)*16/10)*/
+
+#endif
diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Include/Platform/Exynos5250.h b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Include/Platform/Exynos5250.h
new file mode 100644
index 000000000..b0e473d9e
--- /dev/null
+++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Include/Platform/Exynos5250.h
@@ -0,0 +1,730 @@
+/*
+ * (C) Copyright 2012 Samsung Electronics Co. Ltd
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#ifndef _EXYNOS5250_CPU_H
+#define _EXYNOS5250_CPU_H
+
+/* EXYNOS5250 */
+#define EXYNOS5250_PRO_ID 0x10000000
+#define EXYNOS5250_SYSREG_BASE 0x10050000
+#define EXYNOS5250_POWER_BASE 0x10040000
+#define EXYNOS5250_CLOCK_BASE 0x10010000
+#define EXYNOS5250_SROM_BASE 0x12250000
+#define EXYNOS5250_HSMMC_BASE 0x12200000
+#define EXYNOS5250_PWMTIMER_BASE 0x12DD0000
+#define EXYNOS5250_INF_REG_BASE 0x10040800
+#define EXYNOS5250_TZPC_BASE 0x10100000
+#define EXYNOS5250_UART_BASE 0x12C00000
+
+#define BIT0 0x00000001
+#define BIT1 0x00000002
+#define BIT2 0x00000004
+#define BIT3 0x00000008
+#define BIT4 0x00000010
+#define BIT5 0x00000020
+#define BIT6 0x00000040
+#define BIT7 0x00000080
+#define BIT8 0x00000100
+#define BIT9 0x00000200
+#define BIT10 0x00000400
+#define BIT11 0x00000800
+#define BIT12 0x00001000
+#define BIT13 0x00002000
+#define BIT14 0x00004000
+#define BIT15 0x00008000
+#define BIT16 0x00010000
+#define BIT17 0x00020000
+#define BIT18 0x00040000
+#define BIT19 0x00080000
+#define BIT20 0x00100000
+#define BIT21 0x00200000
+#define BIT22 0x00400000
+#define BIT23 0x00800000
+#define BIT24 0x01000000
+#define BIT25 0x02000000
+#define BIT26 0x04000000
+#define BIT27 0x08000000
+#define BIT28 0x10000000
+#define BIT29 0x20000000
+#define BIT30 0x40000000
+#define BIT31 0x80000000
+
+
+#define __REG(x) (*(unsigned int *)(x))
+
+/*
+ * CHIP ID
+ */
+#define CHIP_ID_BASE EXYNOS5250_PRO_ID
+#define PRO_ID_OFFSET 0x0
+#define PRO_ID __REG(CHIP_ID_BASE+PRO_ID_OFFSET)
+
+/*
+ * SYSREG
+ */
+#define USB_CFG_OFFSET 0x230
+#define USB_CFG_REG (EXYNOS5250_SYSREG_BASE + USB_CFG_OFFSET)
+
+/*
+ * POWER
+ */
+#define ELFIN_POWER_BASE EXYNOS5250_POWER_BASE
+#define OMR_OFFSET 0x0
+#define SW_RST_REG_OFFSET 0x400
+#define SW_RST_REG __REG(EXYNOS5250_POWER_BASE + SW_RST_REG_OFFSET)
+
+#define INF_REG_BASE EXYNOS5250_INF_REG_BASE
+
+#define INF_REG0_OFFSET 0x00
+#define INF_REG1_OFFSET 0x04
+#define INF_REG2_OFFSET 0x08
+#define INF_REG3_OFFSET 0x0C
+#define INF_REG4_OFFSET 0x10
+#define INF_REG5_OFFSET 0x14
+#define INF_REG6_OFFSET 0x18
+#define INF_REG7_OFFSET 0x1C
+
+#define INF_REG0_REG __REG(INF_REG_BASE+INF_REG0_OFFSET)
+#define INF_REG1_REG __REG(INF_REG_BASE+INF_REG1_OFFSET)
+#define INF_REG2_REG __REG(INF_REG_BASE+INF_REG2_OFFSET)
+#define INF_REG3_REG __REG(INF_REG_BASE+INF_REG3_OFFSET)
+#define INF_REG4_REG __REG(INF_REG_BASE+INF_REG4_OFFSET)
+#define INF_REG5_REG __REG(INF_REG_BASE+INF_REG5_OFFSET)
+#define INF_REG6_REG __REG(INF_REG_BASE+INF_REG6_OFFSET)
+#define INF_REG7_REG __REG(INF_REG_BASE+INF_REG7_OFFSET)
+
+#define USB_DEVICE_PHY_CONTROL_OFFSET 0x0704
+#define USB_DEVICE_PHY_CONTROL (EXYNOS5250_POWER_BASE+USB_DEVICE_PHY_CONTROL_OFFSET)
+
+/* Define Mode */
+#define S5P_CHECK_SLEEP 0x00000BAD
+#define S5P_CHECK_DIDLE 0xBAD00000
+#define S5P_CHECK_LPA 0xABAD0000
+
+/*
+ * CLOCK
+ */
+#define ELFIN_CLOCK_BASE EXYNOS5250_CLOCK_BASE
+
+#define APLL_LOCK_OFFSET 0x00000
+#define APLL_CON0_OFFSET 0x00100
+#define APLL_CON1_OFFSET 0x00104
+#define CLK_SRC_CPU_OFFSET 0x00200
+#define CLK_MUX_STAT_CPU_OFFSET 0x00400
+#define CLK_DIV_CPU0_OFFSET 0x00500
+#define CLK_DIV_CPU1_OFFSET 0x00504
+#define CLK_DIV_STAT_CPU0_OFFSET 0x00600
+#define CLK_DIV_STAT_CPU1_OFFSET 0x00604
+#define CLK_GATE_SCLK_CPU_OFFSET 0x00800
+#define CLKOUT_CMU_CPU_OFFSET 0x00A00
+#define CLKOUT_CMU_CPU_DIV_STAT_OFFSET 0x00A04
+#define ARMCLK_STOPCTRL_OFFSET 0x01000
+#define ATCLK_STOPCTRL_OFFSET 0x01004
+#define PARITYFAIL_STATUS_OFFSET 0x01010
+#define PARITYFAIL_CLEAR_OFFSET 0x01014
+#define PWR_CTRL_OFFSET 0x01020
+#define PWR_CTRL2_OFFSET 0x01024
+#define APLL_CON0_L8_OFFSET 0x01100
+#define APLL_CON0_L7_OFFSET 0x01104
+#define APLL_CON0_L6_OFFSET 0x01108
+#define APLL_CON0_L5_OFFSET 0x0110C
+#define APLL_CON0_L4_OFFSET 0x01110
+#define APLL_CON0_L3_OFFSET 0x01114
+#define APLL_CON0_L2_OFFSET 0x01118
+#define APLL_CON0_L1_OFFSET 0x0111C
+#define IEM_CONTROL_OFFSET 0x01120
+#define APLL_CON1_L8_OFFSET 0x01200
+#define APLL_CON1_L7_OFFSET 0x01204
+#define APLL_CON1_L6_OFFSET 0x01208
+#define APLL_CON1_L5_OFFSET 0x0120C
+#define APLL_CON1_L4_OFFSET 0x01210
+#define APLL_CON1_L3_OFFSET 0x01214
+#define APLL_CON1_L2_OFFSET 0x01218
+#define APLL_CON1_L1_OFFSET 0x0121C
+#define CLKDIV_IEM_L8_OFFSET 0x01300
+#define CLKDIV_IEM_L7_OFFSET 0x01304
+#define CLKDIV_IEM_L6_OFFSET 0x01308
+#define CLKDIV_IEM_L5_OFFSET 0x0130C
+#define CLKDIV_IEM_L4_OFFSET 0x01310
+#define CLKDIV_IEM_L3_OFFSET 0x01314
+#define CLKDIV_IEM_L2_OFFSET 0x01318
+#define CLKDIV_IEM_L1_OFFSET 0x0131C
+#define MPLL_LOCK_OFFSET 0x04000
+#define MPLL_CON0_OFFSET 0x04100
+#define MPLL_CON1_OFFSET 0x04104
+#define CLK_SRC_CORE0_OFFSET 0x04200
+#define CLK_SRC_CORE1_OFFSET 0x04204
+#define CLK_SRC_MASK_CORE0_OFFSET 0x04300
+#define CLK_MUX_STAT_CORE1_OFFSET 0x04404
+#define CLK_DIV_CORE0_OFFSET 0x04500
+#define CLK_DIV_CORE1_OFFSET 0x04504
+#define CLK_DIV_STAT_CORE0_OFFSET 0x04600
+#define CLK_DIV_STAT_CORE1_OFFSET 0x04604
+#define CLK_GATE_IP_CORE_OFFSET 0x04900
+#define CLKOUT_CMU_CORE_OFFSET 0x04A00
+#define CLKOUT_CMU_CORE_DIV_STAT_OFFSET 0x04A04
+#define DCGIDX_MAP0_OFFSET 0x05000
+#define DCGIDX_MAP1_OFFSET 0x05004
+#define DCGIDX_MAP2_OFFSET 0x05008
+#define DCGPERF_MAP0_OFFSET 0x05020
+#define DCGPERF_MAP1_OFFSET 0x05024
+#define DVCIDX_MAP_OFFSET 0x05040
+#define FREQ_CPU_OFFSET 0x05060
+#define FREQ_DPM_OFFSET 0x05064
+#define DVSEMCLK_EN_OFFSET 0x05080
+#define MAXPERF_OFFSET 0x05084
+#define CLK_DIV_ACP_OFFSET 0x08500
+#define CLK_DIV_STAT_ACP_OFFSET 0x08600
+#define CLK_GATE_IP_ACP_OFFSET 0x08800
+#define CLKOUT_CMU_ACP_OFFSET 0x08A00
+#define CLKOUT_CMU_ACP_DIV_STAT_OFFSET 0x08A04
+#define CLK_DIV_ISP0_OFFSET 0x0C300
+#define CLK_DIV_ISP1_OFFSET 0x0C304
+#define CLK_DIV_ISP2_OFFSET 0x0C308
+#define CLK_DIV_STAT_ISP0_OFFSET 0x0C400
+#define CLK_DIV_STAT_ISP1_OFFSET 0x0C404
+#define CLK_DIV_STAT_ISP2_OFFSET 0x0C408
+#define CLK_GATE_IP_ISP0_OFFSET 0x0C800
+#define CLK_GATE_IP_ISP1_OFFSET 0x0C804
+#define CLK_GATE_SCLK_ISP_OFFSET 0x0C900
+#define MCUISP_PWR_CTRL_OFFSET 0x0C910
+#define CLKOUT_CMU_ISP_OFFSET 0x0CA00
+#define CLKOUT_CMU_ISP_DIV_STAT_OFFSET 0x0CA04
+#define CPLL_LOCK_OFFSET 0x10020
+#define EPLL_LOCK_OFFSET 0x10030
+#define VPLL_LOCK_OFFSET 0x10040
+#define CPLL_CON0_OFFSET 0x10120
+#define CPLL_CON1_OFFSET 0x10124
+#define EPLL_CON0_OFFSET 0x10130
+#define EPLL_CON1_OFFSET 0x10134
+#define EPLL_CON2_OFFSET 0x10138
+#define VPLL_CON0_OFFSET 0x10140
+#define VPLL_CON1_OFFSET 0x10144
+#define VPLL_CON2_OFFSET 0x10148
+#define CLK_SRC_TOP0_OFFSET 0x10210
+#define CLK_SRC_TOP1_OFFSET 0x10214
+#define CLK_SRC_TOP2_OFFSET 0x10218
+#define CLK_SRC_TOP3_OFFSET 0x1021C
+#define CLK_SRC_GSCL_OFFSET 0x10220
+#define CLK_SRC_DISP1_0_OFFSET 0x1022C
+#define CLK_SRC_DISP1_1_OFFSET 0x10230
+#define CLK_SRC_MAU_OFFSET 0x10240
+#define CLK_SRC_FSYS_OFFSET 0x10244
+#define CLK_SRC_PERIC0_OFFSET 0x10250
+#define CLK_SRC_PERIC1_OFFSET 0x10254
+#define SCLK_SRC_ISP_OFFSET 0x10270
+#define CLK_SRC_MASK_TOP_OFFSET 0x10310
+#define CLK_SRC_MASK_GSCL_OFFSET 0x10320
+#define CLK_SRC_MASK_DISP1_0_OFFSET 0x1032C
+#define CLK_SRC_MASK_DISP1_1_OFFSET 0x10330
+#define CLK_SRC_MASK_MAU_OFFSET 0x10334
+#define CLK_SRC_MASK_FSYS_OFFSET 0x10340
+#define CLK_SRC_MASK_PERIC0_OFFSET 0x10350
+#define CLK_SRC_MASK_PERIC1_OFFSET 0x10354
+#define SCLK_SRC_MASK_ISP_OFFSET 0x10370
+#define CLK_MUX_STAT_TOP0_OFFSET 0x10410
+#define CLK_MUX_STAT_TOP1_OFFSET 0x10414
+#define CLK_MUX_STAT_TOP2_OFFSET 0x10418
+#define CLK_MUX_STAT_TOP3_OFFSET 0x1041C
+#define CLK_DIV_TOP0_OFFSET 0x10510
+#define CLK_DIV_TOP1_OFFSET 0x10514
+#define CLK_DIV_GSCL_OFFSET 0x10520
+#define CLK_DIV_DISP1_0_OFFSET 0x1052C
+#define CLK_DIV_DISP1_1_OFFSET 0x10530
+#define CLK_DIV_GEN_OFFSET 0x1053C
+#define CLK_DIV_MAU_OFFSET 0x10544
+#define CLK_DIV_FSYS0_OFFSET 0x10548
+#define CLK_DIV_FSYS1_OFFSET 0x1054C
+#define CLK_DIV_FSYS2_OFFSET 0x10550
+#define CLK_DIV_FSYS3_OFFSET 0x10554
+#define CLK_DIV_PERIC0_OFFSET 0x10558
+#define CLK_DIV_PERIC1_OFFSET 0x1055C
+#define CLK_DIV_PERIC2_OFFSET 0x10560
+#define CLK_DIV_PERIC3_OFFSET 0x10564
+#define CLK_DIV_PERIC4_OFFSET 0x10568
+#define CLK_DIV_PERIC5_OFFSET 0x1056C
+#define SCLK_DIV_ISP_OFFSET 0x10580
+#define CLKDIV2_RATIO0_OFFSET 0x10590
+#define CLKDIV2_RATIO1_OFFSET 0x10594
+#define CLKDIV4_RATIO_OFFSET 0x105A0
+#define CLK_DIV_STAT_TOP0_OFFSET 0x10610
+#define CLK_DIV_STAT_TOP1_OFFSET 0x10614
+#define CLK_DIV_STAT_GSCL_OFFSET 0x10620
+#define CLK_DIV_STAT_DISP1_0_OFFSET 0x1062C
+#define CLK_DIV_STAT_DISP1_1_OFFSET 0x10630
+#define CLK_DIV_STAT_GEN_OFFSET 0x1063C
+#define CLK_DIV_STAT_MAUDIO_OFFSET 0x10644
+#define CLK_DIV_STAT_FSYS0_OFFSET 0x10648
+#define CLK_DIV_STAT_FSYS1_OFFSET 0x1064C
+#define CLK_DIV_STAT_FSYS2_OFFSET 0x10650
+#define CLK_DIV_STAT_FSYS3_OFFSET 0x10654
+#define CLK_DIV_STAT_PERIC0_OFFSET 0x10658
+#define CLK_DIV_STAT_PERIC1_OFFSET 0x1065C
+#define CLK_DIV_STAT_PERIC2_OFFSET 0x10660
+#define CLK_DIV_STAT_PERIC3_OFFSET 0x10664
+#define CLK_DIV_STAT_PERIC4_OFFSET 0x10668
+#define CLK_DIV_STAT_PERIC5_OFFSET 0x1066C
+#define SCLK_DIV_STAT_ISP_OFFSET 0x10680
+#define CLKDIV2_STAT0_OFFSET 0x10690
+#define CLKDIV2_STAT1_OFFSET 0x10694
+#define CLKDIV4_STAT_OFFSET 0x106A0
+#define CLK_GATE_TOP_SCLK_DISP1_OFFSET 0x10828
+#define CLK_GATE_TOP_SCLK_GEN_OFFSET 0x1082C
+#define CLK_GATE_TOP_SCLK_MAU_OFFSET 0x1083C
+#define CLK_GATE_TOP_SCLK_FSYS_OFFSET 0x10840
+#define CLK_GATE_TOP_SCLK_PERIC_OFFSET 0x10850
+#define CLK_GATE_TOP_SCLK_ISP_OFFSET 0x10870
+#define CLK_GATE_IP_GSCL_OFFSET 0x10920
+#define CLK_GATE_IP_DISP1_OFFSET 0x10928
+#define CLK_GATE_IP_MFC_OFFSET 0x1092C
+#define CLK_GATE_IP_G3D_OFFSET 0x10930
+#define CLK_GATE_IP_GEN_OFFSET 0x10934
+#define CLK_GATE_IP_FSYS_OFFSET 0x10944
+#define CLK_GATE_IP_GPS_OFFSET 0x1094C
+#define CLK_GATE_IP_PERIC_OFFSET 0x10950
+#define CLK_GATE_IP_PERIS_OFFSET 0x10960
+#define CLK_GATE_BLOCK_OFFSET 0x10980
+#define CLKOUT_CMU_TOP_OFFSET 0x10A00
+#define CLKOUT_CMU_TOP_DIV_STAT_OFFSET 0x10A04
+#define CLK_SRC_LEX_OFFSET 0x14200
+#define CLK_DIV_LEX_OFFSET 0x14500
+#define CLK_DIV_STAT_LEX_OFFSET 0x14600
+#define CLK_GATE_IP_LEX_OFFSET 0x14800
+#define CLKOUT_CMU_LEX_OFFSET 0x14A00
+#define CLKOUT_CMU_LEX_DIV_STAT_OFFSET 0x14A04
+#define CLK_DIV_R0X_OFFSET 0x18500
+#define CLK_DIV_STAT_R0X_OFFSET 0x18600
+#define CLK_GATE_IP_R0X_OFFSET 0x18800
+#define CLKOUT_CMU_R0X_OFFSET 0x18A00
+#define CLKOUT_CMU_R0X_DIV_STAT_OFFSET 0x18A04
+#define CLK_DIV_R1X_OFFSET 0x1C500
+#define CLK_DIV_STAT_R1X_OFFSET 0x1C600
+#define CLK_GATE_IP_R1X_OFFSET 0x1C800
+#define CLKOUT_CMU_R1X_OFFSET 0x1CA00
+#define CLKOUT_CMU_R1X_DIV_STAT_OFFSET 0x1CA04
+#define BPLL_LOCK_OFFSET 0x20010
+#define BPLL_CON0_OFFSET 0x20110
+#define BPLL_CON1_OFFSET 0x20114
+#define CLK_SRC_CDREX_OFFSET 0x20200
+#define CLK_MUX_STAT_CDREX_OFFSET 0x20400
+#define CLK_DIV_CDREX_OFFSET 0x20500
+#define CLK_DIV_CDREX2_OFFSET 0x20504
+#define CLK_DIV_STAT_CDREX_OFFSET 0x20600
+#define CLK_GATE_IP_CDREX_OFFSET 0x20900
+#define C2C_MONITOR_OFFSET 0x20910
+#define DMC_PWR_CTRL 0x20914
+#define DREX2_PAUSE_OFFSET 0x2091C
+#define CLKOUT_CMU_CDREX_OFFSET 0x20A00
+#define CLKOUT_CMU_CDREX_DIV_STAT_OFFSET 0x20A04
+#define LPDDR3PHY_CTRL 0x20A10
+
+#define CLK_SRC_FSYS __REG(ELFIN_CLOCK_BASE+CLK_SRC_FSYS_OFFSET)
+#define CLK_DIV_FSYS1 __REG(ELFIN_CLOCK_BASE+CLK_DIV_FSYS1_OFFSET)
+#define CLK_DIV_FSYS2 __REG(ELFIN_CLOCK_BASE+CLK_DIV_FSYS2_OFFSET)
+#define CLK_DIV_FSYS3 __REG(ELFIN_CLOCK_BASE+CLK_DIV_FSYS3_OFFSET)
+#define APLL_CON0_REG __REG(ELFIN_CLOCK_BASE+APLL_CON0_OFFSET)
+#define MPLL_CON0_REG __REG(ELFIN_CLOCK_BASE+MPLL_CON0_OFFSET)
+#define EPLL_CON0_REG __REG(ELFIN_CLOCK_BASE+EPLL_CON0_OFFSET)
+#define VPLL_CON0_REG __REG(ELFIN_CLOCK_BASE+VPLL_CON0_OFFSET)
+
+#define FIMD1_SCLKMPLL (0x06)
+#define FIMD1_CLK_DIV (0x00)
+
+#define CLK_GATE_FIMD1_MASK (0x01 << 0x00)
+#define CLK_SRC_FIMD1_MASK (0x0F << 0x00)
+#define CLK_DIV_FIMD1_MASK (0x0F << 0x00)
+
+#define CLK_SRC_FIMD1_SEL(x) ((x) << 0x00)
+#define CLK_DIV_FIMD1_SEL(x) ((x) << 0x00)
+#define CLK_SRC_DISP1_0_UNMASK (0x01 << 0x00)
+
+#define CLK_GATE_DSIM1_MASK (0x01 << 0x03)
+
+/*
+ * TZPC
+ */
+#define TZPC0_OFFSET 0x00000
+#define TZPC1_OFFSET 0x10000
+#define TZPC2_OFFSET 0x20000
+#define TZPC3_OFFSET 0x30000
+#define TZPC4_OFFSET 0x40000
+#define TZPC5_OFFSET 0x50000
+#define TZPC6_OFFSET 0x60000
+#define TZPC7_OFFSET 0x70000
+#define TZPC8_OFFSET 0x80000
+#define TZPC9_OFFSET 0x90000
+
+#define ELFIN_TZPC0_BASE (EXYNOS5250_TZPC_BASE + TZPC0_OFFSET)
+#define ELFIN_TZPC1_BASE (EXYNOS5250_TZPC_BASE + TZPC1_OFFSET)
+#define ELFIN_TZPC2_BASE (EXYNOS5250_TZPC_BASE + TZPC2_OFFSET)
+#define ELFIN_TZPC3_BASE (EXYNOS5250_TZPC_BASE + TZPC3_OFFSET)
+#define ELFIN_TZPC4_BASE (EXYNOS5250_TZPC_BASE + TZPC4_OFFSET)
+#define ELFIN_TZPC5_BASE (EXYNOS5250_TZPC_BASE + TZPC5_OFFSET)
+#define ELFIN_TZPC6_BASE (EXYNOS5250_TZPC_BASE + TZPC6_OFFSET)
+#define ELFIN_TZPC7_BASE (EXYNOS5250_TZPC_BASE + TZPC7_OFFSET)
+#define ELFIN_TZPC8_BASE (EXYNOS5250_TZPC_BASE + TZPC8_OFFSET)
+#define ELFIN_TZPC9_BASE (EXYNOS5250_TZPC_BASE + TZPC9_OFFSET)
+
+#define TZPC_DECPROT0SET_OFFSET 0x804
+#define TZPC_DECPROT1SET_OFFSET 0x810
+#define TZPC_DECPROT2SET_OFFSET 0x81C
+#define TZPC_DECPROT3SET_OFFSET 0x828
+
+/*
+ * Memory controller
+ */
+#define ELFIN_SROM_BASE EXYNOS5250_SROM_BASE
+
+#define SROM_BW_REG __REG(ELFIN_SROM_BASE+0x0)
+#define SROM_BC0_REG __REG(ELFIN_SROM_BASE+0x4)
+#define SROM_BC1_REG __REG(ELFIN_SROM_BASE+0x8)
+#define SROM_BC2_REG __REG(ELFIN_SROM_BASE+0xC)
+#define SROM_BC3_REG __REG(ELFIN_SROM_BASE+0x10)
+
+/*
+ * SDRAM Controller
+ */
+
+/* DMC control register */
+#define DMC_CTRL_BASE 0x10DD0000
+
+#define DMC_CONCONTROL 0x00
+#define DMC_MEMCONTROL 0x04
+#define DMC_MEMCONFIG0 0x08
+#define DMC_MEMCONFIG1 0x0C
+#define DMC_DIRECTCMD 0x10
+#define DMC_PRECHCONFIG 0x14
+#define DMC_PHYCONTROL0 0x18
+#define DMC_PWRDNCONFIG 0x28
+#define DMC_TIMINGPZQ 0x2C
+#define DMC_TIMINGAREF 0x30
+#define DMC_TIMINGROW 0x34
+#define DMC_TIMINGDATA 0x38
+#define DMC_TIMINGPOWER 0x3C
+#define DMC_PHYSTATUS 0x40
+#define DMC_CHIPSTATUS_CH0 0x48
+#define DMC_CHIPSTATUS_CH1 0x4C
+#define DMC_MRSTATUS 0x54
+#define DMC_QOSCONTROL0 0x60
+#define DMC_QOSCONTROL1 0x68
+#define DMC_QOSCONTROL2 0x70
+#define DMC_QOSCONTROL3 0x78
+#define DMC_QOSCONTROL4 0x80
+#define DMC_QOSCONTROL5 0x88
+#define DMC_QOSCONTROL6 0x90
+#define DMC_QOSCONTROL7 0x98
+#define DMC_QOSCONTROL8 0xA0
+#define DMC_QOSCONTROL9 0xA8
+#define DMC_QOSCONTROL10 0xB0
+#define DMC_QOSCONTROL11 0xB8
+#define DMC_QOSCONTROL12 0xC0
+#define DMC_QOSCONTROL13 0xC8
+#define DMC_QOSCONTROL14 0xD0
+#define DMC_QOSCONTROL15 0xD8
+#define DMC_IVCONTROL 0xF0
+#define DMC_WRTRA_CONFIG 0x00F4
+#define DMC_RDLVL_CONFIG 0x00F8
+#define DMC_BRBRSVCONTROL 0x0100
+#define DMC_BRBRSVCONFIG 0x0104
+#define DMC_BRBQOSCONFIG 0x0108
+#define DMC_MEMBASECONFIG0 0x010C
+#define DMC_MEMBASECONFIG1 0x0110
+#define DMC_WRLVL_CONFIG 0x0120
+#define DMC_PMNC_PPC 0xE000
+#define DMC_CNTENS_PPC 0xE010
+#define DMC_CNTENC_PPC 0xE020
+#define DMC_INTENS_PPC 0xE030
+#define DMC_INTENC_PPC 0xE040
+#define DMC_FLAG_PPC 0xE050
+#define DMC_CCNT_PPC 0xE100
+#define DMC_PMCNT0_PPC 0xE110
+#define DMC_PMCNT1_PPC 0xE120
+#define DMC_PMCNT2_PPC 0xE130
+#define DMC_PMCNT3_PPC 0xE140
+
+/* PHY Control Register */
+#define PHY0_CTRL_BASE 0x10C00000
+#define PHY1_CTRL_BASE 0x10C10000
+
+#define DMC_PHY_CON0 0x00
+#define DMC_PHY_CON1 0x04
+#define DMC_PHY_CON2 0x08
+#define DMC_PHY_CON3 0x0C
+#define DMC_PHY_CON4 0x10
+#define DMC_PHY_CON6 0x18
+#define DMC_PHY_CON8 0x20
+#define DMC_PHY_CON10 0x28
+#define DMC_PHY_CON11 0x2C
+#define DMC_PHY_CON12 0x30
+#define DMC_PHY_CON13 0x34
+#define DMC_PHY_CON14 0x38
+#define DMC_PHY_CON15 0x3C
+#define DMC_PHY_CON16 0x40
+#define DMC_PHY_CON17 0x48
+#define DMC_PHY_CON18 0x4C
+#define DMC_PHY_CON19 0x50
+#define DMC_PHY_CON20 0x54
+#define DMC_PHY_CON21 0x58
+#define DMC_PHY_CON22 0x5C
+#define DMC_PHY_CON23 0x60
+#define DMC_PHY_CON24 0x64
+#define DMC_PHY_CON25 0x68
+#define DMC_PHY_CON26 0x6C
+#define DMC_PHY_CON27 0x70
+#define DMC_PHY_CON28 0x74
+#define DMC_PHY_CON29 0x78
+#define DMC_PHY_CON30 0x7C
+#define DMC_PHY_CON31 0x80
+#define DMC_PHY_CON32 0x84
+#define DMC_PHY_CON33 0x88
+#define DMC_PHY_CON34 0x8C
+#define DMC_PHY_CON35 0x90
+#define DMC_PHY_CON36 0x94
+#define DMC_PHY_CON37 0x98
+#define DMC_PHY_CON38 0x9C
+#define DMC_PHY_CON39 0xA0
+#define DMC_PHY_CON40 0xA4
+#define DMC_PHY_CON41 0xA8
+#define DMC_PHY_CON42 0xAC
+/*
+ * UART
+ */
+
+#define UART0_OFFSET 0x00000
+#define UART1_OFFSET 0x10000
+#define UART2_OFFSET 0x20000
+#define UART3_OFFSET 0x30000
+#define UART4_OFFSET 0x40000
+
+#if defined(CONFIG_SERIAL0)
+#define UART_CONSOLE_BASE (EXYNOS5250_UART_BASE + UART0_OFFSET)
+#elif defined(CONFIG_SERIAL1)
+#define UART_CONSOLE_BASE (EXYNOS5250_UART_BASE + UART1_OFFSET)
+#elif defined(CONFIG_SERIAL2)
+#define UART_CONSOLE_BASE (EXYNOS5250_UART_BASE + UART2_OFFSET)
+#elif defined(CONFIG_SERIAL3)
+#define UART_CONSOLE_BASE (EXYNOS5250_UART_BASE + UART3_OFFSET)
+#elif defined(CONFIG_SERIAL4)
+#define UART_CONSOLE_BASE (EXYNOS5250_UART_BASE + UART4_OFFSET)
+#else
+#define UART_CONSOLE_BASE (EXYNOS5250_UART_BASE + UART0_OFFSET)
+#endif
+
+#define ULCON_OFFSET 0x00
+#define UCON_OFFSET 0x04
+#define UFCON_OFFSET 0x08
+#define UMCON_OFFSET 0x0C
+#define UTRSTAT_OFFSET 0x10
+#define UERSTAT_OFFSET 0x14
+#define UFSTAT_OFFSET 0x18
+#define UMSTAT_OFFSET 0x1C
+#define UTXH_OFFSET 0x20
+#define URXH_OFFSET 0x24
+#define UBRDIV_OFFSET 0x28
+#define UDIVSLOT_OFFSET 0x2C
+#define UINTP_OFFSET 0x30
+#define UINTSP_OFFSET 0x34
+#define UINTM_OFFSET 0x38
+//#define UTRSTAT_TX_EMPTY BIT2
+//#define UTRSTAT_RX_READY BIT0
+#define UART_ERR_MASK 0xF
+
+/*
+ * HS MMC
+ */
+#define HSMMC_0_OFFSET 0x00000
+#define HSMMC_1_OFFSET 0x10000
+#define HSMMC_2_OFFSET 0x20000
+#define HSMMC_3_OFFSET 0x30000
+#define HSMMC_4_OFFSET 0x40000
+
+#define ELFIN_HSMMC_0_BASE (EXYNOS5250_HSMMC_BASE + HSMMC_0_OFFSET)
+#define ELFIN_HSMMC_1_BASE (EXYNOS5250_HSMMC_BASE + HSMMC_1_OFFSET)
+#define ELFIN_HSMMC_2_BASE (EXYNOS5250_HSMMC_BASE + HSMMC_2_OFFSET)
+#define ELFIN_HSMMC_3_BASE (EXYNOS5250_HSMMC_BASE + HSMMC_3_OFFSET)
+#define ELFIN_HSMMC_4_BASE (EXYNOS5250_HSMMC_BASE + HSMMC_4_OFFSET)
+
+#define HM_SYSAD (0x00)
+#define HM_BLKSIZE (0x04)
+#define HM_BLKCNT (0x06)
+#define HM_ARGUMENT (0x08)
+#define HM_TRNMOD (0x0c)
+#define HM_CMDREG (0x0e)
+#define HM_RSPREG0 (0x10)
+#define HM_RSPREG1 (0x14)
+#define HM_RSPREG2 (0x18)
+#define HM_RSPREG3 (0x1c)
+#define HM_BDATA (0x20)
+#define HM_PRNSTS (0x24)
+#define HM_HOSTCTL (0x28)
+#define HM_PWRCON (0x29)
+#define HM_BLKGAP (0x2a)
+#define HM_WAKCON (0x2b)
+#define HM_CLKCON (0x2c)
+#define HM_TIMEOUTCON (0x2e)
+#define HM_SWRST (0x2f)
+#define HM_NORINTSTS (0x30)
+#define HM_ERRINTSTS (0x32)
+#define HM_NORINTSTSEN (0x34)
+#define HM_ERRINTSTSEN (0x36)
+#define HM_NORINTSIGEN (0x38)
+#define HM_ERRINTSIGEN (0x3a)
+#define HM_ACMD12ERRSTS (0x3c)
+#define HM_CAPAREG (0x40)
+#define HM_MAXCURR (0x48)
+#define HM_CONTROL2 (0x80)
+#define HM_CONTROL3 (0x84)
+#define HM_CONTROL4 (0x8c)
+#define HM_HCVER (0xfe)
+
+/* PENDING BIT */
+#define BIT_EINT0 (0x1)
+#define BIT_EINT1 (0x1<<1)
+#define BIT_EINT2 (0x1<<2)
+#define BIT_EINT3 (0x1<<3)
+#define BIT_EINT4_7 (0x1<<4)
+#define BIT_EINT8_23 (0x1<<5)
+#define BIT_BAT_FLT (0x1<<7)
+#define BIT_TICK (0x1<<8)
+#define BIT_WDT (0x1<<9)
+#define BIT_TIMER0 (0x1<<10)
+#define BIT_TIMER1 (0x1<<11)
+#define BIT_TIMER2 (0x1<<12)
+#define BIT_TIMER3 (0x1<<13)
+#define BIT_TIMER4 (0x1<<14)
+#define BIT_UART2 (0x1<<15)
+#define BIT_LCD (0x1<<16)
+#define BIT_DMA0 (0x1<<17)
+#define BIT_DMA1 (0x1<<18)
+#define BIT_DMA2 (0x1<<19)
+#define BIT_DMA3 (0x1<<20)
+#define BIT_SDI (0x1<<21)
+#define BIT_SPI0 (0x1<<22)
+#define BIT_UART1 (0x1<<23)
+#define BIT_USBH (0x1<<26)
+#define BIT_IIC (0x1<<27)
+#define BIT_UART0 (0x1<<28)
+#define BIT_SPI1 (0x1<<29)
+#define BIT_RTC (0x1<<30)
+#define BIT_ADC (0x1<<31)
+#define BIT_ALLMSK (0xFFFFFFFF)
+
+#define PWMTIMER_BASE EXYNOS5250_PWMTIMER_BASE
+
+/*
+ * USBD3 SFR
+ */
+#define USBDEVICE3_LINK_BASE 0x12000000
+#define USBDEVICE3_PHYCTRL_BASE 0x12100000
+
+//==========================
+// Global Registers (Gxxxx)
+//==========================
+// Global Common Registers
+#define rGSBUSCFG0 (USBDEVICE3_LINK_BASE + 0xc100)
+#define rGSBUSCFG1 (USBDEVICE3_LINK_BASE + 0xc104)
+#define rGTXTHRCFG (USBDEVICE3_LINK_BASE + 0xc108)
+#define rGRXTHRCFG (USBDEVICE3_LINK_BASE + 0xc10c)
+#define rGCTL (USBDEVICE3_LINK_BASE + 0xc110)
+#define rGEVTEN (USBDEVICE3_LINK_BASE + 0xc114)
+#define rGSTS (USBDEVICE3_LINK_BASE + 0xc118)
+#define rGSNPSID (USBDEVICE3_LINK_BASE + 0xc120)
+#define rGGPIO (USBDEVICE3_LINK_BASE + 0xc124)
+#define rGUID (USBDEVICE3_LINK_BASE + 0xc128)
+#define rGUCTL (USBDEVICE3_LINK_BASE + 0xc12c)
+#define rGBUSERRADDR_LO (USBDEVICE3_LINK_BASE + 0xc130)
+#define rGBUSERRADDR_HI (USBDEVICE3_LINK_BASE + 0xc134)
+
+// Global Port to USB Instance Mapping Registers
+#define rGPRTBIMAP_LO (USBDEVICE3_LINK_BASE + 0xc138)
+#define rGPRTBIMAP_HI (USBDEVICE3_LINK_BASE + 0xc13c)
+#define rGPRTBIMAP_HS_LO (USBDEVICE3_LINK_BASE + 0xc180)
+#define rGPRTBIMAP_HS_HI (USBDEVICE3_LINK_BASE + 0xc184)
+#define rGPRTBIMAP_FS_LO (USBDEVICE3_LINK_BASE + 0xc188)
+#define rGPRTBIMAP_FS_HI (USBDEVICE3_LINK_BASE + 0xc18c)
+
+// Global Hardware Parameter Registers
+#define rGHWPARAMS0 (USBDEVICE3_LINK_BASE + 0xc140) // 0x20204000 @c510
+#define rGHWPARAMS1 (USBDEVICE3_LINK_BASE + 0xc144) // 0x0060c93b @c510
+#define rGHWPARAMS2 (USBDEVICE3_LINK_BASE + 0xc148) // 0x12345678 @c510
+#define rGHWPARAMS3 (USBDEVICE3_LINK_BASE + 0xc14c) // 0x10420085 @c510
+#define rGHWPARAMS4 (USBDEVICE3_LINK_BASE + 0xc150) // 0x48820004 @c510
+#define rGHWPARAMS5 (USBDEVICE3_LINK_BASE + 0xc154) // 0x04204108 @c510
+#define rGHWPARAMS6 (USBDEVICE3_LINK_BASE + 0xc158) // 0x04008020 @c510
+#define rGHWPARAMS7 (USBDEVICE3_LINK_BASE + 0xc15c) // 0x018516fe @c510
+#define rGHWPARAMS8 (USBDEVICE3_LINK_BASE + 0xc600) // 0x00000386 @c510
+
+// Global Debug Registers
+#define rGDBGFIFOSPACE (USBDEVICE3_LINK_BASE + 0xc160)
+#define rGDBGLTSSM (USBDEVICE3_LINK_BASE + 0xc164)
+#define rGDBGLSPMUX (USBDEVICE3_LINK_BASE + 0xc170)
+#define rGDBGLSP (USBDEVICE3_LINK_BASE + 0xc174)
+#define rGDBGEPINFO0 (USBDEVICE3_LINK_BASE + 0xc178)
+#define rGDBGEPINFO1 (USBDEVICE3_LINK_BASE + 0xc17c)
+
+// Global PHY Registers
+#define rGUSB2PHYCFG (USBDEVICE3_LINK_BASE + 0xc200)
+#define rGUSB2I2CCTL (USBDEVICE3_LINK_BASE + 0xc240)
+#define rGUSB2PHYACC (USBDEVICE3_LINK_BASE + 0xc280)
+#define rGUSB3PIPECTL (USBDEVICE3_LINK_BASE + 0xc2c0)
+
+// Global FIFO Size Registers (0 <= num <= 15 @510)
+#define rGTXFIFOSIZ(num) ((USBDEVICE3_LINK_BASE + 0xc300) + 0x04*num)
+#define rGRXFIFOSIZ0 (USBDEVICE3_LINK_BASE + 0xc380)
+
+// Global Event Buffer Registers (DWC_USB3_DEVICE_NUM_INT = 1 @C510, GHWPARAMS1[20:15])
+#define rGEVNTADR_LO0 (USBDEVICE3_LINK_BASE + 0xc400)
+#define rGEVNTADR_HI0 (USBDEVICE3_LINK_BASE + 0xc404)
+#define rGEVNTSIZ0 (USBDEVICE3_LINK_BASE + 0xc408)
+#define rGEVNTCOUNT0 (USBDEVICE3_LINK_BASE + 0xc40c)
+
+//==========================
+// Device Registers (Dxxxx)
+//==========================
+// Device Common Registers
+#define rDCFG (USBDEVICE3_LINK_BASE + 0xc700)
+#define rDCTL (USBDEVICE3_LINK_BASE + 0xc704)
+#define rDEVTEN (USBDEVICE3_LINK_BASE + 0xc708)
+#define rDSTS (USBDEVICE3_LINK_BASE + 0xc70c)
+#define rDGCMDPAR (USBDEVICE3_LINK_BASE + 0xc710)
+#define rDGCMD (USBDEVICE3_LINK_BASE + 0xc714)
+#define rDALEPENA (USBDEVICE3_LINK_BASE + 0xc720)
+
+// Device Endpoint Registers (0 <= ep <= 15)
+#define rDOEPCMDPAR2(ep) ((USBDEVICE3_LINK_BASE + 0xc800) + 0x20*ep)
+#define rDOEPCMDPAR1(ep) ((USBDEVICE3_LINK_BASE + 0xc804) + 0x20*ep)
+#define rDOEPCMDPAR0(ep) ((USBDEVICE3_LINK_BASE + 0xc808) + 0x20*ep)
+#define rDOEPCMD(ep) ((USBDEVICE3_LINK_BASE + 0xc80c) + 0x20*ep)
+
+#define rDIEPCMDPAR2(ep) ((USBDEVICE3_LINK_BASE + 0xc810) + 0x20*ep)
+#define rDIEPCMDPAR1(ep) ((USBDEVICE3_LINK_BASE + 0xc814) + 0x20*ep)
+#define rDIEPCMDPAR0(ep) ((USBDEVICE3_LINK_BASE + 0xc818) + 0x20*ep)
+#define rDIEPCMD(ep) ((USBDEVICE3_LINK_BASE + 0xc81c) + 0x20*ep)
+
+//==========================
+// USB DEVICE PHY CONTROL REGISTERS
+//==========================
+#define EXYNOS_PHY_LINKSYSTEM (USBDEVICE3_PHYCTRL_BASE + 0x04)
+#define EXYNOS_PHY_UTMI (USBDEVICE3_PHYCTRL_BASE + 0x08)
+#define EXYNOS_PHY_PIPE (USBDEVICE3_PHYCTRL_BASE + 0x0C)
+#define EXYNOS_PHY_CLKPWR (USBDEVICE3_PHYCTRL_BASE + 0x10)
+#define EXYNOS_PHY_REG0 (USBDEVICE3_PHYCTRL_BASE + 0x14)
+#define EXYNOS_PHY_REG1 (USBDEVICE3_PHYCTRL_BASE + 0x18)
+#define EXYNOS_PHY_PARAM0 (USBDEVICE3_PHYCTRL_BASE + 0x1C)
+#define EXYNOS_PHY_PARAM1 (USBDEVICE3_PHYCTRL_BASE + 0x20)
+#define EXYNOS_PHY_TERM (USBDEVICE3_PHYCTRL_BASE + 0x24)
+#define EXYNOS_PHY_TEST (USBDEVICE3_PHYCTRL_BASE + 0x28)
+#define EXYNOS_PHY_ADP (USBDEVICE3_PHYCTRL_BASE + 0x2C)
+#define EXYNOS_PHY_BATCHG (USBDEVICE3_PHYCTRL_BASE + 0x30)
+#define EXYNOS_PHY_RESUME (USBDEVICE3_PHYCTRL_BASE + 0x34)
+
+#endif /* _EXYNOS5250_CPU_H */
diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Include/Platform/Exynos5250_Evt1.h b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Include/Platform/Exynos5250_Evt1.h
new file mode 100755
index 000000000..e229a1377
--- /dev/null
+++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Include/Platform/Exynos5250_Evt1.h
@@ -0,0 +1,763 @@
+/*
+ * (C) Copyright 2012 Samsung Electronics Co. Ltd
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#ifndef _EXYNOS5250_CPU_H
+#define _EXYNOS5250_CPU_H
+
+/* EXYNOS5250 */
+#define EXYNOS5250_PRO_ID 0x10000000
+#define EXYNOS5250_SYSREG_BASE 0x10050000
+#define EXYNOS5250_POWER_BASE 0x10040000
+#define EXYNOS5250_CLOCK_BASE 0x10010000
+#define EXYNOS5250_SROM_BASE 0x12250000
+#define EXYNOS5250_HSMMC_BASE 0x12200000
+#define EXYNOS5250_PWMTIMER_BASE 0x12DD0000
+#define EXYNOS5250_INF_REG_BASE 0x10040800
+#define EXYNOS5250_TZPC_BASE 0x10100000
+#define EXYNOS5250_UART_BASE 0x12C00000
+
+#define BIT0 0x00000001
+#define BIT1 0x00000002
+#define BIT2 0x00000004
+#define BIT3 0x00000008
+#define BIT4 0x00000010
+#define BIT5 0x00000020
+#define BIT6 0x00000040
+#define BIT7 0x00000080
+#define BIT8 0x00000100
+#define BIT9 0x00000200
+#define BIT10 0x00000400
+#define BIT11 0x00000800
+#define BIT12 0x00001000
+#define BIT13 0x00002000
+#define BIT14 0x00004000
+#define BIT15 0x00008000
+#define BIT16 0x00010000
+#define BIT17 0x00020000
+#define BIT18 0x00040000
+#define BIT19 0x00080000
+#define BIT20 0x00100000
+#define BIT21 0x00200000
+#define BIT22 0x00400000
+#define BIT23 0x00800000
+#define BIT24 0x01000000
+#define BIT25 0x02000000
+#define BIT26 0x04000000
+#define BIT27 0x08000000
+#define BIT28 0x10000000
+#define BIT29 0x20000000
+#define BIT30 0x40000000
+#define BIT31 0x80000000
+
+
+#define __REG(x) (*(unsigned int *)(x))
+
+/*
+ * CHIP ID
+ */
+#define CHIP_ID_BASE EXYNOS5250_PRO_ID
+#define PRO_ID_OFFSET 0x0
+#define PRO_ID __REG(CHIP_ID_BASE+PRO_ID_OFFSET)
+#define PRO_MAINREV ((PRO_ID >> 0x4) & 0x0f)
+#define PRO_SUBREV (PRO_ID & 0x0f)
+#define PRO_PKGINFO ((PRO_ID >> 0x8) & 0x0f)
+#define SCP_TYPE 0x0
+#define POP_TYPE 0x2
+
+/*
+ * SYSREG
+ */
+#define USB_CFG_OFFSET 0x230
+#define USB_CFG_REG (EXYNOS5250_SYSREG_BASE + USB_CFG_OFFSET)
+
+/*
+ * POWER
+ */
+#define ELFIN_POWER_BASE EXYNOS5250_POWER_BASE
+#define OMR_OFFSET 0x0
+#define SW_RST_REG_OFFSET 0x400
+#define SW_RST_REG __REG(EXYNOS5250_POWER_BASE + SW_RST_REG_OFFSET)
+
+#define FSYS_ARM_CONFIGURATION_OFFSET 0x2200
+#define EFNAND_PHY_CONTROL_OFFSET 0x070C
+#define SATA_PHY_CONTROL_OFFSET 0x0724
+
+#define INF_REG_BASE EXYNOS5250_INF_REG_BASE
+
+#define INF_REG0_OFFSET 0x00
+#define INF_REG1_OFFSET 0x04
+#define INF_REG2_OFFSET 0x08
+#define INF_REG3_OFFSET 0x0C
+#define INF_REG4_OFFSET 0x10
+#define INF_REG5_OFFSET 0x14
+#define INF_REG6_OFFSET 0x18
+#define INF_REG7_OFFSET 0x1C
+
+#define INF_REG0_REG __REG(INF_REG_BASE+INF_REG0_OFFSET)
+#define INF_REG1_REG __REG(INF_REG_BASE+INF_REG1_OFFSET)
+#define INF_REG2_REG __REG(INF_REG_BASE+INF_REG2_OFFSET)
+#define INF_REG3_REG __REG(INF_REG_BASE+INF_REG3_OFFSET)
+#define INF_REG4_REG __REG(INF_REG_BASE+INF_REG4_OFFSET)
+#define INF_REG5_REG __REG(INF_REG_BASE+INF_REG5_OFFSET)
+#define INF_REG6_REG __REG(INF_REG_BASE+INF_REG6_OFFSET)
+#define INF_REG7_REG __REG(INF_REG_BASE+INF_REG7_OFFSET)
+
+#define USB_DEVICE_PHY_CONTROL_OFFSET 0x0704
+#define USB_PHY_CONTROL_OFFSET 0x0708
+#define USB_DEVICE_PHY_CONTROL (EXYNOS5250_POWER_BASE+USB_DEVICE_PHY_CONTROL_OFFSET)
+#define USB_PHY_CONTROL (EXYNOS5250_POWER_BASE+USB_PHY_CONTROL_OFFSET)
+
+/* Define Mode */
+#define S5P_CHECK_SLEEP 0x00000BAD
+#define S5P_CHECK_DIDLE 0xBAD00000
+#define S5P_CHECK_LPA 0xABAD0000
+
+/*
+ * CLOCK
+ */
+#define ELFIN_CLOCK_BASE EXYNOS5250_CLOCK_BASE
+
+#define APLL_LOCK_OFFSET 0x00000
+#define APLL_CON0_OFFSET 0x00100
+#define APLL_CON1_OFFSET 0x00104
+#define CLK_SRC_CPU_OFFSET 0x00200
+#define CLK_MUX_STAT_CPU_OFFSET 0x00400
+#define CLK_DIV_CPU0_OFFSET 0x00500
+#define CLK_DIV_CPU1_OFFSET 0x00504
+#define CLK_DIV_STAT_CPU0_OFFSET 0x00600
+#define CLK_DIV_STAT_CPU1_OFFSET 0x00604
+#define CLK_GATE_SCLK_CPU_OFFSET 0x00800
+#define CLKOUT_CMU_CPU_OFFSET 0x00A00
+#define CLKOUT_CMU_CPU_DIV_STAT_OFFSET 0x00A04
+#define ARMCLK_STOPCTRL_OFFSET 0x01000
+#define PARITYFAIL_STATUS_OFFSET 0x01010
+#define PARITYFAIL_CLEAR_OFFSET 0x01014
+#define PWR_CTRL_OFFSET 0x01020
+#define PWR_CTRL2_OFFSET 0x01024
+#define APLL_CON0_L8_OFFSET 0x01100
+#define APLL_CON0_L7_OFFSET 0x01104
+#define APLL_CON0_L6_OFFSET 0x01108
+#define APLL_CON0_L5_OFFSET 0x0110C
+#define APLL_CON0_L4_OFFSET 0x01110
+#define APLL_CON0_L3_OFFSET 0x01114
+#define APLL_CON0_L2_OFFSET 0x01118
+#define APLL_CON0_L1_OFFSET 0x0111C
+#define IEM_CONTROL_OFFSET 0x01120
+#define APLL_CON1_L8_OFFSET 0x01200
+#define APLL_CON1_L7_OFFSET 0x01204
+#define APLL_CON1_L6_OFFSET 0x01208
+#define APLL_CON1_L5_OFFSET 0x0120C
+#define APLL_CON1_L4_OFFSET 0x01210
+#define APLL_CON1_L3_OFFSET 0x01214
+#define APLL_CON1_L2_OFFSET 0x01218
+#define APLL_CON1_L1_OFFSET 0x0121C
+#define CLKDIV_IEM_L8_OFFSET 0x01300
+#define CLKDIV_IEM_L7_OFFSET 0x01304
+#define CLKDIV_IEM_L6_OFFSET 0x01308
+#define CLKDIV_IEM_L5_OFFSET 0x0130C
+#define CLKDIV_IEM_L4_OFFSET 0x01310
+#define CLKDIV_IEM_L3_OFFSET 0x01314
+#define CLKDIV_IEM_L2_OFFSET 0x01318
+#define CLKDIV_IEM_L1_OFFSET 0x0131C
+#define MPLL_LOCK_OFFSET 0x04000
+#define MPLL_CON0_OFFSET 0x04100
+#define MPLL_CON1_OFFSET 0x04104
+#define CLK_SRC_CORE0_OFFSET 0x04200
+#define CLK_SRC_CORE1_OFFSET 0x04204
+#define CLK_SRC_MASK_CORE0_OFFSET 0x04300
+#define CLK_MUX_STAT_CORE1_OFFSET 0x04404
+#define CLK_DIV_CORE0_OFFSET 0x04500
+#define CLK_DIV_CORE1_OFFSET 0x04504
+#define CLK_DIV_SYSRGT_OFFSET 0x04508
+#define CLK_DIV_STAT_CORE0_OFFSET 0x04600
+#define CLK_DIV_STAT_CORE1_OFFSET 0x04604
+#define CLK_DIV_STAT_SYSRGT_OFFSET 0x04608
+#define CLK_GATE_IP_CORE_OFFSET 0x04900
+#define CLK_GATE_IP_SYSRGT_OFFSET 0x04904
+#define C2C_MONITOR_OFFSET 0x04910
+#define CLKOUT_CMU_CORE_OFFSET 0x04A00
+#define CLKOUT_CMU_CORE_DIV_STAT_OFFSET 0x04A04
+#define DCGIDX_MAP0_OFFSET 0x05000
+#define DCGIDX_MAP1_OFFSET 0x05004
+#define DCGIDX_MAP2_OFFSET 0x05008
+#define DCGPERF_MAP0_OFFSET 0x05020
+#define DCGPERF_MAP1_OFFSET 0x05024
+#define DVCIDX_MAP_OFFSET 0x05040
+#define FREQ_CPU_OFFSET 0x05060
+#define FREQ_DPM_OFFSET 0x05064
+#define DVSEMCLK_EN_OFFSET 0x05080
+#define MAXPERF_OFFSET 0x05084
+#define C2C_CONFIG_OFFSET 0x06000
+#define CLK_DIV_ACP_OFFSET 0x08500
+#define CLK_DIV_STAT_ACP_OFFSET 0x08600
+#define CLK_GATE_IP_ACP_OFFSET 0x08800
+#define CLK_DIV_SYSLFT_OFFSET 0x08900
+#define CLK_DIV_STAT_SYSLFT_OFFSET 0x08910
+#define CLK_GATE_IP_SYSLFT_OFFSET 0x08930
+#define CLKOUT_CMU_ACP_OFFSET 0x08A00
+#define CLKOUT_CMU_ACP_DIV_STAT_OFFSET 0x08A04
+#define UFMC_CONFIG_OFFSET 0x08A10
+#define CLK_DIV_ISP0_OFFSET 0x0C300
+#define CLK_DIV_ISP1_OFFSET 0x0C304
+#define CLK_DIV_ISP2_OFFSET 0x0C308
+#define CLK_DIV_STAT_ISP0_OFFSET 0x0C400
+#define CLK_DIV_STAT_ISP1_OFFSET 0x0C404
+#define CLK_DIV_STAT_ISP2_OFFSET 0x0C408
+#define CLK_GATE_IP_ISP0_OFFSET 0x0C800
+#define CLK_GATE_IP_ISP1_OFFSET 0x0C804
+#define CLK_GATE_SCLK_ISP_OFFSET 0x0C900
+#define MCUISP_PWR_CTRL_OFFSET 0x0C910
+#define CLKOUT_CMU_ISP_OFFSET 0x0CA00
+#define CLKOUT_CMU_ISP_DIV_STAT_OFFSET 0x0CA04
+#define CPLL_LOCK_OFFSET 0x10020
+#define EPLL_LOCK_OFFSET 0x10030
+#define VPLL_LOCK_OFFSET 0x10040
+#define GPLL_LOCK_OFFSET 0x10050
+#define CPLL_CON0_OFFSET 0x10120
+#define CPLL_CON1_OFFSET 0x10124
+#define EPLL_CON0_OFFSET 0x10130
+#define EPLL_CON1_OFFSET 0x10134
+#define EPLL_CON2_OFFSET 0x10138
+#define VPLL_CON0_OFFSET 0x10140
+#define VPLL_CON1_OFFSET 0x10144
+#define VPLL_CON2_OFFSET 0x10148
+#define GPLL_CON0_OFFSET 0x10150
+#define GPLL_CON1_OFFSET 0x10154
+#define CLK_SRC_TOP0_OFFSET 0x10210
+#define CLK_SRC_TOP1_OFFSET 0x10214
+#define CLK_SRC_TOP2_OFFSET 0x10218
+#define CLK_SRC_TOP3_OFFSET 0x1021C
+#define CLK_SRC_GSCL_OFFSET 0x10220
+#define CLK_SRC_DISP1_0_OFFSET 0x1022C
+#define CLK_SRC_MAU_OFFSET 0x10240
+#define CLK_SRC_FSYS_OFFSET 0x10244
+#define CLK_SRC_GEN_OFFSET 0x10248
+#define CLK_SRC_PERIC0_OFFSET 0x10250
+#define CLK_SRC_PERIC1_OFFSET 0x10254
+#define SCLK_SRC_ISP_OFFSET 0x10270
+#define CLK_SRC_MASK_TOP_OFFSET 0x10310
+#define CLK_SRC_MASK_GSCL_OFFSET 0x10320
+#define CLK_SRC_MASK_DISP1_0_OFFSET 0x1032C
+#define CLK_SRC_MASK_DISP1_1_OFFSET 0x10330
+#define CLK_SRC_MASK_MAU_OFFSET 0x10334
+#define CLK_SRC_MASK_FSYS_OFFSET 0x10340
+#define CLK_SRC_MASK_GEN_OFFSET 0x10344
+#define CLK_SRC_MASK_PERIC0_OFFSET 0x10350
+#define CLK_SRC_MASK_PERIC1_OFFSET 0x10354
+#define SCLK_SRC_MASK_ISP_OFFSET 0x10370
+#define CLK_MUX_STAT_TOP0_OFFSET 0x10410
+#define CLK_MUX_STAT_TOP1_OFFSET 0x10414
+#define CLK_MUX_STAT_TOP2_OFFSET 0x10418
+#define CLK_MUX_STAT_TOP3_OFFSET 0x1041C
+#define CLK_DIV_TOP0_OFFSET 0x10510
+#define CLK_DIV_TOP1_OFFSET 0x10514
+#define CLK_DIV_GSCL_OFFSET 0x10520
+#define CLK_DIV_DISP1_0_OFFSET 0x1052C
+#define CLK_DIV_GEN_OFFSET 0x1053C
+#define CLK_DIV_MAU_OFFSET 0x10544
+#define CLK_DIV_FSYS0_OFFSET 0x10548
+#define CLK_DIV_FSYS1_OFFSET 0x1054C
+#define CLK_DIV_FSYS2_OFFSET 0x10550
+#define CLK_DIV_PERIC0_OFFSET 0x10558
+#define CLK_DIV_PERIC1_OFFSET 0x1055C
+#define CLK_DIV_PERIC2_OFFSET 0x10560
+#define CLK_DIV_PERIC3_OFFSET 0x10564
+#define CLK_DIV_PERIC4_OFFSET 0x10568
+#define CLK_DIV_PERIC5_OFFSET 0x1056C
+#define SCLK_DIV_ISP_OFFSET 0x10580
+#define CLKDIV2_RATIO0_OFFSET 0x10590
+#define CLKDIV2_RATIO1_OFFSET 0x10594
+#define CLKDIV4_RATIO_OFFSET 0x105A0
+#define CLK_DIV_STAT_TOP0_OFFSET 0x10610
+#define CLK_DIV_STAT_TOP1_OFFSET 0x10614
+#define CLK_DIV_STAT_GSCL_OFFSET 0x10620
+#define CLK_DIV_STAT_DISP1_0_OFFSET 0x1062C
+#define CLK_DIV_STAT_GEN_OFFSET 0x1063C
+#define CLK_DIV_STAT_MAU_OFFSET 0x10644
+#define CLK_DIV_STAT_FSYS0_OFFSET 0x10648
+#define CLK_DIV_STAT_FSYS1_OFFSET 0x1064C
+#define CLK_DIV_STAT_FSYS2_OFFSET 0x10650
+#define CLK_DIV_STAT_PERIC0_OFFSET 0x10658
+#define CLK_DIV_STAT_PERIC1_OFFSET 0x1065C
+#define CLK_DIV_STAT_PERIC2_OFFSET 0x10660
+#define CLK_DIV_STAT_PERIC3_OFFSET 0x10664
+#define CLK_DIV_STAT_PERIC4_OFFSET 0x10668
+#define CLK_DIV_STAT_PERIC5_OFFSET 0x1066C
+#define SCLK_DIV_STAT_ISP_OFFSET 0x10680
+#define CLKDIV2_STAT0_OFFSET 0x10690
+#define CLKDIV2_STAT1_OFFSET 0x10694
+#define CLKDIV4_STAT_OFFSET 0x106A0
+#define CLK_GATE_TOP_SCLK_DISP1_OFFSET 0x10828
+#define CLK_GATE_TOP_SCLK_GEN_OFFSET 0x1082C
+#define CLK_GATE_TOP_SCLK_MAU_OFFSET 0x1083C
+#define CLK_GATE_TOP_SCLK_FSYS_OFFSET 0x10840
+#define CLK_GATE_TOP_SCLK_PERIC_OFFSET 0x10850
+#define CLK_GATE_TOP_SCLK_ISP_OFFSET 0x10870
+#define CLK_GATE_IP_GSCL_OFFSET 0x10920
+#define CLK_GATE_IP_DISP1_OFFSET 0x10928
+#define CLK_GATE_IP_MFC_OFFSET 0x1092C
+#define CLK_GATE_IP_G3D_OFFSET 0x10930
+#define CLK_GATE_IP_GEN_OFFSET 0x10934
+#define CLK_GATE_IP_FSYS_OFFSET 0x10944
+#define CLK_GATE_IP_PERIC_OFFSET 0x10950
+#define CLK_GATE_IP_PERIS_OFFSET 0x10960
+#define CLK_GATE_BLOCK_OFFSET 0x10980
+#define MCUIOP_PWR_CTRL_OFFSET 0x109A0
+#define CLKOUT_CMU_TOP_OFFSET 0x10A00
+#define CLKOUT_CMU_TOP_DIV_STAT_OFFSET 0x10A04
+#define CLK_SRC_LEX_OFFSET 0x14200
+#define CLK_MUX_STAT_LEX_OFFSET 0x14400
+#define CLK_DIV_LEX_OFFSET 0x14500
+#define CLK_DIV_STAT_LEX_OFFSET 0x14600
+#define CLK_GATE_IP_LEX_OFFSET 0x14800
+#define CLKOUT_CMU_LEX_OFFSET 0x14A00
+#define CLKOUT_CMU_LEX_DIV_STAT_OFFSET 0x14A04
+#define CLK_DIV_R0X_OFFSET 0x18500
+#define CLK_DIV_STAT_R0X_OFFSET 0x18600
+#define CLK_GATE_IP_R0X_OFFSET 0x18800
+#define CLKOUT_CMU_R0X_OFFSET 0x18A00
+#define CLKOUT_CMU_R0X_DIV_STAT_OFFSET 0x18A04
+#define CLK_DIV_R1X_OFFSET 0x1C500
+#define CLK_DIV_STAT_R1X_OFFSET 0x1C600
+#define CLK_GATE_IP_R1X_OFFSET 0x1C800
+#define CLKOUT_CMU_R1X_OFFSET 0x1CA00
+#define CLKOUT_CMU_R1X_DIV_STAT_OFFSET 0x1CA04
+#define BPLL_LOCK_OFFSET 0x20010
+#define BPLL_CON0_OFFSET 0x20110
+#define BPLL_CON1_OFFSET 0x20114
+#define CLK_SRC_CDREX_OFFSET 0x20200
+#define CLK_MUX_STAT_CDREX_OFFSET 0x20400
+#define CLK_DIV_CDREX_OFFSET 0x20500
+#define CLK_DIV_STAT_CDREX_OFFSET 0x20600
+#define CLK_GATE_IP_CDREX_OFFSET 0x20900
+#define DMC_FREQ_CTRL_OFFSET 0x20914
+#define DREX2_PAUSE_OFFSET 0x2091C
+#define CLKOUT_CMU_CDREX_OFFSET 0x20A00
+#define CLKOUT_CMU_CDREX_DIV_STAT_OFFSET 0x20A04
+#define LPDDR3PHY_CTRL 0x20A10
+#define LPDDR3PHY_CTRL_CON0 0x20A14
+#define LPDDR3PHY_CTRL_CON1 0x20A18
+#define LPDDR3PHY_CTRL_CON2 0x20A1C
+#define LPDDR3PHY_CTRL_CON3 0x20A20
+#define PLL_DIV2_SEL_OFFSET 0x20A24
+
+#define CLK_SRC_FSYS __REG(ELFIN_CLOCK_BASE+CLK_SRC_FSYS_OFFSET)
+#define CLK_DIV_FSYS0 __REG(ELFIN_CLOCK_BASE+CLK_DIV_FSYS0_OFFSET)
+#define CLK_DIV_FSYS1 __REG(ELFIN_CLOCK_BASE+CLK_DIV_FSYS1_OFFSET)
+#define CLK_DIV_FSYS2 __REG(ELFIN_CLOCK_BASE+CLK_DIV_FSYS2_OFFSET)
+#define APLL_CON0_REG __REG(ELFIN_CLOCK_BASE+APLL_CON0_OFFSET)
+#define MPLL_CON0_REG __REG(ELFIN_CLOCK_BASE+MPLL_CON0_OFFSET)
+#define EPLL_CON0_REG __REG(ELFIN_CLOCK_BASE+EPLL_CON0_OFFSET)
+#define VPLL_CON0_REG __REG(ELFIN_CLOCK_BASE+VPLL_CON0_OFFSET)
+
+/*
+ * TZPC
+ */
+#define TZPC0_OFFSET 0x00000
+#define TZPC1_OFFSET 0x10000
+#define TZPC2_OFFSET 0x20000
+#define TZPC3_OFFSET 0x30000
+#define TZPC4_OFFSET 0x40000
+#define TZPC5_OFFSET 0x50000
+#define TZPC6_OFFSET 0x60000
+#define TZPC7_OFFSET 0x70000
+#define TZPC8_OFFSET 0x80000
+#define TZPC9_OFFSET 0x90000
+
+#define ELFIN_TZPC0_BASE (EXYNOS5250_TZPC_BASE + TZPC0_OFFSET)
+#define ELFIN_TZPC1_BASE (EXYNOS5250_TZPC_BASE + TZPC1_OFFSET)
+#define ELFIN_TZPC2_BASE (EXYNOS5250_TZPC_BASE + TZPC2_OFFSET)
+#define ELFIN_TZPC3_BASE (EXYNOS5250_TZPC_BASE + TZPC3_OFFSET)
+#define ELFIN_TZPC4_BASE (EXYNOS5250_TZPC_BASE + TZPC4_OFFSET)
+#define ELFIN_TZPC5_BASE (EXYNOS5250_TZPC_BASE + TZPC5_OFFSET)
+#define ELFIN_TZPC6_BASE (EXYNOS5250_TZPC_BASE + TZPC6_OFFSET)
+#define ELFIN_TZPC7_BASE (EXYNOS5250_TZPC_BASE + TZPC7_OFFSET)
+#define ELFIN_TZPC8_BASE (EXYNOS5250_TZPC_BASE + TZPC8_OFFSET)
+#define ELFIN_TZPC9_BASE (EXYNOS5250_TZPC_BASE + TZPC9_OFFSET)
+
+#define TZPC_DECPROT0SET_OFFSET 0x804
+#define TZPC_DECPROT1SET_OFFSET 0x810
+#define TZPC_DECPROT2SET_OFFSET 0x81C
+#define TZPC_DECPROT3SET_OFFSET 0x828
+
+/*
+ * Memory controller
+ */
+#define ELFIN_SROM_BASE EXYNOS5250_SROM_BASE
+
+#define SROM_BW_REG __REG(ELFIN_SROM_BASE+0x0)
+#define SROM_BC0_REG __REG(ELFIN_SROM_BASE+0x4)
+#define SROM_BC1_REG __REG(ELFIN_SROM_BASE+0x8)
+#define SROM_BC2_REG __REG(ELFIN_SROM_BASE+0xC)
+#define SROM_BC3_REG __REG(ELFIN_SROM_BASE+0x10)
+
+/*
+ * SDRAM Controller
+ */
+
+/* DMC control register */
+#define DMC_CTRL_BASE 0x10DD0000
+
+#define DMC_CONCONTROL 0x00
+#define DMC_MEMCONTROL 0x04
+#define DMC_MEMCONFIG0 0x08
+#define DMC_MEMCONFIG1 0x0C
+#define DMC_DIRECTCMD 0x10
+#define DMC_PRECHCONFIG 0x14
+#define DMC_PHYCONTROL0 0x18
+#define DMC_PWRDNCONFIG 0x28
+#define DMC_TIMINGPZQ 0x2C
+#define DMC_TIMINGAREF 0x30
+#define DMC_TIMINGROW 0x34
+#define DMC_TIMINGDATA 0x38
+#define DMC_TIMINGPOWER 0x3C
+#define DMC_PHYSTATUS 0x40
+#define DMC_CHIPSTATUS_CH0 0x48
+#define DMC_CHIPSTATUS_CH1 0x4C
+#define DMC_MRSTATUS 0x54
+#define DMC_QOSCONTROL0 0x60
+#define DMC_QOSCONTROL1 0x68
+#define DMC_QOSCONTROL2 0x70
+#define DMC_QOSCONTROL3 0x78
+#define DMC_QOSCONTROL4 0x80
+#define DMC_QOSCONTROL5 0x88
+#define DMC_QOSCONTROL6 0x90
+#define DMC_QOSCONTROL7 0x98
+#define DMC_QOSCONTROL8 0xA0
+#define DMC_QOSCONTROL9 0xA8
+#define DMC_QOSCONTROL10 0xB0
+#define DMC_QOSCONTROL11 0xB8
+#define DMC_QOSCONTROL12 0xC0
+#define DMC_QOSCONTROL13 0xC8
+#define DMC_QOSCONTROL14 0xD0
+#define DMC_QOSCONTROL15 0xD8
+#define DMC_IVCONTROL 0xF0
+#define DMC_WRTRA_CONFIG 0xF4
+#define DMC_RDLVL_CONFIG 0xF8
+#define DMC_BRBRSVCONTROL 0x0100
+#define DMC_BRBRSVCONFIG 0x0104
+#define DMC_BRBQOSCONFIG 0x0108
+#define DMC_MEMBASECONFIG0 0x010C
+#define DMC_MEMBASECONFIG1 0x0110
+#define DMC_WRLVLCONFIG0 0x0120
+#define DMC_WRLVLCONFIG1 0x0124
+#define DMC_WRLVLSTATUS 0x0128
+#define DMC_PEREVCONTROL 0x0130
+#define DMC_PEREV0CONFIG 0x0134
+#define DMC_PEREV1CONFIG 0x0138
+#define DMC_PEREV2CONFIG 0x013C
+#define DMC_PEREV3CONFIG 0x0140
+#define DMC_CTRL_IO_RDATA_CH0 0x0150
+#define DMC_CTRL_IO_RDATA_CH1 0x0154
+#define DMC_CACAL_CONFIG0 0x0160
+#define DMC_CACAL_CONFIG1 0x0164
+#define DMC_CACAL_STATUS 0x0168
+#define DMC_PMNC_PPC 0xE000
+#define DMC_CNTENS_PPC 0xE010
+#define DMC_CNTENC_PPC 0xE020
+#define DMC_INTENS_PPC 0xE030
+#define DMC_INTENC_PPC 0xE040
+#define DMC_FLAG_PPC 0xE050
+#define DMC_CCNT_PPC 0xE100
+#define DMC_PMCNT0_PPC 0xE110
+#define DMC_PMCNT1_PPC 0xE120
+#define DMC_PMCNT2_PPC 0xE130
+#define DMC_PMCNT3_PPC 0xE140
+
+/* PHY Control Register */
+#define PHY0_CTRL_BASE 0x10C00000
+#define PHY1_CTRL_BASE 0x10C10000
+
+#define DMC_PHY_CON0 0x00
+#define DMC_PHY_CON1 0x04
+#define DMC_PHY_CON2 0x08
+#define DMC_PHY_CON3 0x0C
+#define DMC_PHY_CON4 0x10
+#define DMC_PHY_CON6 0x18
+#define DMC_PHY_CON8 0x20
+#define DMC_PHY_CON10 0x28
+#define DMC_PHY_CON11 0x2C
+#define DMC_PHY_CON12 0x30
+#define DMC_PHY_CON13 0x34
+#define DMC_PHY_CON14 0x38
+#define DMC_PHY_CON15 0x3C
+#define DMC_PHY_CON16 0x40
+#define DMC_PHY_CON17 0x48
+#define DMC_PHY_CON18 0x4C
+#define DMC_PHY_CON19 0x50
+#define DMC_PHY_CON20 0x54
+#define DMC_PHY_CON21 0x58
+#define DMC_PHY_CON22 0x5C
+#define DMC_PHY_CON23 0x60
+#define DMC_PHY_CON24 0x64
+#define DMC_PHY_CON25 0x68
+#define DMC_PHY_CON26 0x6C
+#define DMC_PHY_CON27 0x70
+#define DMC_PHY_CON28 0x74
+#define DMC_PHY_CON29 0x78
+#define DMC_PHY_CON30 0x7C
+#define DMC_PHY_CON31 0x80
+#define DMC_PHY_CON32 0x84
+#define DMC_PHY_CON33 0x88
+#define DMC_PHY_CON34 0x8C
+#define DMC_PHY_CON35 0x90
+#define DMC_PHY_CON36 0x94
+#define DMC_PHY_CON37 0x98
+#define DMC_PHY_CON38 0x9C
+#define DMC_PHY_CON39 0xA0
+#define DMC_PHY_CON40 0xA4
+#define DMC_PHY_CON41 0xA8
+#define DMC_PHY_CON42 0xAC
+
+
+/*
+ * FBM
+ */
+#define DDR_R1_FBM_BASE 0x10c30000
+#define DDR_R0_FBM_BASE 0x10dc0000
+
+#define FBM_MODESEL0 0x0
+#define FBM_THRESHOLDSEL0 0x40
+
+/*
+ * UART
+ */
+
+#define UART0_OFFSET 0x00000
+#define UART1_OFFSET 0x10000
+#define UART2_OFFSET 0x20000
+#define UART3_OFFSET 0x30000
+
+#if defined(CONFIG_SERIAL0)
+#define UART_CONSOLE_BASE (EXYNOS5250_UART_BASE + UART0_OFFSET)
+#elif defined(CONFIG_SERIAL1)
+#define UART_CONSOLE_BASE (EXYNOS5250_UART_BASE + UART1_OFFSET)
+#elif defined(CONFIG_SERIAL2)
+#define UART_CONSOLE_BASE (EXYNOS5250_UART_BASE + UART2_OFFSET)
+#elif defined(CONFIG_SERIAL3)
+#define UART_CONSOLE_BASE (EXYNOS5250_UART_BASE + UART3_OFFSET)
+#else
+#define UART_CONSOLE_BASE (EXYNOS5250_UART_BASE + UART0_OFFSET)
+#endif
+
+#define ULCON_OFFSET 0x00
+#define UCON_OFFSET 0x04
+#define UFCON_OFFSET 0x08
+#define UMCON_OFFSET 0x0C
+#define UTRSTAT_OFFSET 0x10
+#define UERSTAT_OFFSET 0x14
+#define UFSTAT_OFFSET 0x18
+#define UMSTAT_OFFSET 0x1C
+#define UTXH_OFFSET 0x20
+#define URXH_OFFSET 0x24
+#define UBRDIV_OFFSET 0x28
+#define UDIVSLOT_OFFSET 0x2C
+#define UINTP_OFFSET 0x30
+#define UINTSP_OFFSET 0x34
+#define UINTM_OFFSET 0x38
+//#define UTRSTAT_TX_EMPTY BIT2
+//#define UTRSTAT_RX_READY BIT0
+#define UART_ERR_MASK 0xF
+
+/*
+ * HS MMC
+ */
+#define HSMMC_0_OFFSET 0x00000
+#define HSMMC_1_OFFSET 0x10000
+#define HSMMC_2_OFFSET 0x20000
+#define HSMMC_3_OFFSET 0x30000
+
+#define ELFIN_HSMMC_0_BASE (EXYNOS5250_HSMMC_BASE + HSMMC_0_OFFSET)
+#define ELFIN_HSMMC_1_BASE (EXYNOS5250_HSMMC_BASE + HSMMC_1_OFFSET)
+#define ELFIN_HSMMC_2_BASE (EXYNOS5250_HSMMC_BASE + HSMMC_2_OFFSET)
+#define ELFIN_HSMMC_3_BASE (EXYNOS5250_HSMMC_BASE + HSMMC_3_OFFSET)
+
+#define HM_SYSAD (0x00)
+#define HM_BLKSIZE (0x04)
+#define HM_BLKCNT (0x06)
+#define HM_ARGUMENT (0x08)
+#define HM_TRNMOD (0x0c)
+#define HM_CMDREG (0x0e)
+#define HM_RSPREG0 (0x10)
+#define HM_RSPREG1 (0x14)
+#define HM_RSPREG2 (0x18)
+#define HM_RSPREG3 (0x1c)
+#define HM_BDATA (0x20)
+#define HM_PRNSTS (0x24)
+#define HM_HOSTCTL (0x28)
+#define HM_PWRCON (0x29)
+#define HM_BLKGAP (0x2a)
+#define HM_WAKCON (0x2b)
+#define HM_CLKCON (0x2c)
+#define HM_TIMEOUTCON (0x2e)
+#define HM_SWRST (0x2f)
+#define HM_NORINTSTS (0x30)
+#define HM_ERRINTSTS (0x32)
+#define HM_NORINTSTSEN (0x34)
+#define HM_ERRINTSTSEN (0x36)
+#define HM_NORINTSIGEN (0x38)
+#define HM_ERRINTSIGEN (0x3a)
+#define HM_ACMD12ERRSTS (0x3c)
+#define HM_CAPAREG (0x40)
+#define HM_MAXCURR (0x48)
+#define HM_CONTROL2 (0x80)
+#define HM_CONTROL3 (0x84)
+#define HM_CONTROL4 (0x8c)
+#define HM_HCVER (0xfe)
+
+/* PENDING BIT */
+#define BIT_EINT0 (0x1)
+#define BIT_EINT1 (0x1<<1)
+#define BIT_EINT2 (0x1<<2)
+#define BIT_EINT3 (0x1<<3)
+#define BIT_EINT4_7 (0x1<<4)
+#define BIT_EINT8_23 (0x1<<5)
+#define BIT_BAT_FLT (0x1<<7)
+#define BIT_TICK (0x1<<8)
+#define BIT_WDT (0x1<<9)
+#define BIT_TIMER0 (0x1<<10)
+#define BIT_TIMER1 (0x1<<11)
+#define BIT_TIMER2 (0x1<<12)
+#define BIT_TIMER3 (0x1<<13)
+#define BIT_TIMER4 (0x1<<14)
+#define BIT_UART2 (0x1<<15)
+#define BIT_LCD (0x1<<16)
+#define BIT_DMA0 (0x1<<17)
+#define BIT_DMA1 (0x1<<18)
+#define BIT_DMA2 (0x1<<19)
+#define BIT_DMA3 (0x1<<20)
+#define BIT_SDI (0x1<<21)
+#define BIT_SPI0 (0x1<<22)
+#define BIT_UART1 (0x1<<23)
+#define BIT_USBH (0x1<<26)
+#define BIT_IIC (0x1<<27)
+#define BIT_UART0 (0x1<<28)
+#define BIT_SPI1 (0x1<<29)
+#define BIT_RTC (0x1<<30)
+#define BIT_ADC (0x1<<31)
+#define BIT_ALLMSK (0xFFFFFFFF)
+
+#define PWMTIMER_BASE EXYNOS5250_PWMTIMER_BASE
+
+/*
+ * USBD3 SFR
+ */
+#define USBDEVICE3_LINK_BASE 0x12000000
+#define USBDEVICE3_PHYCTRL_BASE 0x12100000
+
+//==========================
+// Global Registers (Gxxxx)
+//==========================
+// Global Common Registers
+#define rGSBUSCFG0 (USBDEVICE3_LINK_BASE + 0xc100)
+#define rGSBUSCFG1 (USBDEVICE3_LINK_BASE + 0xc104)
+#define rGTXTHRCFG (USBDEVICE3_LINK_BASE + 0xc108)
+#define rGRXTHRCFG (USBDEVICE3_LINK_BASE + 0xc10c)
+#define rGCTL (USBDEVICE3_LINK_BASE + 0xc110)
+#define rGEVTEN (USBDEVICE3_LINK_BASE + 0xc114)
+#define rGSTS (USBDEVICE3_LINK_BASE + 0xc118)
+#define rGSNPSID (USBDEVICE3_LINK_BASE + 0xc120)
+#define rGGPIO (USBDEVICE3_LINK_BASE + 0xc124)
+#define rGUID (USBDEVICE3_LINK_BASE + 0xc128)
+#define rGUCTL (USBDEVICE3_LINK_BASE + 0xc12c)
+#define rGBUSERRADDR_LO (USBDEVICE3_LINK_BASE + 0xc130)
+#define rGBUSERRADDR_HI (USBDEVICE3_LINK_BASE + 0xc134)
+
+// Global Port to USB Instance Mapping Registers
+#define rGPRTBIMAP_LO (USBDEVICE3_LINK_BASE + 0xc138)
+#define rGPRTBIMAP_HI (USBDEVICE3_LINK_BASE + 0xc13c)
+#define rGPRTBIMAP_HS_LO (USBDEVICE3_LINK_BASE + 0xc180)
+#define rGPRTBIMAP_HS_HI (USBDEVICE3_LINK_BASE + 0xc184)
+#define rGPRTBIMAP_FS_LO (USBDEVICE3_LINK_BASE + 0xc188)
+#define rGPRTBIMAP_FS_HI (USBDEVICE3_LINK_BASE + 0xc18c)
+
+// Global Hardware Parameter Registers
+#define rGHWPARAMS0 (USBDEVICE3_LINK_BASE + 0xc140) // 0x20204000 @c510
+#define rGHWPARAMS1 (USBDEVICE3_LINK_BASE + 0xc144) // 0x0060c93b @c510
+#define rGHWPARAMS2 (USBDEVICE3_LINK_BASE + 0xc148) // 0x12345678 @c510
+#define rGHWPARAMS3 (USBDEVICE3_LINK_BASE + 0xc14c) // 0x10420085 @c510
+#define rGHWPARAMS4 (USBDEVICE3_LINK_BASE + 0xc150) // 0x48820004 @c510
+#define rGHWPARAMS5 (USBDEVICE3_LINK_BASE + 0xc154) // 0x04204108 @c510
+#define rGHWPARAMS6 (USBDEVICE3_LINK_BASE + 0xc158) // 0x04008020 @c510
+#define rGHWPARAMS7 (USBDEVICE3_LINK_BASE + 0xc15c) // 0x018516fe @c510
+#define rGHWPARAMS8 (USBDEVICE3_LINK_BASE + 0xc600) // 0x00000386 @c510
+
+// Global Debug Registers
+#define rGDBGFIFOSPACE (USBDEVICE3_LINK_BASE + 0xc160)
+#define rGDBGLTSSM (USBDEVICE3_LINK_BASE + 0xc164)
+#define rGDBGLSPMUX (USBDEVICE3_LINK_BASE + 0xc170)
+#define rGDBGLSP (USBDEVICE3_LINK_BASE + 0xc174)
+#define rGDBGEPINFO0 (USBDEVICE3_LINK_BASE + 0xc178)
+#define rGDBGEPINFO1 (USBDEVICE3_LINK_BASE + 0xc17c)
+
+// Global PHY Registers
+#define rGUSB2PHYCFG (USBDEVICE3_LINK_BASE + 0xc200)
+#define rGUSB2I2CCTL (USBDEVICE3_LINK_BASE + 0xc240)
+#define rGUSB2PHYACC (USBDEVICE3_LINK_BASE + 0xc280)
+#define rGUSB3PIPECTL (USBDEVICE3_LINK_BASE + 0xc2c0)
+
+// Global FIFO Size Registers (0 <= num <= 15 @510)
+#define rGTXFIFOSIZ(num) ((USBDEVICE3_LINK_BASE + 0xc300) + 0x04*num)
+#define rGRXFIFOSIZ0 (USBDEVICE3_LINK_BASE + 0xc380)
+
+// Global Event Buffer Registers (DWC_USB3_DEVICE_NUM_INT = 1 @C510, GHWPARAMS1[20:15])
+#define rGEVNTADR_LO0 (USBDEVICE3_LINK_BASE + 0xc400)
+#define rGEVNTADR_HI0 (USBDEVICE3_LINK_BASE + 0xc404)
+#define rGEVNTSIZ0 (USBDEVICE3_LINK_BASE + 0xc408)
+#define rGEVNTCOUNT0 (USBDEVICE3_LINK_BASE + 0xc40c)
+
+//==========================
+// Device Registers (Dxxxx)
+//==========================
+// Device Common Registers
+#define rDCFG (USBDEVICE3_LINK_BASE + 0xc700)
+#define rDCTL (USBDEVICE3_LINK_BASE + 0xc704)
+#define rDEVTEN (USBDEVICE3_LINK_BASE + 0xc708)
+#define rDSTS (USBDEVICE3_LINK_BASE + 0xc70c)
+#define rDGCMDPAR (USBDEVICE3_LINK_BASE + 0xc710)
+#define rDGCMD (USBDEVICE3_LINK_BASE + 0xc714)
+#define rDALEPENA (USBDEVICE3_LINK_BASE + 0xc720)
+
+// Device Endpoint Registers (0 <= ep <= 15)
+#define rDOEPCMDPAR2(ep) ((USBDEVICE3_LINK_BASE + 0xc800) + 0x20*ep)
+#define rDOEPCMDPAR1(ep) ((USBDEVICE3_LINK_BASE + 0xc804) + 0x20*ep)
+#define rDOEPCMDPAR0(ep) ((USBDEVICE3_LINK_BASE + 0xc808) + 0x20*ep)
+#define rDOEPCMD(ep) ((USBDEVICE3_LINK_BASE + 0xc80c) + 0x20*ep)
+
+#define rDIEPCMDPAR2(ep) ((USBDEVICE3_LINK_BASE + 0xc810) + 0x20*ep)
+#define rDIEPCMDPAR1(ep) ((USBDEVICE3_LINK_BASE + 0xc814) + 0x20*ep)
+#define rDIEPCMDPAR0(ep) ((USBDEVICE3_LINK_BASE + 0xc818) + 0x20*ep)
+#define rDIEPCMD(ep) ((USBDEVICE3_LINK_BASE + 0xc81c) + 0x20*ep)
+
+//==========================
+// USB DEVICE PHY CONTROL REGISTERS
+//==========================
+#define EXYNOS_PHY_LINKSYSTEM (USBDEVICE3_PHYCTRL_BASE + 0x04)
+#define EXYNOS_PHY_UTMI (USBDEVICE3_PHYCTRL_BASE + 0x08)
+#define EXYNOS_PHY_PIPE (USBDEVICE3_PHYCTRL_BASE + 0x0C)
+#define EXYNOS_PHY_CLKPWR (USBDEVICE3_PHYCTRL_BASE + 0x10)
+#define EXYNOS_PHY_REG0 (USBDEVICE3_PHYCTRL_BASE + 0x14)
+#define EXYNOS_PHY_REG1 (USBDEVICE3_PHYCTRL_BASE + 0x18)
+#define EXYNOS_PHY_PARAM0 (USBDEVICE3_PHYCTRL_BASE + 0x1C)
+#define EXYNOS_PHY_PARAM1 (USBDEVICE3_PHYCTRL_BASE + 0x20)
+#define EXYNOS_PHY_TERM (USBDEVICE3_PHYCTRL_BASE + 0x24)
+#define EXYNOS_PHY_TEST (USBDEVICE3_PHYCTRL_BASE + 0x28)
+#define EXYNOS_PHY_ADP (USBDEVICE3_PHYCTRL_BASE + 0x2C)
+#define EXYNOS_PHY_BATCHG (USBDEVICE3_PHYCTRL_BASE + 0x30)
+#define EXYNOS_PHY_RESUME (USBDEVICE3_PHYCTRL_BASE + 0x34)
+#define EXYNOS_PHY_LINK_PORT (USBDEVICE3_PHYCTRL_BASE + 0x44)
+
+/* USBD 2.0 SFR */
+#define USBOTG_LINK_BASE (0x12140000)
+#define USBOTG_PHY_BASE (0x12130000)
+
+#endif /* _EXYNOS5250_CPU_H */
diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Include/Protocol/ExynosGpio.h b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Include/Protocol/ExynosGpio.h
new file mode 100644
index 000000000..35fe93bf6
--- /dev/null
+++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Include/Protocol/ExynosGpio.h
@@ -0,0 +1,199 @@
+/** @file
+
+ Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef __EXYNOS_GPIO_H__
+#define __EXYNOS_GPIO_H__
+
+//
+// Protocol interface structure
+//
+typedef struct _EXYNOS_GPIO EXYNOS_GPIO;
+
+//
+// Data Types
+//
+typedef UINTN EXYNOS_GPIO_PIN;
+
+#define GPIO(Port, Pin) ((EXYNOS_GPIO_PIN)(((Port) << (16)) | (Pin)))
+#define GPIO_PIN(x) ((EXYNOS_GPIO_PIN)(x) & (0xFFFF))
+#define GPIO_PORT(x) ((EXYNOS_GPIO_PIN)(x) >> (16))
+
+typedef enum {
+ GPIO_MODE_INPUT = 0x00,
+ GPIO_MODE_OUTPUT_0 = 0x0E,
+ GPIO_MODE_OUTPUT_1 = 0x0F,
+ GPIO_MODE_SPECIAL_FUNCTION_2 = 0x02,
+ GPIO_MODE_SPECIAL_FUNCTION_3 = 0x03,
+ GPIO_MODE_SPECIAL_FUNCTION_4 = 0x04,
+ GPIO_MODE_SPECIAL_FUNCTION_5 = 0x05,
+ GPIO_MODE_SPECIAL_FUNCTION_6 = 0x06,
+ GPIO_MODE_SPECIAL_FUNCTION_7 = 0x07
+} EXYNOS_GPIO_MODE;
+
+typedef enum {
+ GPIO_PULL_NONE,
+ GPIO_PULL_UP,
+ GPIO_PULL_DOWN
+} EXYNOS_GPIO_PULL;
+
+typedef enum {
+ GPIO_DRV_1X,
+ GPIO_DRV_2X,
+ GPIO_DRV_3X,
+ GPIO_DRV_4X
+} EXYNOS_GPIO_STRN;
+
+//
+// Function Prototypes
+//
+typedef
+EFI_STATUS
+(EFIAPI *EXYNOS_GPIO_GET) (
+ IN EXYNOS_GPIO *This,
+ IN EXYNOS_GPIO_PIN Gpio,
+ OUT UINTN *Value
+ );
+/*++
+
+Routine Description:
+
+ Gets the state of a GPIO pin
+
+Arguments:
+
+ This - pointer to protocol
+ Gpio - which pin to read
+ Value - state of the pin
+
+Returns:
+
+ EFI_SUCCESS - GPIO state returned in Value
+
+--*/
+
+
+typedef
+EFI_STATUS
+(EFIAPI *EXYNOS_GPIO_SET) (
+ IN EXYNOS_GPIO *This,
+ IN EXYNOS_GPIO_PIN Gpio,
+ IN EXYNOS_GPIO_MODE Mode
+ );
+/*++
+
+Routine Description:
+
+ Sets the state of a GPIO pin
+
+Arguments:
+
+ This - pointer to protocol
+ Gpio - which pin to modify
+ Mode - mode to set
+
+Returns:
+
+ EFI_SUCCESS - GPIO set as requested
+
+--*/
+
+
+typedef
+EFI_STATUS
+(EFIAPI *EXYNOS_GPIO_GET_MODE) (
+ IN EXYNOS_GPIO *This,
+ IN EXYNOS_GPIO_PIN Gpio,
+ OUT EXYNOS_GPIO_MODE *Mode
+ );
+/*++
+
+Routine Description:
+
+ Gets the mode (function) of a GPIO pin
+
+Arguments:
+
+ This - pointer to protocol
+ Gpio - which pin
+ Mode - pointer to output mode value
+
+Returns:
+
+ EFI_SUCCESS - mode value retrieved
+
+--*/
+
+
+typedef
+EFI_STATUS
+(EFIAPI *EXYNOS_GPIO_SET_PULL) (
+ IN EXYNOS_GPIO *This,
+ IN EXYNOS_GPIO_PIN Gpio,
+ IN EXYNOS_GPIO_PULL Direction
+ );
+/*++
+
+Routine Description:
+
+ Sets the pull-up / pull-down resistor of a GPIO pin
+
+Arguments:
+
+ This - pointer to protocol
+ Gpio - which pin
+ Direction - pull-up, pull-down, or none
+
+Returns:
+
+ EFI_SUCCESS - pin was set
+
+--*/
+
+typedef EFI_STATUS
+(EFIAPI *EXYNOS_GPIO_DRV) (
+ IN EXYNOS_GPIO *This,
+ IN EXYNOS_GPIO_PIN Gpio,
+ IN EXYNOS_GPIO_STRN Strength
+ );
+/*++
+
+Routine Description:
+
+ Sets the Driving strength resistor of a GPIO pin
+
+Arguments:
+
+ This - pointer to protocol
+ Gpio - which pin
+ Strength - 0=1x,1=2x,2=3x,3=4x
+
+Returns:
+
+ EFI_SUCCESS - pin was set
+
+--*/
+
+
+
+struct _EXYNOS_GPIO {
+ EXYNOS_GPIO_GET Get;
+ EXYNOS_GPIO_SET Set;
+ EXYNOS_GPIO_GET_MODE GetMode;
+ EXYNOS_GPIO_SET_PULL SetPull;
+ EXYNOS_GPIO_DRV SetStrength;
+};
+
+extern EFI_GUID gSamsungPlatformGpioProtocolGuid;
+
+#endif
diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Include/Protocol/ExynosRng.h b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Include/Protocol/ExynosRng.h
new file mode 100644
index 000000000..58376b530
--- /dev/null
+++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Include/Protocol/ExynosRng.h
@@ -0,0 +1,52 @@
+/** @file
+
+ Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef __EXYNOS_RNG_H__
+#define __EXYNOS_RNG_H__
+
+//
+// Protocol interface structure
+//
+typedef struct _EFI_RNG_PROTOCOL EFI_RNG_PROTOCOL;
+
+/**
+ * Generates a pseudorandom byte stream of the specified size.
+ *
+ * If Output is NULL, then return FALSE.
+ *
+ * @param[out] Output Pointer to buffer to receive random value
+ * @param[in] Size Size of random bytes to generate
+ *
+ * @retval TRUE Pseudorandom byte stream generated successfully.
+ * @retval FALSE Pseudorandom number generator fails to generate due to lack of entropy.
+ *
+ **/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_RANDOM_BYTES) (
+ IN CONST EFI_RNG_PROTOCOL *This,
+ OUT UINT8 *Output,
+ IN UINTN Size
+ );
+
+///
+/// This protocol allows creating peudorandom random number using HW RNG engine.
+///
+struct _EFI_RNG_PROTOCOL {
+ EFI_RANDOM_BYTES RandomBytes;
+};
+
+extern EFI_GUID gSamsungPlatformRngProtocolGuid;
+
+#endif
diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Library/ExynosLib/ExynosLib.c b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Library/ExynosLib/ExynosLib.c
new file mode 100644
index 000000000..3dbee6de5
--- /dev/null
+++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Library/ExynosLib/ExynosLib.c
@@ -0,0 +1,51 @@
+/** @file
+
+ Copyright (c) 2012, Samsung Electronics Co. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <Base.h>
+#include <Library/DebugLib.h>
+#include <Library/PcdLib.h>
+#include <Platform/ArmPlatform.h>
+
+UINT32
+GpioBase (
+ IN UINTN Port
+ )
+{
+
+ ASSERT( ((Port >= GPA0) && (Port <= GPY6))
+ || ((Port >= GPX0) && (Port <= GPX3))
+ || ((Port >= GPE0) && (Port <= GPH1))
+ || ((Port >= GPV0) && (Port <= GPV4))
+ || (Port == GPZ));
+
+ /*decide which part of gpio is being requested. give the corresponding base address*/
+ if(Port >= 0x90) {
+ /* 0x0386_0000 */
+ Port -= 0x90;
+ return (PcdGet32(PcdGpioPart4Base) + (Port*DISTANCE_BTWN_PORTS));
+ }else if(Port >= 0x80) {
+ /* 0x10D1_0000 */
+ Port -= 0x80;
+ return (PcdGet32(PcdGpioPart3Base) + (Port*DISTANCE_BTWN_PORTS));
+ }else if(Port >= 0x70) {
+ /* 0x1340_0000 */
+ Port -= 0x70;
+ return (PcdGet32(PcdGpioPart2Base) + (Port*DISTANCE_BTWN_PORTS));
+ }else {
+ /* 0x1140_0000 */
+ return (PcdGet32(PcdGpioPart1Base) + (Port*DISTANCE_BTWN_PORTS));
+ }
+
+ ASSERT(FALSE); return 0;
+}
diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Library/ExynosLib/ExynosLib.inf b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Library/ExynosLib/ExynosLib.inf
new file mode 100644
index 000000000..f2b5f1dc2
--- /dev/null
+++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Library/ExynosLib/ExynosLib.inf
@@ -0,0 +1,42 @@
+#/** @file
+#
+# Copyright (c) 2012, Samsung Electronics Co. All rights reserved.<BR>
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#**/
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = ExynosLib
+ FILE_GUID = d035f5c2-1b92-4746-9f6c-5ff6202970df
+ MODULE_TYPE = UEFI_DRIVER
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = ExynosLib
+
+[Sources.common]
+ ExynosLib.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ EmbeddedPkg/EmbeddedPkg.dec
+ SamsungPlatformPkg/ExynosPkg/Exynos5250/ExynosPkg.dec
+
+[LibraryClasses]
+ DebugLib
+ IoLib
+
+[Protocols]
+
+[Guids]
+
+[Pcd]
+ gExynosPkgTokenSpaceGuid.PcdGpioPart1Base
+ gExynosPkgTokenSpaceGuid.PcdGpioPart2Base
+ gExynosPkgTokenSpaceGuid.PcdGpioPart3Base
+ gExynosPkgTokenSpaceGuid.PcdGpioPart4Base
diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Library/GdbSerialLib/GdbSerialLib.c b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Library/GdbSerialLib/GdbSerialLib.c
new file mode 100644
index 000000000..db4eddf6e
--- /dev/null
+++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Library/GdbSerialLib/GdbSerialLib.c
@@ -0,0 +1,118 @@
+/** @file
+ Basic serial IO abstaction for GDB
+
+ Copyright (c) 2012, Samsung Electronics Co. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <Uefi.h>
+#include <Library/GdbSerialLib.h>
+#include <Library/PcdLib.h>
+#include <Library/IoLib.h>
+#include <Platform/ArmPlatform.h>
+
+RETURN_STATUS
+EFIAPI
+GdbSerialLibConstructor (
+ VOID
+ )
+{
+ return GdbSerialInit (115200, 0, 8, 1);
+}
+
+RETURN_STATUS
+EFIAPI
+GdbSerialInit (
+ IN UINT64 BaudRate,
+ IN UINT8 Parity,
+ IN UINT8 DataBits,
+ IN UINT8 StopBits
+ )
+{
+ if ((Parity != 0) || (DataBits != 8) || (StopBits != 1)) {
+ return RETURN_UNSUPPORTED;
+ }
+
+ if (BaudRate != 115200) {
+ // Could add support for different Baud rates....
+ return RETURN_UNSUPPORTED;
+ }
+
+ UINT32 Base = PcdGet32 (PcdGdbUartBase);
+
+ // initialize baud rate generator to 115200 based on EB clock REFCLK24MHZ
+ MmioWrite32 (Base + UARTIBRD, UART_115200_IDIV);
+ MmioWrite32 (Base + UARTFBRD, UART_115200_FDIV);
+
+ // no parity, 1 stop, no fifo, 8 data bits
+ MmioWrite32 (Base + UARTLCR_H, 0x60);
+
+ // clear any pending errors
+ MmioWrite32 (Base + UARTECR, 0);
+
+ // enable tx, rx, and uart overall
+ MmioWrite32 (Base + UARTCR, 0x301);
+
+ return RETURN_SUCCESS;
+}
+
+BOOLEAN
+EFIAPI
+GdbIsCharAvailable (
+ VOID
+ )
+{
+ UINT32 FR = PcdGet32 (PcdGdbUartBase) + UTRSTAT_OFFSET;
+
+ if ((MmioRead32 (FR) & UART_RX_EMPTY_FLAG_MASK) == 0) {
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+}
+
+CHAR8
+EFIAPI
+GdbGetChar (
+ VOID
+ )
+{
+ UINT32 FR = PcdGet32 (PcdGdbUartBase) + UTRSTAT_OFFSET;
+ UINT32 DR = PcdGet32 (PcdGdbUartBase) + URXH_OFFSET;
+
+ while ((MmioRead32 (FR) & UART_RX_EMPTY_FLAG_MASK) == 0);
+ return MmioRead8 (DR);
+}
+
+VOID
+EFIAPI
+GdbPutChar (
+ IN CHAR8 Char
+ )
+{
+ UINT32 FR = PcdGet32 (PcdGdbUartBase) + UTRSTAT_OFFSET;
+ UINT32 DR = PcdGet32 (PcdGdbUartBase) + UTXH_OFFSET;
+
+ while ((MmioRead32 (FR) & UART_TX_EMPTY_FLAG_MASK) != 0);
+ MmioWrite8 (DR, Char);
+ return;
+}
+
+VOID
+GdbPutString (
+ IN CHAR8 *String
+ )
+{
+ while (*String != '\0') {
+ GdbPutChar (*String);
+ String++;
+ }
+}
diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Library/GdbSerialLib/GdbSerialLib.inf b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Library/GdbSerialLib/GdbSerialLib.inf
new file mode 100644
index 000000000..c557407e1
--- /dev/null
+++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Library/GdbSerialLib/GdbSerialLib.inf
@@ -0,0 +1,40 @@
+#/** @file
+#
+# Copyright (c) 2012, Samsung Electronics Co. All rights reserved.<BR>
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#**/
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = GdbSerialLib
+ FILE_GUID = E8EA1309-2F14-428f-ABE3-7016CE4B4305
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = GdbSerialLib
+
+ CONSTRUCTOR = GdbSerialLibConstructor
+
+
+[Sources.common]
+ GdbSerialLib.c
+
+
+[Packages]
+ MdePkg/MdePkg.dec
+ SamsungPlatformPkg/ExynosPkg/Exynos5250/ExynosPkg.dec
+ EmbeddedPkg/EmbeddedPkg.dec
+
+
+[LibraryClasses]
+ DebugLib
+ IoLib
+
+[FixedPcd]
+ gExynosPkgTokenSpaceGuid.PcdGdbUartBase
diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Library/RealTimeClockLib/RealTimeClockLib.c b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Library/RealTimeClockLib/RealTimeClockLib.c
new file mode 100644
index 000000000..2325a31b0
--- /dev/null
+++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Library/RealTimeClockLib/RealTimeClockLib.c
@@ -0,0 +1,363 @@
+/** @file
+ Implement EFI RealTimeClock runtime services via RTC Lib.
+
+ Currently this driver does not support runtime virtual calling.
+
+ Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+
+#include <PiDxe.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/RealTimeClockLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Protocol/RealTimeClock.h>
+#include <Guid/GlobalVariable.h>
+
+
+/*
+ * Kimoon added on 2011.12.08
+ */
+#include <Library/PcdLib.h>
+#include <Platform/ArmPlatform.h>
+
+#define RTC_YEAR_DATUM 2000
+
+unsigned bcd2bin(unsigned char val)
+{
+ return (val & 0x0f) + (val >> 4) * 10;
+}
+
+unsigned char bin2bcd(unsigned val)
+{
+ return ((val / 10) << 4) + val % 10;
+}
+
+/**
+ Returns the current time and date information, and the time-keeping capabilities
+ of the hardware platform.
+
+ @param Time A pointer to storage to receive a snapshot of the current time.
+ @param Capabilities An optional pointer to a buffer to receive the real time clock
+ device's capabilities.
+
+ @retval EFI_SUCCESS The operation completed successfully.
+ @retval EFI_INVALID_PARAMETER Time is NULL.
+ @retval EFI_DEVICE_ERROR The time could not be retrieved due to hardware error.
+
+**/
+EFI_STATUS
+EFIAPI
+LibGetTime (
+ OUT EFI_TIME *Time,
+ OUT EFI_TIME_CAPABILITIES *Capabilities
+ )
+{
+ /*
+ * Kimoon added on 2011.12.08
+ */
+ UINT32 RtcBaseAddr;
+ BOOLEAN Retried = FALSE;
+
+ DEBUG((EFI_D_INFO, "++%a:%d\n", __func__, __LINE__));
+
+ /*
+ * Check set time
+ */
+ if (Time == NULL)
+ goto cleanUp;
+
+ /*
+ * 1. Get RTC base address
+ */
+ RtcBaseAddr = PcdGet32(PcdRtcBase);
+
+ /*
+ * 2. Read registers
+ */
+RetryGetTime:
+ Time->Minute = MmioRead32(RtcBaseAddr + EXYNOS_BCDMIN);
+ Time->Hour = MmioRead32(RtcBaseAddr + EXYNOS_BCDHOUR);
+ Time->Day = MmioRead32(RtcBaseAddr + EXYNOS_BCDDAY);
+ Time->Month = MmioRead32(RtcBaseAddr + EXYNOS_BCDMON);
+ Time->Year = MmioRead32(RtcBaseAddr + EXYNOS_BCDYEAR);
+ Time->Second = MmioRead32(RtcBaseAddr + EXYNOS_BCDSEC);
+
+ /*
+ * 3. if second value is 0, try to read registers to escape errors.
+ */
+ if (Time->Second == 0 && !Retried) {
+ Retried = TRUE;
+ goto RetryGetTime;
+ }
+
+ /*
+ * 4. Change BCD values to real values.
+ */
+ Time->Second = bcd2bin(Time->Second);
+ Time->Minute = bcd2bin(Time->Minute);
+ Time->Hour = bcd2bin(Time->Hour);
+ Time->Day = bcd2bin(Time->Day);
+ Time->Month = bcd2bin(Time->Month);
+ Time->Year = bcd2bin(Time->Year) + RTC_YEAR_DATUM;
+
+ // Update the Capabilities info
+ if (Capabilities != NULL) {
+ // PL031 runs at frequency 1Hz
+ Capabilities->Resolution = 1;
+ // Accuracy in ppm multiplied by 1,000,000, e.g. for 50ppm set 50,000,000
+ Capabilities->Accuracy = 1000000;
+ // FALSE: Setting the time does not clear the values below the resolution level
+ Capabilities->SetsToZero = FALSE;
+ }
+
+
+ DEBUG((EFI_D_INFO, "--%a:%d (%d/%d/%d %d:%d:%d)\n",
+ __func__, __LINE__,
+ Time->Year, Time->Month, Time->Day, Time->Hour, Time->Minute, Time->Second));
+ return EFI_SUCCESS;
+
+cleanUp:
+ DEBUG((EFI_D_ERROR, "ERROR: %a:%d\n", __func__, __LINE__));
+ return EFI_DEVICE_ERROR;
+
+}
+
+
+/**
+ Sets the current local time and date information.
+
+ @param Time A pointer to the current time.
+
+ @retval EFI_SUCCESS The operation completed successfully.
+ @retval EFI_INVALID_PARAMETER A time field is out of range.
+ @retval EFI_DEVICE_ERROR The time could not be set due due to hardware error.
+
+**/
+EFI_STATUS
+EFIAPI
+LibSetTime (
+ IN EFI_TIME *Time
+ )
+{
+ /*
+ * Kimoon added on 2011.12.08
+ */
+ UINT32 RtcBaseAddr;
+
+ DEBUG((EFI_D_ERROR, "++%a:%d (%d/%d/%d %d:%d:%d)\n",
+ __func__, __LINE__,
+ Time->Year, Time->Month, Time->Day, Time->Hour, Time->Minute, Time->Second));
+
+ /*
+ * Check set time
+ */
+ if (Time == NULL)
+ goto cleanUp;
+
+ /*
+ * The RTC will only support a BCD year value of 0 - 99. The year datum is
+ * 2000, so any dates greater than 2099 will fail unless the datum is
+ * adjusted.
+ */
+ if ((Time->Year < RTC_YEAR_DATUM) || (Time->Year - RTC_YEAR_DATUM > 99)) {
+ DEBUG((EFI_D_ERROR, "RTC cannot support a year greater than %d or less than %d (value %d)\n",
+ (RTC_YEAR_DATUM + 99), RTC_YEAR_DATUM, Time->Year));
+ goto cleanUp;
+ }
+
+ /*
+ * 1. Get RTC base address
+ */
+ RtcBaseAddr = PcdGet32(PcdRtcBase);
+
+ /*
+ * 2. Set EXYNOS_RTCCON_RTCEN to Set BCD registers
+ * &= ~EXYNOS_RTCCON_RTCEN
+ * |= EXYNOS_RTCCON_RTCEN
+ */
+ MmioAndThenOr32(RtcBaseAddr + EXYNOS_RTCCON, \
+ ~EXYNOS_RTCCON_RTCEN, EXYNOS_RTCCON_RTCEN);
+
+ /*
+ * 3. Set BCD registers
+ */
+ MmioWrite32(RtcBaseAddr + EXYNOS_BCDSEC, bin2bcd(Time->Second));
+ MmioWrite32(RtcBaseAddr + EXYNOS_BCDMIN, bin2bcd(Time->Minute));
+ MmioWrite32(RtcBaseAddr + EXYNOS_BCDHOUR, bin2bcd(Time->Hour));
+ MmioWrite32(RtcBaseAddr + EXYNOS_BCDDAY, bin2bcd(Time->Day));
+ MmioWrite32(RtcBaseAddr + EXYNOS_BCDMON, bin2bcd(Time->Month));
+ MmioWrite32(RtcBaseAddr + EXYNOS_BCDYEAR, bin2bcd(Time->Year - RTC_YEAR_DATUM));
+
+ /*
+ * 4. Clear EXYNOS_RTCCON_RTCEN to close setting BCD registers
+ * &= ~EXYNOS_RTCCON_RTCEN
+ */
+ MmioAndThenOr32(RtcBaseAddr + EXYNOS_RTCCON, \
+ ~EXYNOS_RTCCON_RTCEN, (0<<0));
+
+ DEBUG((EFI_D_ERROR, "--%a:%d\n", __func__, __LINE__));
+ return EFI_SUCCESS;
+
+cleanUp:
+ DEBUG((EFI_D_ERROR, "ERROR: %a:%d\n", __func__, __LINE__));
+ return EFI_DEVICE_ERROR;
+
+}
+
+
+/**
+ Returns the current wakeup alarm clock setting.
+
+ @param Enabled Indicates if the alarm is currently enabled or disabled.
+ @param Pending Indicates if the alarm signal is pending and requires acknowledgement.
+ @param Time The current alarm setting.
+
+ @retval EFI_SUCCESS The alarm settings were returned.
+ @retval EFI_INVALID_PARAMETER Any parameter is NULL.
+ @retval EFI_DEVICE_ERROR The wakeup time could not be retrieved due to a hardware error.
+
+**/
+EFI_STATUS
+EFIAPI
+LibGetWakeupTime (
+ OUT BOOLEAN *Enabled,
+ OUT BOOLEAN *Pending,
+ OUT EFI_TIME *Time
+ )
+{
+ // Not a required feature
+ return EFI_UNSUPPORTED;
+}
+
+
+/**
+ Sets the system wakeup alarm clock time.
+
+ @param Enabled Enable or disable the wakeup alarm.
+ @param Time If Enable is TRUE, the time to set the wakeup alarm for.
+
+ @retval EFI_SUCCESS If Enable is TRUE, then the wakeup alarm was enabled. If
+ Enable is FALSE, then the wakeup alarm was disabled.
+ @retval EFI_INVALID_PARAMETER A time field is out of range.
+ @retval EFI_DEVICE_ERROR The wakeup time could not be set due to a hardware error.
+ @retval EFI_UNSUPPORTED A wakeup timer is not supported on this platform.
+
+**/
+EFI_STATUS
+EFIAPI
+LibSetWakeupTime (
+ IN BOOLEAN Enabled,
+ OUT EFI_TIME *Time
+ )
+{
+ // Not a required feature
+ return EFI_UNSUPPORTED;
+}
+
+
+
+/**
+ This is the declaration of an EFI image entry point. This can be the entry point to an application
+ written to this specification, an EFI boot service driver, or an EFI runtime driver.
+
+ @param ImageHandle Handle that identifies the loaded image.
+ @param SystemTable System Table for this image.
+
+ @retval EFI_SUCCESS The operation completed successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+LibRtcInitialize (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_HANDLE Handle;
+ EFI_TIME Time;
+
+ /*
+ * Kimoon added on 2011.12.08
+ */
+ DEBUG((EFI_D_INFO, "++%a:%d\n", __func__, __LINE__));
+
+ /*
+ * Mask RTC gating (bit clear)
+ */
+ MmioAndThenOr32((PcdGet32(PcdCmuBase) + CLK_GATE_IP_PERIR), \
+ ~CLK_RTC_OFFSET, CLK_RTC_MASK);
+
+ /*
+ * Unmask RTC gating (bit set)
+ */
+ MmioAndThenOr32((PcdGet32(PcdCmuBase) + CLK_GATE_IP_PERIR), \
+ ~CLK_RTC_OFFSET, CLK_RTC_UNMASK);
+
+
+ // Setup the setters and getters
+ gRT->GetTime = LibGetTime;
+ gRT->SetTime = LibSetTime;
+ gRT->GetWakeupTime = LibGetWakeupTime;
+ gRT->SetWakeupTime = LibSetWakeupTime;
+
+ Time.Second = 0;
+ Time.Minute = 0;
+ Time.Hour = 9;
+ Time.Day = 15;
+ Time.Month = 3;
+ Time.Year = 2012;
+
+ LibSetTime(&Time);
+
+ // Install the protocol
+ Handle = NULL;
+ gBS->InstallMultipleProtocolInterfaces (
+ &Handle,
+ &gEfiRealTimeClockArchProtocolGuid, NULL,
+ NULL
+ );
+
+ DEBUG((EFI_D_INFO, "--%a:%d\n", __func__, __LINE__));
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Fixup internal data so that EFI can be call in virtual mode.
+ Call the passed in Child Notify event and convert any pointers in
+ lib to virtual mode.
+
+ @param[in] Event The Event that is being processed
+ @param[in] Context Event Context
+**/
+VOID
+EFIAPI
+LibRtcVirtualNotifyEvent (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ //
+ // Only needed if you are going to support the OS calling RTC functions in virtual mode.
+ // You will need to call EfiConvertPointer (). To convert any stored physical addresses
+ // to virtual address. After the OS transistions to calling in virtual mode, all future
+ // runtime calls will be made in virtual mode.
+ //
+ return;
+}
+
+
+
diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Library/RealTimeClockLib/RealTimeClockLib.inf b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Library/RealTimeClockLib/RealTimeClockLib.inf
new file mode 100644
index 000000000..78c6937a6
--- /dev/null
+++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Library/RealTimeClockLib/RealTimeClockLib.inf
@@ -0,0 +1,42 @@
+#/** @file
+# Memory Status Code Library for UEFI drivers
+#
+# Lib to provide memory journal status code reporting Routines
+# Copyright (c) 2006, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#
+#**/
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = TemplateRealTimeClockLib
+ FILE_GUID = B661E02D-A90B-42AB-A5F9-CF841AAA43D9
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = RealTimeClockLib
+
+
+[Sources.common]
+ RealTimeClockLib.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ EmbeddedPkg/EmbeddedPkg.dec
+ ArmPlatformPkg/ArmPlatformPkg.dec
+ SamsungPlatformPkg/ExynosPkg/Exynos5250/ExynosPkg.dec
+
+[LibraryClasses]
+ IoLib
+ UefiLib
+ DebugLib
+
+[Pcd.common]
+ gExynosPkgTokenSpaceGuid.PcdRtcBase
+ gExynosPkgTokenSpaceGuid.PcdCmuBase
diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Library/ResetSystemLib/ResetSystemLib.c b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Library/ResetSystemLib/ResetSystemLib.c
new file mode 100644
index 000000000..295a42546
--- /dev/null
+++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Library/ResetSystemLib/ResetSystemLib.c
@@ -0,0 +1,241 @@
+/** @file
+ Template library implementation to support ResetSystem Runtime call.
+
+ Fill in the templates with what ever makes you system reset.
+
+
+ Copyright (c) 2012, Samsung Electronics Co. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+
+#include <PiDxe.h>
+
+#include <Library/UefiRuntimeLib.h>
+#include <Library/DxeServicesTableLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/ArmLib.h>
+#include <Library/BaseLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PcdLib.h>
+#include <Library/IoLib.h>
+#include <Library/DebugLib.h>
+#include <Library/EfiResetSystemLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/CacheMaintenanceLib.h>
+#include <Platform/ArmPlatform.h>
+
+#include <Guid/EventGroup.h>
+
+
+/* Round off to 4KB pages */
+#define ROUND_TO_PAGE(x) (x & 0xfffff000)
+
+
+UINT32 gPmuBaseAddress = 0;
+EFI_EVENT VirtualAddressChangeEvent = NULL;
+
+VOID DestroyExynosMemMap(VOID);
+typedef VOID (EFIAPI *ptrImageStart)(VOID);
+
+/**
+ Virtual address change notification call back. It converts global pointer
+ to virtual address.
+
+ @param Event Event whose notification function is being invoked.
+ @param Context Pointer to the notification function's context, which is
+ always zero in current implementation.
+**/
+VOID
+EFIAPI
+VirtualAddressChangeCallBack (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ gRT->ConvertPointer(0, (VOID**)&gPmuBaseAddress);
+ gRT->ConvertPointer(0, (VOID**)&gRT);
+}
+
+
+VOID
+DestroyExynosMemMap (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ UINTN MemoryMapSize;
+ EFI_MEMORY_DESCRIPTOR *MemoryMap;
+ UINTN MapKey;
+ UINTN DescriptorSize;
+ UINTN DescriptorVersion;
+ UINTN Pages;
+
+ MemoryMap = NULL;
+ MemoryMapSize = 0;
+ do {
+ Status = gBS->GetMemoryMap (
+ &MemoryMapSize,
+ MemoryMap,
+ &MapKey,
+ &DescriptorSize,
+ &DescriptorVersion
+ );
+ if (Status == EFI_BUFFER_TOO_SMALL) {
+
+ Pages = EFI_SIZE_TO_PAGES (MemoryMapSize) + 1;
+ MemoryMap = AllocatePages (Pages);
+
+ //
+ // Get System MemoryMap
+ //
+ Status = gBS->GetMemoryMap (
+ &MemoryMapSize,
+ MemoryMap,
+ &MapKey,
+ &DescriptorSize,
+ &DescriptorVersion
+ );
+ // Don't do anything between the GetMemoryMap() and ExitBootServices()
+ if (!EFI_ERROR (Status)) {
+ Status = gBS->ExitBootServices (gImageHandle, MapKey);
+ if (EFI_ERROR (Status)) {
+ FreePages (MemoryMap, Pages);
+ MemoryMap = NULL;
+ MemoryMapSize = 0;
+ }
+ }
+ }
+ } while (EFI_ERROR (Status));
+
+ //Clean and invalidate caches.
+ WriteBackInvalidateDataCache();
+ InvalidateInstructionCache();
+
+ //Turning off Caches and MMU
+ ArmDisableDataCache ();
+ ArmDisableInstructionCache ();
+ ArmDisableMmu ();
+}
+
+
+
+/**
+ Resets the entire platform.
+
+ @param ResetType The type of reset to perform.
+ @param ResetStatus The status code for the reset.
+ @param DataSize The size, in bytes, of WatchdogData.
+ @param ResetData For a ResetType of EfiResetCold, EfiResetWarm, or
+ EfiResetShutdown the data buffer starts with a Null-terminated
+ Unicode string, optionally followed by additional binary data.
+
+**/
+EFI_STATUS
+EFIAPI
+LibResetSystem (
+ IN EFI_RESET_TYPE ResetType,
+ IN EFI_STATUS ResetStatus,
+ IN UINTN DataSize,
+ IN CHAR16 *ResetData OPTIONAL
+ )
+{
+ volatile UINT32 count = 0;
+
+ if (EfiAtRuntime())
+ {
+ while (count < 0x1000000)
+ {
+ count++;
+ }
+ }
+
+ switch (ResetType) {
+ case EfiResetShutdown:
+ case EfiResetCold:
+ case EfiResetWarm:
+ //Perform warm reset of the system by jumping to the begining of the FV
+ //((ptrImageStart)PcdGet32(PcdFvBaseAddress))();
+ //break;
+ default:
+ if(EfiAtRuntime () == 0)
+ {
+ DestroyExynosMemMap();
+ }
+
+ /* Perform cold reset of the system - should not return */
+ MmioWrite32 ((gPmuBaseAddress + SWRESET_OFFSET), 0x01);
+ while ((MmioRead32(gPmuBaseAddress + SWRESET_OFFSET)) != 0x1);
+ break;
+ }
+
+ // If the reset didn't work, return an error.
+ ASSERT (FALSE);
+ return EFI_SUCCESS;
+}
+
+
+
+/**
+ Initialize any infrastructure required for LibResetSystem () to function.
+
+ @param ImageHandle The firmware allocated handle for the EFI image.
+ @param SystemTable A pointer to the EFI System Table.
+
+ @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS.
+
+**/
+EFI_STATUS
+EFIAPI
+LibInitializeResetSystem (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+
+ EFI_GCD_MEMORY_SPACE_DESCRIPTOR PmuMemoryDescriptor;
+
+ gPmuBaseAddress = PcdGet32(PcdPmuBase);
+
+ /*
+ * Get the GCD Memory Descriptor specified by WdtBaseAddress page boundary
+ */
+ Status = gDS->GetMemorySpaceDescriptor (ROUND_TO_PAGE(gPmuBaseAddress),
+ &PmuMemoryDescriptor);
+ ASSERT_EFI_ERROR (Status);
+
+ /*
+ * Mark the 4KB region as EFI_RUNTIME_MEMORY so the OS
+ * will allocate a virtual address range.
+ */
+ Status = gDS->SetMemorySpaceAttributes (
+ ROUND_TO_PAGE(gPmuBaseAddress),
+ EFI_PAGE_SIZE,
+ PmuMemoryDescriptor.Attributes | EFI_MEMORY_RUNTIME);
+ ASSERT_EFI_ERROR (Status);
+
+ Status = gBS->CreateEventEx (
+ EVT_NOTIFY_SIGNAL,
+ TPL_NOTIFY,
+ VirtualAddressChangeCallBack,
+ NULL,
+ &gEfiEventVirtualAddressChangeGuid,
+ &VirtualAddressChangeEvent
+ );
+ ASSERT_EFI_ERROR (Status);
+
+
+
+
+ return EFI_SUCCESS;
+}
diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Library/ResetSystemLib/ResetSystemLib.inf b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Library/ResetSystemLib/ResetSystemLib.inf
new file mode 100644
index 000000000..314078c32
--- /dev/null
+++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Library/ResetSystemLib/ResetSystemLib.inf
@@ -0,0 +1,52 @@
+#/** @file
+# Reset System lib to make it easy to port new platforms
+#
+# Copyright (c) 2012, Samsung Electronics Co. All rights reserved.<BR>
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#
+#**/
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = ResetSystemLib
+ FILE_GUID = CEFFA65C-B568-453e-9E11-B81AE683D035
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = EfiResetSystemLib
+
+
+[Sources.common]
+ ResetSystemLib.c
+
+[Packages]
+ ArmPkg/ArmPkg.dec
+ MdePkg/MdePkg.dec
+ EmbeddedPkg/EmbeddedPkg.dec
+ ArmPlatformPkg/ArmPlatformPkg.dec
+ SamsungPlatformPkg/ExynosPkg/Exynos5250/ExynosPkg.dec
+
+[LibraryClasses]
+ DxeServicesTableLib
+ UefiBootServicesTableLib
+ UefiRuntimeServicesTableLib
+ UefiRuntimeLib
+ DebugLib
+ BaseLib
+ IoLib
+ MemoryAllocationLib
+ ArmLib
+ CacheMaintenanceLib
+
+[Pcd]
+ gArmTokenSpaceGuid.PcdFvBaseAddress
+ gExynosPkgTokenSpaceGuid.PcdPmuBase
+
+[Guids]
+ gEfiEventVirtualAddressChangeGuid
diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Library/SerialPortLib/SerialPortLib_Evt1.c b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Library/SerialPortLib/SerialPortLib_Evt1.c
new file mode 100755
index 000000000..1e5791bd8
--- /dev/null
+++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Library/SerialPortLib/SerialPortLib_Evt1.c
@@ -0,0 +1,159 @@
+/** @file
+ Serial I/O Port library functions with no library constructor/destructor
+
+
+ Copyright (c) 2012, Samsung Electronics Co. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <Include/Uefi.h>
+#include <Library/SerialPortLib.h>
+#include <Library/PcdLib.h>
+#include <Library/IoLib.h>
+#include <Platform/ArmPlatform.h>
+#include <Library/DebugLib.h>
+
+/*
+
+ Programmed hardware of Serial port.
+ Irrespective of the previous settings Initialize it to current requirement
+**/
+RETURN_STATUS
+EFIAPI
+SerialPortInitialize (
+ VOID
+ )
+{
+ UINT32 UARTConsoleBase;
+ UINT32 Tmp;
+
+ UARTConsoleBase=PcdGet32(PcdConsoleUartBase);
+
+ // GPIO
+ MmioWrite32(0x11400000, 0x00002222);
+ MmioWrite32(0x11400020, 0x222222);
+ MmioWrite32(0x11400160, 0x2222);
+
+ // CMU
+ Tmp = MmioRead32(0x10020250);
+// DEBUG ((EFI_D_ERROR, "%X \n", Tmp));
+
+ Tmp &= ~((0xF << 16) + (0xF << 12) + (0xF << 8) + (0xF << 4) + (0xF << 0));
+ Tmp |= ((0x6 << 16) + (0x6 << 12) + (0x6 << 8) + (0x6 << 4) + (0x6 << 0));
+ MmioWrite32 (0x10020250, Tmp);
+
+ Tmp = MmioRead32(0x10020558);
+ Tmp &= ~((0xF << 16) + (0xF << 12) + (0xF << 8) + (0xF << 4) + (0xF << 0));
+ Tmp |= ((0x7 << 16) + (0x7 << 12) + (0x7 << 8) + (0x7 << 4) + (0x7 << 0));
+ MmioWrite32 (0x10020558, Tmp);
+
+ // UART
+ MmioWrite32(UARTConsoleBase, 0x3);
+ MmioWrite32(UARTConsoleBase+0x4, 0x3C5);
+ MmioWrite32(UARTConsoleBase+0x8, 0x111);
+ MmioWrite32(UARTConsoleBase+0x28, 0x23);
+ MmioWrite32(UARTConsoleBase+0x2C, 0x2);
+/*
+ MmioWrite32(UARTConsoleBase+0x20, 0x4F);
+ MmioWrite32(UARTConsoleBase+0x20, 0x4F);
+ MmioWrite32(UARTConsoleBase+0x20, 0x4F);
+ MmioWrite32(UARTConsoleBase+0x20, 0x4F);
+ MmioWrite32(UARTConsoleBase+0x20, 0x4F);
+ MmioWrite32(UARTConsoleBase+0x20, 0x4F);
+*/
+ // For WindDebug Uart initialization
+ UARTConsoleBase=PcdGet32(PcdWinDebugUartBase);
+ MmioWrite32(UARTConsoleBase, 0x3);
+ MmioWrite32(UARTConsoleBase+0x4, 0x3C5);
+ MmioWrite32(UARTConsoleBase+0x8, 0x111);
+ MmioWrite32(UARTConsoleBase+0x28, 0x35);
+ MmioWrite32(UARTConsoleBase+0x2C, 0x4);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Write data to serial device.
+
+ @param Buffer Point of data buffer which need to be writed.
+ @param NumberOfBytes Number of output bytes which are cached in Buffer.
+
+ @retval 0 Write data failed.
+ @retval !0 Actual number of bytes writed to serial device.
+
+**/
+UINTN
+EFIAPI
+SerialPortWrite (
+ IN UINT8 *Buffer,
+ IN UINTN NumberOfBytes
+)
+{
+ UINTN Count;
+ UINT32 UARTConsoleBase;
+
+ UARTConsoleBase=PcdGet32(PcdConsoleUartBase);
+ for (Count = 0; Count < NumberOfBytes; Count++, Buffer++) {
+ while ((MmioRead32 (UARTConsoleBase + UTRSTAT_OFFSET) & UART_TX_EMPTY_FLAG_MASK) == 0);
+ MmioWrite8 (UARTConsoleBase + UTXH_OFFSET, *Buffer);
+ }
+
+ return NumberOfBytes;
+}
+
+/**
+ Read data from serial device and save the datas in buffer.
+
+ @param Buffer Point of data buffer which need to be writed.
+ @param NumberOfBytes Number of output bytes which are cached in Buffer.
+
+ @retval 0 Read data failed.
+ @retval !0 Aactual number of bytes read from serial device.
+
+**/
+UINTN
+EFIAPI
+SerialPortRead (
+ OUT UINT8 *Buffer,
+ IN UINTN NumberOfBytes
+)
+{
+ UINTN Count;
+ UINT32 UARTConsoleBase;
+
+ UARTConsoleBase=PcdGet32(PcdConsoleUartBase);
+ for (Count = 0; Count < NumberOfBytes; Count++, Buffer++) {
+ while ((MmioRead32 (UARTConsoleBase + UTRSTAT_OFFSET) & UART_RX_EMPTY_FLAG_MASK) == 0);
+ *Buffer = MmioRead8 (UARTConsoleBase + URXH_OFFSET);
+ }
+
+ return NumberOfBytes;
+}
+
+/**
+ Check to see if any data is avaiable to be read from the debug device.
+
+ @retval EFI_SUCCESS At least one byte of data is avaiable to be read
+ @retval EFI_NOT_READY No data is avaiable to be read
+ @retval EFI_DEVICE_ERROR The serial device is not functioning properly
+
+**/
+BOOLEAN
+EFIAPI
+SerialPortPoll (
+ VOID
+ )
+{
+ UINT32 UARTConsoleBase;
+ UARTConsoleBase=PcdGet32(PcdConsoleUartBase);
+
+ return ((MmioRead32 (UARTConsoleBase + UTRSTAT_OFFSET) & UART_RX_EMPTY_FLAG_MASK) != 0);
+}
diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Library/SerialPortLib/SerialPortLib_Evt1.inf b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Library/SerialPortLib/SerialPortLib_Evt1.inf
new file mode 100755
index 000000000..de89bad23
--- /dev/null
+++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Library/SerialPortLib/SerialPortLib_Evt1.inf
@@ -0,0 +1,38 @@
+#/** @file
+#
+# Component discription file for NorFlashDxe module
+#
+# Copyright (c) 2012, Samsung Electronics Co. All rights reserved.<BR>
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#**/
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = SerialPortLib
+ FILE_GUID = 8ecefc8f-a2c4-4091-b80f-20f7aeb0567f
+ MODULE_TYPE = PEIM
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = SerialPortLib
+
+[Sources.common]
+ SerialPortLib_Evt1.c
+
+[LibraryClasses]
+ IoLib
+
+[Packages]
+ MdePkg/MdePkg.dec
+ # ArmPlatformPkg/ArmPlatformPkg.dec
+ SamsungPlatformPkg/ExynosPkg/Exynos5250/ExynosPkg.dec
+
+[FixedPcd]
+ gExynosPkgTokenSpaceGuid.PcdConsoleUartBase
+ gExynosPkgTokenSpaceGuid.PcdWinDebugUartBase
+ gExynosPkgTokenSpaceGuid.PcdCmuBase
diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Library/TimerLib/TimerLib.c b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Library/TimerLib/TimerLib.c
new file mode 100644
index 000000000..f828b53fa
--- /dev/null
+++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Library/TimerLib/TimerLib.c
@@ -0,0 +1,287 @@
+/** @file
+
+ Copyright (c) 2012, Samsung Electronics Co. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <Base.h>
+
+#include <Library/BaseLib.h>
+#include <Library/TimerLib.h>
+#include <Library/DebugLib.h>
+#include <Library/PcdLib.h>
+#include <Library/IoLib.h>
+#include <Platform/ArmPlatform.h>
+#include <Library/ExynosTimerLib.h>
+
+
+// Setup SP810's Timer2 for managing delay functions. And Timer3 for Performance counter
+// Note: ArmVE's Timer0 and Timer1 are used by TimerDxe.
+RETURN_STATUS
+EFIAPI
+TimerConstructor (
+ VOID
+ )
+{
+ UINT32 PWMTimerBase;
+ UINT32 Tmp;
+
+ PWMTimerBase = PcdGet32(PcdPWMTimerBase);
+
+/**
+ This function is for initializing for PWM Timer
+ Timer 2 = > Delay Counter
+ Timer 3 = > Performance Counter
+**/
+// PWM Input Clock(ACLK_100) is 100 Mhz so We need to prescale about 1Mhz to make udelay function
+ Tmp = MmioRead32 (PWMTimerBase + PWM_TCFG0_OFFSET);
+ Tmp &= ~(0xFF << 8);
+ Tmp |= (0x63 << 8);
+ MmioWrite32 ((PWMTimerBase + PWM_TCFG0_OFFSET), Tmp);
+ MmioWrite32 ((PWMTimerBase + PWM_TCFG1_OFFSET), 0x0);
+
+// PWM Timer INT disable
+ Tmp = MmioRead32 (PWMTimerBase + PWM_TINT_CSTAT_OFFSET);
+ Tmp &= ~(0x3 << 2);
+ MmioWrite32 ((PWMTimerBase + PWM_TINT_CSTAT_OFFSET), Tmp);
+
+// PWM Timer 2,3 make to stop
+ Tmp = MmioRead32 (PWMTimerBase + PWM_TCON_OFFSET);
+ Tmp &= ~(0xFF << 12);
+ MmioWrite32 ((PWMTimerBase + PWM_TCON_OFFSET), Tmp);
+
+// PWM Timer 3 used by Free running counter with Auto re-load mode
+ MmioWrite32 ((PWMTimerBase + PWM_TCNTB3_OFFSET), 0xFFFFFFFF);
+// Set and Clear PWM Manually update for Timer 3
+ Tmp |= (0x2 << 16);
+ MmioWrite32 ((PWMTimerBase + PWM_TCON_OFFSET), Tmp);
+ Tmp &= ~(0x2 << 16);
+ MmioWrite32 ((PWMTimerBase + PWM_TCON_OFFSET), Tmp);
+// Set Auto re-load and start Timer
+ Tmp |= (0x9 << 16);
+ MmioWrite32 ((PWMTimerBase + PWM_TCON_OFFSET), Tmp);
+
+ DEBUG ((EFI_D_ERROR, "Timer 2,3 Enabled\n"));
+
+ return RETURN_SUCCESS;
+}
+
+/**
+ Stalls the CPU for at least the given number of microseconds.
+
+ Stalls the CPU for the number of microseconds specified by MicroSeconds.
+
+ @param MicroSeconds The minimum number of microseconds to delay.
+
+ @return The value of MicroSeconds inputted.
+
+**/
+UINTN
+EFIAPI
+MicroSecondDelay (
+ IN UINTN MicroSeconds
+ )
+{
+ UINT32 Tmp;
+ UINT32 PWMTimerBase;
+ UINT32 i = 0;
+
+ PWMTimerBase=PcdGet32(PcdPWMTimerBase);
+ /* load the timer count register */
+ MmioWrite32 ((PWMTimerBase + PWM_TCNTB2_OFFSET), MicroSeconds);
+
+ Tmp = MmioRead32 (PWMTimerBase + PWM_TCON_OFFSET);
+
+ /* Stop Timer 2 */
+ Tmp &= ~(0xF << 12);
+ MmioWrite32 ((PWMTimerBase + PWM_TCON_OFFSET), Tmp);
+ /* Set and Clear for Manually Update Counter Buffer */
+ Tmp |= (0x2 << 12);
+ MmioWrite32 ((PWMTimerBase + PWM_TCON_OFFSET), Tmp);
+ Tmp &= ~(0x2 << 12);
+ MmioWrite32 ((PWMTimerBase + PWM_TCON_OFFSET), Tmp);
+ /* Start Timer 2 */
+ Tmp |= (0x1 << 12);
+ MmioWrite32 ((PWMTimerBase + PWM_TCON_OFFSET), Tmp);
+
+ /*
+ * When ARM clock is 1GHz, 1 clock time is 1us.
+ * Simply counting, CounterValue maybe can't be updated within 10 instruction execution.
+ * So it is needed to check CounterValue register a couple of times
+ */
+ do {
+ /* Doesn't need to check if timer starts */
+ if ((MmioRead32 (PWMTimerBase + PWM_TCNTO2_OFFSET)) != 0)
+ break;
+ /* Supports meaningful delay */
+ if (MicroSeconds < 10000)
+ break;
+ /* Timer should start Within this time */
+ if (i++ > 20)
+ break;
+ } while ((MmioRead32 (PWMTimerBase + PWM_TCNTO2_OFFSET)) == 0);
+
+ /* Wait for requested delay time */
+ while (MmioRead32 (PWMTimerBase + PWM_TCNTO2_OFFSET) > 0) {
+ ;
+ }
+
+ /* Stop Timer 2 */
+ Tmp &= ~(0xF << 12);
+ MmioWrite32 ((PWMTimerBase + PWM_TCON_OFFSET), Tmp);
+
+ return MicroSeconds;
+}
+
+/**
+ Stalls the CPU for at least the given number of nanoseconds.
+
+ Stalls the CPU for the number of nanoseconds specified by NanoSeconds.
+
+ @param NanoSeconds The minimum number of nanoseconds to delay.
+
+ @return The value of NanoSeconds inputted.
+
+**/
+UINTN
+EFIAPI
+NanoSecondDelay (
+ IN UINTN NanoSeconds
+ )
+{
+ UINT32 MicroSeconds;
+ UINT32 Tmp;
+ UINT32 PWMTimerBase;
+
+ PWMTimerBase=PcdGet32(PcdPWMTimerBase);
+
+ // Round up to 1us Tick Number
+ MicroSeconds = (UINT32)NanoSeconds / 1000;
+ MicroSeconds += ((UINT32)NanoSeconds % 1000) == 0 ? 0 : 1;
+ // load the timer count register
+ MmioWrite32 ((PWMTimerBase + PWM_TCNTB2_OFFSET), MicroSeconds);
+
+ Tmp = MmioRead32 (PWMTimerBase + PWM_TCON_OFFSET);
+ //Stop Timer 2
+ Tmp &= ~(0xF << 12);
+ MmioWrite32 ((PWMTimerBase + PWM_TCON_OFFSET), Tmp);
+ //Set and Clear for Manually Update Counter Buffer
+ Tmp |= (0x2 << 12);
+ MmioWrite32 ((PWMTimerBase + PWM_TCON_OFFSET), Tmp);
+ Tmp &= ~(0x2 << 12);
+ MmioWrite32 ((PWMTimerBase + PWM_TCON_OFFSET), Tmp);
+ //Start Timer 2
+ Tmp |= (0x1 << 12);
+ MmioWrite32 ((PWMTimerBase + PWM_TCON_OFFSET), Tmp);
+
+ //Wait for requested delay time
+ while (MmioRead32 (PWMTimerBase + PWM_TCNTO2_OFFSET) > 0) {
+ ;
+ }
+
+ return NanoSeconds;
+}
+
+/**
+ Retrieves the current value of a 64-bit free running performance counter.
+
+ The counter can either count up by 1 or count down by 1. If the physical
+ performance counter counts by a larger increment, then the counter values
+ must be translated. The properties of the counter can be retrieved from
+ GetPerformanceCounterProperties().
+
+ @return The current value of the free running performance counter.
+
+**/
+UINT64
+EFIAPI
+GetPerformanceCounter (
+ VOID
+ )
+{
+ UINT32 PWMTimerBase;
+
+ PWMTimerBase=PcdGet32(PcdPWMTimerBase);
+ // Free running 64-bit/32-bit counter is needed here.
+ // Don't think we need this to boot, just to do performance profile
+ // ASSERT (FALSE);
+ UINT32 val = MmioRead32 (PWMTimerBase + PWM_TCNTO3_OFFSET);
+
+ ASSERT(val > 0);
+
+ return (UINT64)val;
+}
+
+
+/**
+ Retrieves the 64-bit frequency in Hz and the range of performance counter
+ values.
+
+ If StartValue is not NULL, then the value that the performance counter starts
+ with immediately after is it rolls over is returned in StartValue. If
+ EndValue is not NULL, then the value that the performance counter end with
+ immediately before it rolls over is returned in EndValue. The 64-bit
+ frequency of the performance counter in Hz is always returned. If StartValue
+ is less than EndValue, then the performance counter counts up. If StartValue
+ is greater than EndValue, then the performance counter counts down. For
+ example, a 64-bit free running counter that counts up would have a StartValue
+ of 0 and an EndValue of 0xFFFFFFFFFFFFFFFF. A 24-bit free running counter
+ that counts down would have a StartValue of 0xFFFFFF and an EndValue of 0.
+
+ @param StartValue The value the performance counter starts with when it
+ rolls over.
+ @param EndValue The value that the performance counter ends with before
+ it rolls over.
+
+ @return The frequency in Hz.
+
+**/
+UINT64
+EFIAPI
+GetPerformanceCounterProperties (
+ OUT UINT64 *StartValue, OPTIONAL
+ OUT UINT64 *EndValue OPTIONAL
+ )
+{
+ if (StartValue != NULL) {
+ // Timer starts with the reload value
+ *StartValue = (UINT64)0ULL;
+ }
+
+ if (EndValue != NULL) {
+ // Timer counts up to 0xFFFFFFFF
+ *EndValue = 0xFFFFFFFF;
+ }
+
+ return 1000000;
+}
+
+/**
+ Converts elapsed ticks of performance counter to time in nanoseconds.
+
+ This function converts the elapsed ticks of running performance counter to
+ time value in unit of nanoseconds.
+
+ @param Ticks The number of elapsed ticks of running performance counter.
+
+ @return The elapsed time in nanoseconds.
+
+**/
+UINT64
+EFIAPI
+GetTimeInNanoSecond (
+ IN UINT64 Ticks
+)
+{
+ ASSERT (TRUE);
+ return 0;
+}
+
diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Library/TimerLib/TimerLib.inf b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Library/TimerLib/TimerLib.inf
new file mode 100644
index 000000000..b8b745aa3
--- /dev/null
+++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Library/TimerLib/TimerLib.inf
@@ -0,0 +1,41 @@
+#/** @file
+# Timer library implementation
+#
+#
+# Copyright (c) 2012, Samsung Electronics Co. All rights reserved.<BR>
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#**/
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = Exynos4210TimerLib
+ FILE_GUID = 34cfa85e-a798-4e46-8d38-1843d7a0caea
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = TimerLib
+
+ CONSTRUCTOR = TimerConstructor
+
+[Sources.common]
+ TimerLib.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ ArmPkg/ArmPkg.dec
+ ArmPlatformPkg/ArmPlatformPkg.dec
+ SamsungPlatformPkg/ExynosPkg/Exynos5250/ExynosPkg.dec
+
+[LibraryClasses]
+ DebugLib
+ IoLib
+ BaseLib
+
+[Pcd.common]
+ gExynosPkgTokenSpaceGuid.PcdPWMTimerBase
diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/MemoryInitPei/MemoryInitPeiLib.c b/SamsungPlatformPkg/ExynosPkg/Exynos5250/MemoryInitPei/MemoryInitPeiLib.c
new file mode 100644
index 000000000..affc7da58
--- /dev/null
+++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/MemoryInitPei/MemoryInitPeiLib.c
@@ -0,0 +1,182 @@
+/** @file
+*
+* Copyright (c) 2011, ARM Limited. All rights reserved.
+*
+* This program and the accompanying materials
+* are licensed and made available under the terms and conditions of the BSD License
+* which accompanies this distribution. The full text of the license may be found at
+* http://opensource.org/licenses/bsd-license.php
+*
+* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#include <PiPei.h>
+
+#include <Library/ArmPlatformLib.h>
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PcdLib.h>
+
+VOID
+BuildMemoryTypeInformationHob (
+ VOID
+ );
+
+VOID
+InitMmu (
+ VOID
+ )
+{
+ ARM_MEMORY_REGION_DESCRIPTOR *MemoryTable;
+ VOID *TranslationTableBase;
+ UINTN TranslationTableSize;
+
+ // Get Virtual Memory Map from the Platform Library
+ ArmPlatformGetVirtualMemoryMap(&MemoryTable);
+
+ //Note: Because we called PeiServicesInstallPeiMemory() before to call InitMmu() the MMU Page Table resides in
+ // DRAM (even at the top of DRAM as it is the first permanent memory allocation)
+ ArmConfigureMmu (MemoryTable, &TranslationTableBase, &TranslationTableSize);
+}
+
+/*++
+
+Routine Description:
+
+
+
+Arguments:
+
+ FileHandle - Handle of the file being invoked.
+ PeiServices - Describes the list of possible PEI Services.
+
+Returns:
+
+ Status - EFI_SUCCESS if the boot mode could be set
+
+--*/
+EFI_STATUS
+EFIAPI
+MemoryPeim (
+ IN EFI_PHYSICAL_ADDRESS UefiMemoryBase,
+ IN UINT64 UefiMemorySize
+ )
+{
+ EFI_RESOURCE_ATTRIBUTE_TYPE ResourceAttributes;
+ UINT64 ResourceLength;
+ EFI_PEI_HOB_POINTERS NextHob;
+ EFI_PHYSICAL_ADDRESS FdTop;
+ EFI_PHYSICAL_ADDRESS SystemMemoryTop;
+ EFI_PHYSICAL_ADDRESS ResourceTop;
+ BOOLEAN Found;
+
+ // Ensure PcdSystemMemorySize has been set
+ ASSERT (PcdGet32 (PcdSystemMemorySize) != 0);
+
+ //
+ // Now, the permanent memory has been installed, we can call AllocatePages()
+ //
+ ResourceAttributes = (
+ EFI_RESOURCE_ATTRIBUTE_PRESENT |
+ EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
+ EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
+ EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
+ EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
+ EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE |
+ EFI_RESOURCE_ATTRIBUTE_TESTED
+ );
+
+ // Reserved the memory space occupied by the firmware volume
+ BuildResourceDescriptorHob (
+ EFI_RESOURCE_MEMORY_MAPPED_IO,
+ EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE,
+ 0x10000000,//PcdGet32 (PcdPmuBase),
+ 0x087FFFFF
+ );
+
+ // Reserved the memory space occupied by the firmware volume
+ BuildResourceDescriptorHob (
+ EFI_RESOURCE_SYSTEM_MEMORY,
+ ResourceAttributes,
+ PcdGet32 (PcdSystemMemoryBase),
+ PcdGet32 (PcdSystemMemorySize)
+ );
+
+ SystemMemoryTop = PcdGet32 (PcdSystemMemoryBase) + PcdGet32 (PcdSystemMemorySize);
+ FdTop = PcdGet32(PcdFdBaseAddress) + PcdGet32(PcdFdSize);
+
+ // EDK2 does not have the concept of boot firmware copied into DRAM. To avoid the DXE
+ // core to overwrite this area we must mark the region with the attribute non-present
+ if ((PcdGet32 (PcdFdBaseAddress) >= PcdGet32 (PcdSystemMemoryBase)) && (FdTop <= SystemMemoryTop)) {
+ Found = FALSE;
+
+ // Search for System Memory Hob that contains the firmware
+ NextHob.Raw = GetHobList ();
+ while ((NextHob.Raw = GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, NextHob.Raw)) != NULL) {
+ if ((NextHob.ResourceDescriptor->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) &&
+ (PcdGet32(PcdFdBaseAddress) >= NextHob.ResourceDescriptor->PhysicalStart) &&
+ (FdTop <= NextHob.ResourceDescriptor->PhysicalStart + NextHob.ResourceDescriptor->ResourceLength))
+ {
+ ResourceAttributes = NextHob.ResourceDescriptor->ResourceAttribute;
+ ResourceLength = NextHob.ResourceDescriptor->ResourceLength;
+ ResourceTop = NextHob.ResourceDescriptor->PhysicalStart + ResourceLength;
+
+ if (PcdGet32(PcdFdBaseAddress) == NextHob.ResourceDescriptor->PhysicalStart) {
+ if (SystemMemoryTop == FdTop) {
+ NextHob.ResourceDescriptor->ResourceAttribute = ResourceAttributes & ~EFI_RESOURCE_ATTRIBUTE_PRESENT;
+ } else {
+ // Create the System Memory HOB for the firmware with the non-present attribute
+ BuildResourceDescriptorHob (EFI_RESOURCE_SYSTEM_MEMORY,
+ ResourceAttributes & ~EFI_RESOURCE_ATTRIBUTE_PRESENT,
+ PcdGet32(PcdFdBaseAddress),
+ PcdGet32(PcdFdSize));
+
+ DEBUG((EFI_D_ERROR, "PcdFdBaseAddress : 0x%X, PcdFdSize: 0x%X\n", PcdGet32(PcdFdBaseAddress),PcdGet32(PcdFdSize)));
+
+ // Top of the FD is system memory available for UEFI
+ NextHob.ResourceDescriptor->PhysicalStart += PcdGet32(PcdFdSize);
+ NextHob.ResourceDescriptor->ResourceLength -= PcdGet32(PcdFdSize);
+ }
+ } else {
+ // Create the System Memory HOB for the firmware with the non-present attribute
+ BuildResourceDescriptorHob (EFI_RESOURCE_SYSTEM_MEMORY,
+ ResourceAttributes & ~EFI_RESOURCE_ATTRIBUTE_PRESENT,
+ PcdGet32(PcdFdBaseAddress),
+ PcdGet32(PcdFdSize));
+ DEBUG((EFI_D_ERROR, "PcdFdBaseAddress : 0x%X, PcdFdSize: 0x%X\n", PcdGet32(PcdFdBaseAddress),PcdGet32(PcdFdSize)));
+
+ // Update the HOB
+ NextHob.ResourceDescriptor->ResourceLength = PcdGet32(PcdFdBaseAddress) - NextHob.ResourceDescriptor->PhysicalStart;
+
+ // If there is some memory available on the top of the FD then create a HOB
+ if (FdTop < NextHob.ResourceDescriptor->PhysicalStart + ResourceLength) {
+ // Create the System Memory HOB for the remaining region (top of the FD)
+ BuildResourceDescriptorHob (EFI_RESOURCE_SYSTEM_MEMORY,
+ ResourceAttributes,
+ FdTop,
+ ResourceTop - FdTop);
+ DEBUG((EFI_D_ERROR, "FdTop : 0x%X, ResourceTop - FdTop : 0x%X\n", FdTop, ResourceTop - FdTop));
+ }
+ }
+ Found = TRUE;
+ break;
+ }
+ NextHob.Raw = GET_NEXT_HOB (NextHob);
+ }
+
+ ASSERT(Found);
+ }
+
+ // Build Memory Allocation Hob
+ InitMmu ();
+
+ if (FeaturePcdGet (PcdPrePiProduceMemoryTypeInformationHob)) {
+ // Optional feature that helps prevent EFI memory map fragmentation.
+ BuildMemoryTypeInformationHob ();
+ }
+
+ return EFI_SUCCESS;
+}
diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/MemoryInitPei/MemoryInitPeiLib.inf b/SamsungPlatformPkg/ExynosPkg/Exynos5250/MemoryInitPei/MemoryInitPeiLib.inf
new file mode 100644
index 000000000..3afbfc8d4
--- /dev/null
+++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/MemoryInitPei/MemoryInitPeiLib.inf
@@ -0,0 +1,69 @@
+#/** @file
+#
+# Copyright (c) 2011, ARM Ltd. All rights reserved.<BR>
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#**/
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = ArmMemoryInitPeiLib
+ FILE_GUID = 55ddb6e0-70b5-11e0-b33e-0002a5d5c51b
+ MODULE_TYPE = SEC
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = PlatformPeiLib
+
+[Sources]
+ MemoryInitPeiLib.c
+
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ EmbeddedPkg/EmbeddedPkg.dec
+ ArmPkg/ArmPkg.dec
+ ArmPlatformPkg/ArmPlatformPkg.dec
+ SamsungPlatformPkg/ExynosPkg/Exynos5250/ExynosPkg.dec
+
+[LibraryClasses]
+ DebugLib
+ HobLib
+ ArmLib
+ ArmPlatformLib
+
+[Guids]
+ gEfiMemoryTypeInformationGuid
+
+[Ppis]
+
+[FeaturePcd]
+ gEmbeddedTokenSpaceGuid.PcdPrePiProduceMemoryTypeInformationHob
+
+[FixedPcd]
+ gArmTokenSpaceGuid.PcdFdBaseAddress
+ gArmTokenSpaceGuid.PcdFdSize
+
+ gArmTokenSpaceGuid.PcdSystemMemoryBase
+ gArmTokenSpaceGuid.PcdSystemMemorySize
+ gArmPlatformTokenSpaceGuid.PcdSystemMemoryUefiRegionSize
+
+ gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiACPIReclaimMemory
+ gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiACPIMemoryNVS
+ gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiReservedMemoryType
+ gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesData
+ gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesCode
+ gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiBootServicesCode
+ gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiBootServicesData
+ gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiLoaderCode
+ gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiLoaderData
+
+ gExynosPkgTokenSpaceGuid.PcdPmuBase
+
+[depex]
+ TRUE
diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/MemoryInitPei/MemoryInitPeim.c b/SamsungPlatformPkg/ExynosPkg/Exynos5250/MemoryInitPei/MemoryInitPeim.c
new file mode 100644
index 000000000..0fc6b4aa9
--- /dev/null
+++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/MemoryInitPei/MemoryInitPeim.c
@@ -0,0 +1,157 @@
+/** @file
+*
+* Copyright (c) 2011, ARM Limited. All rights reserved.
+*
+* This program and the accompanying materials
+* are licensed and made available under the terms and conditions of the BSD License
+* which accompanies this distribution. The full text of the license may be found at
+* http://opensource.org/licenses/bsd-license.php
+*
+* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#include <PiPei.h>
+
+//
+// The protocols, PPI and GUID defintions for this module
+//
+#include <Ppi/MasterBootMode.h>
+#include <Ppi/BootInRecoveryMode.h>
+#include <Guid/MemoryTypeInformation.h>
+//
+// The Library classes this module consumes
+//
+#include <Library/ArmPlatformLib.h>
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/PeimEntryPoint.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/PcdLib.h>
+
+EFI_STATUS
+EFIAPI
+MemoryPeim (
+ IN EFI_PHYSICAL_ADDRESS UefiMemoryBase,
+ IN UINT64 UefiMemorySize
+ );
+
+// May want to put this into a library so you only need the PCD settings if you are using the feature?
+VOID
+BuildMemoryTypeInformationHob (
+ VOID
+ )
+{
+ EFI_MEMORY_TYPE_INFORMATION Info[10];
+
+ Info[0].Type = EfiACPIReclaimMemory;
+ Info[0].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiACPIReclaimMemory);
+ Info[1].Type = EfiACPIMemoryNVS;
+ Info[1].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiACPIMemoryNVS);
+ Info[2].Type = EfiReservedMemoryType;
+ Info[2].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiReservedMemoryType);
+ Info[3].Type = EfiRuntimeServicesData;
+ Info[3].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiRuntimeServicesData);
+ Info[4].Type = EfiRuntimeServicesCode;
+ Info[4].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiRuntimeServicesCode);
+ Info[5].Type = EfiBootServicesCode;
+ Info[5].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiBootServicesCode);
+ Info[6].Type = EfiBootServicesData;
+ Info[6].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiBootServicesData);
+ Info[7].Type = EfiLoaderCode;
+ Info[7].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiLoaderCode);
+ Info[8].Type = EfiLoaderData;
+ Info[8].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiLoaderData);
+
+ DEBUG ((EFI_D_ERROR, "BuildMemoryTypeInformationHob PcdMemoryTypeEfiRuntimeServicesCode: %d, PcdMemoryTypeEfiRuntimeServicesData: %d\n", Info[4].NumberOfPages, Info[3].NumberOfPages));
+ // Terminator for the list
+ Info[9].Type = EfiMaxMemoryType;
+ Info[9].NumberOfPages = 0;
+
+ BuildGuidDataHob (&gEfiMemoryTypeInformationGuid, &Info, sizeof (Info));
+}
+
+/*++
+
+Routine Description:
+
+
+
+Arguments:
+
+ FileHandle - Handle of the file being invoked.
+ PeiServices - Describes the list of possible PEI Services.
+
+Returns:
+
+ Status - EFI_SUCCESS if the boot mode could be set
+
+--*/
+EFI_STATUS
+EFIAPI
+InitializeMemory (
+ IN EFI_PEI_FILE_HANDLE FileHandle,
+ IN CONST EFI_PEI_SERVICES **PeiServices
+ )
+{
+ EFI_STATUS Status;
+ UINTN SystemMemoryBase;
+ UINTN SystemMemoryTop;
+ UINTN FdBase;
+ UINTN FdTop;
+ UINTN UefiMemoryBase;
+
+ DEBUG ((EFI_D_ERROR, "Memory Init PEIM Loaded\n"));
+
+ // Ensure PcdSystemMemorySize has been set
+ ASSERT (FixedPcdGet32 (PcdSystemMemorySize) != 0);
+
+ SystemMemoryBase = (UINTN)FixedPcdGet32 (PcdSystemMemoryBase);
+ SystemMemoryTop = SystemMemoryBase + (UINTN)FixedPcdGet32 (PcdSystemMemorySize);
+ FdBase = (UINTN)PcdGet32 (PcdFdBaseAddress);
+ FdTop = FdBase + (UINTN)PcdGet32 (PcdFdSize);
+
+ DEBUG ((EFI_D_ERROR, "SystemMemoryBase : 0x%X, SystemMemoryTop : 0x%X, FdBase : 0x%X, FdTop : 0x%X\n", SystemMemoryBase, SystemMemoryTop, FdBase, FdTop));
+ //
+ // Initialize the System Memory (DRAM)
+ //
+ if (!FeaturePcdGet (PcdSystemMemoryInitializeInSec)) {
+ // In case the DRAM has not been initialized by the secure firmware
+ ArmPlatformInitializeSystemMemory ();
+ }
+
+ //
+ // Declare the UEFI memory to PEI
+ //
+
+ // In case the firmware has been shadowed in the System Memory
+ if ((FdBase >= SystemMemoryBase) && (FdTop <= SystemMemoryTop)) {
+ // Check if there is enough space between the top of the system memory and the top of the
+ // firmware to place the UEFI memory (for PEI & DXE phases)
+ if (SystemMemoryTop - FdTop >= FixedPcdGet32 (PcdSystemMemoryUefiRegionSize)) {
+ UefiMemoryBase = SystemMemoryTop - FixedPcdGet32 (PcdSystemMemoryUefiRegionSize);
+ } else {
+ // Check there is enough space for the UEFI memory
+ ASSERT (SystemMemoryBase + FixedPcdGet32 (PcdSystemMemoryUefiRegionSize) <= FdBase);
+
+ UefiMemoryBase = FdBase - FixedPcdGet32 (PcdSystemMemoryUefiRegionSize);
+ }
+ } else {
+ // Check the Firmware does not overlapped with the system memory
+ ASSERT ((FdBase < SystemMemoryBase) || (FdBase >= SystemMemoryTop));
+ ASSERT ((FdTop <= SystemMemoryBase) || (FdTop > SystemMemoryTop));
+
+ UefiMemoryBase = SystemMemoryTop - FixedPcdGet32 (PcdSystemMemoryUefiRegionSize);
+ }
+
+ DEBUG ((EFI_D_ERROR, "UefiMemoryBase : 0x%X, PcdSystemMemoryUefiRegionSize : 0x%X\n", UefiMemoryBase, FixedPcdGet32(PcdSystemMemoryUefiRegionSize)));
+ Status = PeiServicesInstallPeiMemory (UefiMemoryBase, FixedPcdGet32 (PcdSystemMemoryUefiRegionSize));
+ ASSERT_EFI_ERROR (Status);
+
+ // Initialize MMU and Memory HOBs (Resource Descriptor HOBs)
+ Status = MemoryPeim (UefiMemoryBase, FixedPcdGet32 (PcdSystemMemoryUefiRegionSize));
+ ASSERT_EFI_ERROR (Status);
+
+ return Status;
+}
diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/MemoryInitPei/MemoryInitPeim.inf b/SamsungPlatformPkg/ExynosPkg/Exynos5250/MemoryInitPei/MemoryInitPeim.inf
new file mode 100644
index 000000000..23d245ef1
--- /dev/null
+++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/MemoryInitPei/MemoryInitPeim.inf
@@ -0,0 +1,75 @@
+#/** @file
+#
+# Copyright (c) 2011, ARM Ltd. All rights reserved.<BR>
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#**/
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = MemoryInit
+ FILE_GUID = c61ef796-b50d-4f98-9f78-4f6f79d800d5
+ MODULE_TYPE = PEIM
+ VERSION_STRING = 1.0
+
+ ENTRY_POINT = InitializeMemory
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF EBC ARM
+#
+
+[Sources]
+ MemoryInitPeim.c
+ MemoryInitPeiLib.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ EmbeddedPkg/EmbeddedPkg.dec
+ ArmPkg/ArmPkg.dec
+ ArmPlatformPkg/ArmPlatformPkg.dec
+ SamsungPlatformPkg/ExynosPkg/Exynos5250/ExynosPkg.dec
+
+[LibraryClasses]
+ PeimEntryPoint
+ DebugLib
+ HobLib
+ ArmLib
+ ArmPlatformLib
+
+[Guids]
+ gEfiMemoryTypeInformationGuid
+
+[FeaturePcd]
+ gEmbeddedTokenSpaceGuid.PcdPrePiProduceMemoryTypeInformationHob
+ gArmPlatformTokenSpaceGuid.PcdSystemMemoryInitializeInSec
+
+[FixedPcd]
+ gArmTokenSpaceGuid.PcdFdBaseAddress
+ gArmTokenSpaceGuid.PcdFdSize
+
+ gArmTokenSpaceGuid.PcdSystemMemoryBase
+ gArmTokenSpaceGuid.PcdSystemMemorySize
+ gArmPlatformTokenSpaceGuid.PcdSystemMemoryUefiRegionSize
+
+ gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiACPIReclaimMemory
+ gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiACPIMemoryNVS
+ gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiReservedMemoryType
+ gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesData
+ gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesCode
+ gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiBootServicesCode
+ gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiBootServicesData
+ gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiLoaderCode
+ gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiLoaderData
+
+ gExynosPkgTokenSpaceGuid.PcdPmuBase
+[Depex]
+ TRUE
diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/PlatformPei/PlatformPeiLib.c b/SamsungPlatformPkg/ExynosPkg/Exynos5250/PlatformPei/PlatformPeiLib.c
new file mode 100644
index 000000000..813c1d349
--- /dev/null
+++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/PlatformPei/PlatformPeiLib.c
@@ -0,0 +1,30 @@
+/** @file
+*
+* Copyright (c) 2011-2012, ARM Limited. All rights reserved.
+*
+* This program and the accompanying materials
+* are licensed and made available under the terms and conditions of the BSD License
+* which accompanies this distribution. The full text of the license may be found at
+* http://opensource.org/licenses/bsd-license.php
+*
+* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#include <PiPei.h>
+
+#include <Library/ArmPlatformLib.h>
+#include <Library/HobLib.h>
+#include <Library/PcdLib.h>
+
+EFI_STATUS
+EFIAPI
+PlatformPeim (
+ VOID
+ )
+{
+ BuildFvHob (PcdGet32(PcdFvBaseAddress), PcdGet32(PcdFvSize));
+
+ return EFI_SUCCESS;
+}
diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/PlatformPei/PlatformPeiLib.inf b/SamsungPlatformPkg/ExynosPkg/Exynos5250/PlatformPei/PlatformPeiLib.inf
new file mode 100644
index 000000000..01f935952
--- /dev/null
+++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/PlatformPei/PlatformPeiLib.inf
@@ -0,0 +1,53 @@
+#/** @file
+#
+# Copyright (c) 2011-2012, ARM Limited. All rights reserved.
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#**/
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = ArmPlatformPeiLib
+ FILE_GUID = 49d37060-70b5-11e0-aa2d-0002a5d5c51b
+ MODULE_TYPE = SEC
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = PlatformPeiLib
+
+[Sources]
+ PlatformPeiLib.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ EmbeddedPkg/EmbeddedPkg.dec
+ ArmPkg/ArmPkg.dec
+ ArmPlatformPkg/ArmPlatformPkg.dec
+
+[LibraryClasses]
+ DebugLib
+ HobLib
+ ArmPlatformLib
+
+[Ppis]
+ gEfiPeiMasterBootModePpiGuid # PPI ALWAYS_PRODUCED
+ gEfiPeiBootInRecoveryModePpiGuid # PPI SOMETIMES_PRODUCED
+
+[FixedPcd]
+ gArmTokenSpaceGuid.PcdFdBaseAddress
+ gArmTokenSpaceGuid.PcdFdSize
+
+ gArmTokenSpaceGuid.PcdFvBaseAddress
+ gArmTokenSpaceGuid.PcdFvSize
+
+ gEmbeddedTokenSpaceGuid.PcdPrePiCpuMemorySize
+ gEmbeddedTokenSpaceGuid.PcdPrePiCpuIoSize
+
+[depex]
+ TRUE
diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/PlatformPei/PlatformPeim.c b/SamsungPlatformPkg/ExynosPkg/Exynos5250/PlatformPei/PlatformPeim.c
new file mode 100644
index 000000000..8663409ed
--- /dev/null
+++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/PlatformPei/PlatformPeim.c
@@ -0,0 +1,138 @@
+/** @file
+*
+* Copyright (c) 2011, ARM Limited. All rights reserved.
+*
+* This program and the accompanying materials
+* are licensed and made available under the terms and conditions of the BSD License
+* which accompanies this distribution. The full text of the license may be found at
+* http://opensource.org/licenses/bsd-license.php
+*
+* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#include <PiPei.h>
+
+//
+// The protocols, PPI and GUID defintions for this module
+//
+#include <Ppi/ArmGlobalVariable.h>
+#include <Ppi/MasterBootMode.h>
+#include <Ppi/BootInRecoveryMode.h>
+#include <Ppi/GuidedSectionExtraction.h>
+//
+// The Library classes this module consumes
+//
+#include <Library/ArmPlatformLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/PeimEntryPoint.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/PcdLib.h>
+
+#include <Guid/ArmGlobalVariableHob.h>
+
+EFI_STATUS
+EFIAPI
+InitializePlatformPeim (
+ IN EFI_PEI_FILE_HANDLE FileHandle,
+ IN CONST EFI_PEI_SERVICES **PeiServices
+ );
+
+EFI_STATUS
+EFIAPI
+PlatformPeim (
+ VOID
+ );
+
+//
+// Module globals
+//
+EFI_PEI_PPI_DESCRIPTOR mPpiListBootMode = {
+ (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gEfiPeiMasterBootModePpiGuid,
+ NULL
+};
+
+EFI_PEI_PPI_DESCRIPTOR mPpiListRecoveryBootMode = {
+ (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gEfiPeiBootInRecoveryModePpiGuid,
+ NULL
+};
+
+VOID
+EFIAPI
+BuildGlobalVariableHob (
+ IN EFI_PHYSICAL_ADDRESS GlobalVariableBase,
+ IN UINT32 GlobalVariableSize
+ )
+{
+ EFI_STATUS Status;
+ ARM_HOB_GLOBAL_VARIABLE *Hob;
+
+ Status = PeiServicesCreateHob (EFI_HOB_TYPE_GUID_EXTENSION, sizeof (ARM_HOB_GLOBAL_VARIABLE), (VOID**)&Hob);
+ if (!EFI_ERROR(Status)) {
+ CopyGuid (&(Hob->Header.Name), &gArmGlobalVariableGuid);
+ Hob->GlobalVariableBase = GlobalVariableBase;
+ Hob->GlobalVariableSize = GlobalVariableSize;
+ }
+}
+
+/*++
+
+Routine Description:
+
+
+
+Arguments:
+
+ FileHandle - Handle of the file being invoked.
+ PeiServices - Describes the list of possible PEI Services.
+
+Returns:
+
+ Status - EFI_SUCCESS if the boot mode could be set
+
+--*/
+EFI_STATUS
+EFIAPI
+InitializePlatformPeim (
+ IN EFI_PEI_FILE_HANDLE FileHandle,
+ IN CONST EFI_PEI_SERVICES **PeiServices
+ )
+{
+ EFI_STATUS Status;
+ UINTN BootMode;
+ ARM_GLOBAL_VARIABLE_PPI *ArmGlobalVariablePpi;
+ EFI_PHYSICAL_ADDRESS GlobalVariableBase;
+
+ DEBUG ((EFI_D_ERROR, "Platform PEIM Loaded\n"));
+
+ PlatformPeim ();
+
+ Status = PeiServicesLocatePpi (&gArmGlobalVariablePpiGuid, 0, NULL, (VOID**)&ArmGlobalVariablePpi);
+ if (!EFI_ERROR(Status)) {
+ Status = ArmGlobalVariablePpi->GetGlobalVariableMemory (&GlobalVariableBase);
+
+ if (!EFI_ERROR(Status)) {
+ // Declare the Global Variable HOB
+ BuildGlobalVariableHob (GlobalVariableBase, FixedPcdGet32 (PcdPeiGlobalVariableSize));
+ }
+ }
+
+ BootMode = ArmPlatformGetBootMode ();
+ Status = (**PeiServices).SetBootMode (PeiServices, (UINT8) BootMode);
+ ASSERT_EFI_ERROR (Status);
+
+ Status = (**PeiServices).InstallPpi (PeiServices, &mPpiListBootMode);
+ ASSERT_EFI_ERROR (Status);
+
+ if (BootMode == BOOT_IN_RECOVERY_MODE) {
+ Status = (**PeiServices).InstallPpi (PeiServices, &mPpiListRecoveryBootMode);
+ ASSERT_EFI_ERROR (Status);
+ }
+
+ return Status;
+}
diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/PlatformPei/PlatformPeim.inf b/SamsungPlatformPkg/ExynosPkg/Exynos5250/PlatformPei/PlatformPeim.inf
new file mode 100755
index 000000000..cd1cd7a51
--- /dev/null
+++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/PlatformPei/PlatformPeim.inf
@@ -0,0 +1,69 @@
+#/** @file
+#
+# Copyright (c) 2011-2012, ARM Limited. All rights reserved.
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#**/
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = PlatformPei
+ FILE_GUID = 2ad0fc59-2314-4bf3-8633-13fa22a624a0
+ MODULE_TYPE = PEIM
+ VERSION_STRING = 1.0
+
+ ENTRY_POINT = InitializePlatformPeim
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF EBC ARM
+#
+
+[Sources]
+ PlatformPeim.c
+ PlatformPeiLib.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ EmbeddedPkg/EmbeddedPkg.dec
+ ArmPkg/ArmPkg.dec
+ ArmPlatformPkg/ArmPlatformPkg.dec
+
+[LibraryClasses]
+ PeimEntryPoint
+ DebugLib
+ HobLib
+ ArmPlatformLib
+
+[Ppis]
+ gEfiPeiMasterBootModePpiGuid # PPI ALWAYS_PRODUCED
+ gEfiPeiBootInRecoveryModePpiGuid # PPI SOMETIMES_PRODUCED
+ gArmGlobalVariablePpiGuid
+
+[Guids]
+ gArmGlobalVariableGuid
+
+[FixedPcd]
+ gArmTokenSpaceGuid.PcdFdBaseAddress
+ gArmTokenSpaceGuid.PcdFdSize
+
+ gArmTokenSpaceGuid.PcdFvBaseAddress
+ gArmTokenSpaceGuid.PcdFvSize
+
+ gEmbeddedTokenSpaceGuid.PcdPrePiCpuMemorySize
+ gEmbeddedTokenSpaceGuid.PcdPrePiCpuIoSize
+
+ gArmPlatformTokenSpaceGuid.PcdPeiGlobalVariableSize
+
+[Depex]
+ TRUE
+
diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Sec/Helper.S b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Sec/Helper.S
new file mode 100644
index 000000000..ad53ab320
--- /dev/null
+++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Sec/Helper.S
@@ -0,0 +1,84 @@
+#========================================================================================
+# Copyright (c) 2011-2012, ARM Limited. All rights reserved.
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http:#opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#=======================================================================================
+
+#start of the code section
+.text
+.align 3
+
+GCC_ASM_EXPORT(return_from_exception)
+GCC_ASM_EXPORT(enter_monitor_mode)
+GCC_ASM_EXPORT(copy_cpsr_into_spsr)
+GCC_ASM_EXPORT(set_non_secure_mode)
+
+# r0: Monitor World EntryPoint
+# r1: MpId
+# r2: Secure Monitor mode stack
+ASM_PFX(enter_monitor_mode):
+ cmp r2, #0 @ If a Secure Monitor stack base has not been defined then use the Secure stack
+ moveq r2, sp
+
+ mrs r4, cpsr @ Save current mode (SVC) in r4
+ bic r3, r4, #0x1f @ Clear all mode bits
+ orr r3, r3, #0x16 @ Set bits for Monitor mode
+ msr cpsr_cxsf, r3 @ We are now in Monitor Mode
+
+ mov sp, r2 @ Set the stack of the Monitor Mode
+
+ mov lr, r0 @ Use the pass entrypoint as lr
+
+ msr spsr_cxsf, r4 @ Use saved mode for the MOVS jump to the kernel
+
+ mov r4, r0 @ Swap EntryPoint and MpId registers
+ mov r0, r1
+
+ bx r4
+
+# We cannot use the instruction 'movs pc, lr' because the caller can be written either in ARM or Thumb2 assembler.
+# When we will jump into this function, we will set the CPSR flag to ARM assembler. By copying directly 'lr' into
+# 'pc'; we will not change the CPSR flag and it will crash.
+# The way to fix this limitation is to do the movs into the ARM assmbler code and then do a 'bx'.
+ASM_PFX(return_from_exception):
+ ldr lr, returned_exception
+
+ #The following instruction breaks the code.
+ #movs pc, lr
+ mrs r2, cpsr
+ bic r2, r2, #0x1f
+ orr r2, r2, #0x13
+ msr cpsr_c, r2
+
+returned_exception: @ We are now in non-secure state
+ bx r0
+
+# Save the current Program Status Register (PSR) into the Saved PSR
+ASM_PFX(copy_cpsr_into_spsr):
+ mrs r0, cpsr
+ msr spsr_cxsf, r0
+ bx lr
+
+# Set the Non Secure Mode
+ASM_PFX(set_non_secure_mode):
+ push { r1 }
+ and r0, r0, #0x1f @ Keep only the mode bits
+ mrs r1, spsr @ Read the spsr
+ bic r1, r1, #0x1f @ Clear all mode bits
+ orr r1, r1, r0
+ msr spsr_cxsf, r1 @ write back spsr (may have caused a mode switch)
+ isb
+ pop { r1 }
+ bx lr @ return (hopefully thumb-safe!)
+
+dead:
+ b dead
+
+ASM_FUNCTION_REMOVE_IF_UNREFERENCED
diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Sec/Helper.asm b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Sec/Helper.asm
new file mode 100644
index 000000000..c4eaec1a7
--- /dev/null
+++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Sec/Helper.asm
@@ -0,0 +1,75 @@
+//
+// Copyright (c) 2011-2012, ARM Limited. All rights reserved.
+//
+// This program and the accompanying materials
+// are licensed and made available under the terms and conditions of the BSD License
+// which accompanies this distribution. The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+//
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+//
+
+ EXPORT return_from_exception
+ EXPORT enter_monitor_mode
+ EXPORT copy_cpsr_into_spsr
+ EXPORT set_non_secure_mode
+
+ AREA Helper, CODE, READONLY
+
+// r0: Monitor World EntryPoint
+// r1: MpId
+// r2: Secure Monitor mode stack
+enter_monitor_mode
+ cmp r2, #0 // If a Secure Monitor stack base has not been defined then use the Secure stack
+ moveq r2, sp
+
+ mrs r4, cpsr // Save current mode (SVC) in r4
+ bic r3, r4, #0x1f // Clear all mode bits
+ orr r3, r3, #0x16 // Set bits for Monitor mode
+ msr cpsr_cxsf, r3 // We are now in Monitor Mode
+
+ mov sp, r2 // Set the stack of the Monitor Mode
+
+ mov lr, r0 // Use the pass entrypoint as lr
+
+ msr spsr_cxsf, r4 // Use saved mode for the MOVS jump to the kernel
+
+ mov r4, r0 // Swap EntryPoint and MpId registers
+ mov r0, r1
+
+ bx r4
+
+// We cannot use the instruction 'movs pc, lr' because the caller can be written either in ARM or Thumb2 assembler.
+// When we will jump into this function, we will set the CPSR flag to ARM assembler. By copying directly 'lr' into
+// 'pc'; we will not change the CPSR flag and it will crash.
+// The way to fix this limitation is to do the movs into the ARM assmbler code and then do a 'bx'.
+return_from_exception
+ adr lr, returned_exception
+ movs pc, lr
+returned_exception // We are now in non-secure state
+ bx r0
+
+// Save the current Program Status Register (PSR) into the Saved PSR
+copy_cpsr_into_spsr
+ mrs r0, cpsr
+ msr spsr_cxsf, r0
+ bx lr
+
+// Set the Non Secure Mode
+set_non_secure_mode
+ push { r1 }
+ and r0, r0, #0x1f // Keep only the mode bits
+ mrs r1, spsr // Read the spsr
+ bic r1, r1, #0x1f // Clear all mode bits
+ orr r1, r1, r0
+ msr spsr_cxsf, r1 // write back spsr (may have caused a mode switch)
+ isb
+ pop { r1 }
+ bx lr // return (hopefully thumb-safe!)
+
+dead
+ B dead
+
+ END
diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Sec/Sec.c b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Sec/Sec.c
new file mode 100644
index 000000000..3c4f4983f
--- /dev/null
+++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Sec/Sec.c
@@ -0,0 +1,222 @@
+/** @file
+* Main file supporting the SEC Phase on ARM Platforms
+*
+* Copyright (c) 2011-2012, ARM Limited. All rights reserved.
+*
+* This program and the accompanying materials
+* are licensed and made available under the terms and conditions of the BSD License
+* which accompanies this distribution. The full text of the license may be found at
+* http://opensource.org/licenses/bsd-license.php
+*
+* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#include <Library/ArmTrustedMonitorLib.h>
+#include <Library/DebugAgentLib.h>
+#include <Library/PrintLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/SerialPortLib.h>
+#include <Library/ArmGicLib.h>
+#include <Library/ArmCpuLib.h>
+#include <Library/IoLib.h>
+#include <Library/ArmPlatformLib.h>
+#include "SecInternal.h"
+#include "Smc.h"
+
+#define SerialPrint(txt) SerialPortWrite ((UINT8*)txt, AsciiStrLen(txt)+1);
+
+extern VOID *monitor_vector_table;
+
+#define ISRAM_ADDRESS 0x02020000
+#define EXTERNAL_FUNC_ADDRESS (ISRAM_ADDRESS + 0x0030)
+#define MSH_ReadFromFIFO_eMMC_ADDRESS (EXTERNAL_FUNC_ADDRESS + 0x14)
+#define MSH_EndBootOp_eMMC_ADDRESS (EXTERNAL_FUNC_ADDRESS + 0x18)
+
+#define SDMMC_ReadBlocks(uStartBlk, uNumOfBlks, uDstAddr) \
+ (((VOID(*)(UINT32, UINT32, UINT32*))(*((UINT32 *)EXTERNAL_FUNC_ADDRESS)))(uStartBlk, uNumOfBlks, uDstAddr))
+
+#define EMMC_ReadBlocks(uNumOfBlks, uDstAddr) \
+ (((VOID(*)(UINT32, UINT32*))(*((UINT32 *)MSH_ReadFromFIFO_eMMC_ADDRESS)))(uNumOfBlks, uDstAddr))
+
+#define EMMC_EndBootOp() \
+ (((VOID(*)())(*((UINT32 *)MSH_EndBootOp_eMMC_ADDRESS)))())
+
+VOID CopyFirmwareFromSDMMC(VOID)
+{
+ SDMMC_ReadBlocks(49, ((1536*1024)/512), (UINT32 *)0x40000000);
+}
+
+VOID CopyFirmwareFromEMMC(VOID)
+{
+ if (FixedPcdGetBool (PcdTrustzoneSupport)) {
+ load_uefi_image(EMMC);
+ } else {
+ EMMC_ReadBlocks(((1536*1024)/512), (UINT32 *)0x40000000);
+ EMMC_EndBootOp();
+ }
+}
+
+VOID ColdBootForTzsw(UINT32 StartupAddr)
+{
+ coldboot(EMMC, StartupAddr);
+}
+
+VOID
+CEntryPoint (
+ IN UINTN MpId
+ )
+{
+ CHAR8 Buffer[100];
+ UINTN CharCount;
+ UINTN JumpAddress;
+
+ if (!FixedPcdGetBool (PcdTrustzoneSupport)) {
+ // Invalidate the data cache. Doesn't have to do the Data cache clean.
+ ArmInvalidateDataCache();
+
+ // Invalidate Instruction Cache
+ ArmInvalidateInstructionCache();
+
+ // Invalidate I & D TLBs
+ ArmInvalidateInstructionAndDataTlb();
+
+ // CPU specific settings
+ ArmCpuSetup (MpId);
+
+ // Enable Floating Point Coprocessor if supported by the platform
+ if (FixedPcdGet32 (PcdVFPEnabled)) {
+ ArmEnableVFP();
+ }
+ // Initialize peripherals that must be done at the early stage
+ // Example: Some L2 controller, interconnect, clock, DMC, etc
+ ArmPlatformSecInitialize (MpId);
+ }
+
+ // Primary CPU clears out the SCU tag RAMs, secondaries wait
+ if (ArmPlatformIsPrimaryCore (MpId)) {
+ if (ArmIsMpCore()) {
+ // Is UEFI built as it is assumed that TZSW is running?
+ // PcdTrustzoneSupport==1: YES.
+ // PcdTrustzoneSupport==1: NO. UEFI is built as it is assumed that TZSW is not needed.
+ if (FixedPcdGetBool (PcdTrustzoneSupport)) {
+ // IS UEFI executed after TZSW ran? (In other words, UEFI is fuzed and running?
+ // ArmReadNsacr()==1: YES.
+ // ArmReadNsacr()!=1: No. UEFI(assumed TZSW is running) is executed after uploaded with T32(not fuzed)
+ if(ArmReadNsacr()) {
+ exynos_smc(SMC_CMD_CPU1BOOT, 0, 0, 0);
+ }
+ }
+ }
+
+ // SEC phase needs to run library constructors by hand. This assumes we are linked against the SerialLib
+ // In non SEC modules the init call is in autogenerated code.
+ SerialPortInitialize ();
+
+ // Start talking
+ if (FixedPcdGetBool (PcdTrustzoneSupport)) {
+ CharCount = AsciiSPrint (Buffer,sizeof (Buffer),"Secure firmware (version %s built at %a on %a)\n\r",
+ (CHAR16*)PcdGetPtr(PcdFirmwareVersionString), __TIME__, __DATE__);
+ } else {
+ CharCount = AsciiSPrint (Buffer,sizeof (Buffer),"Boot firmware (version %s built at %a on %a)\n\r",
+ (CHAR16*)PcdGetPtr(PcdFirmwareVersionString), __TIME__, __DATE__);
+ }
+ SerialPortWrite ((UINT8 *) Buffer, CharCount);
+
+ // Initialize the Debug Agent for Source Level Debugging
+ InitializeDebugAgent (DEBUG_AGENT_INIT_PREMEM_SEC, NULL, NULL);
+ SaveAndSetDebugTimerInterrupt (TRUE);
+
+ // Enable the GIC distributor and CPU Interface
+ // - no other Interrupts are enabled, doesn't have to worry about the priority.
+ // - all the cores are in secure state, use secure SGI's
+ ArmGicEnableDistributor (PcdGet32(PcdGicDistributorBase));
+ ArmGicEnableInterruptInterface (PcdGet32(PcdGicInterruptInterfaceBase));
+
+ } else {
+ // Enable the GIC CPU Interface
+ ArmGicEnableInterruptInterface (PcdGet32(PcdGicInterruptInterfaceBase));
+ }
+
+ // Enable Full Access to CoProcessors
+ ArmWriteCpacr (CPACR_CP_FULL_ACCESS);
+
+ // With Trustzone support the transition from Sec to Normal world is done by return_from_exception().
+ // If we want to keep this function call we need to ensure the SVC's SPSR point to the same Program
+ // Status Register as the the current one (CPSR).
+ copy_cpsr_into_spsr ();
+
+ // Call the Platform specific function to execute additional actions if required
+ JumpAddress = PcdGet32 (PcdFvBaseAddress);
+ ArmPlatformSecExtraAction (MpId, &JumpAddress);
+
+ NonTrustedWorldTransition (MpId, JumpAddress);
+
+ ASSERT (0); // We must never return from the above function
+}
+
+VOID
+TrustedWorldInitialization (
+ IN UINTN MpId
+ )
+{
+ UINTN JumpAddress;
+
+ //-------------------- Monitor Mode ---------------------
+
+ // Set up Monitor World (Vector Table, etc)
+ ArmSecureMonitorWorldInitialize ();
+
+ // Transfer the interrupt to Non-secure World
+ ArmGicSetupNonSecure (MpId, PcdGet32(PcdGicDistributorBase), PcdGet32(PcdGicInterruptInterfaceBase));
+
+ // Initialize platform specific security policy
+ ArmPlatformSecTrustzoneInit (MpId);
+
+ // Setup the Trustzone Chipsets
+ if (ArmPlatformIsPrimaryCore (MpId)) {
+ if (ArmIsMpCore()) {
+ // Signal the secondary core the Security settings is done (event: EVENT_SECURE_INIT)
+ ArmCallSEV ();
+ }
+ } else {
+ // The secondary cores need to wait until the Trustzone chipsets configuration is done
+ // before switching to Non Secure World
+
+ // Wait for the Primary Core to finish the initialization of the Secure World (event: EVENT_SECURE_INIT)
+ ArmCallWFE ();
+ }
+
+ // Call the Platform specific function to execute additional actions if required
+ JumpAddress = PcdGet32 (PcdFvBaseAddress);
+ ArmPlatformSecExtraAction (MpId, &JumpAddress);
+
+ // Write to CP15 Non-secure Access Control Register
+ ArmWriteNsacr (PcdGet32 (PcdArmNsacr));
+
+ // CP15 Secure Configuration Register
+ ArmWriteScr (PcdGet32 (PcdArmScr));
+
+ NonTrustedWorldTransition (MpId, JumpAddress);
+}
+
+VOID
+NonTrustedWorldTransition (
+ IN UINTN MpId,
+ IN UINTN JumpAddress
+ )
+{
+ // If PcdArmNonSecModeTransition is defined then set this specific mode to CPSR before the transition
+ // By not set, the mode for Non Secure World is SVC
+ if (PcdGet32 (PcdArmNonSecModeTransition) != 0) {
+ set_non_secure_mode ((ARM_PROCESSOR_MODE)PcdGet32 (PcdArmNonSecModeTransition));
+ }
+
+ return_from_exception (JumpAddress);
+ //-------------------- Non Secure Mode ---------------------
+
+ // PEI Core should always load and never return
+ ASSERT (FALSE);
+}
+
diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Sec/Sec.inf b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Sec/Sec.inf
new file mode 100644
index 000000000..1cda8c3ad
--- /dev/null
+++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Sec/Sec.inf
@@ -0,0 +1,85 @@
+#/** @file
+# SEC - Reset vector code that jumps to C and loads DXE core
+#
+# Copyright (c) 2011, ARM Limited. All rights reserved.
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#**/
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = ArmPlatformSec
+ FILE_GUID = c536bbfe-c813-4e48-9f90-01fe1ecf9d54
+ MODULE_TYPE = SEC
+ VERSION_STRING = 1.0
+
+[Sources.ARM]
+ Helper.asm | RVCT
+ Helper.S | GCC
+ Sec.c
+ SecEntryPoint.S | GCC
+ SecEntryPoint.asm | RVCT
+ Smc.c
+ SecFromTzsw.S | GCC
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ ArmPkg/ArmPkg.dec
+ ArmPlatformPkg/ArmPlatformPkg.dec
+ SamsungPlatformPkg/ExynosPkg/Exynos5250/ExynosPkg.dec
+
+[LibraryClasses]
+ ArmCpuLib
+ ArmLib
+ ArmPlatformSecLib
+ ArmTrustedMonitorLib
+ BaseLib
+ DebugLib
+ DebugAgentLib
+ IoLib
+ ArmGicLib
+ PrintLib
+ SerialPortLib
+
+[FeaturePcd]
+ gArmPlatformTokenSpaceGuid.PcdSystemMemoryInitializeInSec
+
+[FixedPcd]
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVersionString
+
+ gArmTokenSpaceGuid.PcdTrustzoneSupport
+ gArmTokenSpaceGuid.PcdVFPEnabled
+
+ gArmTokenSpaceGuid.PcdArmScr
+ gArmTokenSpaceGuid.PcdArmNsacr
+ gArmTokenSpaceGuid.PcdArmNonSecModeTransition
+
+ gArmTokenSpaceGuid.PcdSecureFvBaseAddress
+ gArmTokenSpaceGuid.PcdSecureFvSize
+
+ gArmTokenSpaceGuid.PcdFvBaseAddress
+ gArmTokenSpaceGuid.PcdFdBaseAddress
+
+ gArmPlatformTokenSpaceGuid.PcdCPUCoresSecStackBase
+ gArmPlatformTokenSpaceGuid.PcdCPUCoreSecPrimaryStackSize
+ gArmPlatformTokenSpaceGuid.PcdCPUCoreSecSecondaryStackSize
+ gArmPlatformTokenSpaceGuid.PcdCPUCoresSecMonStackBase
+ gArmPlatformTokenSpaceGuid.PcdCPUCoreSecMonStackSize
+
+ gArmTokenSpaceGuid.PcdGicDistributorBase
+ gArmTokenSpaceGuid.PcdGicInterruptInterfaceBase
+
+ gArmPlatformTokenSpaceGuid.PcdSecGlobalVariableSize
+
+ gExynosPkgTokenSpaceGuid.PcdMpSharedArgsBase
+
+ gExynosPkgTokenSpaceGuid.PcdiRamStackBase
+ gExynosPkgTokenSpaceGuid.PcdiRamStackSize
diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Sec/SecEntryPoint.S b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Sec/SecEntryPoint.S
new file mode 100644
index 000000000..aecbc939f
--- /dev/null
+++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Sec/SecEntryPoint.S
@@ -0,0 +1,287 @@
+//
+// Copyright (c) 2011-2012, ARM Limited. All rights reserved.
+//
+// This program and the accompanying materials
+// are licensed and made available under the terms and conditions of the BSD License
+// which accompanies this distribution. The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+//
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+//
+
+#include <AutoGen.h>
+#include <AsmMacroIoLib.h>
+#include <Library/ArmPlatformLib.h>
+#include <ArmPlatform.h>
+#include "SecInternal.h"
+
+.text
+.align 3
+
+GCC_ASM_IMPORT(CEntryPoint)
+GCC_ASM_IMPORT(ArmPlatformIsPrimaryCore)
+GCC_ASM_IMPORT(CopyFirmwareFromEMMC)
+GCC_ASM_IMPORT(CopyFirmwareFromSDMMC)
+GCC_ASM_IMPORT(ArmPlatformClockInitialize)
+GCC_ASM_IMPORT(ArmPlatformSecBootAction)
+GCC_ASM_IMPORT(ArmPlatformSecBootMemoryInit)
+GCC_ASM_IMPORT(ArmDisableInterrupts)
+GCC_ASM_IMPORT(ArmDisableCachesAndMmu)
+GCC_ASM_IMPORT(ArmEnableBranchPrediction)
+GCC_ASM_IMPORT(ArmReadMpidr)
+GCC_ASM_IMPORT(ArmCallWFE)
+GCC_ASM_IMPORT(_SecEntryFromTzsw)
+GCC_ASM_EXPORT(_ModuleEntryPoint)
+
+SecStartupAddr: .word ASM_PFX(_SecEntryFromTzsw)
+StartupAddr: .word ASM_PFX(CEntryPoint)
+
+// Convert the (ClusterId,CoreId) into a Core Position
+// 0x0F03 is the magic value for ARM_CORE_MASK | ARM_CLUSTER_MASK
+//Core is 0-1 bits and cluster is 8-11 bits
+#define GetCorePositionFromMpId(Pos, MpId, Tmp) \
+ ldr Tmp, =0x0F03 ; \
+ and MpId, Tmp ; \
+ lsr Pos, MpId, #6 ; \
+ and Tmp, MpId, #3 ; \
+ add Pos, Pos, Tmp
+
+// Reserve a region at the top of the IRAM Core stack
+// for Global variables for the XIP phase
+#define SetiRamStack(StackTop, GlobalSize, Tmp) \
+ and Tmp, GlobalSize, #7 ; \
+ rsbne Tmp, Tmp, #8 ; \
+ add GlobalSize, GlobalSize, Tmp ; \
+ sub sp, StackTop, GlobalSize ; \
+ ; \
+ mov Tmp, sp ; \
+ mov GlobalSize, #0x0 ; \
+_SetiRamStackInitGlobals: ; \
+ cmp Tmp, StackTop ; \
+ beq _SetiRamStackEnd ; \
+ str GlobalSize, [Tmp], #4 ; \
+ b _SetiRamStackInitGlobals ; \
+_SetiRamStackEnd:
+
+
+ASM_PFX(_ModuleEntryPoint):
+ // First ensure all interrupts are disabled
+ bl ASM_PFX(ArmDisableInterrupts)
+
+ // Ensure that the MMU and caches are off
+ bl ASM_PFX(ArmDisableCachesAndMmu)
+
+ // Jump to Platform Specific Boot Action function
+ blx ASM_PFX(ArmPlatformSecBootAction)
+
+ # Enable branch prediction
+ bl ASM_PFX(ArmEnableBranchPrediction)
+
+ # TZPC1_DECPROT1Set (work-around for connecting T32 in SD booting mode)
+// ldr r0, =0x10110810
+// mov r1, #0xF
+// str r1, [r0]
+// dsb
+// isb
+// sev
+
+// ldr r0, =0x1
+// ldr r1, =0x2
+//infloop:
+// cmp r0, r1
+// bme infloop
+
+
+_IdentifyCpu:
+ // Identify CPU ID
+ bl ASM_PFX(ArmReadMpidr)
+ // Keep a copy of the MpId register value
+ mov r5, r0
+
+ // Is it the Primary Core ?
+ bl ASM_PFX(ArmPlatformIsPrimaryCore)
+ cmp r0, #1
+
+ // Only the primary core initialize the memory (SMC)
+ beq _InitMem
+
+_WaitInitMem:
+ // Wait for the primary core to initialize the initial memory (event: BOOT_MEM_INIT)
+ bl ASM_PFX(ArmCallWFE)
+ // Now the Init Mem is initialized, we setup the secondary core stacks
+ b _SetupSecondaryCoreStack
+
+_InitMem:
+ // Initialize Init Boot Memory
+ mov r0, pc
+ ldr r1, =0x40000000
+ cmp r0, r1
+ bgt _SetupPrimaryCoreStack
+
+ bl ASM_PFX(ArmPlatformClockInitialize)
+
+ LoadConstantToReg (FixedPcdGet32(PcdiRamStackBase), r1)
+ LoadConstantToReg (FixedPcdGet32(PcdiRamStackSize), r2)
+
+ // The reserved space for global variable must be 8-bytes aligned for pushing
+ // 64-bit variable on the stack
+ SetiRamStack (r1, r2, r3)
+
+ bl ASM_PFX(ArmPlatformSecBootMemoryInit)
+
+_SetupPrimaryCoreStack:
+ // Get the top of the primary stacks (and the base of the secondary stacks)
+ LoadConstantToReg (FixedPcdGet32(PcdCPUCoresSecStackBase), r1)
+ LoadConstantToReg (FixedPcdGet32(PcdCPUCoreSecPrimaryStackSize), r2)
+ add r1, r1, r2
+
+ LoadConstantToReg (FixedPcdGet32(PcdSecGlobalVariableSize), r2)
+
+ // The reserved space for global variable must be 8-bytes aligned for pushing
+ // 64-bit variable on the stack
+ SetPrimaryStack (r1, r2, r3)
+
+ mov r0, pc
+ ldr r1, =0x40000000
+ cmp r0, r1
+ bgt _PrepareArguments_NonTZ
+
+ b _CopyFirmware
+
+_SetupSecondaryCoreStack:
+ // Get the top of the primary stacks (and the base of the secondary stacks)
+ LoadConstantToReg (FixedPcdGet32(PcdCPUCoresSecStackBase), r1)
+ LoadConstantToReg (FixedPcdGet32(PcdCPUCoreSecPrimaryStackSize), r2)
+ add r1, r1, r2
+
+ // Get the Core Position (ClusterId * 4) + CoreId
+ GetCorePositionFromMpId(r0, r5, r2)
+ // The stack starts at the top of the stack region. Add '1' to the Core Position to get the top of the stack
+ add r0, r0, #1
+
+ // StackOffset = CorePos * StackSize
+ LoadConstantToReg (FixedPcdGet32(PcdCPUCoreSecSecondaryStackSize), r2)
+ mul r0, r0, r2
+ // SP = StackBase + StackOffset
+ add sp, r1, r0
+
+ b _PrepareArguments_NonTZ
+
+_PrepareArguments:
+ // Move sec startup address into a data register
+ // Ensure we're jumping to FV version of the code (not boot remapped alias)
+ LoadConstantToReg (FixedPcdGet32(PcdTrustzoneSupport), r2)
+ cmp r2, #0x1 /* TrustZone Enable */
+ beq _PrepareArguments_TZ
+
+_PrepareArguments_NonTZ:
+ ldr r3, StartupAddr
+ // Jump to SEC C code
+ // r0 = mp_id
+ mov r0, r5
+ blx r3
+
+_PrepareArguments_TZ:
+ /* Load IRAM_NS on IRAM_NS_BASE */
+ /* TZSW will call IRAM_NS code */
+ bl relocate_code
+
+ /* Jump to Coldboot in TZSW */
+ ldr r0, SecStartupAddr
+ b _ColdBootTzsw
+
+_CopyFirmware:
+ ldr r0, =Exynos5250_CMU_BASE
+ ldr r2, =CLK_DIV_FSYS2_OFFSET
+ ldr r1, [r0, r2]
+ bic r1, r1, #(0xFF << 8)
+ bic r1, r1, #(0xF)
+ orr r1, r1, #(0x9<< 8)
+ orr r1, r1, #0x3
+ str r1, [r0, r2]
+
+ /* Read booting information */
+ ldr r0, =0x10040000
+ ldr r1, [r0,#0x0]
+ bic r2, r1, #0xffffffc1
+
+ cmp r2, #0x8
+ beq _CopyFirmwareEMMC
+
+ /* SD/MMC BOOT */
+ cmp r2, #0x4
+ beq _CopyFirmwareSDMMC
+
+
+_CopyFirmwareSDMMC:
+ bl ASM_PFX(CopyFirmwareFromSDMMC)
+ b _PrepareArguments
+
+_CopyFirmwareEMMC:
+ bl ASM_PFX(CopyFirmwareFromEMMC)
+ b _PrepareArguments
+
+_ColdBootTzsw:
+ bl ASM_PFX(ColdBootForTzsw)
+_NeverReturn:
+ b _NeverReturn
+
+
+/*
+ * relocate_code: load NonSecure code(cpu1_wait)
+ */
+relocate_code:
+ adr r0, nscode_base @ r0: source address (start)
+ adr r1, nscode_end @ r1: source address (end)
+ ldr r2, =CONFIG_PHY_IRAM_NS_BASE @ r2: target address
+
+1:
+ ldmia r0!, {r3-r6}
+ stmia r2!, {r3-r6}
+ cmp r0, r1
+ blt 1b
+
+ .word 0xF57FF04F @dsb sy
+ .word 0xF57FF06F @isb sy
+
+ mov pc, lr
+
+/*
+ * CPU1 waits here until CPU0 wake it up.
+ * - below code is copied to CONFIG_PHY_IRAM_NS_BASE, which is non-secure memory.
+ */
+nscode_base:
+ adr r0, _ns_reg5
+ b 1f
+
+ .word 0x0 @ REG0: RESUME_ADDR
+ .word 0x0 @ REG1: RESUME_FLAG
+ .word 0x0 @ REG2
+ .word 0x0 @ REG3
+ .word 0x0 @ REG4
+_ns_reg5:
+ .word 0x0 @ REG5: CPU1_BOOT_REG
+ .word 0x0 @ REG6: REG_DIRECTGO_FLAG
+ .word 0x0 @ REG7: REG_DIRECTGO_ADDR
+ .word 0x0 @ REG8
+ .word 0x0 @ REG9
+
+ nop
+ nop
+
+1:
+#if 0 /* Exynos5250 do not require this code */
+ mrc p15, 0, r1, c0, c0, 5 @ MPIDR
+ and r1, r1, #0x3
+ add r0, r0, r1, lsl #0x2
+#endif
+cpu1_wait:
+ .word 0xE320F002 @ wfe instruction
+ ldr r1, [r0]
+ cmp r1, #0x0
+ bxne r1
+ b cpu1_wait
+ nop
+nscode_end:
diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Sec/SecEntryPoint.asm b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Sec/SecEntryPoint.asm
new file mode 100644
index 000000000..07ad1289b
--- /dev/null
+++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Sec/SecEntryPoint.asm
@@ -0,0 +1,112 @@
+//
+// Copyright (c) 2011-2012, ARM Limited. All rights reserved.
+//
+// This program and the accompanying materials
+// are licensed and made available under the terms and conditions of the BSD License
+// which accompanies this distribution. The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+//
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+//
+
+#include <AutoGen.h>
+#include <AsmMacroIoLib.h>
+#include "SecInternal.h"
+
+ INCLUDE AsmMacroIoLib.inc
+
+ IMPORT CEntryPoint
+ IMPORT ArmPlatformSecBootAction
+ IMPORT ArmPlatformSecBootMemoryInit
+ IMPORT ArmDisableInterrupts
+ IMPORT ArmDisableCachesAndMmu
+ IMPORT ArmReadMpidr
+ IMPORT ArmCallWFE
+ EXPORT _ModuleEntryPoint
+
+ PRESERVE8
+ AREA SecEntryPoint, CODE, READONLY
+
+StartupAddr DCD CEntryPoint
+
+_ModuleEntryPoint
+ // First ensure all interrupts are disabled
+ blx ArmDisableInterrupts
+
+ // Ensure that the MMU and caches are off
+ blx ArmDisableCachesAndMmu
+
+ // Jump to Platform Specific Boot Action function
+ blx ArmPlatformSecBootAction
+
+_IdentifyCpu
+ // Identify CPU ID
+ bl ArmReadMpidr
+ // Get ID of this CPU in Multicore system
+ LoadConstantToReg (FixedPcdGet32(PcdArmPrimaryCoreMask), r1)
+ and r5, r0, r1
+
+ // Is it the Primary Core ?
+ LoadConstantToReg (FixedPcdGet32(PcdArmPrimaryCore), r3)
+ cmp r5, r3
+ // Only the primary core initialize the memory (SMC)
+ beq _InitMem
+
+_WaitInitMem
+ // Wait for the primary core to initialize the initial memory (event: BOOT_MEM_INIT)
+ bl ArmCallWFE
+ // Now the Init Mem is initialized, we setup the secondary core stacks
+ b _SetupSecondaryCoreStack
+
+_InitMem
+ // Initialize Init Boot Memory
+ bl ArmPlatformSecBootMemoryInit
+
+ // Only Primary CPU could run this line (the secondary cores have jumped from _IdentifyCpu to _SetupStack)
+ LoadConstantToReg (FixedPcdGet32(PcdArmPrimaryCore), r5)
+
+_SetupPrimaryCoreStack
+ // Get the top of the primary stacks (and the base of the secondary stacks)
+ LoadConstantToReg (FixedPcdGet32(PcdCPUCoresSecStackBase), r1)
+ LoadConstantToReg (FixedPcdGet32(PcdCPUCoreSecPrimaryStackSize), r2)
+ add r1, r1, r2
+
+ LoadConstantToReg (FixedPcdGet32(PcdSecGlobalVariableSize), r2)
+
+ // The reserved space for global variable must be 8-bytes aligned for pushing
+ // 64-bit variable on the stack
+ SetPrimaryStack (r1, r2, r3)
+ b _PrepareArguments
+
+_SetupSecondaryCoreStack
+ // Get the top of the primary stacks (and the base of the secondary stacks)
+ LoadConstantToReg (FixedPcdGet32(PcdCPUCoresSecStackBase), r1)
+ LoadConstantToReg (FixedPcdGet32(PcdCPUCoreSecPrimaryStackSize), r2)
+ add r1, r1, r2
+
+ // Get the Core Position (ClusterId * 4) + CoreId
+ GetCorePositionInStack(r0, r5, r2)
+ // The stack starts at the top of the stack region. Add '1' to the Core Position to get the top of the stack
+ add r0, r0, #1
+
+ // StackOffset = CorePos * StackSize
+ LoadConstantToReg (FixedPcdGet32(PcdCPUCoreSecSecondaryStackSize), r2)
+ mul r0, r0, r2
+ // SP = StackBase + StackOffset
+ add sp, r1, r0
+
+_PrepareArguments
+ // Move sec startup address into a data register
+ // Ensure we're jumping to FV version of the code (not boot remapped alias)
+ ldr r3, StartupAddr
+
+ // Jump to SEC C code
+ // r0 = mp_id
+ mov r0, r5
+ blx r3
+
+_NeverReturn
+ b _NeverReturn
+ END
diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Sec/SecFromTzsw.S b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Sec/SecFromTzsw.S
new file mode 100644
index 000000000..aa6a896c9
--- /dev/null
+++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Sec/SecFromTzsw.S
@@ -0,0 +1,13 @@
+
+.text
+
+GCC_ASM_IMPORT(CEntryPoint)
+GCC_ASM_EXPORT(_SecEntryFromTzsw)
+
+StartupAddr: .word ASM_PFX(CEntryPoint)
+
+ASM_PFX(_SecEntryFromTzsw):
+ mov r0, #0
+ ldr r3, StartupAddr
+ blx r3
+
diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Sec/SecInternal.h b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Sec/SecInternal.h
new file mode 100644
index 000000000..eff157a64
--- /dev/null
+++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Sec/SecInternal.h
@@ -0,0 +1,75 @@
+/** @file
+* Main file supporting the SEC Phase on ARM PLatforms
+*
+* Copyright (c) 2011-2012, ARM Limited. All rights reserved.
+*
+* This program and the accompanying materials
+* are licensed and made available under the terms and conditions of the BSD License
+* which accompanies this distribution. The full text of the license may be found at
+* http://opensource.org/licenses/bsd-license.php
+*
+* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#ifndef __SEC_H__
+#define __SEC_H__
+
+#include <Base.h>
+#include <Library/ArmLib.h>
+#include <Library/ArmCpuLib.h>
+#include <Library/ArmPlatformSecLib.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/PcdLib.h>
+#include <ArmPlatform.h>
+
+#define IS_ALIGNED(Address, Align) (((UINTN)Address & (Align-1)) == 0)
+
+VOID
+TrustedWorldInitialization (
+ IN UINTN MpId
+ );
+
+VOID
+NonTrustedWorldTransition (
+ IN UINTN MpId,
+ IN UINTN JumpAddress
+ );
+
+VOID
+ArmSetupGicNonSecure (
+ IN INTN GicDistributorBase,
+ IN INTN GicInterruptInterfaceBase
+);
+
+VOID
+enter_monitor_mode (
+ IN UINTN MonitorEntryPoint,
+ IN UINTN MpId,
+ IN VOID* Stack
+ );
+
+VOID
+return_from_exception (
+ IN UINTN NonSecureBase
+ );
+
+VOID
+copy_cpsr_into_spsr (
+ VOID
+ );
+
+VOID
+set_non_secure_mode (
+ IN ARM_PROCESSOR_MODE Mode
+ );
+
+VOID
+SecCommonExceptionEntry (
+ IN UINT32 Entry,
+ IN UINT32 LR
+ );
+
+#endif
diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Sec/Smc.c b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Sec/Smc.c
new file mode 100644
index 000000000..3de899a11
--- /dev/null
+++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Sec/Smc.c
@@ -0,0 +1,110 @@
+/** @file
+* Main file supporting the SMC call on ARM Platforms
+*
+* Copyright (c) 2011-2012, ARM Limited. All rights reserved.
+*
+* This program and the accompanying materials
+* are licensed and made available under the terms and conditions of the BSD License
+* which accompanies this distribution. The full text of the license may be found at
+* http://opensource.org/licenses/bsd-license.php
+*
+* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#include "Smc.h"
+
+#define SMC_CMD_LOAD_UEFI (-230)
+#define SMC_CMD_COLDBOOT (-231)
+#define SMC_CMD_WARMBOOT (-232)
+
+#define SIGNATURE_SIZE 0
+
+#define MOVI_BLKSIZE (1 << 9)
+#define PART_SIZE_UEFI (2560 * 1024)
+#define PART_SIZE_TZSW (156 * 1024)
+#define MOVI_UEFI_BLKCNT (PART_SIZE_UEFI / MOVI_BLKSIZE)
+#define MOVI_TZSW_BLKCNT (PART_SIZE_TZSW / MOVI_BLKSIZE)
+
+typedef struct sdmmc_dev {
+ /* for SDMMC */
+ UINT32 image_pos;
+ UINT32 blkcnt;
+ UINT32 base_addr;
+} sdmmc_t;
+
+typedef struct emmc_dev {
+ /* for eMMC */
+ UINT32 blkcnt;
+ UINT32 base_addr;
+} emmc_t;
+
+/* boot device */
+typedef union boot_device_u {
+ sdmmc_t sdmmc;
+ emmc_t emmc;
+} boot_device_t;
+
+typedef struct ld_image_info {
+ UINT32 image_base_addr;
+ UINT32 size;
+ UINT32 secure_context_base;
+ UINT32 signature_size;
+ boot_device_t bootdev;
+} image_info;
+
+UINT32 exynos_smc(UINT32 cmd, UINT32 arg1, UINT32 arg2, UINT32 arg3)
+{
+ register UINT32 reg0 __asm__("r0") = cmd;
+ register UINT32 reg1 __asm__("r1") = arg1;
+ register UINT32 reg2 __asm__("r2") = arg2;
+ register UINT32 reg3 __asm__("r3") = arg3;
+
+ __asm__ volatile (
+ ".arch_extension sec\n"
+ "smc 0\n"
+ : "+r"(reg0), "+r"(reg1), "+r"(reg2), "+r"(reg3)
+
+ );
+
+ return reg0;
+}
+
+void load_uefi_image(UINT32 boot_device)
+{
+ image_info *info_image;
+
+ info_image = (image_info *) CONFIG_IMAGE_INFO_BASE;
+
+ if (boot_device == EMMC) {
+ info_image->bootdev.emmc.blkcnt = MOVI_UEFI_BLKCNT;
+ info_image->bootdev.emmc.base_addr = CONFIG_PHY_UEFI_BASE;
+ }
+
+ info_image->image_base_addr = CONFIG_PHY_UEFI_BASE;
+ info_image->size = (MOVI_UEFI_BLKCNT * MOVI_BLKSIZE);
+ info_image->secure_context_base = CONFIG_SECURE_CONTEXT_BASE;
+ info_image->signature_size = SIGNATURE_SIZE;
+
+ exynos_smc(SMC_CMD_LOAD_UEFI, boot_device, CONFIG_IMAGE_INFO_BASE, 0);
+}
+
+void coldboot(UINT32 boot_device, UINT32 JumpAddress)
+{
+ image_info *info_image;
+
+ info_image = (image_info *) CONFIG_IMAGE_INFO_BASE;
+
+ if (boot_device == EMMC) {
+ info_image->bootdev.emmc.blkcnt = MOVI_TZSW_BLKCNT;
+ info_image->bootdev.emmc.base_addr = CONFIG_PHY_TZSW_BASE;
+ }
+
+ info_image->image_base_addr = CONFIG_PHY_TZSW_BASE;
+ info_image->size = (MOVI_TZSW_BLKCNT * MOVI_BLKSIZE);
+ info_image->secure_context_base = CONFIG_SECURE_CONTEXT_BASE;
+ info_image->signature_size = SIGNATURE_SIZE;
+
+ exynos_smc(SMC_CMD_COLDBOOT, boot_device, CONFIG_IMAGE_INFO_BASE, JumpAddress);
+}
diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Sec/Smc.h b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Sec/Smc.h
new file mode 100644
index 000000000..1dcb1ac79
--- /dev/null
+++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Sec/Smc.h
@@ -0,0 +1,60 @@
+/** @file
+* Header file supporting the SMC call on ARM Platforms
+*
+* Copyright (c) 2011-2012, ARM Limited. All rights reserved.
+*
+* This program and the accompanying materials
+* are licensed and made available under the terms and conditions of the BSD License
+* which accompanies this distribution. The full text of the license may be found at
+* http://opensource.org/licenses/bsd-license.php
+*
+* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#ifndef __SMC_H__
+#define __SMC_H__
+
+#include <Platform/ArmPlatform.h>
+
+/* Boot Device */
+#define SDMMC_CH2 0x0
+#define SDMMC_CH0 0x4
+#define EMMC 0x14
+
+/* SMC call define */
+#define SMC_CMD_INIT (-1)
+#define SMC_CMD_INFO (-2)
+/* For Power Management */
+#define SMC_CMD_SLEEP (-3)
+#define SMC_CMD_CPU1BOOT (-4)
+#define SMC_CMD_CPU0AFTR (-5)
+/* For CP15 Access */
+#define SMC_CMD_C15RESUME (-11)
+/* For L2 Cache Access */
+#define SMC_CMD_L2X0CTRL (-21)
+#define SMC_CMD_L2X0SETUP1 (-22)
+#define SMC_CMD_L2X0SETUP2 (-23)
+#define SMC_CMD_L2X0INVALL (-24)
+#define SMC_CMD_L2X0DEBUG (-25)
+
+/* For Accessing CP15/SFR (General) */
+#define SMC_CMD_REG (-101)
+
+/* MACRO for SMC_CMD_REG */
+#define SMC_REG_CLASS_CP15 (0x0 << 30)
+#define SMC_REG_CLASS_SFR_W (0x1 << 30)
+#define SMC_REG_CLASS_SFR_R (0x3 << 30)
+#define SMC_REG_CLASS_MASK (0x3 << 30)
+#define SMC_REG_ID_CP15(CRn, Op1, CRm, Op2) \
+ (SMC_REG_CLASS_CP15 | \
+ ((CRn) << 10) | ((Op1) << 7) | ((CRm) << 3) | (Op2))
+#define SMC_REG_ID_SFR_W(ADDR) (SMC_REG_CLASS_SFR_W | ((ADDR) >> 2))
+#define SMC_REG_ID_SFR_R(ADDR) (SMC_REG_CLASS_SFR_R | ((ADDR) >> 2))
+
+void load_uefi_image(UINT32 boot_device);
+void coldboot(UINT32 boot_device, UINT32 JumpAddress);
+UINT32 exynos_smc(UINT32 cmd, UINT32 arg1, UINT32 arg2, UINT32 arg3);
+
+#endif /* __SMC_H__ */
diff --git a/SamsungPlatformPkg/Include/Library/PlatformBdsLib.h b/SamsungPlatformPkg/Include/Library/PlatformBdsLib.h
new file mode 100644
index 000000000..8c8c288c5
--- /dev/null
+++ b/SamsungPlatformPkg/Include/Library/PlatformBdsLib.h
@@ -0,0 +1,156 @@
+/** @file
+ Platform BDS library definition. A platform can implement
+ instances to support platform-specific behavior.
+
+Copyright (c) 2008 - 2010, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials are licensed and made available under
+the terms and conditions of the BSD License that accompanies this distribution.
+The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php.
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef __PLATFORM_BDS_LIB_H_
+#define __PLATFORM_BDS_LIB_H_
+
+#include <Protocol/GenericMemoryTest.h>
+#include <Library/GenericBdsLib.h>
+
+/**
+ Perform the memory test base on the memory test intensive level,
+ and update the memory resource.
+
+ @param Level The memory test intensive level.
+
+ @retval EFI_STATUS Successfully test all the system memory, and update
+ the memory resource
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *BASEM_MEMORY_TEST)(
+ IN EXTENDMEM_COVERAGE_LEVEL Level
+ );
+
+/**
+ This routine is called to see if there are any capsules we need to process.
+ If the boot mode is not UPDATE, then we do nothing. Otherwise, find the
+ capsule HOBS and produce firmware volumes for them via the DXE service.
+ Then call the dispatcher to dispatch drivers from them. Finally, check
+ the status of the updates.
+
+ This function should be called by BDS in case we need to do some
+ sort of processing even if there is no capsule to process. We
+ need to do this if an earlier update went away and we need to
+ clear the capsule variable so on the next reset PEI does not see it and
+ think there is a capsule available.
+
+ @param BootMode The current boot mode
+
+ @retval EFI_INVALID_PARAMETER The boot mode is not correct for an update.
+ @retval EFI_SUCCESS There is no error when processing a capsule.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *PROCESS_CAPSULES)(
+ IN EFI_BOOT_MODE BootMode
+ );
+
+/**
+ Platform Bds initialization. Includes the platform firmware vendor, revision
+ and so crc check.
+
+**/
+VOID
+EFIAPI
+PlatformBdsInit (
+ VOID
+ );
+
+/**
+ The function will excute with as the platform policy, current policy
+ is driven by boot mode. IBV/OEM can customize this code for their specific
+ policy action.
+
+ @param DriverOptionList The header of the driver option link list
+ @param BootOptionList The header of the boot option link list
+ @param ProcessCapsules A pointer to ProcessCapsules()
+ @param BaseMemoryTest A pointer to BaseMemoryTest()
+
+**/
+VOID
+EFIAPI
+PlatformBdsPolicyBehavior (
+ IN LIST_ENTRY *DriverOptionList,
+ IN LIST_ENTRY *BootOptionList,
+ IN PROCESS_CAPSULES ProcessCapsules,
+ IN BASEM_MEMORY_TEST BaseMemoryTest
+ );
+
+/**
+ Hook point for a user-provided function, for after a boot attempt fails.
+
+ @param Option A pointer to Boot Option that failed to boot.
+ @param Status The status returned from failed boot.
+ @param ExitData The exit data returned from failed boot.
+ @param ExitDataSize The exit data size returned from failed boot.
+
+**/
+VOID
+EFIAPI
+PlatformBdsBootFail (
+ IN BDS_COMMON_OPTION *Option,
+ IN EFI_STATUS Status,
+ IN CHAR16 *ExitData,
+ IN UINTN ExitDataSize
+ );
+
+/**
+ Hook point after a boot attempt succeeds. We don't expect a boot option to
+ return, so the UEFI 2.0 specification defines that you will default to an
+ interactive mode and stop processing the BootOrder list in this case. This
+ is also a platform implementation, and can be customized by an IBV/OEM.
+
+ @param Option A pointer to the Boot Option that successfully booted.
+
+**/
+VOID
+EFIAPI
+PlatformBdsBootSuccess (
+ IN BDS_COMMON_OPTION *Option
+ );
+
+
+/**
+ This function locks platform flash that is not allowed to be updated during normal boot path.
+ The flash layout is platform specific.
+
+ **/
+VOID
+EFIAPI
+PlatformBdsLockNonUpdatableFlash (
+ VOID
+ );
+
+/**
+ Lock the ConsoleIn device in system table. All key
+ presses will be ignored until the Password is typed in. The only way to
+ disable the password is to type it in to a ConIn device.
+
+ @param Password The password used to lock ConIn device.
+
+ @retval EFI_SUCCESS Lock the Console In Spliter virtual handle successfully.
+ @retval EFI_UNSUPPORTED Password not found.
+
+**/
+EFI_STATUS
+EFIAPI
+LockKeyboards (
+ IN CHAR16 *Password
+ );
+
+#endif
diff --git a/SamsungPlatformPkg/Library/PlatformBdsLib/BdsPlatform.c b/SamsungPlatformPkg/Library/PlatformBdsLib/BdsPlatform.c
new file mode 100644
index 000000000..4107f85d8
--- /dev/null
+++ b/SamsungPlatformPkg/Library/PlatformBdsLib/BdsPlatform.c
@@ -0,0 +1,588 @@
+/*++
+
+Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ BdsPlatform.c
+
+Abstract:
+
+ This file include all platform action which can be customized
+ by IBV/OEM.
+
+--*/
+
+#include "BdsPlatform.h"
+
+//EXYNOS_SYSTEM_CONFIGURATION mSystemConfigData;
+
+VOID
+SetupVariableInit (
+ VOID
+ )
+{
+#if 0
+ EFI_STATUS Status;
+ UINTN Size;
+
+ Size = sizeof (mSystemConfigData);
+ Status = gRT->GetVariable (
+ L"Setup",
+ &gEfiUnixSystemConfigGuid,
+ NULL,
+ &Size,
+ (VOID *) &mSystemConfigData
+ );
+
+ if (EFI_ERROR (Status)) {
+ //
+ // SetupVariable is corrupt
+ //
+ mSystemConfigData.ConOutRow = PcdGet32 (PcdConOutColumn);
+ mSystemConfigData.ConOutColumn = PcdGet32 (PcdConOutRow);
+
+ Status = gRT->SetVariable (
+ L"Setup",
+ &gEfiUnixSystemConfigGuid,
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
+ sizeof (mSystemConfigData),
+ (VOID *) &mSystemConfigData
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "Failed to save Setup Variable to non-volatile storage, Status = %r\n", Status));
+ }
+ }
+#endif
+}
+
+//
+// BDS Platform Functions
+//
+VOID
+EFIAPI
+PlatformBdsInit (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ Platform Bds init. Include the platform firmware vendor, revision
+ and so crc check.
+
+Arguments:
+
+Returns:
+
+ None.
+
+--*/
+{
+ DEBUG((EFI_D_ERROR, "++%a:%d\n", __FUNCTION__, __LINE__));
+ SetupVariableInit ();
+ DEBUG((EFI_D_ERROR, "--%a:%d\n", __FUNCTION__, __LINE__));
+}
+
+EFI_STATUS
+PlatformBdsConnectConsole (
+ IN BDS_CONSOLE_CONNECT_ENTRY *PlatformConsole
+ )
+/*++
+
+Routine Description:
+
+ Connect the predefined platform default console device. Always try to find
+ and enable the vga device if have.
+
+Arguments:
+
+ PlatformConsole - Predfined platform default console device array.
+
+Returns:
+
+ EFI_SUCCESS - Success connect at least one ConIn and ConOut
+ device, there must have one ConOut device is
+ active vga device.
+
+ EFI_STATUS - Return the status of
+ BdsLibConnectAllDefaultConsoles ()
+
+--*/
+{
+ DEBUG((EFI_D_ERROR, "++%a:%d\n", __FUNCTION__, __LINE__));
+ EFI_STATUS Status;
+ UINTN Index;
+
+ Index = 0;
+ Status = EFI_SUCCESS;
+
+ //
+ // Have chance to connect the platform default console,
+ // the platform default console is the minimue device group
+ // the platform should support
+ //
+ while (PlatformConsole[Index].DevicePath != NULL) {
+ //
+ // Update the console variable with the connect type
+ //
+ if ((PlatformConsole[Index].ConnectType & CONSOLE_IN) == CONSOLE_IN) {
+ BdsLibUpdateConsoleVariable (L"ConIn", PlatformConsole[Index].DevicePath, NULL);
+ }
+
+ if ((PlatformConsole[Index].ConnectType & CONSOLE_OUT) == CONSOLE_OUT) {
+ BdsLibUpdateConsoleVariable (L"ConOut", PlatformConsole[Index].DevicePath, NULL);
+ }
+
+ if ((PlatformConsole[Index].ConnectType & STD_ERROR) == STD_ERROR) {
+ BdsLibUpdateConsoleVariable (L"ErrOut", PlatformConsole[Index].DevicePath, NULL);
+ }
+
+ DEBUG((EFI_D_ERROR, "Index: %d\n", Index));
+ Index++;
+ }
+ //
+ // Connect the all the default console with current cosole variable
+ //
+ Status = BdsLibConnectAllDefaultConsoles ();
+ BdsLibConnectAllConsoles ();
+ DEBUG((EFI_D_ERROR, "--%a:%d (Status: %X)\n", __FUNCTION__, __LINE__, Status));
+ return Status;
+}
+
+VOID
+PlatformBdsConnectSequence (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ Connect with predeined platform connect sequence,
+ the OEM/IBV can customize with their own connect sequence.
+
+Arguments:
+
+ None.
+
+Returns:
+
+ None.
+
+--*/
+{
+ DEBUG((EFI_D_ERROR, "++%a:%d\n", __FUNCTION__, __LINE__));
+ UINTN Index;
+
+ Index = 0;
+
+ //
+ // Here we can get the customized platform connect sequence
+ // Notes: we can connect with new variable which record the
+ // last time boots connect device path sequence
+ //
+ while (gPlatformConnectSequence[Index] != NULL) {
+ //
+ // Build the platform boot option
+ //
+ BdsLibConnectDevicePath (gPlatformConnectSequence[Index]);
+ Index++;
+ }
+
+ //
+ // Just use the simple policy to connect all devices
+ //
+ BdsLibConnectAll ();
+ DEBUG((EFI_D_ERROR, "--%a:%d\n", __FUNCTION__, __LINE__));
+}
+
+VOID
+PlatformBdsGetDriverOption (
+ IN OUT LIST_ENTRY *BdsDriverLists
+ )
+/*++
+
+Routine Description:
+
+ Load the predefined driver option, OEM/IBV can customize this
+ to load their own drivers
+
+Arguments:
+
+ BdsDriverLists - The header of the driver option link list.
+
+Returns:
+
+ None.
+
+--*/
+{
+ DEBUG((EFI_D_ERROR, "++%a:%d\n", __FUNCTION__, __LINE__));
+ UINTN Index;
+
+ Index = 0;
+
+ //
+ // Here we can get the customized platform driver option
+ //
+ while (gPlatformDriverOption[Index] != NULL) {
+ //
+ // Build the platform boot option
+ //
+ BdsLibRegisterNewOption (BdsDriverLists, gPlatformDriverOption[Index], NULL, L"DriverOrder");
+ Index++;
+ }
+ DEBUG((EFI_D_ERROR, "--%a:%d\n", __FUNCTION__, __LINE__));
+
+}
+
+VOID
+PlatformBdsDiagnostics (
+ IN EXTENDMEM_COVERAGE_LEVEL MemoryTestLevel,
+ IN BOOLEAN QuietBoot,
+ IN BASEM_MEMORY_TEST BaseMemoryTest
+ )
+/*++
+
+Routine Description:
+
+ Perform the platform diagnostic, such like test memory. OEM/IBV also
+ can customize this fuction to support specific platform diagnostic.
+
+Arguments:
+
+ MemoryTestLevel - The memory test intensive level
+
+ QuietBoot - Indicate if need to enable the quiet boot
+
+ BaseMemoryTest - A pointer to BdsMemoryTest()
+
+Returns:
+
+ None.
+
+--*/
+{
+ DEBUG((EFI_D_ERROR, "++%a:%d\n", __FUNCTION__, __LINE__));
+ EFI_STATUS Status;
+
+ //
+ // Here we can decide if we need to show
+ // the diagnostics screen
+ // Notes: this quiet boot code should be remove
+ // from the graphic lib
+ //
+ if (QuietBoot) {
+ EnableQuietBoot (PcdGetPtr(PcdLogoFile));
+ //
+ // Perform system diagnostic
+ //
+ Status = BaseMemoryTest (MemoryTestLevel);
+ if (EFI_ERROR (Status)) {
+ DisableQuietBoot ();
+ }
+
+ DEBUG((EFI_D_ERROR, "--%a:%d (Status: %X)\n", __FUNCTION__, __LINE__, Status));
+ return ;
+ }
+ //
+ // Perform system diagnostic
+ //
+ Status = BaseMemoryTest (MemoryTestLevel);
+ DEBUG((EFI_D_ERROR, "--%a:%d\n", __FUNCTION__, __LINE__));
+}
+
+VOID
+EFIAPI
+PlatformBdsPolicyBehavior (
+ IN OUT LIST_ENTRY *DriverOptionList,
+ IN OUT LIST_ENTRY *BootOptionList,
+ IN PROCESS_CAPSULES ProcessCapsules,
+ IN BASEM_MEMORY_TEST BaseMemoryTest
+ )
+/*++
+
+Routine Description:
+
+ The function will excute with as the platform policy, current policy
+ is driven by boot mode. IBV/OEM can customize this code for their specific
+ policy action.
+
+Arguments:
+
+ DriverOptionList - The header of the driver option link list
+
+ BootOptionList - The header of the boot option link list
+
+ ProcessCapsules - A pointer to ProcessCapsules()
+
+ BaseMemoryTest - A pointer to BaseMemoryTest()
+
+Returns:
+
+ None.
+
+--*/
+{
+ DEBUG((EFI_D_ERROR, "++%a:%d\n", __FUNCTION__, __LINE__));
+ EFI_STATUS Status;
+ UINT16 Timeout;
+ EFI_BOOT_MODE BootMode;
+
+ //
+ // Init the time out value
+ //
+ Timeout = 5;//PcdGet16 (PcdPlatformBootTimeOut);
+
+ //
+ // Load the driver option as the driver option list
+ //
+ PlatformBdsGetDriverOption (DriverOptionList);
+
+ //
+ // Get current Boot Mode
+ //
+ Status = BdsLibGetBootMode (&BootMode);
+
+ //
+ // Go the different platform policy with different boot mode
+ // Notes: this part code can be change with the table policy
+ //
+ switch (BootMode) {
+
+ case BOOT_ASSUMING_NO_CONFIGURATION_CHANGES:
+ case BOOT_WITH_MINIMAL_CONFIGURATION:
+ //
+ // In no-configuration boot mode, we can connect the
+ // console directly.
+ //
+ BdsLibConnectAllDefaultConsoles ();
+ PlatformBdsDiagnostics (IGNORE, TRUE, BaseMemoryTest);
+
+ //
+ // Perform some platform specific connect sequence
+ //
+ PlatformBdsConnectSequence ();
+
+ //
+ // Notes: current time out = 0 can not enter the
+ // front page
+ //
+ PlatformBdsEnterFrontPage (Timeout, FALSE);
+
+ //
+ // Check the boot option with the boot option list
+ //
+ BdsLibBuildOptionFromVar (BootOptionList, L"BootOrder");
+ break;
+
+ case BOOT_ON_FLASH_UPDATE:
+ //
+ // Boot with the specific configuration
+ //
+ PlatformBdsConnectConsole (gPlatformConsole);
+ PlatformBdsDiagnostics (EXTENSIVE, FALSE, BaseMemoryTest);
+ BdsLibConnectAll ();
+ ProcessCapsules (BOOT_ON_FLASH_UPDATE);
+ break;
+
+ case BOOT_IN_RECOVERY_MODE:
+ //
+ // In recovery mode, just connect platform console
+ // and show up the front page
+ //
+ PlatformBdsConnectConsole (gPlatformConsole);
+ PlatformBdsDiagnostics (EXTENSIVE, FALSE, BaseMemoryTest);
+
+ //
+ // In recovery boot mode, we still enter to the
+ // frong page now
+ //
+ PlatformBdsEnterFrontPage (Timeout, FALSE);
+ break;
+
+ case BOOT_WITH_FULL_CONFIGURATION:
+ case BOOT_WITH_FULL_CONFIGURATION_PLUS_DIAGNOSTICS:
+ case BOOT_WITH_DEFAULT_SETTINGS:
+ default:
+ //
+ // Connect platform console
+ //
+ Status = PlatformBdsConnectConsole (gPlatformConsole);
+ if (EFI_ERROR (Status)) {
+ //
+ // Here OEM/IBV can customize with defined action
+ //
+ PlatformBdsNoConsoleAction ();
+ }
+
+ PlatformBdsDiagnostics (IGNORE, TRUE, BaseMemoryTest);
+
+ //
+ // Perform some platform specific connect sequence
+ //
+ PlatformBdsConnectSequence ();
+
+ //
+ // Give one chance to enter the setup if we
+ // have the time out
+ //
+ PlatformBdsEnterFrontPage (Timeout, FALSE);
+
+ //
+ // Here we have enough time to do the enumeration of boot device
+ //
+ BdsLibEnumerateAllBootOption (BootOptionList);
+ break;
+ }
+
+ DEBUG((EFI_D_ERROR, "--%a:%d\n", __FUNCTION__, __LINE__));
+ return ;
+
+}
+
+VOID
+EFIAPI
+PlatformBdsBootSuccess (
+ IN BDS_COMMON_OPTION *Option
+ )
+/*++
+
+Routine Description:
+
+ Hook point after a boot attempt succeeds. We don't expect a boot option to
+ return, so the EFI 1.0 specification defines that you will default to an
+ interactive mode and stop processing the BootOrder list in this case. This
+ is alos a platform implementation and can be customized by IBV/OEM.
+
+Arguments:
+
+ Option - Pointer to Boot Option that succeeded to boot.
+
+Returns:
+
+ None.
+
+--*/
+{
+ DEBUG((EFI_D_ERROR, "++%a:%d\n", __FUNCTION__, __LINE__));
+ CHAR16 *TmpStr;
+
+ //
+ // If Boot returned with EFI_SUCCESS and there is not in the boot device
+ // select loop then we need to pop up a UI and wait for user input.
+ //
+ TmpStr = Option->StatusString;
+ if (TmpStr != NULL) {
+ BdsLibOutputStrings (gST->ConOut, TmpStr, Option->Description, L"\n\r", NULL);
+ FreePool (TmpStr);
+ }
+ DEBUG((EFI_D_ERROR, "--%a:%d\n", __FUNCTION__, __LINE__));
+}
+
+VOID
+EFIAPI
+PlatformBdsBootFail (
+ IN BDS_COMMON_OPTION *Option,
+ IN EFI_STATUS Status,
+ IN CHAR16 *ExitData,
+ IN UINTN ExitDataSize
+ )
+/*++
+
+Routine Description:
+
+ Hook point after a boot attempt fails.
+
+Arguments:
+
+ Option - Pointer to Boot Option that failed to boot.
+
+ Status - Status returned from failed boot.
+
+ ExitData - Exit data returned from failed boot.
+
+ ExitDataSize - Exit data size returned from failed boot.
+
+Returns:
+
+ None.
+
+--*/
+{
+ DEBUG((EFI_D_ERROR, "++%a:%d\n", __FUNCTION__, __LINE__));
+ CHAR16 *TmpStr;
+
+ //
+ // If Boot returned with failed status then we need to pop up a UI and wait
+ // for user input.
+ //
+ TmpStr = Option->StatusString;
+ if (TmpStr != NULL) {
+ BdsLibOutputStrings (gST->ConOut, TmpStr, Option->Description, L"\n\r", NULL);
+ FreePool (TmpStr);
+ }
+ DEBUG((EFI_D_ERROR, "--%a:%d\n", __FUNCTION__, __LINE__));
+}
+
+EFI_STATUS
+PlatformBdsNoConsoleAction (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ This function is remained for IBV/OEM to do some platform action,
+ if there no console device can be connected.
+
+Arguments:
+
+ None.
+
+Returns:
+
+ EFI_SUCCESS - Direct return success now.
+
+--*/
+{
+ DEBUG((EFI_D_ERROR, "++%a:%d\n", __FUNCTION__, __LINE__));
+ DEBUG((EFI_D_ERROR, "--%a:%d\n", __FUNCTION__, __LINE__));
+ return EFI_SUCCESS;
+}
+
+VOID
+EFIAPI
+PlatformBdsLockNonUpdatableFlash (
+ VOID
+ )
+{
+ return;
+}
+
+/**
+ Lock the ConsoleIn device in system table. All key
+ presses will be ignored until the Password is typed in. The only way to
+ disable the password is to type it in to a ConIn device.
+
+ @param Password Password used to lock ConIn device.
+
+ @retval EFI_SUCCESS lock the Console In Spliter virtual handle successfully.
+ @retval EFI_UNSUPPORTED Password not found
+
+**/
+EFI_STATUS
+EFIAPI
+LockKeyboards (
+ IN CHAR16 *Password
+ )
+{
+ return EFI_UNSUPPORTED;
+}
diff --git a/SamsungPlatformPkg/Library/PlatformBdsLib/BdsPlatform.h b/SamsungPlatformPkg/Library/PlatformBdsLib/BdsPlatform.h
new file mode 100644
index 000000000..41aa4459f
--- /dev/null
+++ b/SamsungPlatformPkg/Library/PlatformBdsLib/BdsPlatform.h
@@ -0,0 +1,130 @@
+/*++
+
+Copyright (c) 2006, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ BdsPlatform.h
+
+Abstract:
+
+ Head file for BDS Platform specific code
+
+--*/
+
+#ifndef _BDS_PLATFORM_H
+#define _BDS_PLATFORM_H
+
+#include <PiDxe.h>
+
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/BaseLib.h>
+#include <Library/PcdLib.h>
+#include <Library/GenericBdsLib.h>
+#include <Library/PlatformBdsLib.h>
+#include <Library/DevicePathLib.h>
+
+//#include <Protocol/ExynosThunk.h>
+//#include <Protocol/ExynosIo.h>
+//#include <Guid/ExynosSystemConfig.h>
+
+extern BDS_CONSOLE_CONNECT_ENTRY gPlatformConsole[];
+extern EFI_DEVICE_PATH_PROTOCOL *gPlatformConnectSequence[];
+extern EFI_DEVICE_PATH_PROTOCOL *gPlatformDriverOption[];
+
+
+#pragma pack(1)
+typedef struct {
+ //
+ // Console output mode
+ //
+ UINT32 ConOutColumn;
+ UINT32 ConOutRow;
+} EXYNOS_SYSTEM_CONFIGURATION;
+#pragma pack()
+
+
+#define gEndEntire \
+ { \
+ END_DEVICE_PATH_TYPE,\
+ END_ENTIRE_DEVICE_PATH_SUBTYPE,\
+ END_DEVICE_PATH_LENGTH,\
+ 0\
+ }
+
+typedef struct {
+ VENDOR_DEVICE_PATH VendorDevicePath;
+ UINT32 Instance;
+} EXYNOS_VENDOR_DEVICE_PATH_NODE;
+
+//
+// Below is the platform console device path
+//
+
+typedef struct {
+ VENDOR_DEVICE_PATH ExynosBus;
+ EFI_DEVICE_PATH_PROTOCOL End;
+} EXYNOS_GOP_DEVICE_PATH;
+
+typedef struct {
+ VENDOR_DEVICE_PATH ExynosBus;
+ EFI_DEVICE_PATH_PROTOCOL End;
+} EXYNOS_CONSOLE_DEVICE_PATH;
+//
+// Platform BDS Functions
+//
+VOID
+PlatformBdsGetDriverOption (
+ IN LIST_ENTRY *BdsDriverLists
+ )
+;
+
+EFI_STATUS
+BdsMemoryTest (
+ EXTENDMEM_COVERAGE_LEVEL Level
+ )
+;
+
+
+VOID
+PlatformBdsConnectSequence (
+ VOID
+ )
+;
+
+EFI_STATUS
+ProcessCapsules (
+ EFI_BOOT_MODE BootMode
+ )
+;
+
+EFI_STATUS
+PlatformBdsConnectConsole (
+ IN BDS_CONSOLE_CONNECT_ENTRY *PlatformConsole
+ )
+;
+
+EFI_STATUS
+PlatformBdsNoConsoleAction (
+ VOID
+ )
+;
+
+VOID
+PlatformBdsEnterFrontPage (
+ IN UINT16 TimeoutDefault,
+ IN BOOLEAN ConnectAllHappened
+ );
+
+#endif // _BDS_PLATFORM_H
diff --git a/SamsungPlatformPkg/Library/PlatformBdsLib/PlatformBdsLib.inf b/SamsungPlatformPkg/Library/PlatformBdsLib/PlatformBdsLib.inf
new file mode 100644
index 000000000..93aacbe52
--- /dev/null
+++ b/SamsungPlatformPkg/Library/PlatformBdsLib/PlatformBdsLib.inf
@@ -0,0 +1,63 @@
+## @file
+# Platfrom BDS driver
+#
+# Do platform action customized by IBV/OEM.
+# Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = PlatformBdsLib
+ FILE_GUID = f392b762-8985-11db-be87-0040d02b1835
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = PlatformBdsLib|DXE_DRIVER
+
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF EBC
+#
+
+[Sources]
+ BdsPlatform.c
+ PlatformData.c
+ BdsPlatform.h
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec
+
+[LibraryClasses]
+ BaseLib
+ MemoryAllocationLib
+ UefiBootServicesTableLib
+ UefiRuntimeServicesTableLib
+ BaseMemoryLib
+ DebugLib
+ PcdLib
+ GenericBdsLib
+ DevicePathLib
+
+
+[Guids]
+
+[Pcd]
+ gEfiMdeModulePkgTokenSpaceGuid.PcdConOutRow
+ gEfiMdeModulePkgTokenSpaceGuid.PcdConOutColumn
+ gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdPlatformBootTimeOut
+ gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdLogoFile
+
+[Depex]
+ gEfiVariableArchProtocolGuid AND gEfiVariableWriteArchProtocolGuid
diff --git a/SamsungPlatformPkg/Library/PlatformBdsLib/PlatformData.c b/SamsungPlatformPkg/Library/PlatformBdsLib/PlatformData.c
new file mode 100644
index 000000000..76c31f3ba
--- /dev/null
+++ b/SamsungPlatformPkg/Library/PlatformBdsLib/PlatformData.c
@@ -0,0 +1,88 @@
+/*++
+
+Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ PlatformData.c
+
+Abstract:
+
+ Defined the platform specific device path which will be used by
+ platform Bbd to perform the platform policy connect.
+
+--*/
+
+#include "BdsPlatform.h"
+#include <Protocol/SerialIo.h>
+#include <Protocol/GraphicsOutput.h>
+
+
+//
+// Predefined platform default time out value
+//
+UINT16 gPlatformBootTimeOutDefault = 10;
+
+//
+// Platform specific keyboard device path
+//
+EXYNOS_GOP_DEVICE_PATH gGopDevicePath = {
+ { // ExynosBus
+ HARDWARE_DEVICE_PATH,
+ HW_VENDOR_DP,
+ {
+ (UINT8) (sizeof (VENDOR_DEVICE_PATH)),
+ (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)
+ },
+ EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID
+ },
+ gEndEntire
+};
+
+EXYNOS_CONSOLE_DEVICE_PATH gConsoleDevicePath = {
+ { // ExynosBus
+ HARDWARE_DEVICE_PATH,
+ HW_VENDOR_DP,
+ {
+ (UINT8) (sizeof (VENDOR_DEVICE_PATH)),
+ (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)
+ },
+ EFI_SIMPLE_TEXT_INPUT_PROTOCOL_GUID
+ },
+ gEndEntire
+};
+
+//
+// Predefined platform default console device path
+//
+BDS_CONSOLE_CONNECT_ENTRY gPlatformConsole[] = {
+ {
+ (EFI_DEVICE_PATH_PROTOCOL *) &gConsoleDevicePath,
+ (CONSOLE_OUT | CONSOLE_IN)
+ },
+ {
+ (EFI_DEVICE_PATH_PROTOCOL *) &gGopDevicePath,
+ (CONSOLE_OUT | CONSOLE_IN)
+ },
+ {
+ NULL,
+ 0
+ }
+};
+
+//
+// Predefined platform specific driver option
+//
+EFI_DEVICE_PATH_PROTOCOL *gPlatformDriverOption[] = { NULL };
+
+//
+// Predefined platform connect sequence
+//
+EFI_DEVICE_PATH_PROTOCOL *gPlatformConnectSequence[] = { NULL };
diff --git a/SamsungPlatformPkg/Logo/Logo.bmp b/SamsungPlatformPkg/Logo/Logo.bmp
new file mode 100755
index 000000000..f4db08e4d
--- /dev/null
+++ b/SamsungPlatformPkg/Logo/Logo.bmp
Binary files differ
diff --git a/SamsungPlatformPkg/README b/SamsungPlatformPkg/README
new file mode 100644
index 000000000..a4973c260
--- /dev/null
+++ b/SamsungPlatformPkg/README
@@ -0,0 +1,48 @@
+
+=== ArndaleBoard OVERVIEW ===
+
+The project aims to support UEFI for Exynos 5250 Soc using the edk2
+code base.
+
+=== STATUS ===
+
+Current capabilities:
+* Uefi Boot from microSD card
+
+=== FUTURE PLANS ===
+
+* Support for PXE, SATA, ACPI, USB
+ - KeyBoard, Mouse and MassStorage
+
+=== BUILDING ARNDALE Board ===
+
+Pre-requisites:
+* Build environment capable of build the edk2 MdeModulePkg.
+* A properly configured ASL compiler:
+ - Intel ASL compiler: Available from http://www.acpica.org
+ - Microsoft ASL compiler: Available from http://www.acpi.info
+
+Getting bl1:
+Download the bl1 from https://wiki.linaro.org/Boards/Arndale/Setup/EnterpriseUbuntuServer?action=AttachFile&do=view&target=arndale-bl1.img
+
+Build the ArndaleBoardPkg by running from the Workspace
+build -p SamsungPlatformPkg/ArndaleBoardPkg/arndale-Exynos5250.dsc -a ARM -t ARMGCC -b RELEASE -D EXYNOS5250_EVT1 -D DDR3 for release version
+
+Following the edk2 build process, you will find the Arndale binaries
+under the $WORKSPACE/Build/*/*/FV directory. You can find the below
+mentioned binary image.
+* ARNDALE_EFI.FD
+
+=== RUNNING ArndaleBoardPkg on the Arndale board ===
+* need to be in Linux Environment to do the below procedure
+* Insert the microSD card.
+* copy the arndale-bl1.img to the SD/MMC card by using the comand
+ sudo dd if=arndale-bl1.img of=/dev/sdX bs=512 seek=1
+* Copy the Uefi Image to SD/MMC with below command from the Workspace.
+ sudo dd if=Build/ArndaleBoard-Exynos/RELEASE_ARMGCC/FV/ARNDALE_EFI.fd of=/dev/sdX bs=512 seek=49
+* Now the booting device is ready to be used.
+* Insert the SDMMC card in the Arndale board reader slot MMC Ch2.
+* Connect the Uart cable from the Arndale device to the PC terminal.
+* Power ON the Device.
+* The boot message should be visible on the termial.
+* Finally, it should give boot options.
diff --git a/SamsungPlatformPkg/SamsungPlatformPkg.dec b/SamsungPlatformPkg/SamsungPlatformPkg.dec
new file mode 100644
index 000000000..32c21f4c2
--- /dev/null
+++ b/SamsungPlatformPkg/SamsungPlatformPkg.dec
@@ -0,0 +1,42 @@
+#/** @file
+# Arm RealView EB package.
+#
+# Copyright (c) 2012, Samsung Electronics Co. All rights reserved.<BR>
+#
+# This program and the accompanying materials are licensed and made available under
+# the terms and conditions of the BSD License which accompanies this distribution.
+# The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#**/
+
+[Defines]
+ DEC_SPECIFICATION = 0x00010005
+ PACKAGE_NAME = SamsungPlatformPkg
+ PACKAGE_GUID = ec1a4982-4a00-47e7-8df5-69c8ce895427
+ PACKAGE_VERSION = 0.1
+
+################################################################################
+#
+# Include Section - list of Include Paths that are provided by this package.
+# Comments are used for Keywords and Module Types.
+#
+# Supported Module Types:
+# BASE SEC PEI_CORE PEIM DXE_CORE DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SMM_DRIVER DXE_SAL_DRIVER UEFI_DRIVER UEFI_APPLICATION
+#
+################################################################################
+[Includes.common]
+
+[Guids.common]
+
+[PcdsFeatureFlag.common]
+
+[PcdsFixedAtBuild.common]
+
+[Protocols.common]
+ gSamsungPlatformGpioProtocolGuid = { 0x82b4b2f7, 0x8c18, 0x4dbe, { 0xb7, 0x2e, 0x6a, 0x59, 0xd4, 0x23, 0x0c, 0x40 }}
+ gSamsungPlatformI2CProtocolGuid = { 0x3e71c1f9, 0xe5e4, 0x482b, { 0xac, 0x1e, 0x50, 0xf5, 0x43, 0x59, 0xc8, 0x65 }}
+ gSamsungPlatformRngProtocolGuid = { 0xcdfc7301, 0x38a3, 0x4b4b, { 0xb4, 0x57, 0x8a, 0x72, 0x38, 0xfb, 0xed, 0xf7 }}
diff --git a/SamsungPlatformPkg/build.sh b/SamsungPlatformPkg/build.sh
new file mode 100755
index 000000000..cd2e59c59
--- /dev/null
+++ b/SamsungPlatformPkg/build.sh
@@ -0,0 +1,126 @@
+#!/bin/bash
+unset ARCH
+unset ARMLINUXGCC_TOOLS_PATH
+unset EDK_TOOLS_PATH
+unset WORKSPACE
+
+if [ "$1" = "help" ]
+then
+ echo ""
+ echo "USAGE:"
+ echo " ./build help : shows this message"
+ echo " ./build : build with BaseTools, GccShellPkg"
+ echo " ./build init : build with BaseTools Only"
+ echo " ./build shell : build with GccShellPkg Only"
+ echo " ./build arndale : build with SamsungPlatformPkg for Arndale"
+ echo ""
+ exit
+fi
+
+export ARMLINUXGCC_TOOLS_PATH=/usr/local/arm/bin/
+export EDK_TOOLS_PATH=`pwd`/BaseTools
+. ./edksetup.sh BaseTools
+
+DEFINE_CMD=
+
+for arg in "$@"; do
+ args="${args} ${arg}"
+done
+
+DEFINE_CMD=$args
+
+
+
+if [ "$1" = "arndale" ]
+then
+ DEFINE_CMD=" -D EXYNOS5250_EVT1 -D DDR3"
+else
+ DEFINE_CMD=
+fi
+
+echo " Parameter is ["$DEFINE_CMD"]"
+if [ "$1" = "init" ]
+then
+ if [ ! -d BaseTools/Source/C/bin ]
+ then
+ cd ./BaseTools
+ make clean
+ cd ../
+ make -C ./BaseTools
+ else
+ echo "Already build BaseTools....."
+ echo ""
+ fi
+
+elif [ "$1" = "shell" ]
+then
+ if [ -d GccShellPkg ]
+ then
+ build -p GccShellPkg/GccShellPkg.dsc -a ARM -t ARMLINUXGCC -b DEBUG
+ if [ -f Build/GccShellPkg/DEBUG_ARMLINUXGCC/ARM/ShellFull.efi ]
+ then
+ cp Build/GccShellPkg/DEBUG_ARMLINUXGCC/ARM/ShellFull.efi EdkShellBinPkg/FullShell/ARM/Shell_Full.efi
+ echo "To copy ShellFull.efi to EdkShellBinPkg/FullShell/ARM is done......"
+ echo ""
+ fi
+ else
+ echo ""
+ echo "Not found Directory : ---------> GccShellPkg !!!!"
+ echo ""
+ exit
+ fi
+
+elif [ "$1" = "arndale" ]
+then
+ if [ ! -d BaseTools/Source/C/bin ]
+ then
+ cd ./BaseTools
+ make clean
+ cd ../
+ make -C ./BaseTools
+ else
+ echo "Already build BaseTools....."
+ echo ""
+ fi
+
+ if [ -d SamsungPlatformPkg ]
+ then
+ build -p SamsungPlatformPkg/ArndaleBoardPkg/arndale-Exynos5250.dsc -a ARM -t ARMLINUXGCC -b DEBUG $DEFINE_CMD
+ echo "ARNDALE_EFI.fd can be found in path Build/Arndale-Exynos/DEBUG_ARMLINUXGCC/FV/"
+ else
+ echo ""
+ echo "Not found Directory : ---------> SamsungPlatformPkg !!!!"
+ echo ""
+ exit
+ fi
+
+else
+ # Build BaseTools
+ if [ ! -d BaseTools/Source/C/bin ]
+ then
+ cd ./BaseTools
+ make clean
+ cd ../
+ make -C ./BaseTools
+ else
+ echo "Already build BaseTools....."
+ echo ""
+ fi
+
+ # Build GccShellPkg
+ if [ -d GccShellPkg ]
+ then
+ build -p GccShellPkg/GccShellPkg.dsc -a ARM -t ARMLINUXGCC -b DEBUG
+ if [ -f Build/GccShellPkg/DEBUG_ARMLINUXGCC/ARM/ShellFull.efi ]
+ then
+ cp Build/GccShellPkg/DEBUG_ARMLINUXGCC/ARM/ShellFull.efi EdkShellBinPkg/FullShell/ARM/Shell_Full.efi
+ echo "To copy ShellFull.efi to EdkShellBinPkg/FullShell/ARM is done......"
+ echo ""
+ fi
+ else
+ echo ""
+ echo "Not found Directory : ---------> GccShellPkg !!!!"
+ echo ""
+ fi
+
+fi
diff --git a/SamsungPlatformPkg/patches/0001-The-patch-created-to-incorporate-auto-boot-feature.patch b/SamsungPlatformPkg/patches/0001-The-patch-created-to-incorporate-auto-boot-feature.patch
new file mode 100644
index 000000000..91aea9603
--- /dev/null
+++ b/SamsungPlatformPkg/patches/0001-The-patch-created-to-incorporate-auto-boot-feature.patch
@@ -0,0 +1,150 @@
+From 011bc2be4b3f2a5a5413511d7380b6fe3632d0f5 Mon Sep 17 00:00:00 2001
+From: Shivamurthy Shastri <shiva.murthy@samsung.com>
+Date: Wed, 5 Dec 2012 14:44:57 +0530
+Subject: [PATCH] The patch created to incorporate auto boot feature for
+ arndale board.
+
+Signed-off-by: Shivamurthy Shastri <shiva.murthy@samsung.com>
+---
+ ArmPlatformPkg/Bds/BootOption.c | 71 ++++++++++++++++++++++++++++++++++++++---
+ 1 file changed, 67 insertions(+), 4 deletions(-)
+
+diff --git a/ArmPlatformPkg/Bds/BootOption.c b/ArmPlatformPkg/Bds/BootOption.c
+index 289d36a..468050d 100644
+--- a/ArmPlatformPkg/Bds/BootOption.c
++++ b/ArmPlatformPkg/Bds/BootOption.c
+@@ -14,6 +14,11 @@
+
+ #include "BdsInternal.h"
+
++#include <Library/DxeServicesTableLib.h>
++#include <Protocol/BlockIo.h>
++#include <Guid/DebugImageInfoTable.h>
++#include <Protocol/DevicePathToText.h>
++
+ extern EFI_HANDLE mImageHandle;
+
+ EFI_STATUS
+@@ -22,26 +27,61 @@ BootOptionStart (
+ )
+ {
+ EFI_STATUS Status;
+- EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL* EfiDevicePathFromTextProtocol;
++ //EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL* EfiDevicePathFromTextProtocol;
+ UINT32 LoaderType;
+ ARM_BDS_LOADER_OPTIONAL_DATA* OptionalData;
+ ARM_BDS_LINUX_ARGUMENTS* LinuxArguments;
+ EFI_DEVICE_PATH_PROTOCOL* FdtDevicePath;
+- EFI_DEVICE_PATH_PROTOCOL* DefaultFdtDevicePath;
+- UINTN FdtDevicePathSize;
++ //EFI_DEVICE_PATH_PROTOCOL* DefaultFdtDevicePath;
++ //UINTN FdtDevicePathSize;
+ UINTN CmdLineSize;
+ UINTN InitrdSize;
+ EFI_DEVICE_PATH* Initrd;
+ UINT16 LoadOptionIndexSize;
+
++ UINTN HandleCount;
++ EFI_HANDLE *HandleBuffer;
++ UINTN Index;
++ //CHAR16* String;
++ //EFI_DEVICE_PATH_PROTOCOL* DevicePathProtocol;
++ EFI_DEVICE_PATH_TO_TEXT_PROTOCOL* DevicePathToTextProtocol;
++ EFI_DEVICE_PATH_PROTOCOL *LoadImageDevicePath;
++ EFI_DEVICE_PATH_PROTOCOL *FileSystemDevicePath;
++
+ if (IS_ARM_BDS_BOOTENTRY (BootOption)) {
+ Status = EFI_UNSUPPORTED;
+ OptionalData = BootOption->OptionalData;
+ LoaderType = ReadUnaligned32 ((CONST UINT32*)&OptionalData->Header.LoaderType);
+
++ BdsConnectAllDrivers();
++
++ Status = gBS->LocateProtocol(&gEfiDevicePathToTextProtocolGuid, NULL, (VOID **)&DevicePathToTextProtocol);
++ if (EFI_ERROR (Status)) {
++ AsciiPrint ("Did not find the DevicePathToTextProtocol.\n");
++ return Status;
++ }
++
++ Status = gBS->LocateHandleBuffer (ByProtocol, &gEfiBlockIoProtocolGuid, NULL, &HandleCount, &HandleBuffer);
++ if (EFI_ERROR (Status)) {
++ AsciiPrint ("No device path found\n");
++ return Status;
++ }
++
++ /*for (Index = 0; Index < HandleCount; Index++) {
++ Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiDevicePathProtocolGuid, (VOID **)&DevicePathProtocol);
++ String = DevicePathToTextProtocol->ConvertDevicePathToText(DevicePathProtocol,TRUE,TRUE);
++ Print (L"[0x%X] %s\n",(UINT32)HandleBuffer[Index], String);
++ }*/
++
++ for (Index = 0; Index < HandleCount; Index++) {
++ //Get the device path
++ FileSystemDevicePath = DevicePathFromHandle(HandleBuffer[Index]);
++ if (FileSystemDevicePath == NULL) {
++ continue;
++ }
++
+ if (LoaderType == BDS_LOADER_EFI_APPLICATION) {
+ // Need to connect every drivers to ensure no dependencies are missing for the application
+- BdsConnectAllDrivers();
+
+ Status = BdsStartEfiApplication (mImageHandle, BootOption->FilePathList, 0, NULL);
+ } else if (LoaderType == BDS_LOADER_KERNEL_LINUX_ATAG) {
+@@ -55,9 +95,18 @@ BootOptionStart (
+ Initrd = NULL;
+ }
+
++ //Check if zImage file on SD-MMC.
++ LoadImageDevicePath = FileDevicePath(HandleBuffer[Index], L"uImage");
++ Status = BdsBootLinuxAtag (LoadImageDevicePath, Initrd, (CHAR8*)(LinuxArguments + 1));
++ if (EFI_ERROR(Status)) {
++ continue;
++ }
++
++#if 0
+ Status = BdsBootLinuxAtag (BootOption->FilePathList,
+ Initrd, // Initrd
+ (CHAR8*)(LinuxArguments + 1)); // CmdLine
++#endif
+ } else if (LoaderType == BDS_LOADER_KERNEL_LINUX_FDT) {
+ LinuxArguments = &(OptionalData->Arguments.LinuxArguments);
+ CmdLineSize = ReadUnaligned16 ((CONST UINT16*)&LinuxArguments->CmdLineSize);
+@@ -69,6 +118,7 @@ BootOptionStart (
+ Initrd = NULL;
+ }
+
++#if 0
+ // Get the default FDT device path
+ Status = gBS->LocateProtocol (&gEfiDevicePathFromTextProtocolGuid, NULL, (VOID **)&EfiDevicePathFromTextProtocol);
+ ASSERT_EFI_ERROR(Status);
+@@ -78,13 +128,26 @@ BootOptionStart (
+ FdtDevicePathSize = GetDevicePathSize (DefaultFdtDevicePath);
+ Status = GetEnvironmentVariable ((CHAR16 *)L"Fdt", DefaultFdtDevicePath, &FdtDevicePathSize, (VOID **)&FdtDevicePath);
+ ASSERT_EFI_ERROR(Status);
++#endif
++
++ //Check if zImage file on SD-MMC.
++ LoadImageDevicePath = FileDevicePath(HandleBuffer[Index], L"uImage");
++ FdtDevicePath = FileDevicePath(HandleBuffer[Index], L"exynos5250-arndale.dtb");
++ Status = BdsBootLinuxFdt (LoadImageDevicePath, Initrd, (CHAR8*)(LinuxArguments + 1), FdtDevicePath);
++ FreePool (FdtDevicePath);
++ if (EFI_ERROR(Status)) {
++ continue;
++ }
++ }
+
++#if 0
+ Status = BdsBootLinuxFdt (BootOption->FilePathList,
+ Initrd, // Initrd
+ (CHAR8*)(LinuxArguments + 1),
+ FdtDevicePath);
+
+ FreePool (FdtDevicePath);
++#endif
+ }
+ } else {
+ // Set BootCurrent variable
+--
+1.8.0
+