From e2ca350e698d3ec8ad42976e390c99949ba2d25c Mon Sep 17 00:00:00 2001 From: Rony Nandy Date: Wed, 5 Dec 2012 16:45:12 +0530 Subject: Samsung/Arndale: Initial Commit Signed-off-by: Rony Nandy Signed-off-by: Shivamurthy Shastri --- SamsungPlatformPkg/Apps/Ebl.efi | Bin 0 -> 121600 bytes .../TestApps/HashServicesTest/HashServicesTest.c | 54 + .../TestApps/HashServicesTest/HashServicesTest.inf | 46 + .../MiscellaneousServicesTest.c | 143 ++ .../MiscellaneousServicesTest.inf | 65 + .../TestApps/RngServicesTest/RngServicesTest.c | 56 + .../TestApps/RngServicesTest/RngServicesTest.inf | 41 + .../TestApps/TimeServicesTest/TimeServicesTest.c | 156 ++ .../TestApps/TimeServicesTest/TimeServicesTest.inf | 52 + .../VariableServicesTestNonSec.c | 193 ++ .../VariableServicesTestNonSec.inf | 64 + SamsungPlatformPkg/Apps/Tools/fwupdate/fwupdate.c | 541 +++++ .../Apps/Tools/fwupdate/fwupdate_5250.inf | 54 + .../Apps/Tools/mkbl2/5250/fwbl1_5250.bin | Bin 0 -> 8192 bytes .../Apps/Tools/mkbl2/5250/fwbl1_5250_evt1.bin | Bin 0 -> 8192 bytes .../Apps/Tools/mkbl2/5250/fwbl1_5250_evt1_pop.bin | Bin 0 -> 8192 bytes .../Tools/mkbl2/5250/fwbl2-5250-ddr3-no-tz.bin | Bin 0 -> 16384 bytes .../mkbl2/5250/fwbl2-5250-none-evt1-no-tz.bin | Bin 0 -> 16384 bytes SamsungPlatformPkg/Apps/Tools/mkbl2/Makefile | 21 + SamsungPlatformPkg/Apps/Tools/mkbl2/imgburn.sh | 57 + SamsungPlatformPkg/Apps/Tools/mkbl2/mkbl2.c | 88 + .../ArndaleBoardPkg/ArndaleBoardPkg.dec | 43 + .../ArndaleBoardPkg/ArndaleBoardPkg.dsc.inc | 314 +++ .../Debugger_scripts/EBLoadSecSyms.inc | 15 + .../ArndaleBoardPkg/Debugger_scripts/EfiFuncs.inc | 463 ++++ .../Debugger_scripts/rvi_boot_from_ram.inc | 20 + .../Debugger_scripts/rvi_convert_symbols.sh | 22 + .../Debugger_scripts/rvi_hw_setup.inc | 67 + .../Debugger_scripts/rvi_load_symbols.inc | 21 + .../Debugger_scripts/rvi_symbols_macros.inc | 193 ++ .../Debugger_scripts/rvi_unload_symbols.inc | 118 + SamsungPlatformPkg/ArndaleBoardPkg/FvbDxe/FvbDxe.c | 621 ++++++ .../ArndaleBoardPkg/FvbDxe/FvbDxe.inf | 57 + .../Library/ArndaleBoardLib/Exynos5250/Board.c | 226 ++ .../Library/ArndaleBoardLib/Exynos5250/BoardBoot.S | 468 ++++ .../ArndaleBoardLib/Exynos5250/BoardBoot.asm | 52 + .../ArndaleBoardLib/Exynos5250/BoardHelper.S | 71 + .../ArndaleBoardLib/Exynos5250/BoardHelper.asm | 73 + .../ArndaleBoardLib/Exynos5250/BoardLib.inf | 69 + .../Library/ArndaleBoardLib/Exynos5250/BoardMem.c | 221 ++ .../Library/ArndaleBoardLib/Exynos5250/BoardSec.c | 52 + .../ArndaleBoardLib/Exynos5250/BoardSecLib.inf | 60 + .../Library/ArndaleBoardLib/Exynos5250/dmc_init.c | 787 +++++++ .../ArndaleBoardLib/Exynos5250/mem_init_ddr3.S | 412 ++++ .../DebugAgentTimerLib/DebugAgentTimerLib.c | 78 + .../DebugAgentTimerLib/DebugAgentTimerLib.inf | 37 + .../ArndaleBoardPkg/arndale-Exynos5250.dsc | 377 ++++ .../ArndaleBoardPkg/arndale-Exynos5250.fdf | 409 ++++ .../Exynos5250/Drivers/DisplayDxe/DisplayDxe.c | 693 ++++++ .../Exynos5250/Drivers/DisplayDxe/DisplayDxe.h | 277 +++ .../Exynos5250/Drivers/DisplayDxe/DisplayDxe.inf | 65 + .../ExynosPkg/Exynos5250/Drivers/EthDxe/EthDxe.c | 788 +++++++ .../ExynosPkg/Exynos5250/Drivers/EthDxe/EthDxe.h | 612 +++++ .../ExynosPkg/Exynos5250/Drivers/EthDxe/EthDxe.inf | 59 + .../Exynos5250/Drivers/Gic400Dxe/PL390Gic.c | 70 + .../Exynos5250/Drivers/Gic400Dxe/PL390GicDxe.c | 415 ++++ .../Exynos5250/Drivers/Gic400Dxe/PL390GicDxe.inf | 54 + .../Exynos5250/Drivers/Gic400Dxe/PL390GicLib.inf | 28 + .../Exynos5250/Drivers/Gic400Dxe/PL390GicNonSec.c | 44 + .../Exynos5250/Drivers/Gic400Dxe/PL390GicSec.c | 118 + .../Drivers/Gic400Dxe/PL390GicSecLib.inf | 38 + .../ExynosPkg/Exynos5250/Drivers/Gpio/Gpio.c | 177 ++ .../ExynosPkg/Exynos5250/Drivers/Gpio/Gpio.inf | 46 + .../ExynosPkg/Exynos5250/Drivers/HashDxe/HashDxe.c | 241 ++ .../ExynosPkg/Exynos5250/Drivers/HashDxe/HashDxe.h | 417 ++++ .../Exynos5250/Drivers/HashDxe/HashDxe.inf | 57 + .../Exynos5250/Drivers/OhciDxe/ComponentName.c | 231 ++ .../Exynos5250/Drivers/OhciDxe/ComponentName.h | 145 ++ .../ExynosPkg/Exynos5250/Drivers/OhciDxe/Ohci.c | 2345 ++++++++++++++++++++ .../ExynosPkg/Exynos5250/Drivers/OhciDxe/Ohci.h | 229 ++ .../Exynos5250/Drivers/OhciDxe/OhciDebug.c | 181 ++ .../Exynos5250/Drivers/OhciDxe/OhciDebug.h | 51 + .../Exynos5250/Drivers/OhciDxe/OhciDxe.inf | 88 + .../Exynos5250/Drivers/OhciDxe/OhciQueue.c | 993 +++++++++ .../Exynos5250/Drivers/OhciDxe/OhciQueue.h | 395 ++++ .../ExynosPkg/Exynos5250/Drivers/OhciDxe/OhciReg.c | 292 +++ .../ExynosPkg/Exynos5250/Drivers/OhciDxe/OhciReg.h | 286 +++ .../Exynos5250/Drivers/OhciDxe/OhciSched.c | 1254 +++++++++++ .../Exynos5250/Drivers/OhciDxe/OhciSched.h | 270 +++ .../Exynos5250/Drivers/OhciDxe/UsbHcMem.c | 564 +++++ .../Exynos5250/Drivers/OhciDxe/UsbHcMem.h | 161 ++ .../Exynos5250/Drivers/PciEmulation/Exynos5_USB.c | 353 +++ .../Drivers/PciEmulation/Exynos5_USB2Phy.h | 114 + .../Drivers/PciEmulation/Exynos5_USB3Drd.h | 403 ++++ .../Drivers/PciEmulation/Exynos5_USB3Phy.h | 80 + .../Exynos5250/Drivers/PciEmulation/PciEmulation.c | 684 ++++++ .../Exynos5250/Drivers/PciEmulation/PciEmulation.h | 290 +++ .../Drivers/PciEmulation/PciEmulation.inf | 64 + .../Drivers/PciEmulation/PciRootBridgeIo.c | 306 +++ .../ExynosPkg/Exynos5250/Drivers/RngDxe/RngDxe.c | 120 + .../ExynosPkg/Exynos5250/Drivers/RngDxe/RngDxe.h | 40 + .../ExynosPkg/Exynos5250/Drivers/RngDxe/RngDxe.inf | 49 + .../Exynos5250/Drivers/SDHCDxe_EVT1/SDHCDxe.c | 1349 +++++++++++ .../Exynos5250/Drivers/SDHCDxe_EVT1/SDHCDxe.h | 259 +++ .../Exynos5250/Drivers/SDHCDxe_EVT1/SDHCDxe.inf | 58 + .../Exynos5250/Drivers/SDHCDxe_EVT1/SDHCDxe_5250.c | 658 ++++++ .../Exynos5250/Drivers/SDHCDxe_EVT1/SDHCDxe_5250.h | 323 +++ .../Exynos5250/Drivers/SDHCDxe_EVT1/SDHCDxe_CMD.h | 165 ++ .../Exynos5250/Drivers/TimerDxe/TimerDxe.c | 469 ++++ .../Exynos5250/Drivers/TimerDxe/TimerDxe.inf | 54 + .../ExynosPkg/Exynos5250/Drivers/eMMCDxe/eMMCDxe.c | 1381 ++++++++++++ .../ExynosPkg/Exynos5250/Drivers/eMMCDxe/eMMCDxe.h | 308 +++ .../Exynos5250/Drivers/eMMCDxe/eMMCDxe.inf | 64 + .../Exynos5250/Drivers/eMMCDxe/eMMCDxe_5250.c | 721 ++++++ .../Exynos5250/Drivers/eMMCDxe/eMMCDxe_5250.h | 322 +++ .../Exynos5250/Drivers/eMMCDxe/eMMCDxe_CMD.h | 165 ++ .../Exynos5250/Drivers/eMMCDxe/eMMC_Fvb.c | 587 +++++ .../ExynosPkg/Exynos5250/ExynosPkg.dec | 101 + .../Exynos5250/Include/Library/ExynosLib.h | 42 + .../Exynos5250/Include/Library/ExynosTimerLib.h | 56 + .../Exynos5250/Include/Library/MpParkLib.h | 51 + .../Exynos5250/Include/Library/com_dtypes.h | 186 ++ .../Exynos5250/Include/Platform/ArmPlatform.h | 692 ++++++ .../Exynos5250/Include/Platform/Arndale5250.h | 337 +++ .../Exynos5250/Include/Platform/Arndale5250_Val.h | 402 ++++ .../Exynos5250/Include/Platform/Exynos5250.h | 730 ++++++ .../Exynos5250/Include/Platform/Exynos5250_Evt1.h | 763 +++++++ .../Exynos5250/Include/Protocol/ExynosGpio.h | 199 ++ .../Exynos5250/Include/Protocol/ExynosRng.h | 52 + .../Exynos5250/Library/ExynosLib/ExynosLib.c | 51 + .../Exynos5250/Library/ExynosLib/ExynosLib.inf | 42 + .../Exynos5250/Library/GdbSerialLib/GdbSerialLib.c | 118 + .../Library/GdbSerialLib/GdbSerialLib.inf | 40 + .../Library/RealTimeClockLib/RealTimeClockLib.c | 364 +++ .../Library/RealTimeClockLib/RealTimeClockLib.inf | 42 + .../Library/ResetSystemLib/ResetSystemLib.c | 241 ++ .../Library/ResetSystemLib/ResetSystemLib.inf | 52 + .../Library/SerialPortLib/SerialPortLib_Evt1.c | 159 ++ .../Library/SerialPortLib/SerialPortLib_Evt1.inf | 38 + .../Exynos5250/Library/TimerLib/TimerLib.c | 287 +++ .../Exynos5250/Library/TimerLib/TimerLib.inf | 41 + .../Exynos5250/MemoryInitPei/MemoryInitPeiLib.c | 182 ++ .../Exynos5250/MemoryInitPei/MemoryInitPeiLib.inf | 69 + .../Exynos5250/MemoryInitPei/MemoryInitPeim.c | 157 ++ .../Exynos5250/MemoryInitPei/MemoryInitPeim.inf | 75 + .../Exynos5250/PlatformPei/PlatformPeiLib.c | 30 + .../Exynos5250/PlatformPei/PlatformPeiLib.inf | 53 + .../Exynos5250/PlatformPei/PlatformPeim.c | 138 ++ .../Exynos5250/PlatformPei/PlatformPeim.inf | 69 + .../ExynosPkg/Exynos5250/Sec/Helper.S | 84 + .../ExynosPkg/Exynos5250/Sec/Helper.asm | 75 + SamsungPlatformPkg/ExynosPkg/Exynos5250/Sec/Sec.c | 221 ++ .../ExynosPkg/Exynos5250/Sec/Sec.inf | 88 + .../ExynosPkg/Exynos5250/Sec/SecEntryPoint.S | 278 +++ .../ExynosPkg/Exynos5250/Sec/SecEntryPoint.asm | 112 + .../ExynosPkg/Exynos5250/Sec/SecFromTzsw.S | 13 + .../ExynosPkg/Exynos5250/Sec/SecInternal.h | 75 + SamsungPlatformPkg/ExynosPkg/Exynos5250/Sec/Smc.c | 109 + SamsungPlatformPkg/ExynosPkg/Exynos5250/Sec/Smc.h | 60 + .../Include/Library/PlatformBdsLib.h | 156 ++ .../Library/PlatformBdsLib/BdsPlatform.c | 588 +++++ .../Library/PlatformBdsLib/BdsPlatform.h | 130 ++ .../Library/PlatformBdsLib/PlatformBdsLib.inf | 63 + .../Library/PlatformBdsLib/PlatformData.c | 88 + SamsungPlatformPkg/Logo/Logo.bmp | Bin 0 -> 118838 bytes SamsungPlatformPkg/README | 48 + SamsungPlatformPkg/SamsungPlatformPkg.dec | 42 + 157 files changed, 36136 insertions(+) create mode 100644 SamsungPlatformPkg/Apps/Ebl.efi create mode 100644 SamsungPlatformPkg/Apps/TestApps/HashServicesTest/HashServicesTest.c create mode 100644 SamsungPlatformPkg/Apps/TestApps/HashServicesTest/HashServicesTest.inf create mode 100644 SamsungPlatformPkg/Apps/TestApps/MiscellaneousServicesTest/MiscellaneousServicesTest.c create mode 100644 SamsungPlatformPkg/Apps/TestApps/MiscellaneousServicesTest/MiscellaneousServicesTest.inf create mode 100644 SamsungPlatformPkg/Apps/TestApps/RngServicesTest/RngServicesTest.c create mode 100644 SamsungPlatformPkg/Apps/TestApps/RngServicesTest/RngServicesTest.inf create mode 100644 SamsungPlatformPkg/Apps/TestApps/TimeServicesTest/TimeServicesTest.c create mode 100644 SamsungPlatformPkg/Apps/TestApps/TimeServicesTest/TimeServicesTest.inf create mode 100644 SamsungPlatformPkg/Apps/TestApps/VariableServicesTestNonSec/VariableServicesTestNonSec.c create mode 100644 SamsungPlatformPkg/Apps/TestApps/VariableServicesTestNonSec/VariableServicesTestNonSec.inf create mode 100755 SamsungPlatformPkg/Apps/Tools/fwupdate/fwupdate.c create mode 100644 SamsungPlatformPkg/Apps/Tools/fwupdate/fwupdate_5250.inf create mode 100644 SamsungPlatformPkg/Apps/Tools/mkbl2/5250/fwbl1_5250.bin create mode 100644 SamsungPlatformPkg/Apps/Tools/mkbl2/5250/fwbl1_5250_evt1.bin create mode 100644 SamsungPlatformPkg/Apps/Tools/mkbl2/5250/fwbl1_5250_evt1_pop.bin create mode 100644 SamsungPlatformPkg/Apps/Tools/mkbl2/5250/fwbl2-5250-ddr3-no-tz.bin create mode 100644 SamsungPlatformPkg/Apps/Tools/mkbl2/5250/fwbl2-5250-none-evt1-no-tz.bin create mode 100644 SamsungPlatformPkg/Apps/Tools/mkbl2/Makefile create mode 100755 SamsungPlatformPkg/Apps/Tools/mkbl2/imgburn.sh create mode 100644 SamsungPlatformPkg/Apps/Tools/mkbl2/mkbl2.c create mode 100644 SamsungPlatformPkg/ArndaleBoardPkg/ArndaleBoardPkg.dec create mode 100644 SamsungPlatformPkg/ArndaleBoardPkg/ArndaleBoardPkg.dsc.inc create mode 100644 SamsungPlatformPkg/ArndaleBoardPkg/Debugger_scripts/EBLoadSecSyms.inc create mode 100644 SamsungPlatformPkg/ArndaleBoardPkg/Debugger_scripts/EfiFuncs.inc create mode 100644 SamsungPlatformPkg/ArndaleBoardPkg/Debugger_scripts/rvi_boot_from_ram.inc create mode 100644 SamsungPlatformPkg/ArndaleBoardPkg/Debugger_scripts/rvi_convert_symbols.sh create mode 100644 SamsungPlatformPkg/ArndaleBoardPkg/Debugger_scripts/rvi_hw_setup.inc create mode 100644 SamsungPlatformPkg/ArndaleBoardPkg/Debugger_scripts/rvi_load_symbols.inc create mode 100644 SamsungPlatformPkg/ArndaleBoardPkg/Debugger_scripts/rvi_symbols_macros.inc create mode 100644 SamsungPlatformPkg/ArndaleBoardPkg/Debugger_scripts/rvi_unload_symbols.inc create mode 100755 SamsungPlatformPkg/ArndaleBoardPkg/FvbDxe/FvbDxe.c create mode 100755 SamsungPlatformPkg/ArndaleBoardPkg/FvbDxe/FvbDxe.inf create mode 100644 SamsungPlatformPkg/ArndaleBoardPkg/Library/ArndaleBoardLib/Exynos5250/Board.c create mode 100755 SamsungPlatformPkg/ArndaleBoardPkg/Library/ArndaleBoardLib/Exynos5250/BoardBoot.S create mode 100644 SamsungPlatformPkg/ArndaleBoardPkg/Library/ArndaleBoardLib/Exynos5250/BoardBoot.asm create mode 100644 SamsungPlatformPkg/ArndaleBoardPkg/Library/ArndaleBoardLib/Exynos5250/BoardHelper.S create mode 100644 SamsungPlatformPkg/ArndaleBoardPkg/Library/ArndaleBoardLib/Exynos5250/BoardHelper.asm create mode 100755 SamsungPlatformPkg/ArndaleBoardPkg/Library/ArndaleBoardLib/Exynos5250/BoardLib.inf create mode 100755 SamsungPlatformPkg/ArndaleBoardPkg/Library/ArndaleBoardLib/Exynos5250/BoardMem.c create mode 100644 SamsungPlatformPkg/ArndaleBoardPkg/Library/ArndaleBoardLib/Exynos5250/BoardSec.c create mode 100755 SamsungPlatformPkg/ArndaleBoardPkg/Library/ArndaleBoardLib/Exynos5250/BoardSecLib.inf create mode 100644 SamsungPlatformPkg/ArndaleBoardPkg/Library/ArndaleBoardLib/Exynos5250/dmc_init.c create mode 100755 SamsungPlatformPkg/ArndaleBoardPkg/Library/ArndaleBoardLib/Exynos5250/mem_init_ddr3.S create mode 100644 SamsungPlatformPkg/ArndaleBoardPkg/Library/DebugAgentTimerLib/DebugAgentTimerLib.c create mode 100644 SamsungPlatformPkg/ArndaleBoardPkg/Library/DebugAgentTimerLib/DebugAgentTimerLib.inf create mode 100755 SamsungPlatformPkg/ArndaleBoardPkg/arndale-Exynos5250.dsc create mode 100755 SamsungPlatformPkg/ArndaleBoardPkg/arndale-Exynos5250.fdf create mode 100644 SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/DisplayDxe/DisplayDxe.c create mode 100644 SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/DisplayDxe/DisplayDxe.h create mode 100644 SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/DisplayDxe/DisplayDxe.inf create mode 100644 SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/EthDxe/EthDxe.c create mode 100644 SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/EthDxe/EthDxe.h create mode 100644 SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/EthDxe/EthDxe.inf create mode 100644 SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/Gic400Dxe/PL390Gic.c create mode 100644 SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/Gic400Dxe/PL390GicDxe.c create mode 100644 SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/Gic400Dxe/PL390GicDxe.inf create mode 100644 SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/Gic400Dxe/PL390GicLib.inf create mode 100644 SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/Gic400Dxe/PL390GicNonSec.c create mode 100644 SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/Gic400Dxe/PL390GicSec.c create mode 100644 SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/Gic400Dxe/PL390GicSecLib.inf create mode 100644 SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/Gpio/Gpio.c create mode 100644 SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/Gpio/Gpio.inf create mode 100644 SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/HashDxe/HashDxe.c create mode 100644 SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/HashDxe/HashDxe.h create mode 100644 SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/HashDxe/HashDxe.inf create mode 100644 SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/OhciDxe/ComponentName.c create mode 100644 SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/OhciDxe/ComponentName.h create mode 100644 SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/OhciDxe/Ohci.c create mode 100644 SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/OhciDxe/Ohci.h create mode 100644 SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/OhciDxe/OhciDebug.c create mode 100644 SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/OhciDxe/OhciDebug.h create mode 100644 SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/OhciDxe/OhciDxe.inf create mode 100644 SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/OhciDxe/OhciQueue.c create mode 100644 SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/OhciDxe/OhciQueue.h create mode 100644 SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/OhciDxe/OhciReg.c create mode 100644 SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/OhciDxe/OhciReg.h create mode 100644 SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/OhciDxe/OhciSched.c create mode 100644 SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/OhciDxe/OhciSched.h create mode 100644 SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/OhciDxe/UsbHcMem.c create mode 100644 SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/OhciDxe/UsbHcMem.h create mode 100644 SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/PciEmulation/Exynos5_USB.c create mode 100644 SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/PciEmulation/Exynos5_USB2Phy.h create mode 100644 SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/PciEmulation/Exynos5_USB3Drd.h create mode 100644 SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/PciEmulation/Exynos5_USB3Phy.h create mode 100644 SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/PciEmulation/PciEmulation.c create mode 100644 SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/PciEmulation/PciEmulation.h create mode 100644 SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/PciEmulation/PciEmulation.inf create mode 100644 SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/PciEmulation/PciRootBridgeIo.c create mode 100644 SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/RngDxe/RngDxe.c create mode 100644 SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/RngDxe/RngDxe.h create mode 100644 SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/RngDxe/RngDxe.inf create mode 100755 SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/SDHCDxe_EVT1/SDHCDxe.c create mode 100755 SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/SDHCDxe_EVT1/SDHCDxe.h create mode 100755 SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/SDHCDxe_EVT1/SDHCDxe.inf create mode 100755 SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/SDHCDxe_EVT1/SDHCDxe_5250.c create mode 100755 SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/SDHCDxe_EVT1/SDHCDxe_5250.h create mode 100755 SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/SDHCDxe_EVT1/SDHCDxe_CMD.h create mode 100644 SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/TimerDxe/TimerDxe.c create mode 100644 SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/TimerDxe/TimerDxe.inf create mode 100755 SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/eMMCDxe/eMMCDxe.c create mode 100755 SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/eMMCDxe/eMMCDxe.h create mode 100755 SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/eMMCDxe/eMMCDxe.inf create mode 100755 SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/eMMCDxe/eMMCDxe_5250.c create mode 100755 SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/eMMCDxe/eMMCDxe_5250.h create mode 100755 SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/eMMCDxe/eMMCDxe_CMD.h create mode 100755 SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/eMMCDxe/eMMC_Fvb.c create mode 100755 SamsungPlatformPkg/ExynosPkg/Exynos5250/ExynosPkg.dec create mode 100644 SamsungPlatformPkg/ExynosPkg/Exynos5250/Include/Library/ExynosLib.h create mode 100644 SamsungPlatformPkg/ExynosPkg/Exynos5250/Include/Library/ExynosTimerLib.h create mode 100644 SamsungPlatformPkg/ExynosPkg/Exynos5250/Include/Library/MpParkLib.h create mode 100644 SamsungPlatformPkg/ExynosPkg/Exynos5250/Include/Library/com_dtypes.h create mode 100755 SamsungPlatformPkg/ExynosPkg/Exynos5250/Include/Platform/ArmPlatform.h create mode 100644 SamsungPlatformPkg/ExynosPkg/Exynos5250/Include/Platform/Arndale5250.h create mode 100755 SamsungPlatformPkg/ExynosPkg/Exynos5250/Include/Platform/Arndale5250_Val.h create mode 100644 SamsungPlatformPkg/ExynosPkg/Exynos5250/Include/Platform/Exynos5250.h create mode 100755 SamsungPlatformPkg/ExynosPkg/Exynos5250/Include/Platform/Exynos5250_Evt1.h create mode 100644 SamsungPlatformPkg/ExynosPkg/Exynos5250/Include/Protocol/ExynosGpio.h create mode 100644 SamsungPlatformPkg/ExynosPkg/Exynos5250/Include/Protocol/ExynosRng.h create mode 100644 SamsungPlatformPkg/ExynosPkg/Exynos5250/Library/ExynosLib/ExynosLib.c create mode 100644 SamsungPlatformPkg/ExynosPkg/Exynos5250/Library/ExynosLib/ExynosLib.inf create mode 100644 SamsungPlatformPkg/ExynosPkg/Exynos5250/Library/GdbSerialLib/GdbSerialLib.c create mode 100644 SamsungPlatformPkg/ExynosPkg/Exynos5250/Library/GdbSerialLib/GdbSerialLib.inf create mode 100644 SamsungPlatformPkg/ExynosPkg/Exynos5250/Library/RealTimeClockLib/RealTimeClockLib.c create mode 100644 SamsungPlatformPkg/ExynosPkg/Exynos5250/Library/RealTimeClockLib/RealTimeClockLib.inf create mode 100644 SamsungPlatformPkg/ExynosPkg/Exynos5250/Library/ResetSystemLib/ResetSystemLib.c create mode 100644 SamsungPlatformPkg/ExynosPkg/Exynos5250/Library/ResetSystemLib/ResetSystemLib.inf create mode 100755 SamsungPlatformPkg/ExynosPkg/Exynos5250/Library/SerialPortLib/SerialPortLib_Evt1.c create mode 100755 SamsungPlatformPkg/ExynosPkg/Exynos5250/Library/SerialPortLib/SerialPortLib_Evt1.inf create mode 100644 SamsungPlatformPkg/ExynosPkg/Exynos5250/Library/TimerLib/TimerLib.c create mode 100644 SamsungPlatformPkg/ExynosPkg/Exynos5250/Library/TimerLib/TimerLib.inf create mode 100644 SamsungPlatformPkg/ExynosPkg/Exynos5250/MemoryInitPei/MemoryInitPeiLib.c create mode 100644 SamsungPlatformPkg/ExynosPkg/Exynos5250/MemoryInitPei/MemoryInitPeiLib.inf create mode 100644 SamsungPlatformPkg/ExynosPkg/Exynos5250/MemoryInitPei/MemoryInitPeim.c create mode 100644 SamsungPlatformPkg/ExynosPkg/Exynos5250/MemoryInitPei/MemoryInitPeim.inf create mode 100644 SamsungPlatformPkg/ExynosPkg/Exynos5250/PlatformPei/PlatformPeiLib.c create mode 100644 SamsungPlatformPkg/ExynosPkg/Exynos5250/PlatformPei/PlatformPeiLib.inf create mode 100644 SamsungPlatformPkg/ExynosPkg/Exynos5250/PlatformPei/PlatformPeim.c create mode 100755 SamsungPlatformPkg/ExynosPkg/Exynos5250/PlatformPei/PlatformPeim.inf create mode 100644 SamsungPlatformPkg/ExynosPkg/Exynos5250/Sec/Helper.S create mode 100644 SamsungPlatformPkg/ExynosPkg/Exynos5250/Sec/Helper.asm create mode 100644 SamsungPlatformPkg/ExynosPkg/Exynos5250/Sec/Sec.c create mode 100644 SamsungPlatformPkg/ExynosPkg/Exynos5250/Sec/Sec.inf create mode 100644 SamsungPlatformPkg/ExynosPkg/Exynos5250/Sec/SecEntryPoint.S create mode 100644 SamsungPlatformPkg/ExynosPkg/Exynos5250/Sec/SecEntryPoint.asm create mode 100644 SamsungPlatformPkg/ExynosPkg/Exynos5250/Sec/SecFromTzsw.S create mode 100644 SamsungPlatformPkg/ExynosPkg/Exynos5250/Sec/SecInternal.h create mode 100644 SamsungPlatformPkg/ExynosPkg/Exynos5250/Sec/Smc.c create mode 100644 SamsungPlatformPkg/ExynosPkg/Exynos5250/Sec/Smc.h create mode 100644 SamsungPlatformPkg/Include/Library/PlatformBdsLib.h create mode 100644 SamsungPlatformPkg/Library/PlatformBdsLib/BdsPlatform.c create mode 100644 SamsungPlatformPkg/Library/PlatformBdsLib/BdsPlatform.h create mode 100644 SamsungPlatformPkg/Library/PlatformBdsLib/PlatformBdsLib.inf create mode 100644 SamsungPlatformPkg/Library/PlatformBdsLib/PlatformData.c create mode 100755 SamsungPlatformPkg/Logo/Logo.bmp create mode 100644 SamsungPlatformPkg/README create mode 100644 SamsungPlatformPkg/SamsungPlatformPkg.dec diff --git a/SamsungPlatformPkg/Apps/Ebl.efi b/SamsungPlatformPkg/Apps/Ebl.efi new file mode 100644 index 000000000..a5d637329 Binary files /dev/null and b/SamsungPlatformPkg/Apps/Ebl.efi 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 + +#include +#include +#include +#include +#include +#include + +#include +#include + +#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 +#include +#include +#include +#include +#include + +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.
+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 +#include +#include +#include +#include + +#include + +#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 +#include +#include +#include +#include +#include +#include + + +/** 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.
+ 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 +#include +#include +#include +#include +#include +#include + + +/** + 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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;iHandleProtocol(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.
+# +# 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 Binary files /dev/null and b/SamsungPlatformPkg/Apps/Tools/mkbl2/5250/fwbl1_5250.bin 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 Binary files /dev/null and b/SamsungPlatformPkg/Apps/Tools/mkbl2/5250/fwbl1_5250_evt1.bin 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 Binary files /dev/null and b/SamsungPlatformPkg/Apps/Tools/mkbl2/5250/fwbl1_5250_evt1_pop.bin 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 Binary files /dev/null and b/SamsungPlatformPkg/Apps/Tools/mkbl2/5250/fwbl2-5250-ddr3-no-tz.bin 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 Binary files /dev/null and b/SamsungPlatformPkg/Apps/Tools/mkbl2/5250/fwbl2-5250-none-evt1-no-tz.bin 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..409749b3f --- /dev/null +++ b/SamsungPlatformPkg/Apps/Tools/mkbl2/imgburn.sh @@ -0,0 +1,57 @@ +#!/bin/bash + + +IMAGE=../../../../../edk2-git/edk2/Build/Arndale-Exynos/DEBUG_ARMLINUXGCC/FV/ARNDALE_EFI.fd + +if [ $# -ne 2 ] +then + echo "" + echo "ERROR: Not input parameter for making image" + echo "" + echo "USAGE:" + echo " sudo ./imgburn.sh 5250 /dev/sdb" + echo "" + exit +fi + +# make mkbl2 +if [ ! -f mkbl2 ] +then + make +fi + +# make BL2 +if [ -f $IMAGE ] +then + ./mkbl2 $IMAGE + echo "BL2 image is created." + echo "" + echo ":::: You SHOULD check platform of ARNDALE_EFI.fd" + echo "" +else + echo "" + echo "ERROR: UEFI is not built.." + echo "" + exit +fi + +# select platform +if [ "$1" = "5250" ] +then + # write BL1 + dd if=./5250/fwbl1_5250.bin of=$2 seek=1 count=16 +else + echo "" + echo "ERROR: Please select platform.." + echo "" + exit +fi + + +# write BL2 +dd if=./fwbl2.bin of=$2 seek=17 count=32 + +# write bootloader file e.g. u-boot or UEFI firmware image +dd if=$IMAGE of=$2 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 +#include +#include +#include +#include + + +#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.
+# +# 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..04a18e9ea --- /dev/null +++ b/SamsungPlatformPkg/ArndaleBoardPkg/ArndaleBoardPkg.dsc.inc @@ -0,0 +1,314 @@ +# +# 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"SD-MMC Booting" + gArmPlatformTokenSpaceGuid.PcdDefaultBootDevicePath|L"VenHw(3A02E7FE-0649-4FB4-BE4F-A862CA1872A9)/HD(2,MBR,0x000A65DC,0x59B303,0x3B7C)/uImage" + gArmPlatformTokenSpaceGuid.PcdFdtDevicePath|L"VenHw(3A02E7FE-0649-4FB4-BE4F-A862CA1872A9)/HD(2,MBR,0x000A65DC,0x59B303,0x3B7C)/exynos5250-arndale.dtb" + gArmPlatformTokenSpaceGuid.PcdDefaultBootArgument|"root=/dev/mmcblk1p1 rw rootwait console=ttySAC2,115200n8 init --no-log" + gArmPlatformTokenSpaceGuid.PcdDefaultBootType|2 + + # 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 +// +// 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.
+# +# 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.
+// +// 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.
+// +// 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.
+// +// 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.
+// +// 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.
+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 +#include +#include +#include +#include +#include +#include +#include +#include + + +//#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;iHandleProtocol(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.
+# 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 +#include +#include +#include + +#include +#include +#include + +/** + 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 +#include +#include +#include +#include + +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 +#include +#include +#include +#include + + 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..1975e6517 --- /dev/null +++ b/SamsungPlatformPkg/ArndaleBoardPkg/Library/ArndaleBoardLib/Exynos5250/BoardHelper.S @@ -0,0 +1,71 @@ +# +# 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 +#include +#include +#include +#.include AsmMacroIoLib.inc + +#include + +.text +.align 2 + +GCC_ASM_EXPORT(ArmGetCpuCountPerCluster) + +# 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_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 +#include +#include + +#include + +#include + + 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 +#include +#include +#include +#include +#include + +// 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 +#include +#include +#include +#include +#include + + +/** + 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 +#include +#include +#include +#include + +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.
+ + 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 + +#include + + +/** + 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.
+# +# 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..6adb2ce87 --- /dev/null +++ b/SamsungPlatformPkg/ArndaleBoardPkg/arndale-Exynos5250.dsc @@ -0,0 +1,377 @@ +# +# 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 + +[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 == -mcpu=cortex-a8 -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] +!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|0x50000000 #0x40000000 + gArmTokenSpaceGuid.PcdSystemMemorySize|0x50000000 + + # 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 { + + ArmGicLib|SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/Gic400Dxe/PL390GicSecLib.inf + } + + # + # PEI Phase modules + # +!ifdef $(EDK2_SKIP_PEICORE) + ArmPlatformPkg/PrePi/PeiMPCore.inf { + + 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 { + + ArmPlatformGlobalVariableLib|ArmPlatformPkg/Library/ArmPlatformGlobalVariableLib/Pei/PeiArmPlatformGlobalVariableLib.inf + } + MdeModulePkg/Core/Pei/PeiMain.inf + MdeModulePkg/Universal/PCD/Pei/Pcd.inf { + + 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 + #Nt32Pkg/BootModePei/BootModePei.inf + MdeModulePkg/Universal/Variable/Pei/VariablePei.inf + MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf { + + NULL|IntelFrameworkModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf + } +!endif + + # + # DXE + # + MdeModulePkg/Core/Dxe/DxeMain.inf { + + 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/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf + #MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.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/ConSplitterDxe/ConSplitterDxe.inf + MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsoleDxe.inf + MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf + EmbeddedPkg/SimpleTextInOutSerial/SimpleTextInOutSerial.inf + #EmbeddedPkg/SerialDxe/SerialDxe.inf + + MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf + MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.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{ + + ExynosLib|SamsungPlatformPkg/ExynosPkg/Exynos5250/Library/ExynosLib/ExynosLib.inf + } + + # + # Semi-hosting filesystem + # + ArmPkg/Filesystem/SemihostFs/SemihostFs.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 + FatPkg/EnhancedFatDxe/Fat.inf + MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf + + # + # Application + # + EmbeddedPkg/Ebl/Ebl.inf + #SamsungPlatformPkg/Apps/TestApps/HashServicesTest/HashServicesTest.inf + #SamsungPlatformPkg/Apps/TestApps/RngServicesTest/RngServicesTest.inf + + # + # 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 + #SamsungPlatformPkg/ExynosPkg/Exynos5250/OhciDxe/OhciDxe.inf + MdeModulePkg/Bus/Pci/EhciDxe/EhciDxe.inf + MdeModulePkg/Bus/Pci/XhciDxe/XhciDxe.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 { + + LockBoxLib|MdeModulePkg/Library/LockBoxNullLib/LockBoxNullLib.inf + } + MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTableDxe/FirmwarePerformanceDxe.inf + #MdeModulePkg/Universal/Acpi/BootGraphicsResourceTableDxe/BootGraphicsResourceTableDxe.inf + + MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.inf + SamsungPlatformPkg/Apps/Tools/fwupdate/fwupdate_5250.inf + + # + # Crypto for Exynos + # + #SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/HashDxe/HashDxe.inf + + # + # Rng for Exynos + # + #SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/RngDxe/RngDxe.inf diff --git a/SamsungPlatformPkg/ArndaleBoardPkg/arndale-Exynos5250.fdf b/SamsungPlatformPkg/ArndaleBoardPkg/arndale-Exynos5250.fdf new file mode 100755 index 000000000..1040cc0d9 --- /dev/null +++ b/SamsungPlatformPkg/ArndaleBoardPkg/arndale-Exynos5250.fdf @@ -0,0 +1,409 @@ +# 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 = 0x00280000|gArmTokenSpaceGuid.PcdFdSize +ErasePolarity = 1 +BlockSize = 0x00014000 +NumBlocks = 0x20 + +################################################################################ +# +# 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 +# +################################################################################ + +0x0000000|0x00014000 +gArmTokenSpaceGuid.PcdSecureFvBaseAddress|gArmTokenSpaceGuid.PcdSecureFvSize +FV = FVMAIN_SEC + +0x00014000|0x00270000 +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 ArmPlatformPkg/Sec/Sec.inf + 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/Variable/RuntimeDxe/VariableRuntimeDxe.inf + #INF MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.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/ConSplitterDxe/ConSplitterDxe.inf + INF MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsoleDxe.inf + INF MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf + INF EmbeddedPkg/SimpleTextInOutSerial/SimpleTextInOutSerial.inf + #INF EmbeddedPkg/SerialDxe/SerialDxe.inf + + INF MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf + INF MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.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 + + # + # Semi-hosting filesystem + # + INF ArmPkg/Filesystem/SemihostFs/SemihostFs.inf + + # + # FAT filesystem + GPT/MBR partitioning + # + INF MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf + INF MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf + INF FatPkg/EnhancedFatDxe/Fat.inf + INF MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf + + # + # USB HOST STACK + # + INF SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/PciEmulation/PciEmulation.inf + #INF SamsungPlatformPkg/ExynosPkg/Exynos5250/OhciDxe/OhciDxe.inf + INF MdeModulePkg/Bus/Pci/EhciDxe/EhciDxe.inf + INF MdeModulePkg/Bus/Pci/XhciDxe/XhciDxe.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 + INF MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTableDxe/FirmwarePerformanceDxe.inf + #INF MdeModulePkg/Universal/Acpi/BootGraphicsResourceTableDxe/BootGraphicsResourceTableDxe.inf + + # Crypto for Exynos + # + #INF SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/HashDxe/HashDxe.inf + #INF SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/RngDxe/RngDxe.inf + + # + # UEFI application (Shell Embedded Boot Loader) + # + INF EmbeddedPkg/Ebl/Ebl.inf + #INF SamsungPlatformPkg/Apps/TestApps/HashServicesTest/HashServicesTest.inf + #INF SamsungPlatformPkg/Apps/TestApps/RngServicesTest/RngServicesTest.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.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..b9029c45d --- /dev/null +++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/DisplayDxe/DisplayDxe.c @@ -0,0 +1,693 @@ +/** @file + Template for Timer Architecture Protocol driver of the ARM flavor + + 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 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#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> 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 + ) +{ + EFI_STATUS Status=EFI_SUCCESS; + UINT8 *VidBuf, *BltBuf, *VidBuf1; + UINTN i, j; + + switch(BltOperation) { + case EfiBltVideoFill: + BltBuf = (UINT8 *)BltBuffer; + + for(i=0;iMode->FrameBufferBase + \ + (DestinationY + i)*This->Mode->Info->PixelsPerScanLine*sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL) + \ + DestinationX*sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL)); + + for(j=0;jCopyMem((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;iMode->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;jCopyMem((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;iMode->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;jCopyMem((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;iMode->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;jCopyMem((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(Status); + } + + 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.
+# 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.
+ + 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#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.
+# 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 +#include +#include +#include + +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.
+Portions copyright (c) 2010, Apple Inc. All rights reserved.
+Portions copyright (c) 2011-2012, ARM Ltd. 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. + +Module Name: + + Gic.c + +Abstract: + + Driver implementing the GIC interrupt controller protocol + +--*/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#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< 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.
+# Copyright (c) 2012, ARM Ltd. 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 = 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 +#include +#include + + +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..f7b6d7c3a --- /dev/null +++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/Gic400Dxe/PL390GicSec.c @@ -0,0 +1,118 @@ +/** @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 +#include +#include +#include +#include + +/* + * 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 (IS_PRIMARY_CORE(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..9e1fd0966 --- /dev/null +++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/Gic400Dxe/PL390GicSecLib.inf @@ -0,0 +1,38 @@ +#/* @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 + MdePkg/MdePkg.dec + +[LibraryClasses] + ArmLib + DebugLib + IoLib + PcdLib + +[FixedPcd.common] + gArmTokenSpaceGuid.PcdArmPrimaryCoreMask + gArmTokenSpaceGuid.PcdArmPrimaryCore 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.
+ + 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 +#include +#include +#include +#include +#include + + + +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.
+# 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 +#include +#include +#include +#include + +#include + +#include +#include + +#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.
+ + 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 + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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.
+# 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.
+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.
+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.
+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 + +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.
+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 + +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +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.
+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.
+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.
+# +# 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.
+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.
+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 +// +// +// + +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.
+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.
+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.
+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.
+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.
+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.
+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.
+ + 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 +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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 + * + * 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.
+ + 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.
+ + 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 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + + +//#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.
+ + 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.
+ + 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.
+ + 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 +#include +#include +#include +#include +#include + +#include + +#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.
+# 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..50e04279a --- /dev/null +++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/SDHCDxe_EVT1/SDHCDxe.c @@ -0,0 +1,1349 @@ +/** @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.
+ + 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 +#include +#include +#include +#include +#include +#include + +#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; + 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>3]))); + +} + + +#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; + 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; + 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; + UINT32 SdMmcBaseAddr; + SdMmcBaseAddr = PcdGet32(PcdSdMmcBase); + + // 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= 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.
+ + 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 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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.
+# 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..8b7eeb2c3 --- /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.
+ + 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 +#include +#include +#include +#include +#include +#include + + +#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.
+ + 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.
+ + 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.
+ + 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 +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +// 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.
+# 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..9d5a80a9f --- /dev/null +++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/eMMCDxe/eMMCDxe.c @@ -0,0 +1,1381 @@ +/** @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.
+ + 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 +#include +#include +#include +#include +#include +#include + +#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; + 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>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; + 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; + 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; + UINT32 SdMmcBaseAddr; + SdMmcBaseAddr = PcdGet32(PcdSdMmcCH0Base); + + // 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); + MSHC_EMMC_Boot_Open(); //do not close boot partition + 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= 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..9bbf13a20 --- /dev/null +++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/eMMCDxe/eMMCDxe.h @@ -0,0 +1,308 @@ +/** @file + + Copyright (c) 2011, 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 _MSHCDXE_H_ +#define _MSHCDXE_H_ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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 0x28 + +#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.
+# 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..676e330f0 --- /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.
+ + 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 +#include +#include +#include +#include +#include +#include +#include + + +#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.
+ + 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.
+ + 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.
+ + 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 +#include +#include +#include +#include +#include +#include + +#include +#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.
+# +# 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.
+ + 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.
+ + 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.
+ + 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 +#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 + * HeungJun Kim + * Inki Dae + * + * 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 /* 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.
+ + 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.
+ + 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.
+ + 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 +#include +#include + +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.
+# 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.
+ + 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 +#include +#include +#include + +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.
+# 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..7b83f0878 --- /dev/null +++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Library/RealTimeClockLib/RealTimeClockLib.c @@ -0,0 +1,364 @@ +/** @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.
+ + 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 +#include +#include +#include +#include +#include +#include +#include + + +/* + * Kimoon added on 2011.12.08 + */ +#include +#include + +#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_STATUS Status; + 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; + Status = 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.
+# +# 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.
+ + 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + + +/* 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.
+# +# 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.
+ + 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 +#include +#include +#include +#include + +/* + + 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.
+# 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.
+ + 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 +#include +#include +#include +#include +#include +#include + + +// 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.
+# 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 + +#include +#include +#include +#include +#include + +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.
+# 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 + +// +// The protocols, PPI and GUID defintions for this module +// +#include +#include +#include +// +// The Library classes this module consumes +// +#include +#include +#include +#include +#include +#include + +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.
+# 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 + +#include +#include +#include + +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 + +// +// The protocols, PPI and GUID defintions for this module +// +#include +#include +#include +#include +// +// The Library classes this module consumes +// +#include +#include +#include +#include +#include +#include +#include + +#include + +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..549171b3b --- /dev/null +++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Sec/Sec.c @@ -0,0 +1,221 @@ +/** @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 +#include +#include +#include +#include +#include +#include +#include +#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 (IS_PRIMARY_CORE(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 (IS_PRIMARY_CORE(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..854b26971 --- /dev/null +++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Sec/Sec.inf @@ -0,0 +1,88 @@ +#/** @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.PcdArmPrimaryCoreMask + gArmTokenSpaceGuid.PcdArmPrimaryCore + + 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..a10eae12a --- /dev/null +++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Sec/SecEntryPoint.S @@ -0,0 +1,278 @@ +// +// 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 +#include +#include +#include "SecInternal.h" + +.text +.align 3 + +GCC_ASM_IMPORT(CEntryPoint) +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) + +// 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) + // 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 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) + + // 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) + + 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, #0x28 + 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 +#include +#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 +#include +#include +#include +#include +#include +#include +#include + +#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..1177139c5 --- /dev/null +++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Sec/Smc.c @@ -0,0 +1,109 @@ +/** @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 ( + "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 + +/* 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.
+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 +#include + +/** + 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.
+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.
+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 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//#include +//#include +//#include + +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.
+# +# 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.
+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 +#include + + +// +// 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 Binary files /dev/null and b/SamsungPlatformPkg/Logo/Logo.bmp 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.
+# +# 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 }} -- cgit v1.2.3 From f49b33d96e115165ede9625d678f2a0648bb9ddc Mon Sep 17 00:00:00 2001 From: Shivamurthy Shastri Date: Thu, 6 Dec 2012 13:52:14 +0530 Subject: Samsung/Arndale: Auto-boot feature for ARNDALE board. Code searches for the FAT filesystem available in the card and boots the kernel. The FAT filesystem can contain kernel image and DT. Signed-off-by: Shivamurthy Shastri Signed-off-by: Rony Nandy --- ...-created-to-incorporate-auto-boot-feature.patch | 150 +++++++++++++++++++++ 1 file changed, 150 insertions(+) create mode 100644 SamsungPlatformPkg/patches/0001-The-patch-created-to-incorporate-auto-boot-feature.patch 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 +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 +--- + 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 ++#include ++#include ++#include ++ + 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 + -- cgit v1.2.3 From 3ae3df80579b3bc272fe6168487f262341852d21 Mon Sep 17 00:00:00 2001 From: Shivamurthy Shastri Date: Wed, 12 Dec 2012 18:26:22 +0530 Subject: Samsung/Arndale: Removed compiler errors for latest GCC toolchain. Signed-off-by: Shivamurthy Shastri Signed-off-by: Leif Lindholm Signed-off-by: Rony Nandy --- SamsungPlatformPkg/ArndaleBoardPkg/arndale-Exynos5250.dsc | 4 ++-- SamsungPlatformPkg/ArndaleBoardPkg/arndale-Exynos5250.fdf | 4 ++-- .../ExynosPkg/Exynos5250/Drivers/SDHCDxe_EVT1/SDHCDxe.c | 6 ++---- .../ExynosPkg/Exynos5250/Drivers/SDHCDxe_EVT1/SDHCDxe_5250.c | 4 ++-- SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/eMMCDxe/eMMCDxe.c | 6 ++---- .../ExynosPkg/Exynos5250/Drivers/eMMCDxe/eMMCDxe_5250.c | 4 ++-- .../Exynos5250/Library/RealTimeClockLib/RealTimeClockLib.c | 3 +-- SamsungPlatformPkg/ExynosPkg/Exynos5250/Sec/Smc.c | 1 + 8 files changed, 14 insertions(+), 18 deletions(-) diff --git a/SamsungPlatformPkg/ArndaleBoardPkg/arndale-Exynos5250.dsc b/SamsungPlatformPkg/ArndaleBoardPkg/arndale-Exynos5250.dsc index 6adb2ce87..243304538 100755 --- a/SamsungPlatformPkg/ArndaleBoardPkg/arndale-Exynos5250.dsc +++ b/SamsungPlatformPkg/ArndaleBoardPkg/arndale-Exynos5250.dsc @@ -274,7 +274,7 @@ #EmbeddedPkg/SerialDxe/SerialDxe.inf MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf - MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf + #MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf SamsungPlatformPkg/ArndaleBoardPkg/FvbDxe/FvbDxe.inf SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/TimerDxe/TimerDxe.inf @@ -345,7 +345,7 @@ SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/PciEmulation/PciEmulation.inf #SamsungPlatformPkg/ExynosPkg/Exynos5250/OhciDxe/OhciDxe.inf MdeModulePkg/Bus/Pci/EhciDxe/EhciDxe.inf - MdeModulePkg/Bus/Pci/XhciDxe/XhciDxe.inf + #MdeModulePkg/Bus/Pci/XhciDxe/XhciDxe.inf MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBusDxe.inf MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassStorageDxe.inf diff --git a/SamsungPlatformPkg/ArndaleBoardPkg/arndale-Exynos5250.fdf b/SamsungPlatformPkg/ArndaleBoardPkg/arndale-Exynos5250.fdf index 1040cc0d9..51eee1b06 100755 --- a/SamsungPlatformPkg/ArndaleBoardPkg/arndale-Exynos5250.fdf +++ b/SamsungPlatformPkg/ArndaleBoardPkg/arndale-Exynos5250.fdf @@ -173,7 +173,7 @@ READ_LOCK_STATUS = TRUE #INF EmbeddedPkg/SerialDxe/SerialDxe.inf INF MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf - INF MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf + #INF MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf !ifdef $(EXYNOS5250_EVT1) INF SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/Gic400Dxe/PL390GicDxe.inf @@ -214,7 +214,7 @@ READ_LOCK_STATUS = TRUE INF SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/PciEmulation/PciEmulation.inf #INF SamsungPlatformPkg/ExynosPkg/Exynos5250/OhciDxe/OhciDxe.inf INF MdeModulePkg/Bus/Pci/EhciDxe/EhciDxe.inf - INF MdeModulePkg/Bus/Pci/XhciDxe/XhciDxe.inf + #INF MdeModulePkg/Bus/Pci/XhciDxe/XhciDxe.inf INF MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBusDxe.inf INF MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassStorageDxe.inf diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/SDHCDxe_EVT1/SDHCDxe.c b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/SDHCDxe_EVT1/SDHCDxe.c index 50e04279a..70dbae15d 100755 --- a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/SDHCDxe_EVT1/SDHCDxe.c +++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/SDHCDxe_EVT1/SDHCDxe.c @@ -654,8 +654,6 @@ TransferBlock ( UINTN Cmd = 0; UINTN CmdInterruptEnable = 0; UINTN CmdArgument = 0; - UINT32 SdMmcBaseAddr; - SdMmcBaseAddr = PcdGet32(PcdSdMmcBase); // 1. FIFO reset // MSHC_SendCmd do the fifo reset @@ -757,13 +755,13 @@ DetectCard ( ) { EFI_STATUS Status; - UINT32 SdMmcBaseAddr; + //UINT32 SdMmcBaseAddr; //DEBUG ((EFI_D_INFO, "===================================\n")); DEBUG ((EFI_D_INFO, "===SDHC: Version %a ===\n", DateInformation)); //DEBUG ((EFI_D_INFO, "===================================\n")); - SdMmcBaseAddr = PcdGet32(PcdSdMmcBase); + //SdMmcBaseAddr = PcdGet32(PcdSdMmcBase); if (!CardPresent ()) { return EFI_NO_MEDIA; diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/SDHCDxe_EVT1/SDHCDxe_5250.c b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/SDHCDxe_EVT1/SDHCDxe_5250.c index 8b7eeb2c3..5408360b0 100755 --- a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/SDHCDxe_EVT1/SDHCDxe_5250.c +++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/SDHCDxe_EVT1/SDHCDxe_5250.c @@ -161,7 +161,7 @@ InitializeMSHC ( EFI_STATUS Status; EXYNOS_GPIO *Gpio; UINT32 CumBaseAddr; - UINT32 SdMmcBaseAddr; + //UINT32 SdMmcBaseAddr; UINT32 i, clock; volatile UINT32 ctl_val; @@ -170,7 +170,7 @@ InitializeMSHC ( ASSERT_EFI_ERROR(Status); CumBaseAddr = PcdGet32(PcdCmuBase); - SdMmcBaseAddr = PcdGet32(PcdSdMmcBase); + //SdMmcBaseAddr = PcdGet32(PcdSdMmcBase); //MmioWrite32((SdMmcBaseAddr + SDHC_SWRST_OFFSET), SRA); diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/eMMCDxe/eMMCDxe.c b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/eMMCDxe/eMMCDxe.c index 9d5a80a9f..c38001a5c 100755 --- a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/eMMCDxe/eMMCDxe.c +++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/eMMCDxe/eMMCDxe.c @@ -699,8 +699,6 @@ TransferBlock ( UINTN Cmd = 0; UINTN CmdInterruptEnable = 0; UINTN CmdArgument = 0; - UINT32 SdMmcBaseAddr; - SdMmcBaseAddr = PcdGet32(PcdSdMmcCH0Base); // 1. FIFO reset // MSHC_SendCmd do the fifo reset @@ -786,13 +784,13 @@ DetectCard ( ) { EFI_STATUS Status; - UINT32 SdMmcBaseAddr; + //UINT32 SdMmcBaseAddr; //DEBUG ((EFI_D_INFO, "===================================\n")); DEBUG ((EFI_D_INFO, "===MSHC: Version %a ===\n", DateInformation)); //DEBUG ((EFI_D_INFO, "===================================\n")); - SdMmcBaseAddr = PcdGet32(PcdSdMmcCH0Base); + //SdMmcBaseAddr = PcdGet32(PcdSdMmcCH0Base); if (!CardPresent ()) { return EFI_NO_MEDIA; diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/eMMCDxe/eMMCDxe_5250.c b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/eMMCDxe/eMMCDxe_5250.c index 676e330f0..511b079d4 100755 --- a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/eMMCDxe/eMMCDxe_5250.c +++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/eMMCDxe/eMMCDxe_5250.c @@ -164,7 +164,7 @@ InitializeMSHC ( EFI_STATUS Status; EXYNOS_GPIO *Gpio; UINT32 CumBaseAddr; - UINT32 SdMmcBaseAddr; + //UINT32 SdMmcBaseAddr; UINT32 i, clock; volatile UINT32 ctl_val; @@ -173,7 +173,7 @@ InitializeMSHC ( ASSERT_EFI_ERROR(Status); CumBaseAddr = PcdGet32(PcdCmuBase); - SdMmcBaseAddr = PcdGet32(PcdSdMmcCH0Base); + //SdMmcBaseAddr = PcdGet32(PcdSdMmcCH0Base); //MmioWrite32((SdMmcBaseAddr + SDHC_SWRST_OFFSET), SRA); diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Library/RealTimeClockLib/RealTimeClockLib.c b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Library/RealTimeClockLib/RealTimeClockLib.c index 7b83f0878..2325a31b0 100644 --- a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Library/RealTimeClockLib/RealTimeClockLib.c +++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Library/RealTimeClockLib/RealTimeClockLib.c @@ -286,7 +286,6 @@ LibRtcInitialize ( IN EFI_SYSTEM_TABLE *SystemTable ) { - EFI_STATUS Status; EFI_HANDLE Handle; EFI_TIME Time; @@ -325,7 +324,7 @@ LibRtcInitialize ( // Install the protocol Handle = NULL; - Status = gBS->InstallMultipleProtocolInterfaces ( + gBS->InstallMultipleProtocolInterfaces ( &Handle, &gEfiRealTimeClockArchProtocolGuid, NULL, NULL diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Sec/Smc.c b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Sec/Smc.c index 1177139c5..3de899a11 100644 --- a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Sec/Smc.c +++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Sec/Smc.c @@ -62,6 +62,7 @@ UINT32 exynos_smc(UINT32 cmd, UINT32 arg1, UINT32 arg2, UINT32 arg3) register UINT32 reg3 __asm__("r3") = arg3; __asm__ volatile ( + ".arch_extension sec\n" "smc 0\n" : "+r"(reg0), "+r"(reg1), "+r"(reg2), "+r"(reg3) -- cgit v1.2.3 From d9b8b5c45067cb3184829b01d5cd046630ff3810 Mon Sep 17 00:00:00 2001 From: Ryan Harkin Date: Wed, 12 Dec 2012 15:08:15 +0000 Subject: Samsung/Arndale: add build.sh helper script Added a script to help users build the arndale BSP. cd into the edk2 directory and run: $ ./SamsungPlatformPkg/build.sh arndale Signed-off-by: Rony Nandy --- SamsungPlatformPkg/build.sh | 126 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 126 insertions(+) create mode 100755 SamsungPlatformPkg/build.sh 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 -- cgit v1.2.3 From 8ed57f671aeb4b01f766524fd4f6f0592166b0ab Mon Sep 17 00:00:00 2001 From: Ryan Harkin Date: Wed, 12 Dec 2012 16:42:08 +0000 Subject: Samsung/Arndale: update path inside imgburn.sh imgburn.sh was relative to the wrong directory path. Now it has been updated to build from within the tree. Signed-off-by: Rony Nandy --- SamsungPlatformPkg/Apps/Tools/mkbl2/imgburn.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SamsungPlatformPkg/Apps/Tools/mkbl2/imgburn.sh b/SamsungPlatformPkg/Apps/Tools/mkbl2/imgburn.sh index 409749b3f..0cdf3eead 100755 --- a/SamsungPlatformPkg/Apps/Tools/mkbl2/imgburn.sh +++ b/SamsungPlatformPkg/Apps/Tools/mkbl2/imgburn.sh @@ -1,7 +1,7 @@ #!/bin/bash -IMAGE=../../../../../edk2-git/edk2/Build/Arndale-Exynos/DEBUG_ARMLINUXGCC/FV/ARNDALE_EFI.fd +IMAGE=../../../../Build/Arndale-Exynos/DEBUG_ARMLINUXGCC/FV/ARNDALE_EFI.fd if [ $# -ne 2 ] then -- cgit v1.2.3 From 75bd829a3b542ceb3858d9189b087e0d8fd50b71 Mon Sep 17 00:00:00 2001 From: Ryan Harkin Date: Wed, 12 Dec 2012 16:46:11 +0000 Subject: Samsung/Arndale: use EFI Shell Use EFI Shell instead of EBL shell. Signed-off-by: Leif Lindholm --- SamsungPlatformPkg/ArndaleBoardPkg/arndale-Exynos5250.dsc | 6 ------ SamsungPlatformPkg/ArndaleBoardPkg/arndale-Exynos5250.fdf | 7 +------ 2 files changed, 1 insertion(+), 12 deletions(-) diff --git a/SamsungPlatformPkg/ArndaleBoardPkg/arndale-Exynos5250.dsc b/SamsungPlatformPkg/ArndaleBoardPkg/arndale-Exynos5250.dsc index 243304538..6116f4eab 100755 --- a/SamsungPlatformPkg/ArndaleBoardPkg/arndale-Exynos5250.dsc +++ b/SamsungPlatformPkg/ArndaleBoardPkg/arndale-Exynos5250.dsc @@ -293,11 +293,6 @@ ExynosLib|SamsungPlatformPkg/ExynosPkg/Exynos5250/Library/ExynosLib/ExynosLib.inf } - # - # Semi-hosting filesystem - # - ArmPkg/Filesystem/SemihostFs/SemihostFs.inf - # # Multimedia Card Interface # @@ -314,7 +309,6 @@ # # Application # - EmbeddedPkg/Ebl/Ebl.inf #SamsungPlatformPkg/Apps/TestApps/HashServicesTest/HashServicesTest.inf #SamsungPlatformPkg/Apps/TestApps/RngServicesTest/RngServicesTest.inf diff --git a/SamsungPlatformPkg/ArndaleBoardPkg/arndale-Exynos5250.fdf b/SamsungPlatformPkg/ArndaleBoardPkg/arndale-Exynos5250.fdf index 51eee1b06..8b5a5a727 100755 --- a/SamsungPlatformPkg/ArndaleBoardPkg/arndale-Exynos5250.fdf +++ b/SamsungPlatformPkg/ArndaleBoardPkg/arndale-Exynos5250.fdf @@ -195,11 +195,6 @@ READ_LOCK_STATUS = TRUE INF SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/eMMCDxe/eMMCDxe.inf INF SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/SDHCDxe_EVT1/SDHCDxe.inf - # - # Semi-hosting filesystem - # - INF ArmPkg/Filesystem/SemihostFs/SemihostFs.inf - # # FAT filesystem + GPT/MBR partitioning # @@ -239,7 +234,7 @@ READ_LOCK_STATUS = TRUE # # UEFI application (Shell Embedded Boot Loader) # - INF EmbeddedPkg/Ebl/Ebl.inf + INF ShellBinPkg/UefiShell/UefiShell.inf #INF SamsungPlatformPkg/Apps/TestApps/HashServicesTest/HashServicesTest.inf #INF SamsungPlatformPkg/Apps/TestApps/RngServicesTest/RngServicesTest.inf -- cgit v1.2.3 From b7fac5c54e3f017d3dcc2ab0def53dc8233bdabd Mon Sep 17 00:00:00 2001 From: Ryan Harkin Date: Fri, 18 Jan 2013 18:09:29 +0000 Subject: Samsung/Arndale: imgburn.sh: add parameters and defaults Add parameters and some sensible defaults to imgburn.sh. The old imgburn.sh took 2 parameters but didn't allow the user to specify the image location. Now, the simplest command form is: ./imgburn --disk /dev/sdX However, other options exist, eg: ./imgburn.sh --disk /dev/sdX --soc 5250 --image filename.fd The default SoC is 5250. The default image is ARNDALE_EFI.fd, with the assumption that we are in uefi-next tree. Signed-off-by: Ryan Harkin --- SamsungPlatformPkg/Apps/Tools/mkbl2/imgburn.sh | 85 ++++++++++++++++++++------ 1 file changed, 67 insertions(+), 18 deletions(-) diff --git a/SamsungPlatformPkg/Apps/Tools/mkbl2/imgburn.sh b/SamsungPlatformPkg/Apps/Tools/mkbl2/imgburn.sh index 0cdf3eead..dee12604a 100755 --- a/SamsungPlatformPkg/Apps/Tools/mkbl2/imgburn.sh +++ b/SamsungPlatformPkg/Apps/Tools/mkbl2/imgburn.sh @@ -1,15 +1,68 @@ #!/bin/bash - +# set the default image filename, this can be overwritten by a parameter IMAGE=../../../../Build/Arndale-Exynos/DEBUG_ARMLINUXGCC/FV/ARNDALE_EFI.fd -if [ $# -ne 2 ] +# 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: Not input parameter for making image" - echo "" - echo "USAGE:" - echo " sudo ./imgburn.sh 5250 /dev/sdb" + echo "ERROR: UEFI image $IMAGE does not exist.." echo "" exit fi @@ -21,25 +74,21 @@ then fi # make BL2 -if [ -f $IMAGE ] +./mkbl2 $IMAGE + +if [ ! -f fwbl2.bin ] then - ./mkbl2 $IMAGE - echo "BL2 image is created." - echo "" - echo ":::: You SHOULD check platform of ARNDALE_EFI.fd" - echo "" -else echo "" - echo "ERROR: UEFI is not built.." + echo "ERROR: Failed to create BL2 image." echo "" exit fi # select platform -if [ "$1" = "5250" ] +if [ "$SOC" = "5250" ] then # write BL1 - dd if=./5250/fwbl1_5250.bin of=$2 seek=1 count=16 + dd if=./5250/fwbl1_5250.bin of=$DISK seek=1 count=16 else echo "" echo "ERROR: Please select platform.." @@ -49,9 +98,9 @@ fi # write BL2 -dd if=./fwbl2.bin of=$2 seek=17 count=32 +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=$2 seek=49 +dd if=$IMAGE of=$DISK seek=49 sync -- cgit v1.2.3 From 77fce1b64e32ff593cf506369bc07dac421b45fc Mon Sep 17 00:00:00 2001 From: Ryan Harkin Date: Tue, 5 Feb 2013 15:44:42 +0000 Subject: Samsung/Arndale: set SD card UUID to zero BDS depends on the UUID in the config matching the UUID on the SD card. My trick is to set the UUID in code to zero, then to zero the UUID on the SD card after running linaro-media-create. THat way, they both match and the default config works. Signed-off-by: Ryan Harkin --- SamsungPlatformPkg/ArndaleBoardPkg/ArndaleBoardPkg.dsc.inc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/SamsungPlatformPkg/ArndaleBoardPkg/ArndaleBoardPkg.dsc.inc b/SamsungPlatformPkg/ArndaleBoardPkg/ArndaleBoardPkg.dsc.inc index 04a18e9ea..03c30fa4b 100644 --- a/SamsungPlatformPkg/ArndaleBoardPkg/ArndaleBoardPkg.dsc.inc +++ b/SamsungPlatformPkg/ArndaleBoardPkg/ArndaleBoardPkg.dsc.inc @@ -297,8 +297,8 @@ ArmPlatformSecLib|ArmPlatformPkg/Library/ArmPlatformSecLibNull/ArmPlatformLibNul # gArmTokenSpaceGuid.PcdArmMachineType|2456 gArmPlatformTokenSpaceGuid.PcdDefaultBootDescription|L"SD-MMC Booting" - gArmPlatformTokenSpaceGuid.PcdDefaultBootDevicePath|L"VenHw(3A02E7FE-0649-4FB4-BE4F-A862CA1872A9)/HD(2,MBR,0x000A65DC,0x59B303,0x3B7C)/uImage" - gArmPlatformTokenSpaceGuid.PcdFdtDevicePath|L"VenHw(3A02E7FE-0649-4FB4-BE4F-A862CA1872A9)/HD(2,MBR,0x000A65DC,0x59B303,0x3B7C)/exynos5250-arndale.dtb" + gArmPlatformTokenSpaceGuid.PcdDefaultBootDevicePath|L"VenHw(3A02E7FE-0649-4FB4-BE4F-A862CA1872A9)/HD(2,MBR,0x00000000,0x59B303,0x3B7C)/uImage" + gArmPlatformTokenSpaceGuid.PcdFdtDevicePath|L"VenHw(3A02E7FE-0649-4FB4-BE4F-A862CA1872A9)/HD(2,MBR,0x00000000,0x59B303,0x3B7C)/exynos5250-arndale.dtb" gArmPlatformTokenSpaceGuid.PcdDefaultBootArgument|"root=/dev/mmcblk1p1 rw rootwait console=ttySAC2,115200n8 init --no-log" gArmPlatformTokenSpaceGuid.PcdDefaultBootType|2 -- cgit v1.2.3 From 5c79bf5026431a23d3b1b1d94045efc9b84df172 Mon Sep 17 00:00:00 2001 From: "Reece R. Pollack" Date: Wed, 13 Feb 2013 07:53:21 +0000 Subject: Samsung/Arndale: fix RELEASE build with ARMLINUXGCC ARMLINUXGCC RELEASE builds have more errors as warnings than debug builds, causing release builds to fail. This patch fixes the build failures by removing several uninitialised and/or unused variables. Signed-off-by: Ryan Harkin --- .../ExynosPkg/Exynos5250/Drivers/DisplayDxe/DisplayDxe.c | 3 +-- .../ExynosPkg/Exynos5250/Drivers/SDHCDxe_EVT1/SDHCDxe.c | 9 +++++---- .../ExynosPkg/Exynos5250/Drivers/eMMCDxe/eMMCDxe.c | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/DisplayDxe/DisplayDxe.c b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/DisplayDxe/DisplayDxe.c index b9029c45d..d1b5a3be6 100644 --- a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/DisplayDxe/DisplayDxe.c +++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/DisplayDxe/DisplayDxe.c @@ -529,7 +529,6 @@ DisplayBlt( IN UINTN Delta OPTIONAL ) { - EFI_STATUS Status=EFI_SUCCESS; UINT8 *VidBuf, *BltBuf, *VidBuf1; UINTN i, j; @@ -604,7 +603,7 @@ DisplayBlt( break; default: - ASSERT_EFI_ERROR(Status); + ASSERT_EFI_ERROR(EFI_SUCCESS); } return EFI_SUCCESS; diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/SDHCDxe_EVT1/SDHCDxe.c b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/SDHCDxe_EVT1/SDHCDxe.c index 70dbae15d..0c3a219a4 100755 --- a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/SDHCDxe_EVT1/SDHCDxe.c +++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/SDHCDxe_EVT1/SDHCDxe.c @@ -118,7 +118,7 @@ MSHC_SendCmd ( UINTN CmdArgument ) { - UINTN MmcStatus; + UINTN MmcStatus = 0; volatile UINTN RetryCount = 0; int cmd_flags = 0; int timeout=0; @@ -246,13 +246,14 @@ static const UINT8 MultiFactor[16]={0, 10, 12, 13, 15, 20, 26, 30, 35, 40, 45, 5 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 } @@ -599,7 +600,7 @@ ReadBlockData ( IN UINTN BlockCount ) { - EFI_STATUS Status; + EFI_STATUS Status = EFI_INVALID_PARAMETER; UINTN DataSize = This->Media->BlockSize/4; DEBUG ((EFI_D_INFO, "SDHC::ReadBlockData start \n")); @@ -625,7 +626,7 @@ WriteBlockData ( IN UINTN BlockCount ) { - EFI_STATUS Status; + EFI_STATUS Status = EFI_INVALID_PARAMETER; UINTN DataSize = This->Media->BlockSize/4; if(MSHC_operation_mode == MSHC_FIFO) diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/eMMCDxe/eMMCDxe.c b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/eMMCDxe/eMMCDxe.c index c38001a5c..d166f662e 100755 --- a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/eMMCDxe/eMMCDxe.c +++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/eMMCDxe/eMMCDxe.c @@ -123,7 +123,7 @@ MSHC_SendCmd ( UINTN CmdArgument ) { - UINTN MmcStatus; + UINTN MmcStatus = 0; volatile UINTN RetryCount = 0; int cmd_flags = 0; int timeout=0; @@ -580,7 +580,7 @@ ReadBlockData ( IN UINTN BlockCount ) { - EFI_STATUS Status; + EFI_STATUS Status = EFI_INVALID_PARAMETER; UINTN DataSize = This->Media->BlockSize/4; DEBUG ((EFI_D_INFO, "MSHC::ReadBlockData start \n")); @@ -606,7 +606,7 @@ WriteBlockData ( IN UINTN BlockCount ) { - EFI_STATUS Status; + EFI_STATUS Status = EFI_INVALID_PARAMETER; UINTN DataSize = This->Media->BlockSize/4; if(MSHC_operation_mode == MSHC_FIFO) -- cgit v1.2.3 From 5541df6c6ba6076de70bb70fe23843788ca5e5bd Mon Sep 17 00:00:00 2001 From: Rony Nandy Date: Fri, 15 Feb 2013 20:10:05 +0530 Subject: Samsung/Arndale: Booting UEFI and linux from eMMC 1. OM register comparison value changed as per the board switch configuration. 2. Removed eMMC boot partition enable code, to access user area. Signed-off-by: Shivamurthy Shastri Signed-off-by: Rony Nandy --- SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/eMMCDxe/eMMCDxe.c | 1 - SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/eMMCDxe/eMMCDxe.h | 2 +- SamsungPlatformPkg/ExynosPkg/Exynos5250/Sec/SecEntryPoint.S | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/eMMCDxe/eMMCDxe.c b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/eMMCDxe/eMMCDxe.c index d166f662e..87f937924 100755 --- a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/eMMCDxe/eMMCDxe.c +++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/eMMCDxe/eMMCDxe.c @@ -840,7 +840,6 @@ DetectCard ( gSDMMCMedia.MediaId++; UpdateMSHCClkFrequency(MSHC_CLK_50M); - MSHC_EMMC_Boot_Open(); //do not close boot partition DEBUG ((EFI_D_INFO, "SD Card Media Change on Handle 0x%08x\n", gImageHandle)); return Status; diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/eMMCDxe/eMMCDxe.h b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/eMMCDxe/eMMCDxe.h index 9bbf13a20..e410d669e 100755 --- a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/eMMCDxe/eMMCDxe.h +++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/eMMCDxe/eMMCDxe.h @@ -65,7 +65,7 @@ NV data for general purpose : 3400 #define BLEN_512BYTES (0x200) #define BLKSIZE_1 (0x1) -#define OM_EMMC 0x28 +#define OM_EMMC 0x8 #define MAX_RETRY_COUNT (100000) #define MMC_REFERENCE_CLK (96000000) diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Sec/SecEntryPoint.S b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Sec/SecEntryPoint.S index a10eae12a..08a893cb0 100644 --- a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Sec/SecEntryPoint.S +++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Sec/SecEntryPoint.S @@ -198,7 +198,7 @@ _CopyFirmware: ldr r1, [r0,#0x0] bic r2, r1, #0xffffffc1 - cmp r2, #0x28 + cmp r2, #0x8 beq _CopyFirmwareEMMC /* SD/MMC BOOT */ -- cgit v1.2.3 From f18f8040c2b72b949247845a7111aff6a85af349 Mon Sep 17 00:00:00 2001 From: Shivamurthy Shastri Date: Fri, 15 Feb 2013 20:10:06 +0530 Subject: Samsung/Arndale: Linux booting problem in presence of initrd Linux was not able to boot with initrd. Resolved by increasing offset for FDT. Signed-off-by: Shivamurthy Shastri Signed-off-by: Rony Nandy --- SamsungPlatformPkg/ArndaleBoardPkg/arndale-Exynos5250.dsc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/SamsungPlatformPkg/ArndaleBoardPkg/arndale-Exynos5250.dsc b/SamsungPlatformPkg/ArndaleBoardPkg/arndale-Exynos5250.dsc index 6116f4eab..a545e8077 100755 --- a/SamsungPlatformPkg/ArndaleBoardPkg/arndale-Exynos5250.dsc +++ b/SamsungPlatformPkg/ArndaleBoardPkg/arndale-Exynos5250.dsc @@ -104,9 +104,12 @@ gArmTokenSpaceGuid.PcdFdSize|0x00200000 # Must be equal to gEmbeddedTokenSpaceGuid.PcdFlashFvMainSize # System Memory (256MB) - gArmTokenSpaceGuid.PcdSystemMemoryBase|0x50000000 #0x40000000 + 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 -- cgit v1.2.3 From e9e6efccacd02059bfb578bb799ae7f7290da030 Mon Sep 17 00:00:00 2001 From: Ryan Harkin Date: Mon, 18 Feb 2013 09:36:28 +0000 Subject: Samsung/Arndale: use Linaro default config This patch updates the default config to boot the kernel (uImage, uInitrd) with a local device tree (board.dtb) using a command line suitable for Linaro Ubuntu based images. Signed-off-by: Ryan Harkin Acked-by: Rony Nandy --- SamsungPlatformPkg/ArndaleBoardPkg/ArndaleBoardPkg.dsc.inc | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/SamsungPlatformPkg/ArndaleBoardPkg/ArndaleBoardPkg.dsc.inc b/SamsungPlatformPkg/ArndaleBoardPkg/ArndaleBoardPkg.dsc.inc index 03c30fa4b..671ef131a 100644 --- a/SamsungPlatformPkg/ArndaleBoardPkg/ArndaleBoardPkg.dsc.inc +++ b/SamsungPlatformPkg/ArndaleBoardPkg/ArndaleBoardPkg.dsc.inc @@ -296,11 +296,13 @@ ArmPlatformSecLib|ArmPlatformPkg/Library/ArmPlatformSecLibNull/ArmPlatformLibNul # ARM OS Loader # gArmTokenSpaceGuid.PcdArmMachineType|2456 - gArmPlatformTokenSpaceGuid.PcdDefaultBootDescription|L"SD-MMC Booting" - gArmPlatformTokenSpaceGuid.PcdDefaultBootDevicePath|L"VenHw(3A02E7FE-0649-4FB4-BE4F-A862CA1872A9)/HD(2,MBR,0x00000000,0x59B303,0x3B7C)/uImage" - gArmPlatformTokenSpaceGuid.PcdFdtDevicePath|L"VenHw(3A02E7FE-0649-4FB4-BE4F-A862CA1872A9)/HD(2,MBR,0x00000000,0x59B303,0x3B7C)/exynos5250-arndale.dtb" - gArmPlatformTokenSpaceGuid.PcdDefaultBootArgument|"root=/dev/mmcblk1p1 rw rootwait console=ttySAC2,115200n8 init --no-log" - gArmPlatformTokenSpaceGuid.PcdDefaultBootType|2 + 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)" -- cgit v1.2.3 From cfef2777cdc6e751cf93ac950c2d737d31c1b7db Mon Sep 17 00:00:00 2001 From: Ryan Harkin Date: Thu, 14 Mar 2013 15:25:53 +0000 Subject: Samsung/Arndale: add ArmSmcLibNull A recent commit adds support for ArmSmcLib/ArmSmcLibNull. This mandates that each BSP includes the SMC or NULL library. Signed-off-by: Ryan Harkin --- SamsungPlatformPkg/ArndaleBoardPkg/arndale-Exynos5250.dsc | 1 + 1 file changed, 1 insertion(+) diff --git a/SamsungPlatformPkg/ArndaleBoardPkg/arndale-Exynos5250.dsc b/SamsungPlatformPkg/ArndaleBoardPkg/arndale-Exynos5250.dsc index a545e8077..fe574af70 100755 --- a/SamsungPlatformPkg/ArndaleBoardPkg/arndale-Exynos5250.dsc +++ b/SamsungPlatformPkg/ArndaleBoardPkg/arndale-Exynos5250.dsc @@ -46,6 +46,7 @@ # 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 -- cgit v1.2.3 From 60d2d3e06736c767d2a98cc6d153bfec366a5595 Mon Sep 17 00:00:00 2001 From: Shivamurthy Shastri Date: Tue, 19 Mar 2013 16:57:05 +0530 Subject: Samsung/Arndale: Enable component name protocol Component Name Protocol been enabled to make sure the shell commands like drivers, devtree and devices shows the device name and other features properly. Signed-off-by: Shivamurthy Shastri Signed-off-by: Rony Nandy --- SamsungPlatformPkg/ArndaleBoardPkg/arndale-Exynos5250.dsc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/SamsungPlatformPkg/ArndaleBoardPkg/arndale-Exynos5250.dsc b/SamsungPlatformPkg/ArndaleBoardPkg/arndale-Exynos5250.dsc index fe574af70..941c6e55c 100755 --- a/SamsungPlatformPkg/ArndaleBoardPkg/arndale-Exynos5250.dsc +++ b/SamsungPlatformPkg/ArndaleBoardPkg/arndale-Exynos5250.dsc @@ -69,6 +69,11 @@ ################################################################################ [PcdsFeatureFlag.common] + gEfiMdePkgTokenSpaceGuid.PcdComponentNameDisable|FALSE + gEfiMdePkgTokenSpaceGuid.PcdDriverDiagnosticsDisable|TRUE + gEfiMdePkgTokenSpaceGuid.PcdComponentName2Disable|FALSE + gEfiMdePkgTokenSpaceGuid.PcdDriverDiagnostics2Disable|TRUE + !ifdef $(EDK2_SKIP_PEICORE) gArmPlatformTokenSpaceGuid.PcdSystemMemoryInitializeInSec|TRUE gArmPlatformTokenSpaceGuid.PcdSendSgiToBringUpSecondaryCores|TRUE -- cgit v1.2.3 From a3331d73beee5e94b28f9a9c73de663084d4de07 Mon Sep 17 00:00:00 2001 From: Rony Nandy Date: Tue, 11 Jun 2013 11:32:59 +0530 Subject: Samsung/Arndale: Fix compilation errors This patch fixes the build breakage issue for Arndale BSP due to the patch "ArmPlatformPkg/ArmPlatformLib: Added support for ArmPlatformIsPrimaryCore()" --- .../ArndaleBoardLib/Exynos5250/BoardHelper.S | 25 ++++++++++++++++++++++ .../ArndaleBoardPkg/arndale-Exynos5250.dsc | 16 -------------- .../ArndaleBoardPkg/arndale-Exynos5250.fdf | 15 ------------- .../Exynos5250/Drivers/Gic400Dxe/PL390GicSec.c | 3 ++- .../Drivers/Gic400Dxe/PL390GicSecLib.inf | 5 ++--- SamsungPlatformPkg/ExynosPkg/Exynos5250/Sec/Sec.c | 5 +++-- .../ExynosPkg/Exynos5250/Sec/Sec.inf | 3 --- .../ExynosPkg/Exynos5250/Sec/SecEntryPoint.S | 25 +++++++++++++++------- 8 files changed, 49 insertions(+), 48 deletions(-) diff --git a/SamsungPlatformPkg/ArndaleBoardPkg/Library/ArndaleBoardLib/Exynos5250/BoardHelper.S b/SamsungPlatformPkg/ArndaleBoardPkg/Library/ArndaleBoardLib/Exynos5250/BoardHelper.S index 1975e6517..d5858630f 100644 --- a/SamsungPlatformPkg/ArndaleBoardPkg/Library/ArndaleBoardLib/Exynos5250/BoardHelper.S +++ b/SamsungPlatformPkg/ArndaleBoardPkg/Library/ArndaleBoardLib/Exynos5250/BoardHelper.S @@ -14,6 +14,7 @@ #include #include #include +#include #include #.include AsmMacroIoLib.inc @@ -23,6 +24,9 @@ .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 @@ -68,4 +72,25 @@ _Return: 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/arndale-Exynos5250.dsc b/SamsungPlatformPkg/ArndaleBoardPkg/arndale-Exynos5250.dsc index 941c6e55c..ade299702 100755 --- a/SamsungPlatformPkg/ArndaleBoardPkg/arndale-Exynos5250.dsc +++ b/SamsungPlatformPkg/ArndaleBoardPkg/arndale-Exynos5250.dsc @@ -56,7 +56,6 @@ [BuildOptions] RVCT:*_*_ARM_PLATFORM_FLAGS == --cpu Cortex-A8 --fpu=softvfp -I$(WORKSPACE)/SamsungPlatformPkg/ExynosPkg/Exynos5250/Include/Platform - #GCC:*_*_ARM_PLATFORM_FLAGS == -mcpu=cortex-a8 -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 @@ -242,7 +241,6 @@ SamsungPlatformPkg/ExynosPkg/Exynos5250/MemoryInitPei/MemoryInitPeim.inf ArmPkg/Drivers/CpuPei/CpuPei.inf IntelFrameworkModulePkg/Universal/StatusCode/Pei/StatusCodePei.inf - #Nt32Pkg/BootModePei/BootModePei.inf MdeModulePkg/Universal/Variable/Pei/VariablePei.inf MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf { @@ -268,22 +266,17 @@ MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf MdeModulePkg/Universal/Variable/EmuRuntimeDxe/EmuVariableRuntimeDxe.inf - #MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf - #MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.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/ConSplitterDxe/ConSplitterDxe.inf MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsoleDxe.inf MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf EmbeddedPkg/SimpleTextInOutSerial/SimpleTextInOutSerial.inf - #EmbeddedPkg/SerialDxe/SerialDxe.inf MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf - #MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf SamsungPlatformPkg/ArndaleBoardPkg/FvbDxe/FvbDxe.inf SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/TimerDxe/TimerDxe.inf @@ -318,9 +311,6 @@ # # Application # - #SamsungPlatformPkg/Apps/TestApps/HashServicesTest/HashServicesTest.inf - #SamsungPlatformPkg/Apps/TestApps/RngServicesTest/RngServicesTest.inf - # # Bds # @@ -346,9 +336,7 @@ # usb host : ehci + bus + pci_emul + mass_storage # SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/PciEmulation/PciEmulation.inf - #SamsungPlatformPkg/ExynosPkg/Exynos5250/OhciDxe/OhciDxe.inf MdeModulePkg/Bus/Pci/EhciDxe/EhciDxe.inf - #MdeModulePkg/Bus/Pci/XhciDxe/XhciDxe.inf MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBusDxe.inf MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassStorageDxe.inf @@ -363,8 +351,6 @@ LockBoxLib|MdeModulePkg/Library/LockBoxNullLib/LockBoxNullLib.inf } - MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTableDxe/FirmwarePerformanceDxe.inf - #MdeModulePkg/Universal/Acpi/BootGraphicsResourceTableDxe/BootGraphicsResourceTableDxe.inf MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.inf SamsungPlatformPkg/Apps/Tools/fwupdate/fwupdate_5250.inf @@ -372,9 +358,7 @@ # # Crypto for Exynos # - #SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/HashDxe/HashDxe.inf # # Rng for Exynos # - #SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/RngDxe/RngDxe.inf diff --git a/SamsungPlatformPkg/ArndaleBoardPkg/arndale-Exynos5250.fdf b/SamsungPlatformPkg/ArndaleBoardPkg/arndale-Exynos5250.fdf index 8b5a5a727..9bccd79bf 100755 --- a/SamsungPlatformPkg/ArndaleBoardPkg/arndale-Exynos5250.fdf +++ b/SamsungPlatformPkg/ArndaleBoardPkg/arndale-Exynos5250.fdf @@ -120,7 +120,6 @@ READ_STATUS = TRUE READ_LOCK_CAP = TRUE READ_LOCK_STATUS = TRUE - #INF ArmPlatformPkg/Sec/Sec.inf INF SamsungPlatformPkg/ExynosPkg/Exynos5250/Sec/Sec.inf @@ -155,8 +154,6 @@ READ_LOCK_STATUS = TRUE INF MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf INF MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf INF MdeModulePkg/Universal/Variable/EmuRuntimeDxe/EmuVariableRuntimeDxe.inf - #INF MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf - #INF MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf INF MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf INF EmbeddedPkg/ResetRuntimeDxe/ResetRuntimeDxe.inf INF EmbeddedPkg/RealTimeClockRuntimeDxe/RealTimeClockRuntimeDxe.inf @@ -166,14 +163,10 @@ READ_LOCK_STATUS = TRUE # Multiple Console IO support # INF MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf - #INF MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitterDxe.inf INF MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsoleDxe.inf INF MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf INF EmbeddedPkg/SimpleTextInOutSerial/SimpleTextInOutSerial.inf - #INF EmbeddedPkg/SerialDxe/SerialDxe.inf - INF MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf - #INF MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf !ifdef $(EXYNOS5250_EVT1) INF SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/Gic400Dxe/PL390GicDxe.inf @@ -207,9 +200,7 @@ READ_LOCK_STATUS = TRUE # USB HOST STACK # INF SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/PciEmulation/PciEmulation.inf - #INF SamsungPlatformPkg/ExynosPkg/Exynos5250/OhciDxe/OhciDxe.inf INF MdeModulePkg/Bus/Pci/EhciDxe/EhciDxe.inf - #INF MdeModulePkg/Bus/Pci/XhciDxe/XhciDxe.inf INF MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBusDxe.inf INF MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassStorageDxe.inf @@ -223,20 +214,14 @@ READ_LOCK_STATUS = TRUE INF MdeModulePkg/Universal/ReportStatusCodeRouter/Pei/ReportStatusCodeRouterPei.inf INF MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportStatusCodeRouterRuntimeDxe.inf INF MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTablePei/FirmwarePerformancePei.inf - INF MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTableDxe/FirmwarePerformanceDxe.inf - #INF MdeModulePkg/Universal/Acpi/BootGraphicsResourceTableDxe/BootGraphicsResourceTableDxe.inf # Crypto for Exynos # - #INF SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/HashDxe/HashDxe.inf - #INF SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/RngDxe/RngDxe.inf # # UEFI application (Shell Embedded Boot Loader) # INF ShellBinPkg/UefiShell/UefiShell.inf - #INF SamsungPlatformPkg/Apps/TestApps/HashServicesTest/HashServicesTest.inf - #INF SamsungPlatformPkg/Apps/TestApps/RngServicesTest/RngServicesTest.inf # # Bds diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/Gic400Dxe/PL390GicSec.c b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/Gic400Dxe/PL390GicSec.c index f7b6d7c3a..82ecfde6e 100644 --- a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/Gic400Dxe/PL390GicSec.c +++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/Gic400Dxe/PL390GicSec.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -50,7 +51,7 @@ ArmGicSetupNonSecure ( } // Only the primary core should set the Non Secure bit to the SPIs (Shared Peripheral Interrupt). - if (IS_PRIMARY_CORE(MpId)) { + 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); diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/Gic400Dxe/PL390GicSecLib.inf b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/Gic400Dxe/PL390GicSecLib.inf index 9e1fd0966..ab399b4fb 100644 --- a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/Gic400Dxe/PL390GicSecLib.inf +++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Drivers/Gic400Dxe/PL390GicSecLib.inf @@ -25,7 +25,9 @@ [Packages] ArmPkg/ArmPkg.dec + ArmPlatformPkg/ArmPlatformPkg.dec MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec [LibraryClasses] ArmLib @@ -33,6 +35,3 @@ IoLib PcdLib -[FixedPcd.common] - gArmTokenSpaceGuid.PcdArmPrimaryCoreMask - gArmTokenSpaceGuid.PcdArmPrimaryCore diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Sec/Sec.c b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Sec/Sec.c index 549171b3b..3c4f4983f 100644 --- a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Sec/Sec.c +++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Sec/Sec.c @@ -21,6 +21,7 @@ #include #include #include +#include #include "SecInternal.h" #include "Smc.h" @@ -94,7 +95,7 @@ CEntryPoint ( } // Primary CPU clears out the SCU tag RAMs, secondaries wait - if (IS_PRIMARY_CORE(MpId)) { + if (ArmPlatformIsPrimaryCore (MpId)) { if (ArmIsMpCore()) { // Is UEFI built as it is assumed that TZSW is running? // PcdTrustzoneSupport==1: YES. @@ -174,7 +175,7 @@ TrustedWorldInitialization ( ArmPlatformSecTrustzoneInit (MpId); // Setup the Trustzone Chipsets - if (IS_PRIMARY_CORE(MpId)) { + if (ArmPlatformIsPrimaryCore (MpId)) { if (ArmIsMpCore()) { // Signal the secondary core the Security settings is done (event: EVENT_SECURE_INIT) ArmCallSEV (); diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Sec/Sec.inf b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Sec/Sec.inf index 854b26971..1cda8c3ad 100644 --- a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Sec/Sec.inf +++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Sec/Sec.inf @@ -62,9 +62,6 @@ gArmTokenSpaceGuid.PcdArmNsacr gArmTokenSpaceGuid.PcdArmNonSecModeTransition - gArmTokenSpaceGuid.PcdArmPrimaryCoreMask - gArmTokenSpaceGuid.PcdArmPrimaryCore - gArmTokenSpaceGuid.PcdSecureFvBaseAddress gArmTokenSpaceGuid.PcdSecureFvSize diff --git a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Sec/SecEntryPoint.S b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Sec/SecEntryPoint.S index 08a893cb0..aecbc939f 100644 --- a/SamsungPlatformPkg/ExynosPkg/Exynos5250/Sec/SecEntryPoint.S +++ b/SamsungPlatformPkg/ExynosPkg/Exynos5250/Sec/SecEntryPoint.S @@ -14,12 +14,14 @@ #include #include #include +#include #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) @@ -36,6 +38,16 @@ 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) \ @@ -85,13 +97,13 @@ ASM_PFX(_ModuleEntryPoint): _IdentifyCpu: // Identify CPU ID bl ASM_PFX(ArmReadMpidr) - // Get ID of this CPU in Multicore system - LoadConstantToReg (FixedPcdGet32(PcdArmPrimaryCoreMask), r1) - and r5, r0, r1 + // Keep a copy of the MpId register value + mov r5, r0 // Is it the Primary Core ? - LoadConstantToReg (FixedPcdGet32(PcdArmPrimaryCore), r3) - cmp r5, r3 + bl ASM_PFX(ArmPlatformIsPrimaryCore) + cmp r0, #1 + // Only the primary core initialize the memory (SMC) beq _InitMem @@ -119,9 +131,6 @@ _InitMem: bl ASM_PFX(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) -- cgit v1.2.3 From 4b540644dab22b8b9b342399c6e66f43054ed6b7 Mon Sep 17 00:00:00 2001 From: Ryan Harkin Date: Wed, 18 Sep 2013 10:41:49 +0100 Subject: Samsung/Arndale: Replaced FatPkg source package by the pre-built FatPkg binary Signed-off-by: Ryan Harkin --- SamsungPlatformPkg/ArndaleBoardPkg/arndale-Exynos5250.dsc | 1 - SamsungPlatformPkg/ArndaleBoardPkg/arndale-Exynos5250.fdf | 10 +++++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/SamsungPlatformPkg/ArndaleBoardPkg/arndale-Exynos5250.dsc b/SamsungPlatformPkg/ArndaleBoardPkg/arndale-Exynos5250.dsc index ade299702..054c90d92 100755 --- a/SamsungPlatformPkg/ArndaleBoardPkg/arndale-Exynos5250.dsc +++ b/SamsungPlatformPkg/ArndaleBoardPkg/arndale-Exynos5250.dsc @@ -305,7 +305,6 @@ # MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf - FatPkg/EnhancedFatDxe/Fat.inf MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf # diff --git a/SamsungPlatformPkg/ArndaleBoardPkg/arndale-Exynos5250.fdf b/SamsungPlatformPkg/ArndaleBoardPkg/arndale-Exynos5250.fdf index 9bccd79bf..cdcbc3ef3 100755 --- a/SamsungPlatformPkg/ArndaleBoardPkg/arndale-Exynos5250.fdf +++ b/SamsungPlatformPkg/ArndaleBoardPkg/arndale-Exynos5250.fdf @@ -193,7 +193,7 @@ READ_LOCK_STATUS = TRUE # INF MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf INF MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf - INF FatPkg/EnhancedFatDxe/Fat.inf + INF FatBinPkg/EnhancedFatDxe/Fat.inf INF MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf # @@ -354,6 +354,14 @@ READ_LOCK_STATUS = TRUE 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 -- cgit v1.2.3 From eafdd4f792145f3470b66e66fdb1d6da2720820b Mon Sep 17 00:00:00 2001 From: Ryan Harkin Date: Wed, 18 Sep 2013 18:15:03 +0100 Subject: Samsung/Arndale: fixed ROM size ROM sizes are specified "start|size", whereas I previously thought they were "start|end" Also, the Arndale sizes were specified to run outside the binary limits. Signed-off-by: Ryan Harkin --- SamsungPlatformPkg/ArndaleBoardPkg/arndale-Exynos5250.fdf | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/SamsungPlatformPkg/ArndaleBoardPkg/arndale-Exynos5250.fdf b/SamsungPlatformPkg/ArndaleBoardPkg/arndale-Exynos5250.fdf index cdcbc3ef3..29e4aa36f 100755 --- a/SamsungPlatformPkg/ArndaleBoardPkg/arndale-Exynos5250.fdf +++ b/SamsungPlatformPkg/ArndaleBoardPkg/arndale-Exynos5250.fdf @@ -28,10 +28,10 @@ [FD.Arndale_EFI] BaseAddress = 0x40000000|gArmTokenSpaceGuid.PcdFdBaseAddress -Size = 0x00280000|gArmTokenSpaceGuid.PcdFdSize +Size = 0x00294000|gArmTokenSpaceGuid.PcdFdSize ErasePolarity = 1 BlockSize = 0x00014000 -NumBlocks = 0x20 +NumBlocks = 0x21 ################################################################################ # @@ -53,7 +53,7 @@ NumBlocks = 0x20 gArmTokenSpaceGuid.PcdSecureFvBaseAddress|gArmTokenSpaceGuid.PcdSecureFvSize FV = FVMAIN_SEC -0x00014000|0x00270000 +0x00014000|0x0026C000 gArmTokenSpaceGuid.PcdFvBaseAddress|gArmTokenSpaceGuid.PcdFvSize FV = FVMAIN_COMPACT -- cgit v1.2.3