From 5fc3b5d6c8f3f23823069f060e8ffc8f80bccdf7 Mon Sep 17 00:00:00 2001 From: andrewfish Date: Thu, 22 Jul 2010 19:22:34 +0000 Subject: [PATCH] Added to support X64 port (with SV5 ABI). May be able to remove after we port everything, but Sec, to EFI X64 ABI. git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@10683 6f19259b-4bc3-4df7-8a09-765794883524 --- UnixPkg/Library/UnixBaseLib/ARShiftU64.c | 41 + .../Library/UnixBaseLib/BaseLibInternals.h | 1655 +++++++++++++ UnixPkg/Library/UnixBaseLib/BitField.c | 868 +++++++ UnixPkg/Library/UnixBaseLib/CheckSum.c | 337 +++ UnixPkg/Library/UnixBaseLib/ChkStkGcc.c | 24 + UnixPkg/Library/UnixBaseLib/Cpu.c | 65 + UnixPkg/Library/UnixBaseLib/CpuDeadLoop.c | 38 + .../Library/UnixBaseLib/DivS64x64Remainder.c | 53 + UnixPkg/Library/UnixBaseLib/DivU64x32.c | 45 + .../Library/UnixBaseLib/DivU64x32Remainder.c | 49 + .../Library/UnixBaseLib/DivU64x64Remainder.c | 49 + UnixPkg/Library/UnixBaseLib/GetPowerOfTwo32.c | 44 + UnixPkg/Library/UnixBaseLib/GetPowerOfTwo64.c | 44 + UnixPkg/Library/UnixBaseLib/HighBitSet32.c | 47 + UnixPkg/Library/UnixBaseLib/HighBitSet64.c | 55 + UnixPkg/Library/UnixBaseLib/LRotU32.c | 42 + UnixPkg/Library/UnixBaseLib/LRotU64.c | 42 + UnixPkg/Library/UnixBaseLib/LShiftU64.c | 41 + UnixPkg/Library/UnixBaseLib/LinkedList.c | 550 +++++ UnixPkg/Library/UnixBaseLib/LongJump.c | 47 + UnixPkg/Library/UnixBaseLib/LowBitSet32.c | 47 + UnixPkg/Library/UnixBaseLib/LowBitSet64.c | 50 + UnixPkg/Library/UnixBaseLib/Math64.c | 368 +++ UnixPkg/Library/UnixBaseLib/ModU64x32.c | 45 + UnixPkg/Library/UnixBaseLib/MultS64x64.c | 42 + UnixPkg/Library/UnixBaseLib/MultU64x32.c | 46 + UnixPkg/Library/UnixBaseLib/MultU64x64.c | 46 + UnixPkg/Library/UnixBaseLib/RRotU32.c | 42 + UnixPkg/Library/UnixBaseLib/RRotU64.c | 42 + UnixPkg/Library/UnixBaseLib/RShiftU64.c | 41 + UnixPkg/Library/UnixBaseLib/SetJump.c | 40 + UnixPkg/Library/UnixBaseLib/String.c | 2109 +++++++++++++++++ UnixPkg/Library/UnixBaseLib/SwapBytes16.c | 39 + UnixPkg/Library/UnixBaseLib/SwapBytes32.c | 45 + UnixPkg/Library/UnixBaseLib/SwapBytes64.c | 39 + UnixPkg/Library/UnixBaseLib/SwitchStack.c | 76 + UnixPkg/Library/UnixBaseLib/Unaligned.c | 222 ++ UnixPkg/Library/UnixBaseLib/UnixBaseLib.inf | 201 ++ .../Library/UnixBaseLib/X64/CpuBreakpoint.S | 25 + .../Library/UnixBaseLib/X64/CpuBreakpoint.asm | 37 + .../Library/UnixBaseLib/X64/CpuBreakpoint.c | 39 + UnixPkg/Library/UnixBaseLib/X64/CpuId.S | 60 + UnixPkg/Library/UnixBaseLib/X64/CpuId.asm | 62 + UnixPkg/Library/UnixBaseLib/X64/CpuIdEx.S | 62 + UnixPkg/Library/UnixBaseLib/X64/CpuIdEx.asm | 64 + UnixPkg/Library/UnixBaseLib/X64/CpuPause.asm | 37 + .../Library/UnixBaseLib/X64/DisableCache.S | 39 + .../Library/UnixBaseLib/X64/DisableCache.asm | 43 + .../UnixBaseLib/X64/DisableInterrupts.asm | 38 + .../Library/UnixBaseLib/X64/DisablePaging64.S | 82 + .../UnixBaseLib/X64/DisablePaging64.asm | 84 + UnixPkg/Library/UnixBaseLib/X64/EnableCache.S | 39 + .../Library/UnixBaseLib/X64/EnableCache.asm | 43 + .../UnixBaseLib/X64/EnableDisableInterrupts.S | 36 + .../X64/EnableDisableInterrupts.asm | 39 + .../UnixBaseLib/X64/EnableInterrupts.asm | 38 + .../UnixBaseLib/X64/FlushCacheLine.asm | 39 + UnixPkg/Library/UnixBaseLib/X64/FxRestore.asm | 38 + UnixPkg/Library/UnixBaseLib/X64/FxSave.asm | 38 + UnixPkg/Library/UnixBaseLib/X64/GccInline.c | 1801 ++++++++++++++ UnixPkg/Library/UnixBaseLib/X64/Invd.asm | 38 + UnixPkg/Library/UnixBaseLib/X64/LongJump.S | 88 + UnixPkg/Library/UnixBaseLib/X64/LongJump.asm | 58 + UnixPkg/Library/UnixBaseLib/X64/Monitor.asm | 43 + UnixPkg/Library/UnixBaseLib/X64/Mwait.asm | 41 + .../Library/UnixBaseLib/X64/Non-existing.c | 153 ++ UnixPkg/Library/UnixBaseLib/X64/ReadCr0.asm | 38 + UnixPkg/Library/UnixBaseLib/X64/ReadCr2.asm | 38 + UnixPkg/Library/UnixBaseLib/X64/ReadCr3.asm | 38 + UnixPkg/Library/UnixBaseLib/X64/ReadCr4.asm | 38 + UnixPkg/Library/UnixBaseLib/X64/ReadCs.asm | 38 + UnixPkg/Library/UnixBaseLib/X64/ReadDr0.asm | 38 + UnixPkg/Library/UnixBaseLib/X64/ReadDr1.asm | 38 + UnixPkg/Library/UnixBaseLib/X64/ReadDr2.asm | 38 + UnixPkg/Library/UnixBaseLib/X64/ReadDr3.asm | 38 + UnixPkg/Library/UnixBaseLib/X64/ReadDr4.asm | 42 + UnixPkg/Library/UnixBaseLib/X64/ReadDr5.asm | 42 + UnixPkg/Library/UnixBaseLib/X64/ReadDr6.asm | 38 + UnixPkg/Library/UnixBaseLib/X64/ReadDr7.asm | 38 + UnixPkg/Library/UnixBaseLib/X64/ReadDs.asm | 38 + .../Library/UnixBaseLib/X64/ReadEflags.asm | 39 + UnixPkg/Library/UnixBaseLib/X64/ReadEs.asm | 38 + UnixPkg/Library/UnixBaseLib/X64/ReadFs.asm | 38 + UnixPkg/Library/UnixBaseLib/X64/ReadGdtr.asm | 38 + UnixPkg/Library/UnixBaseLib/X64/ReadGs.asm | 38 + UnixPkg/Library/UnixBaseLib/X64/ReadIdtr.asm | 38 + UnixPkg/Library/UnixBaseLib/X64/ReadLdtr.asm | 38 + UnixPkg/Library/UnixBaseLib/X64/ReadMm0.asm | 41 + UnixPkg/Library/UnixBaseLib/X64/ReadMm1.asm | 41 + UnixPkg/Library/UnixBaseLib/X64/ReadMm2.asm | 41 + UnixPkg/Library/UnixBaseLib/X64/ReadMm3.asm | 41 + UnixPkg/Library/UnixBaseLib/X64/ReadMm4.asm | 41 + UnixPkg/Library/UnixBaseLib/X64/ReadMm5.asm | 41 + UnixPkg/Library/UnixBaseLib/X64/ReadMm6.asm | 41 + UnixPkg/Library/UnixBaseLib/X64/ReadMm7.asm | 41 + UnixPkg/Library/UnixBaseLib/X64/ReadMsr64.asm | 40 + UnixPkg/Library/UnixBaseLib/X64/ReadMsr64.c | 39 + UnixPkg/Library/UnixBaseLib/X64/ReadPmc.asm | 40 + UnixPkg/Library/UnixBaseLib/X64/ReadSs.asm | 38 + UnixPkg/Library/UnixBaseLib/X64/ReadTr.asm | 38 + UnixPkg/Library/UnixBaseLib/X64/ReadTsc.asm | 40 + UnixPkg/Library/UnixBaseLib/X64/SetJump.S | 82 + UnixPkg/Library/UnixBaseLib/X64/SetJump.asm | 66 + UnixPkg/Library/UnixBaseLib/X64/SwitchStack.S | 79 + .../Library/UnixBaseLib/X64/SwitchStack.asm | 51 + UnixPkg/Library/UnixBaseLib/X64/Thunk16.S | 325 +++ UnixPkg/Library/UnixBaseLib/X64/Thunk16.asm | 314 +++ UnixPkg/Library/UnixBaseLib/X64/Wbinvd.S | 35 + UnixPkg/Library/UnixBaseLib/X64/Wbinvd.asm | 38 + UnixPkg/Library/UnixBaseLib/X64/WriteCr0.asm | 39 + UnixPkg/Library/UnixBaseLib/X64/WriteCr2.asm | 39 + UnixPkg/Library/UnixBaseLib/X64/WriteCr3.asm | 39 + UnixPkg/Library/UnixBaseLib/X64/WriteCr4.asm | 39 + UnixPkg/Library/UnixBaseLib/X64/WriteDr0.asm | 39 + UnixPkg/Library/UnixBaseLib/X64/WriteDr1.asm | 39 + UnixPkg/Library/UnixBaseLib/X64/WriteDr2.asm | 39 + UnixPkg/Library/UnixBaseLib/X64/WriteDr3.asm | 39 + UnixPkg/Library/UnixBaseLib/X64/WriteDr4.asm | 43 + UnixPkg/Library/UnixBaseLib/X64/WriteDr5.asm | 43 + UnixPkg/Library/UnixBaseLib/X64/WriteDr6.asm | 39 + UnixPkg/Library/UnixBaseLib/X64/WriteDr7.asm | 39 + UnixPkg/Library/UnixBaseLib/X64/WriteGdtr.asm | 38 + UnixPkg/Library/UnixBaseLib/X64/WriteIdtr.asm | 41 + UnixPkg/Library/UnixBaseLib/X64/WriteLdtr.asm | 38 + UnixPkg/Library/UnixBaseLib/X64/WriteMm0.asm | 41 + UnixPkg/Library/UnixBaseLib/X64/WriteMm1.asm | 41 + UnixPkg/Library/UnixBaseLib/X64/WriteMm2.asm | 41 + UnixPkg/Library/UnixBaseLib/X64/WriteMm3.asm | 41 + UnixPkg/Library/UnixBaseLib/X64/WriteMm4.asm | 41 + UnixPkg/Library/UnixBaseLib/X64/WriteMm5.asm | 41 + UnixPkg/Library/UnixBaseLib/X64/WriteMm6.asm | 41 + UnixPkg/Library/UnixBaseLib/X64/WriteMm7.asm | 41 + .../Library/UnixBaseLib/X64/WriteMsr64.asm | 41 + UnixPkg/Library/UnixBaseLib/X64/WriteMsr64.c | 42 + .../Library/UnixBaseLib/X86DisablePaging32.c | 66 + .../Library/UnixBaseLib/X86DisablePaging64.c | 63 + .../Library/UnixBaseLib/X86EnablePaging32.c | 69 + .../Library/UnixBaseLib/X86EnablePaging64.c | 65 + UnixPkg/Library/UnixBaseLib/X86FxRestore.c | 49 + UnixPkg/Library/UnixBaseLib/X86FxSave.c | 48 + .../UnixBaseLib/X86GetInterruptState.c | 41 + UnixPkg/Library/UnixBaseLib/X86MemoryFence.c | 32 + UnixPkg/Library/UnixBaseLib/X86Msr.c | 650 +++++ UnixPkg/Library/UnixBaseLib/X86ReadGdtr.c | 39 + UnixPkg/Library/UnixBaseLib/X86ReadIdtr.c | 39 + UnixPkg/Library/UnixBaseLib/X86Thunk.c | 291 +++ UnixPkg/Library/UnixBaseLib/X86WriteGdtr.c | 39 + UnixPkg/Library/UnixBaseLib/X86WriteIdtr.c | 39 + 148 files changed, 15774 insertions(+) create mode 100644 UnixPkg/Library/UnixBaseLib/ARShiftU64.c create mode 100644 UnixPkg/Library/UnixBaseLib/BaseLibInternals.h create mode 100644 UnixPkg/Library/UnixBaseLib/BitField.c create mode 100644 UnixPkg/Library/UnixBaseLib/CheckSum.c create mode 100644 UnixPkg/Library/UnixBaseLib/ChkStkGcc.c create mode 100644 UnixPkg/Library/UnixBaseLib/Cpu.c create mode 100644 UnixPkg/Library/UnixBaseLib/CpuDeadLoop.c create mode 100644 UnixPkg/Library/UnixBaseLib/DivS64x64Remainder.c create mode 100644 UnixPkg/Library/UnixBaseLib/DivU64x32.c create mode 100644 UnixPkg/Library/UnixBaseLib/DivU64x32Remainder.c create mode 100644 UnixPkg/Library/UnixBaseLib/DivU64x64Remainder.c create mode 100644 UnixPkg/Library/UnixBaseLib/GetPowerOfTwo32.c create mode 100644 UnixPkg/Library/UnixBaseLib/GetPowerOfTwo64.c create mode 100644 UnixPkg/Library/UnixBaseLib/HighBitSet32.c create mode 100644 UnixPkg/Library/UnixBaseLib/HighBitSet64.c create mode 100644 UnixPkg/Library/UnixBaseLib/LRotU32.c create mode 100644 UnixPkg/Library/UnixBaseLib/LRotU64.c create mode 100644 UnixPkg/Library/UnixBaseLib/LShiftU64.c create mode 100644 UnixPkg/Library/UnixBaseLib/LinkedList.c create mode 100644 UnixPkg/Library/UnixBaseLib/LongJump.c create mode 100644 UnixPkg/Library/UnixBaseLib/LowBitSet32.c create mode 100644 UnixPkg/Library/UnixBaseLib/LowBitSet64.c create mode 100644 UnixPkg/Library/UnixBaseLib/Math64.c create mode 100644 UnixPkg/Library/UnixBaseLib/ModU64x32.c create mode 100644 UnixPkg/Library/UnixBaseLib/MultS64x64.c create mode 100644 UnixPkg/Library/UnixBaseLib/MultU64x32.c create mode 100644 UnixPkg/Library/UnixBaseLib/MultU64x64.c create mode 100644 UnixPkg/Library/UnixBaseLib/RRotU32.c create mode 100644 UnixPkg/Library/UnixBaseLib/RRotU64.c create mode 100644 UnixPkg/Library/UnixBaseLib/RShiftU64.c create mode 100644 UnixPkg/Library/UnixBaseLib/SetJump.c create mode 100644 UnixPkg/Library/UnixBaseLib/String.c create mode 100644 UnixPkg/Library/UnixBaseLib/SwapBytes16.c create mode 100644 UnixPkg/Library/UnixBaseLib/SwapBytes32.c create mode 100644 UnixPkg/Library/UnixBaseLib/SwapBytes64.c create mode 100644 UnixPkg/Library/UnixBaseLib/SwitchStack.c create mode 100644 UnixPkg/Library/UnixBaseLib/Unaligned.c create mode 100644 UnixPkg/Library/UnixBaseLib/UnixBaseLib.inf create mode 100644 UnixPkg/Library/UnixBaseLib/X64/CpuBreakpoint.S create mode 100644 UnixPkg/Library/UnixBaseLib/X64/CpuBreakpoint.asm create mode 100644 UnixPkg/Library/UnixBaseLib/X64/CpuBreakpoint.c create mode 100644 UnixPkg/Library/UnixBaseLib/X64/CpuId.S create mode 100644 UnixPkg/Library/UnixBaseLib/X64/CpuId.asm create mode 100644 UnixPkg/Library/UnixBaseLib/X64/CpuIdEx.S create mode 100644 UnixPkg/Library/UnixBaseLib/X64/CpuIdEx.asm create mode 100644 UnixPkg/Library/UnixBaseLib/X64/CpuPause.asm create mode 100644 UnixPkg/Library/UnixBaseLib/X64/DisableCache.S create mode 100644 UnixPkg/Library/UnixBaseLib/X64/DisableCache.asm create mode 100644 UnixPkg/Library/UnixBaseLib/X64/DisableInterrupts.asm create mode 100644 UnixPkg/Library/UnixBaseLib/X64/DisablePaging64.S create mode 100644 UnixPkg/Library/UnixBaseLib/X64/DisablePaging64.asm create mode 100644 UnixPkg/Library/UnixBaseLib/X64/EnableCache.S create mode 100644 UnixPkg/Library/UnixBaseLib/X64/EnableCache.asm create mode 100644 UnixPkg/Library/UnixBaseLib/X64/EnableDisableInterrupts.S create mode 100644 UnixPkg/Library/UnixBaseLib/X64/EnableDisableInterrupts.asm create mode 100644 UnixPkg/Library/UnixBaseLib/X64/EnableInterrupts.asm create mode 100644 UnixPkg/Library/UnixBaseLib/X64/FlushCacheLine.asm create mode 100644 UnixPkg/Library/UnixBaseLib/X64/FxRestore.asm create mode 100644 UnixPkg/Library/UnixBaseLib/X64/FxSave.asm create mode 100644 UnixPkg/Library/UnixBaseLib/X64/GccInline.c create mode 100644 UnixPkg/Library/UnixBaseLib/X64/Invd.asm create mode 100644 UnixPkg/Library/UnixBaseLib/X64/LongJump.S create mode 100644 UnixPkg/Library/UnixBaseLib/X64/LongJump.asm create mode 100644 UnixPkg/Library/UnixBaseLib/X64/Monitor.asm create mode 100644 UnixPkg/Library/UnixBaseLib/X64/Mwait.asm create mode 100644 UnixPkg/Library/UnixBaseLib/X64/Non-existing.c create mode 100644 UnixPkg/Library/UnixBaseLib/X64/ReadCr0.asm create mode 100644 UnixPkg/Library/UnixBaseLib/X64/ReadCr2.asm create mode 100644 UnixPkg/Library/UnixBaseLib/X64/ReadCr3.asm create mode 100644 UnixPkg/Library/UnixBaseLib/X64/ReadCr4.asm create mode 100644 UnixPkg/Library/UnixBaseLib/X64/ReadCs.asm create mode 100644 UnixPkg/Library/UnixBaseLib/X64/ReadDr0.asm create mode 100644 UnixPkg/Library/UnixBaseLib/X64/ReadDr1.asm create mode 100644 UnixPkg/Library/UnixBaseLib/X64/ReadDr2.asm create mode 100644 UnixPkg/Library/UnixBaseLib/X64/ReadDr3.asm create mode 100644 UnixPkg/Library/UnixBaseLib/X64/ReadDr4.asm create mode 100644 UnixPkg/Library/UnixBaseLib/X64/ReadDr5.asm create mode 100644 UnixPkg/Library/UnixBaseLib/X64/ReadDr6.asm create mode 100644 UnixPkg/Library/UnixBaseLib/X64/ReadDr7.asm create mode 100644 UnixPkg/Library/UnixBaseLib/X64/ReadDs.asm create mode 100644 UnixPkg/Library/UnixBaseLib/X64/ReadEflags.asm create mode 100644 UnixPkg/Library/UnixBaseLib/X64/ReadEs.asm create mode 100644 UnixPkg/Library/UnixBaseLib/X64/ReadFs.asm create mode 100644 UnixPkg/Library/UnixBaseLib/X64/ReadGdtr.asm create mode 100644 UnixPkg/Library/UnixBaseLib/X64/ReadGs.asm create mode 100644 UnixPkg/Library/UnixBaseLib/X64/ReadIdtr.asm create mode 100644 UnixPkg/Library/UnixBaseLib/X64/ReadLdtr.asm create mode 100644 UnixPkg/Library/UnixBaseLib/X64/ReadMm0.asm create mode 100644 UnixPkg/Library/UnixBaseLib/X64/ReadMm1.asm create mode 100644 UnixPkg/Library/UnixBaseLib/X64/ReadMm2.asm create mode 100644 UnixPkg/Library/UnixBaseLib/X64/ReadMm3.asm create mode 100644 UnixPkg/Library/UnixBaseLib/X64/ReadMm4.asm create mode 100644 UnixPkg/Library/UnixBaseLib/X64/ReadMm5.asm create mode 100644 UnixPkg/Library/UnixBaseLib/X64/ReadMm6.asm create mode 100644 UnixPkg/Library/UnixBaseLib/X64/ReadMm7.asm create mode 100644 UnixPkg/Library/UnixBaseLib/X64/ReadMsr64.asm create mode 100644 UnixPkg/Library/UnixBaseLib/X64/ReadMsr64.c create mode 100644 UnixPkg/Library/UnixBaseLib/X64/ReadPmc.asm create mode 100644 UnixPkg/Library/UnixBaseLib/X64/ReadSs.asm create mode 100644 UnixPkg/Library/UnixBaseLib/X64/ReadTr.asm create mode 100644 UnixPkg/Library/UnixBaseLib/X64/ReadTsc.asm create mode 100644 UnixPkg/Library/UnixBaseLib/X64/SetJump.S create mode 100644 UnixPkg/Library/UnixBaseLib/X64/SetJump.asm create mode 100644 UnixPkg/Library/UnixBaseLib/X64/SwitchStack.S create mode 100644 UnixPkg/Library/UnixBaseLib/X64/SwitchStack.asm create mode 100644 UnixPkg/Library/UnixBaseLib/X64/Thunk16.S create mode 100644 UnixPkg/Library/UnixBaseLib/X64/Thunk16.asm create mode 100644 UnixPkg/Library/UnixBaseLib/X64/Wbinvd.S create mode 100644 UnixPkg/Library/UnixBaseLib/X64/Wbinvd.asm create mode 100644 UnixPkg/Library/UnixBaseLib/X64/WriteCr0.asm create mode 100644 UnixPkg/Library/UnixBaseLib/X64/WriteCr2.asm create mode 100644 UnixPkg/Library/UnixBaseLib/X64/WriteCr3.asm create mode 100644 UnixPkg/Library/UnixBaseLib/X64/WriteCr4.asm create mode 100644 UnixPkg/Library/UnixBaseLib/X64/WriteDr0.asm create mode 100644 UnixPkg/Library/UnixBaseLib/X64/WriteDr1.asm create mode 100644 UnixPkg/Library/UnixBaseLib/X64/WriteDr2.asm create mode 100644 UnixPkg/Library/UnixBaseLib/X64/WriteDr3.asm create mode 100644 UnixPkg/Library/UnixBaseLib/X64/WriteDr4.asm create mode 100644 UnixPkg/Library/UnixBaseLib/X64/WriteDr5.asm create mode 100644 UnixPkg/Library/UnixBaseLib/X64/WriteDr6.asm create mode 100644 UnixPkg/Library/UnixBaseLib/X64/WriteDr7.asm create mode 100644 UnixPkg/Library/UnixBaseLib/X64/WriteGdtr.asm create mode 100644 UnixPkg/Library/UnixBaseLib/X64/WriteIdtr.asm create mode 100644 UnixPkg/Library/UnixBaseLib/X64/WriteLdtr.asm create mode 100644 UnixPkg/Library/UnixBaseLib/X64/WriteMm0.asm create mode 100644 UnixPkg/Library/UnixBaseLib/X64/WriteMm1.asm create mode 100644 UnixPkg/Library/UnixBaseLib/X64/WriteMm2.asm create mode 100644 UnixPkg/Library/UnixBaseLib/X64/WriteMm3.asm create mode 100644 UnixPkg/Library/UnixBaseLib/X64/WriteMm4.asm create mode 100644 UnixPkg/Library/UnixBaseLib/X64/WriteMm5.asm create mode 100644 UnixPkg/Library/UnixBaseLib/X64/WriteMm6.asm create mode 100644 UnixPkg/Library/UnixBaseLib/X64/WriteMm7.asm create mode 100644 UnixPkg/Library/UnixBaseLib/X64/WriteMsr64.asm create mode 100644 UnixPkg/Library/UnixBaseLib/X64/WriteMsr64.c create mode 100644 UnixPkg/Library/UnixBaseLib/X86DisablePaging32.c create mode 100644 UnixPkg/Library/UnixBaseLib/X86DisablePaging64.c create mode 100644 UnixPkg/Library/UnixBaseLib/X86EnablePaging32.c create mode 100644 UnixPkg/Library/UnixBaseLib/X86EnablePaging64.c create mode 100644 UnixPkg/Library/UnixBaseLib/X86FxRestore.c create mode 100644 UnixPkg/Library/UnixBaseLib/X86FxSave.c create mode 100644 UnixPkg/Library/UnixBaseLib/X86GetInterruptState.c create mode 100644 UnixPkg/Library/UnixBaseLib/X86MemoryFence.c create mode 100644 UnixPkg/Library/UnixBaseLib/X86Msr.c create mode 100644 UnixPkg/Library/UnixBaseLib/X86ReadGdtr.c create mode 100644 UnixPkg/Library/UnixBaseLib/X86ReadIdtr.c create mode 100644 UnixPkg/Library/UnixBaseLib/X86Thunk.c create mode 100644 UnixPkg/Library/UnixBaseLib/X86WriteGdtr.c create mode 100644 UnixPkg/Library/UnixBaseLib/X86WriteIdtr.c diff --git a/UnixPkg/Library/UnixBaseLib/ARShiftU64.c b/UnixPkg/Library/UnixBaseLib/ARShiftU64.c new file mode 100644 index 0000000000..6c799faed6 --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/ARShiftU64.c @@ -0,0 +1,41 @@ +/** @file + Math worker functions. + + 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. + +**/ + +#include "BaseLibInternals.h" + +/** + Shifts a 64-bit integer right between 0 and 63 bits. The high bits are filled + with the original integer's bit 63. The shifted value is returned. + + This function shifts the 64-bit value Operand to the right by Count bits. The + high Count bits are set to bit 63 of Operand. The shifted value is returned. + + If Count is greater than 63, then ASSERT(). + + @param Operand The 64-bit operand to shift right. + @param Count The number of bits to shift right. + + @return Operand >> Count + +**/ +UINT64 +EFIAPI +ARShiftU64 ( + IN UINT64 Operand, + IN UINTN Count + ) +{ + ASSERT (Count < 64); + return InternalMathARShiftU64 (Operand, Count); +} diff --git a/UnixPkg/Library/UnixBaseLib/BaseLibInternals.h b/UnixPkg/Library/UnixBaseLib/BaseLibInternals.h new file mode 100644 index 0000000000..a60310ab6f --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/BaseLibInternals.h @@ -0,0 +1,1655 @@ +/** @file + Declaration of internal functions in BaseLib. + + 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. + +**/ + +#ifndef __BASE_LIB_INTERNALS__ +#define __BASE_LIB_INTERNALS__ + +#include +#include +#include +#include +#include + +// +// Math functions +// + +/** + Shifts a 64-bit integer left between 0 and 63 bits. The low bits + are filled with zeros. The shifted value is returned. + + This function shifts the 64-bit value Operand to the left by Count bits. The + low Count bits are set to zero. The shifted value is returned. + + @param Operand The 64-bit operand to shift left. + @param Count The number of bits to shift left. + + @return Operand << Count + +**/ +UINT64 +EFIAPI +InternalMathLShiftU64 ( + IN UINT64 Operand, + IN UINTN Count + ); + +/** + Shifts a 64-bit integer right between 0 and 63 bits. The high bits + are filled with zeros. The shifted value is returned. + + This function shifts the 64-bit value Operand to the right by Count bits. The + high Count bits are set to zero. The shifted value is returned. + + @param Operand The 64-bit operand to shift right. + @param Count The number of bits to shift right. + + @return Operand >> Count + +**/ +UINT64 +EFIAPI +InternalMathRShiftU64 ( + IN UINT64 Operand, + IN UINTN Count + ); + +/** + Shifts a 64-bit integer right between 0 and 63 bits. The high bits + are filled with original integer's bit 63. The shifted value is returned. + + This function shifts the 64-bit value Operand to the right by Count bits. The + high Count bits are set to bit 63 of Operand. The shifted value is returned. + + @param Operand The 64-bit operand to shift right. + @param Count The number of bits to shift right. + + @return Operand arithmetically shifted right by Count + +**/ +UINT64 +EFIAPI +InternalMathARShiftU64 ( + IN UINT64 Operand, + IN UINTN Count + ); + +/** + Rotates a 64-bit integer left between 0 and 63 bits, filling + the low bits with the high bits that were rotated. + + This function rotates the 64-bit value Operand to the left by Count bits. The + low Count bits are filled with the high Count bits of Operand. The rotated + value is returned. + + @param Operand The 64-bit operand to rotate left. + @param Count The number of bits to rotate left. + + @return Operand <<< Count + +**/ +UINT64 +EFIAPI +InternalMathLRotU64 ( + IN UINT64 Operand, + IN UINTN Count + ); + +/** + Rotates a 64-bit integer right between 0 and 63 bits, filling + the high bits with the high low bits that were rotated. + + This function rotates the 64-bit value Operand to the right by Count bits. + The high Count bits are filled with the low Count bits of Operand. The rotated + value is returned. + + @param Operand The 64-bit operand to rotate right. + @param Count The number of bits to rotate right. + + @return Operand >>> Count + +**/ +UINT64 +EFIAPI +InternalMathRRotU64 ( + IN UINT64 Operand, + IN UINTN Count + ); + +/** + Switches the endianess of a 64-bit integer. + + This function swaps the bytes in a 64-bit unsigned value to switch the value + from little endian to big endian or vice versa. The byte swapped value is + returned. + + @param Operand A 64-bit unsigned value. + + @return The byte swapped Operand. + +**/ +UINT64 +EFIAPI +InternalMathSwapBytes64 ( + IN UINT64 Operand + ); + +/** + Multiplies a 64-bit unsigned integer by a 32-bit unsigned integer + and generates a 64-bit unsigned result. + + This function multiplies the 64-bit unsigned value Multiplicand by the 32-bit + unsigned value Multiplier and generates a 64-bit unsigned result. This 64- + bit unsigned result is returned. + + @param Multiplicand A 64-bit unsigned value. + @param Multiplier A 32-bit unsigned value. + + @return Multiplicand * Multiplier + +**/ +UINT64 +EFIAPI +InternalMathMultU64x32 ( + IN UINT64 Multiplicand, + IN UINT32 Multiplier + ); + +/** + Multiplies a 64-bit unsigned integer by a 64-bit unsigned integer + and generates a 64-bit unsigned result. + + This function multiples the 64-bit unsigned value Multiplicand by the 64-bit + unsigned value Multiplier and generates a 64-bit unsigned result. This 64- + bit unsigned result is returned. + + @param Multiplicand A 64-bit unsigned value. + @param Multiplier A 64-bit unsigned value. + + @return Multiplicand * Multiplier + +**/ +UINT64 +EFIAPI +InternalMathMultU64x64 ( + IN UINT64 Multiplicand, + IN UINT64 Multiplier + ); + +/** + Divides a 64-bit unsigned integer by a 32-bit unsigned integer and + generates a 64-bit unsigned result. + + This function divides the 64-bit unsigned value Dividend by the 32-bit + unsigned value Divisor and generates a 64-bit unsigned quotient. This + function returns the 64-bit unsigned quotient. + + @param Dividend A 64-bit unsigned value. + @param Divisor A 32-bit unsigned value. + + @return Dividend / Divisor + +**/ +UINT64 +EFIAPI +InternalMathDivU64x32 ( + IN UINT64 Dividend, + IN UINT32 Divisor + ); + +/** + Divides a 64-bit unsigned integer by a 32-bit unsigned integer and + generates a 32-bit unsigned remainder. + + This function divides the 64-bit unsigned value Dividend by the 32-bit + unsigned value Divisor and generates a 32-bit remainder. This function + returns the 32-bit unsigned remainder. + + @param Dividend A 64-bit unsigned value. + @param Divisor A 32-bit unsigned value. + + @return Dividend % Divisor + +**/ +UINT32 +EFIAPI +InternalMathModU64x32 ( + IN UINT64 Dividend, + IN UINT32 Divisor + ); + +/** + Divides a 64-bit unsigned integer by a 32-bit unsigned integer and + generates a 64-bit unsigned result and an optional 32-bit unsigned remainder. + + This function divides the 64-bit unsigned value Dividend by the 32-bit + unsigned value Divisor and generates a 64-bit unsigned quotient. If Remainder + is not NULL, then the 32-bit unsigned remainder is returned in Remainder. + This function returns the 64-bit unsigned quotient. + + @param Dividend A 64-bit unsigned value. + @param Divisor A 32-bit unsigned value. + @param Remainder A pointer to a 32-bit unsigned value. This parameter is + optional and may be NULL. + + @return Dividend / Divisor + +**/ +UINT64 +EFIAPI +InternalMathDivRemU64x32 ( + IN UINT64 Dividend, + IN UINT32 Divisor, + OUT UINT32 *Remainder OPTIONAL + ); + +/** + Divides a 64-bit unsigned integer by a 64-bit unsigned integer and + generates a 64-bit unsigned result and an optional 64-bit unsigned remainder. + + This function divides the 64-bit unsigned value Dividend by the 64-bit + unsigned value Divisor and generates a 64-bit unsigned quotient. If Remainder + is not NULL, then the 64-bit unsigned remainder is returned in Remainder. + This function returns the 64-bit unsigned quotient. + + @param Dividend A 64-bit unsigned value. + @param Divisor A 64-bit unsigned value. + @param Remainder A pointer to a 64-bit unsigned value. This parameter is + optional and may be NULL. + + @return Dividend / Divisor + +**/ +UINT64 +EFIAPI +InternalMathDivRemU64x64 ( + IN UINT64 Dividend, + IN UINT64 Divisor, + OUT UINT64 *Remainder OPTIONAL + ); + +/** + Divides a 64-bit signed integer by a 64-bit signed integer and + generates a 64-bit signed result and an optional 64-bit signed remainder. + + This function divides the 64-bit signed value Dividend by the 64-bit + signed value Divisor and generates a 64-bit signed quotient. If Remainder + is not NULL, then the 64-bit signed remainder is returned in Remainder. + This function returns the 64-bit signed quotient. + + @param Dividend A 64-bit signed value. + @param Divisor A 64-bit signed value. + @param Remainder A pointer to a 64-bit signed value. This parameter is + optional and may be NULL. + + @return Dividend / Divisor + +**/ +INT64 +EFIAPI +InternalMathDivRemS64x64 ( + IN INT64 Dividend, + IN INT64 Divisor, + OUT INT64 *Remainder OPTIONAL + ); + +/** + Transfers control to a function starting with a new stack. + + Transfers control to the function specified by EntryPoint using the + new stack specified by NewStack and passing in the parameters specified + by Context1 and Context2. Context1 and Context2 are optional and may + be NULL. The function EntryPoint must never return. + Marker will be ignored on IA-32, x64, and EBC. + IPF CPUs expect one additional parameter of type VOID * that specifies + the new backing store pointer. + + If EntryPoint is NULL, then ASSERT(). + If NewStack is NULL, then ASSERT(). + + @param EntryPoint A pointer to function to call with the new stack. + @param Context1 A pointer to the context to pass into the EntryPoint + function. + @param Context2 A pointer to the context to pass into the EntryPoint + function. + @param NewStack A pointer to the new stack to use for the EntryPoint + function. + @param Marker VA_LIST marker for the variable argument list. + +**/ +VOID +EFIAPI +InternalSwitchStack ( + IN SWITCH_STACK_ENTRY_POINT EntryPoint, + IN VOID *Context1, OPTIONAL + IN VOID *Context2, OPTIONAL + IN VOID *NewStack, + IN VA_LIST Marker + ); + + +/** + Worker function that locates the Node in the List. + + By searching the List, finds the location of the Node in List. At the same time, + verifies the validity of this list. + + If List is NULL, then ASSERT(). + If List->ForwardLink is NULL, then ASSERT(). + If List->backLink is NULL, then ASSERT(). + If Node is NULL, then ASSERT(); + If PcdMaximumLinkedListLenth is not zero, and prior to insertion the number + of nodes in ListHead, including the ListHead node, is greater than or + equal to PcdMaximumLinkedListLength, then ASSERT(). + + @param List A pointer to a node in a linked list. + @param Node A pointer to one nod. + + @retval TRUE Node is in List. + @retval FALSE Node isn't in List, or List is invalid. + +**/ +BOOLEAN +EFIAPI +IsNodeInList ( + IN CONST LIST_ENTRY *List, + IN CONST LIST_ENTRY *Node + ); + +/** + Worker function that returns a bit field from Operand. + + Returns the bitfield specified by the StartBit and the EndBit from Operand. + + @param Operand Operand on which to perform the bitfield operation. + @param StartBit The ordinal of the least significant bit in the bit field. + @param EndBit The ordinal of the most significant bit in the bit field. + + @return The bit field read. + +**/ +UINTN +EFIAPI +BitFieldReadUint ( + IN UINTN Operand, + IN UINTN StartBit, + IN UINTN EndBit + ); + + +/** + Worker function that reads a bit field from Operand, performs a bitwise OR, + and returns the result. + + Performs a bitwise OR between the bit field specified by StartBit and EndBit + in Operand and the value specified by AndData. All other bits in Operand are + preserved. The new value is returned. + + @param Operand Operand on which to perform the bitfield operation. + @param StartBit The ordinal of the least significant bit in the bit field. + @param EndBit The ordinal of the most significant bit in the bit field. + @param OrData The value to OR with the read value from the value + + @return The new value. + +**/ +UINTN +EFIAPI +BitFieldOrUint ( + IN UINTN Operand, + IN UINTN StartBit, + IN UINTN EndBit, + IN UINTN OrData + ); + + +/** + Worker function that reads a bit field from Operand, performs a bitwise AND, + and returns the result. + + Performs a bitwise AND between the bit field specified by StartBit and EndBit + in Operand and the value specified by AndData. All other bits in Operand are + preserved. The new value is returned. + + @param Operand Operand on which to perform the bitfield operation. + @param StartBit The ordinal of the least significant bit in the bit field. + @param EndBit The ordinal of the most significant bit in the bit field. + @param AndData The value to And with the read value from the value + + @return The new value. + +**/ +UINTN +EFIAPI +BitFieldAndUint ( + IN UINTN Operand, + IN UINTN StartBit, + IN UINTN EndBit, + IN UINTN AndData + ); + + +/** + Worker function that checks ASSERT condition for JumpBuffer + + Checks ASSERT condition for JumpBuffer. + + If JumpBuffer is NULL, then ASSERT(). + For IPF CPUs, if JumpBuffer is not aligned on a 16-byte boundary, then ASSERT(). + + @param JumpBuffer A pointer to CPU context buffer. + +**/ +VOID +EFIAPI +InternalAssertJumpBuffer ( + IN BASE_LIBRARY_JUMP_BUFFER *JumpBuffer + ); + + +/** + Restores the CPU context that was saved with SetJump(). + + Restores the CPU context from the buffer specified by JumpBuffer. + This function never returns to the caller. + Instead is resumes execution based on the state of JumpBuffer. + + @param JumpBuffer A pointer to CPU context buffer. + @param Value The value to return when the SetJump() context is restored. + +**/ +VOID +EFIAPI +InternalLongJump ( + IN BASE_LIBRARY_JUMP_BUFFER *JumpBuffer, + IN UINTN Value + ); + + +// +// Ia32 and x64 specific functions +// +#if defined (MDE_CPU_IA32) || defined (MDE_CPU_X64) + +/** + Reads the current Global Descriptor Table Register(GDTR) descriptor. + + Reads and returns the current GDTR descriptor and returns it in Gdtr. This + function is only available on IA-32 and x64. + + @param Gdtr The pointer to a GDTR descriptor. + +**/ +VOID +EFIAPI +InternalX86ReadGdtr ( + OUT IA32_DESCRIPTOR *Gdtr + ); + +/** + Writes the current Global Descriptor Table Register (GDTR) descriptor. + + Writes and the current GDTR descriptor specified by Gdtr. This function is + only available on IA-32 and x64. + + @param Gdtr The pointer to a GDTR descriptor. + +**/ +VOID +EFIAPI +InternalX86WriteGdtr ( + IN CONST IA32_DESCRIPTOR *Gdtr + ); + +/** + Reads the current Interrupt Descriptor Table Register(GDTR) descriptor. + + Reads and returns the current IDTR descriptor and returns it in Idtr. This + function is only available on IA-32 and x64. + + @param Idtr The pointer to an IDTR descriptor. + +**/ +VOID +EFIAPI +InternalX86ReadIdtr ( + OUT IA32_DESCRIPTOR *Idtr + ); + +/** + Writes the current Interrupt Descriptor Table Register(GDTR) descriptor. + + Writes the current IDTR descriptor and returns it in Idtr. This function is + only available on IA-32 and x64. + + @param Idtr The pointer to an IDTR descriptor. + +**/ +VOID +EFIAPI +InternalX86WriteIdtr ( + IN CONST IA32_DESCRIPTOR *Idtr + ); + +/** + Save the current floating point/SSE/SSE2 context to a buffer. + + Saves the current floating point/SSE/SSE2 state to the buffer specified by + Buffer. Buffer must be aligned on a 16-byte boundary. This function is only + available on IA-32 and x64. + + @param Buffer The pointer to a buffer to save the floating point/SSE/SSE2 context. + +**/ +VOID +EFIAPI +InternalX86FxSave ( + OUT IA32_FX_BUFFER *Buffer + ); + +/** + Restores the current floating point/SSE/SSE2 context from a buffer. + + Restores the current floating point/SSE/SSE2 state from the buffer specified + by Buffer. Buffer must be aligned on a 16-byte boundary. This function is + only available on IA-32 and x64. + + @param Buffer The pointer to a buffer to save the floating point/SSE/SSE2 context. + +**/ +VOID +EFIAPI +InternalX86FxRestore ( + IN CONST IA32_FX_BUFFER *Buffer + ); + +/** + Enables the 32-bit paging mode on the CPU. + + Enables the 32-bit paging mode on the CPU. CR0, CR3, CR4, and the page tables + must be properly initialized prior to calling this service. This function + assumes the current execution mode is 32-bit protected mode. This function is + only available on IA-32. After the 32-bit paging mode is enabled, control is + transferred to the function specified by EntryPoint using the new stack + specified by NewStack and passing in the parameters specified by Context1 and + Context2. Context1 and Context2 are optional and may be NULL. The function + EntryPoint must never return. + + There are a number of constraints that must be followed before calling this + function: + 1) Interrupts must be disabled. + 2) The caller must be in 32-bit protected mode with flat descriptors. This + means all descriptors must have a base of 0 and a limit of 4GB. + 3) CR0 and CR4 must be compatible with 32-bit protected mode with flat + descriptors. + 4) CR3 must point to valid page tables that will be used once the transition + is complete, and those page tables must guarantee that the pages for this + function and the stack are identity mapped. + + @param EntryPoint A pointer to function to call with the new stack after + paging is enabled. + @param Context1 A pointer to the context to pass into the EntryPoint + function as the first parameter after paging is enabled. + @param Context2 A pointer to the context to pass into the EntryPoint + function as the second parameter after paging is enabled. + @param NewStack A pointer to the new stack to use for the EntryPoint + function after paging is enabled. + +**/ +VOID +EFIAPI +InternalX86EnablePaging32 ( + IN SWITCH_STACK_ENTRY_POINT EntryPoint, + IN VOID *Context1, OPTIONAL + IN VOID *Context2, OPTIONAL + IN VOID *NewStack + ); + +/** + Disables the 32-bit paging mode on the CPU. + + Disables the 32-bit paging mode on the CPU and returns to 32-bit protected + mode. This function assumes the current execution mode is 32-paged protected + mode. This function is only available on IA-32. After the 32-bit paging mode + is disabled, control is transferred to the function specified by EntryPoint + using the new stack specified by NewStack and passing in the parameters + specified by Context1 and Context2. Context1 and Context2 are optional and + may be NULL. The function EntryPoint must never return. + + There are a number of constraints that must be followed before calling this + function: + 1) Interrupts must be disabled. + 2) The caller must be in 32-bit paged mode. + 3) CR0, CR3, and CR4 must be compatible with 32-bit paged mode. + 4) CR3 must point to valid page tables that guarantee that the pages for + this function and the stack are identity mapped. + + @param EntryPoint A pointer to function to call with the new stack after + paging is disabled. + @param Context1 A pointer to the context to pass into the EntryPoint + function as the first parameter after paging is disabled. + @param Context2 A pointer to the context to pass into the EntryPoint + function as the second parameter after paging is + disabled. + @param NewStack A pointer to the new stack to use for the EntryPoint + function after paging is disabled. + +**/ +VOID +EFIAPI +InternalX86DisablePaging32 ( + IN SWITCH_STACK_ENTRY_POINT EntryPoint, + IN VOID *Context1, OPTIONAL + IN VOID *Context2, OPTIONAL + IN VOID *NewStack + ); + +/** + Enables the 64-bit paging mode on the CPU. + + Enables the 64-bit paging mode on the CPU. CR0, CR3, CR4, and the page tables + must be properly initialized prior to calling this service. This function + assumes the current execution mode is 32-bit protected mode with flat + descriptors. This function is only available on IA-32. After the 64-bit + paging mode is enabled, control is transferred to the function specified by + EntryPoint using the new stack specified by NewStack and passing in the + parameters specified by Context1 and Context2. Context1 and Context2 are + optional and may be 0. The function EntryPoint must never return. + + @param Cs The 16-bit selector to load in the CS before EntryPoint + is called. The descriptor in the GDT that this selector + references must be setup for long mode. + @param EntryPoint The 64-bit virtual address of the function to call with + the new stack after paging is enabled. + @param Context1 The 64-bit virtual address of the context to pass into + the EntryPoint function as the first parameter after + paging is enabled. + @param Context2 The 64-bit virtual address of the context to pass into + the EntryPoint function as the second parameter after + paging is enabled. + @param NewStack The 64-bit virtual address of the new stack to use for + the EntryPoint function after paging is enabled. + +**/ +VOID +EFIAPI +InternalX86EnablePaging64 ( + IN UINT16 Cs, + IN UINT64 EntryPoint, + IN UINT64 Context1, OPTIONAL + IN UINT64 Context2, OPTIONAL + IN UINT64 NewStack + ); + +/** + Disables the 64-bit paging mode on the CPU. + + Disables the 64-bit paging mode on the CPU and returns to 32-bit protected + mode. This function assumes the current execution mode is 64-paging mode. + This function is only available on x64. After the 64-bit paging mode is + disabled, control is transferred to the function specified by EntryPoint + using the new stack specified by NewStack and passing in the parameters + specified by Context1 and Context2. Context1 and Context2 are optional and + may be 0. The function EntryPoint must never return. + + @param Cs The 16-bit selector to load in the CS before EntryPoint + is called. The descriptor in the GDT that this selector + references must be setup for 32-bit protected mode. + @param EntryPoint The 64-bit virtual address of the function to call with + the new stack after paging is disabled. + @param Context1 The 64-bit virtual address of the context to pass into + the EntryPoint function as the first parameter after + paging is disabled. + @param Context2 The 64-bit virtual address of the context to pass into + the EntryPoint function as the second parameter after + paging is disabled. + @param NewStack The 64-bit virtual address of the new stack to use for + the EntryPoint function after paging is disabled. + +**/ +VOID +EFIAPI +InternalX86DisablePaging64 ( + IN UINT16 Cs, + IN UINT32 EntryPoint, + IN UINT32 Context1, OPTIONAL + IN UINT32 Context2, OPTIONAL + IN UINT32 NewStack + ); + + +#elif defined (MDE_CPU_IPF) +// +// +// IPF specific functions +// + +/** + Reads control register DCR. + + This is a worker function for AsmReadControlRegister() + when its parameter Index is IPF_CONTROL_REGISTER_DCR. + + @return The 64-bit control register DCR. + +**/ +UINT64 +EFIAPI +AsmReadControlRegisterDcr ( + VOID + ); + + +/** + Reads control register ITM. + + This is a worker function for AsmReadControlRegister() + when its parameter Index is IPF_CONTROL_REGISTER_ITM. + + @return The 64-bit control register ITM. + +**/ +UINT64 +EFIAPI +AsmReadControlRegisterItm ( + VOID + ); + + +/** + Reads control register IVA. + + This is a worker function for AsmReadControlRegister() + when its parameter Index is IPF_CONTROL_REGISTER_IVA. + + @return The 64-bit control register IVA. + +**/ +UINT64 +EFIAPI +AsmReadControlRegisterIva ( + VOID + ); + + +/** + Reads control register PTA. + + This is a worker function for AsmReadControlRegister() + when its parameter Index is IPF_CONTROL_REGISTER_PTA. + + @return The 64-bit control register PTA. + +**/ +UINT64 +EFIAPI +AsmReadControlRegisterPta ( + VOID + ); + + +/** + Reads control register IPSR. + + This is a worker function for AsmReadControlRegister() + when its parameter Index is IPF_CONTROL_REGISTER_IPSR. + + @return The 64-bit control register IPSR. + +**/ +UINT64 +EFIAPI +AsmReadControlRegisterIpsr ( + VOID + ); + + +/** + Reads control register ISR. + + This is a worker function for AsmReadControlRegister() + when its parameter Index is IPF_CONTROL_REGISTER_ISR. + + @return The 64-bit control register ISR. + +**/ +UINT64 +EFIAPI +AsmReadControlRegisterIsr ( + VOID + ); + + +/** + Reads control register IIP. + + This is a worker function for AsmReadControlRegister() + when its parameter Index is IPF_CONTROL_REGISTER_IIP. + + @return The 64-bit control register IIP. + +**/ +UINT64 +EFIAPI +AsmReadControlRegisterIip ( + VOID + ); + + +/** + Reads control register IFA. + + This is a worker function for AsmReadControlRegister() + when its parameter Index is IPF_CONTROL_REGISTER_IFA. + + @return The 64-bit control register IFA. + +**/ +UINT64 +EFIAPI +AsmReadControlRegisterIfa ( + VOID + ); + + +/** + Reads control register ITIR. + + This is a worker function for AsmReadControlRegister() + when its parameter Index is IPF_CONTROL_REGISTER_ITIR. + + @return The 64-bit control register ITIR. + +**/ +UINT64 +EFIAPI +AsmReadControlRegisterItir ( + VOID + ); + + +/** + Reads control register IIPA. + + This is a worker function for AsmReadControlRegister() + when its parameter Index is IPF_CONTROL_REGISTER_IIPA. + + @return The 64-bit control register IIPA. + +**/ +UINT64 +EFIAPI +AsmReadControlRegisterIipa ( + VOID + ); + + +/** + Reads control register IFS. + + This is a worker function for AsmReadControlRegister() + when its parameter Index is IPF_CONTROL_REGISTER_IFS. + + @return The 64-bit control register IFS. + +**/ +UINT64 +EFIAPI +AsmReadControlRegisterIfs ( + VOID + ); + + +/** + Reads control register IIM. + + This is a worker function for AsmReadControlRegister() + when its parameter Index is IPF_CONTROL_REGISTER_IIM. + + @return The 64-bit control register IIM. + +**/ +UINT64 +EFIAPI +AsmReadControlRegisterIim ( + VOID + ); + + +/** + Reads control register IHA. + + This is a worker function for AsmReadControlRegister() + when its parameter Index is IPF_CONTROL_REGISTER_IHA. + + @return The 64-bit control register IHA. + +**/ +UINT64 +EFIAPI +AsmReadControlRegisterIha ( + VOID + ); + + +/** + Reads control register LID. + + This is a worker function for AsmReadControlRegister() + when its parameter Index is IPF_CONTROL_REGISTER_LID. + + @return The 64-bit control register LID. + +**/ +UINT64 +EFIAPI +AsmReadControlRegisterLid ( + VOID + ); + + +/** + Reads control register IVR. + + This is a worker function for AsmReadControlRegister() + when its parameter Index is IPF_CONTROL_REGISTER_IVR. + + @return The 64-bit control register IVR. + +**/ +UINT64 +EFIAPI +AsmReadControlRegisterIvr ( + VOID + ); + + +/** + Reads control register TPR. + + This is a worker function for AsmReadControlRegister() + when its parameter Index is IPF_CONTROL_REGISTER_TPR. + + @return The 64-bit control register TPR. + +**/ +UINT64 +EFIAPI +AsmReadControlRegisterTpr ( + VOID + ); + + +/** + Reads control register EOI. + + This is a worker function for AsmReadControlRegister() + when its parameter Index is IPF_CONTROL_REGISTER_EOI. + + @return The 64-bit control register EOI. + +**/ +UINT64 +EFIAPI +AsmReadControlRegisterEoi ( + VOID + ); + + +/** + Reads control register IRR0. + + This is a worker function for AsmReadControlRegister() + when its parameter Index is IPF_CONTROL_REGISTER_IRR0. + + @return The 64-bit control register IRR0. + +**/ +UINT64 +EFIAPI +AsmReadControlRegisterIrr0 ( + VOID + ); + + +/** + Reads control register IRR1. + + This is a worker function for AsmReadControlRegister() + when its parameter Index is IPF_CONTROL_REGISTER_IRR1. + + @return The 64-bit control register IRR1. + +**/ +UINT64 +EFIAPI +AsmReadControlRegisterIrr1 ( + VOID + ); + + +/** + Reads control register IRR2. + + This is a worker function for AsmReadControlRegister() + when its parameter Index is IPF_CONTROL_REGISTER_IRR2. + + @return The 64-bit control register IRR2. + +**/ +UINT64 +EFIAPI +AsmReadControlRegisterIrr2 ( + VOID + ); + + +/** + Reads control register IRR3. + + This is a worker function for AsmReadControlRegister() + when its parameter Index is IPF_CONTROL_REGISTER_IRR3. + + @return The 64-bit control register IRR3. + +**/ +UINT64 +EFIAPI +AsmReadControlRegisterIrr3 ( + VOID + ); + + +/** + Reads control register ITV. + + This is a worker function for AsmReadControlRegister() + when its parameter Index is IPF_CONTROL_REGISTER_ITV. + + @return The 64-bit control register ITV. + +**/ +UINT64 +EFIAPI +AsmReadControlRegisterItv ( + VOID + ); + + +/** + Reads control register PMV. + + This is a worker function for AsmReadControlRegister() + when its parameter Index is IPF_CONTROL_REGISTER_PMV. + + @return The 64-bit control register PMV. + +**/ +UINT64 +EFIAPI +AsmReadControlRegisterPmv ( + VOID + ); + + +/** + Reads control register CMCV. + + This is a worker function for AsmReadControlRegister() + when its parameter Index is IPF_CONTROL_REGISTER_CMCV. + + @return The 64-bit control register CMCV. + +**/ +UINT64 +EFIAPI +AsmReadControlRegisterCmcv ( + VOID + ); + + +/** + Reads control register LRR0. + + This is a worker function for AsmReadControlRegister() + when its parameter Index is IPF_CONTROL_REGISTER_LRR0. + + @return The 64-bit control register LRR0. + +**/ +UINT64 +EFIAPI +AsmReadControlRegisterLrr0 ( + VOID + ); + + +/** + Reads control register LRR1. + + This is a worker function for AsmReadControlRegister() + when its parameter Index is IPF_CONTROL_REGISTER_LRR1. + + @return The 64-bit control register LRR1. + +**/ +UINT64 +EFIAPI +AsmReadControlRegisterLrr1 ( + VOID + ); + + +/** + Reads application register K0. + + This is a worker function for AsmReadApplicationRegister() + when its parameter Index is IPF_APPLICATION_REGISTER_K0. + + @return The 64-bit application register K0. + +**/ +UINT64 +EFIAPI +AsmReadApplicationRegisterK0 ( + VOID + ); + + + +/** + Reads application register K1. + + This is a worker function for AsmReadApplicationRegister() + when its parameter Index is IPF_APPLICATION_REGISTER_K1. + + @return The 64-bit application register K1. + +**/ +UINT64 +EFIAPI +AsmReadApplicationRegisterK1 ( + VOID + ); + + +/** + Reads application register K2. + + This is a worker function for AsmReadApplicationRegister() + when its parameter Index is IPF_APPLICATION_REGISTER_K2. + + @return The 64-bit application register K2. + +**/ +UINT64 +EFIAPI +AsmReadApplicationRegisterK2 ( + VOID + ); + + +/** + Reads application register K3. + + This is a worker function for AsmReadApplicationRegister() + when its parameter Index is IPF_APPLICATION_REGISTER_K3. + + @return The 64-bit application register K3. + +**/ +UINT64 +EFIAPI +AsmReadApplicationRegisterK3 ( + VOID + ); + + +/** + Reads application register K4. + + This is a worker function for AsmReadApplicationRegister() + when its parameter Index is IPF_APPLICATION_REGISTER_K4. + + @return The 64-bit application register K4. + +**/ +UINT64 +EFIAPI +AsmReadApplicationRegisterK4 ( + VOID + ); + + +/** + Reads application register K5. + + This is a worker function for AsmReadApplicationRegister() + when its parameter Index is IPF_APPLICATION_REGISTER_K5. + + @return The 64-bit application register K5. + +**/ +UINT64 +EFIAPI +AsmReadApplicationRegisterK5 ( + VOID + ); + + +/** + Reads application register K6. + + This is a worker function for AsmReadApplicationRegister() + when its parameter Index is IPF_APPLICATION_REGISTER_K6. + + @return The 64-bit application register K6. + +**/ +UINT64 +EFIAPI +AsmReadApplicationRegisterK6 ( + VOID + ); + + +/** + Reads application register K7. + + This is a worker function for AsmReadApplicationRegister() + when its parameter Index is IPF_APPLICATION_REGISTER_K7. + + @return The 64-bit application register K7. + +**/ +UINT64 +EFIAPI +AsmReadApplicationRegisterK7 ( + VOID + ); + + +/** + Reads application register RSC. + + This is a worker function for AsmReadApplicationRegister() + when its parameter Index is IPF_APPLICATION_REGISTER_RSC. + + @return The 64-bit application register RSC. + +**/ +UINT64 +EFIAPI +AsmReadApplicationRegisterRsc ( + VOID + ); + + +/** + Reads application register BSP. + + This is a worker function for AsmReadApplicationRegister() + when its parameter Index is IPF_APPLICATION_REGISTER_BSP. + + @return The 64-bit application register BSP. + +**/ +UINT64 +EFIAPI +AsmReadApplicationRegisterBsp ( + VOID + ); + + +/** + Reads application register BSPSTORE. + + This is a worker function for AsmReadApplicationRegister() + when its parameter Index is IPF_APPLICATION_REGISTER_BSPSTORE. + + @return The 64-bit application register BSPSTORE. + +**/ +UINT64 +EFIAPI +AsmReadApplicationRegisterBspstore ( + VOID + ); + + +/** + Reads application register RNAT. + + This is a worker function for AsmReadApplicationRegister() + when its parameter Index is IPF_APPLICATION_REGISTER_RNAT. + + @return The 64-bit application register RNAT. + +**/ +UINT64 +EFIAPI +AsmReadApplicationRegisterRnat ( + VOID + ); + + +/** + Reads application register FCR. + + This is a worker function for AsmReadApplicationRegister() + when its parameter Index is IPF_APPLICATION_REGISTER_FCR. + + @return The 64-bit application register FCR. + +**/ +UINT64 +EFIAPI +AsmReadApplicationRegisterFcr ( + VOID + ); + + +/** + Reads application register EFLAG. + + This is a worker function for AsmReadApplicationRegister() + when its parameter Index is IPF_APPLICATION_REGISTER_EFLAG. + + @return The 64-bit application register EFLAG. + +**/ +UINT64 +EFIAPI +AsmReadApplicationRegisterEflag ( + VOID + ); + + +/** + Reads application register CSD. + + This is a worker function for AsmReadApplicationRegister() + when its parameter Index is IPF_APPLICATION_REGISTER_CSD. + + @return The 64-bit application register CSD. + +**/ +UINT64 +EFIAPI +AsmReadApplicationRegisterCsd ( + VOID + ); + + +/** + Reads application register SSD. + + This is a worker function for AsmReadApplicationRegister() + when its parameter Index is IPF_APPLICATION_REGISTER_SSD. + + @return The 64-bit application register SSD. + +**/ +UINT64 +EFIAPI +AsmReadApplicationRegisterSsd ( + VOID + ); + + +/** + Reads application register CFLG. + + This is a worker function for AsmReadApplicationRegister() + when its parameter Index is IPF_APPLICATION_REGISTER_CFLG. + + @return The 64-bit application register CFLG. + +**/ +UINT64 +EFIAPI +AsmReadApplicationRegisterCflg ( + VOID + ); + + +/** + Reads application register FSR. + + This is a worker function for AsmReadApplicationRegister() + when its parameter Index is IPF_APPLICATION_REGISTER_FSR. + + @return The 64-bit application register FSR. + +**/ +UINT64 +EFIAPI +AsmReadApplicationRegisterFsr ( + VOID + ); + + +/** + Reads application register FIR. + + This is a worker function for AsmReadApplicationRegister() + when its parameter Index is IPF_APPLICATION_REGISTER_FIR. + + @return The 64-bit application register FIR. + +**/ +UINT64 +EFIAPI +AsmReadApplicationRegisterFir ( + VOID + ); + + +/** + Reads application register FDR. + + This is a worker function for AsmReadApplicationRegister() + when its parameter Index is IPF_APPLICATION_REGISTER_FDR. + + @return The 64-bit application register FDR. + +**/ +UINT64 +EFIAPI +AsmReadApplicationRegisterFdr ( + VOID + ); + + +/** + Reads application register CCV. + + This is a worker function for AsmReadApplicationRegister() + when its parameter Index is IPF_APPLICATION_REGISTER_CCV. + + @return The 64-bit application register CCV. + +**/ +UINT64 +EFIAPI +AsmReadApplicationRegisterCcv ( + VOID + ); + + +/** + Reads application register UNAT. + + This is a worker function for AsmReadApplicationRegister() + when its parameter Index is IPF_APPLICATION_REGISTER_UNAT. + + @return The 64-bit application register UNAT. + +**/ +UINT64 +EFIAPI +AsmReadApplicationRegisterUnat ( + VOID + ); + + +/** + Reads application register FPSR. + + This is a worker function for AsmReadApplicationRegister() + when its parameter Index is IPF_APPLICATION_REGISTER_FPSR. + + @return The 64-bit application register FPSR. + +**/ +UINT64 +EFIAPI +AsmReadApplicationRegisterFpsr ( + VOID + ); + + +/** + Reads application register ITC. + + This is a worker function for AsmReadApplicationRegister() + when its parameter Index is IPF_APPLICATION_REGISTER_ITC. + + @return The 64-bit application register ITC. + +**/ +UINT64 +EFIAPI +AsmReadApplicationRegisterItc ( + VOID + ); + + +/** + Reads application register PFS. + + This is a worker function for AsmReadApplicationRegister() + when its parameter Index is IPF_APPLICATION_REGISTER_PFS. + + @return The 64-bit application register PFS. + +**/ +UINT64 +EFIAPI +AsmReadApplicationRegisterPfs ( + VOID + ); + + +/** + Reads application register LC. + + This is a worker function for AsmReadApplicationRegister() + when its parameter Index is IPF_APPLICATION_REGISTER_LC. + + @return The 64-bit application register LC. + +**/ +UINT64 +EFIAPI +AsmReadApplicationRegisterLc ( + VOID + ); + + +/** + Reads application register EC. + + This is a worker function for AsmReadApplicationRegister() + when its parameter Index is IPF_APPLICATION_REGISTER_EC. + + @return The 64-bit application register EC. + +**/ +UINT64 +EFIAPI +AsmReadApplicationRegisterEc ( + VOID + ); + + + +/** + Transfers control to a function starting with a new stack. + + Transfers control to the function specified by EntryPoint using the new stack + specified by NewStack and passing in the parameters specified by Context1 and + Context2. Context1 and Context2 are optional and may be NULL. The function + EntryPoint must never return. + + If EntryPoint is NULL, then ASSERT(). + If NewStack is NULL, then ASSERT(). + + @param EntryPoint A pointer to function to call with the new stack. + @param Context1 A pointer to the context to pass into the EntryPoint + function. + @param Context2 A pointer to the context to pass into the EntryPoint + function. + @param NewStack A pointer to the new stack to use for the EntryPoint + function. + @param NewBsp A pointer to the new memory location for RSE backing + store. + +**/ +VOID +EFIAPI +AsmSwitchStackAndBackingStore ( + IN SWITCH_STACK_ENTRY_POINT EntryPoint, + IN VOID *Context1, OPTIONAL + IN VOID *Context2, OPTIONAL + IN VOID *NewStack, + IN VOID *NewBsp + ); + +/** + Internal worker function to invalidate a range of instruction cache lines + in the cache coherency domain of the calling CPU. + + Internal worker function to invalidate the instruction cache lines specified + by Address and Length. If Address is not aligned on a cache line boundary, + then entire instruction cache line containing Address is invalidated. If + Address + Length is not aligned on a cache line boundary, then the entire + instruction cache line containing Address + Length -1 is invalidated. This + function may choose to invalidate the entire instruction cache if that is more + efficient than invalidating the specified range. If Length is 0, the no instruction + cache lines are invalidated. Address is returned. + This function is only available on IPF. + + @param Address The base address of the instruction cache lines to + invalidate. If the CPU is in a physical addressing mode, then + Address is a physical address. If the CPU is in a virtual + addressing mode, then Address is a virtual address. + + @param Length The number of bytes to invalidate from the instruction cache. + + @return Address + +**/ +VOID * +EFIAPI +InternalFlushCacheRange ( + IN VOID *Address, + IN UINTN Length + ); + +#else + +#endif + +#endif diff --git a/UnixPkg/Library/UnixBaseLib/BitField.c b/UnixPkg/Library/UnixBaseLib/BitField.c new file mode 100644 index 0000000000..d17e562407 --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/BitField.c @@ -0,0 +1,868 @@ +/** @file + Bit field functions of BaseLib. + + 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. + +**/ + +#include "BaseLibInternals.h" + +/** + Worker function that returns a bit field from Operand. + + Returns the bitfield specified by the StartBit and the EndBit from Operand. + + @param Operand Operand on which to perform the bitfield operation. + @param StartBit The ordinal of the least significant bit in the bit field. + @param EndBit The ordinal of the most significant bit in the bit field. + + @return The bit field read. + +**/ +UINTN +EFIAPI +InternalBaseLibBitFieldReadUint ( + IN UINTN Operand, + IN UINTN StartBit, + IN UINTN EndBit + ) +{ + // + // ~((UINTN)-2 << EndBit) is a mask in which bit[0] thru bit[EndBit] + // are 1's while bit[EndBit + 1] thru the most significant bit are 0's. + // + return (Operand & ~((UINTN)-2 << EndBit)) >> StartBit; +} + +/** + Worker function that reads a bit field from Operand, performs a bitwise OR, + and returns the result. + + Performs a bitwise OR between the bit field specified by StartBit and EndBit + in Operand and the value specified by AndData. All other bits in Operand are + preserved. The new value is returned. + + @param Operand Operand on which to perform the bitfield operation. + @param StartBit The ordinal of the least significant bit in the bit field. + @param EndBit The ordinal of the most significant bit in the bit field. + @param OrData The value to OR with the read value from the value. + + @return The new value. + +**/ +UINTN +EFIAPI +InternalBaseLibBitFieldOrUint ( + IN UINTN Operand, + IN UINTN StartBit, + IN UINTN EndBit, + IN UINTN OrData + ) +{ + // + // ~((UINTN)-2 << EndBit) is a mask in which bit[0] thru bit[EndBit] + // are 1's while bit[EndBit + 1] thru the most significant bit are 0's. + // + return Operand | ((OrData << StartBit) & ~((UINTN) -2 << EndBit)); +} + +/** + Worker function that reads a bit field from Operand, performs a bitwise AND, + and returns the result. + + Performs a bitwise AND between the bit field specified by StartBit and EndBit + in Operand and the value specified by AndData. All other bits in Operand are + preserved. The new value is returned. + + @param Operand Operand on which to perform the bitfield operation. + @param StartBit The ordinal of the least significant bit in the bit field. + @param EndBit The ordinal of the most significant bit in the bit field. + @param AndData The value to And with the read value from the value. + + @return The new value. + +**/ +UINTN +EFIAPI +InternalBaseLibBitFieldAndUint ( + IN UINTN Operand, + IN UINTN StartBit, + IN UINTN EndBit, + IN UINTN AndData + ) +{ + // + // ~((UINTN)-2 << EndBit) is a mask in which bit[0] thru bit[EndBit] + // are 1's while bit[EndBit + 1] thru the most significant bit are 0's. + // + return Operand & ~((~AndData << StartBit) & ~((UINTN)-2 << EndBit)); +} + +/** + Returns a bit field from an 8-bit value. + + Returns the bitfield specified by the StartBit and the EndBit from Operand. + + If 8-bit operations are not supported, then ASSERT(). + If StartBit is greater than 7, then ASSERT(). + If EndBit is greater than 7, then ASSERT(). + If EndBit is less than StartBit, then ASSERT(). + + @param Operand Operand on which to perform the bitfield operation. + @param StartBit The ordinal of the least significant bit in the bit field. + Range 0..7. + @param EndBit The ordinal of the most significant bit in the bit field. + Range 0..7. + + @return The bit field read. + +**/ +UINT8 +EFIAPI +BitFieldRead8 ( + IN UINT8 Operand, + IN UINTN StartBit, + IN UINTN EndBit + ) +{ + ASSERT (EndBit < 8); + ASSERT (StartBit <= EndBit); + return (UINT8)InternalBaseLibBitFieldReadUint (Operand, StartBit, EndBit); +} + +/** + Writes a bit field to an 8-bit value, and returns the result. + + Writes Value to the bit field specified by the StartBit and the EndBit in + Operand. All other bits in Operand are preserved. The new 8-bit value is + returned. + + If 8-bit operations are not supported, then ASSERT(). + If StartBit is greater than 7, then ASSERT(). + If EndBit is greater than 7, then ASSERT(). + If EndBit is less than StartBit, then ASSERT(). + + @param Operand Operand on which to perform the bitfield operation. + @param StartBit The ordinal of the least significant bit in the bit field. + Range 0..7. + @param EndBit The ordinal of the most significant bit in the bit field. + Range 0..7. + @param Value The new value of the bit field. + + @return The new 8-bit value. + +**/ +UINT8 +EFIAPI +BitFieldWrite8 ( + IN UINT8 Operand, + IN UINTN StartBit, + IN UINTN EndBit, + IN UINT8 Value + ) +{ + ASSERT (EndBit < 8); + ASSERT (StartBit <= EndBit); + return BitFieldAndThenOr8 (Operand, StartBit, EndBit, 0, Value); +} + +/** + Reads a bit field from an 8-bit value, performs a bitwise OR, and returns the + result. + + Performs a bitwise OR between the bit field specified by StartBit + and EndBit in Operand and the value specified by OrData. All other bits in + Operand are preserved. The new 8-bit value is returned. + + If 8-bit operations are not supported, then ASSERT(). + If StartBit is greater than 7, then ASSERT(). + If EndBit is greater than 7, then ASSERT(). + If EndBit is less than StartBit, then ASSERT(). + + @param Operand Operand on which to perform the bitfield operation. + @param StartBit The ordinal of the least significant bit in the bit field. + Range 0..7. + @param EndBit The ordinal of the most significant bit in the bit field. + Range 0..7. + @param OrData The value to OR with the read value from the value. + + @return The new 8-bit value. + +**/ +UINT8 +EFIAPI +BitFieldOr8 ( + IN UINT8 Operand, + IN UINTN StartBit, + IN UINTN EndBit, + IN UINT8 OrData + ) +{ + ASSERT (EndBit < 8); + ASSERT (StartBit <= EndBit); + return (UINT8)InternalBaseLibBitFieldOrUint (Operand, StartBit, EndBit, OrData); +} + +/** + Reads a bit field from an 8-bit value, performs a bitwise AND, and returns + the result. + + Performs a bitwise AND between the bit field specified by StartBit and EndBit + in Operand and the value specified by AndData. All other bits in Operand are + preserved. The new 8-bit value is returned. + + If 8-bit operations are not supported, then ASSERT(). + If StartBit is greater than 7, then ASSERT(). + If EndBit is greater than 7, then ASSERT(). + If EndBit is less than StartBit, then ASSERT(). + + @param Operand Operand on which to perform the bitfield operation. + @param StartBit The ordinal of the least significant bit in the bit field. + Range 0..7. + @param EndBit The ordinal of the most significant bit in the bit field. + Range 0..7. + @param AndData The value to AND with the read value from the value. + + @return The new 8-bit value. + +**/ +UINT8 +EFIAPI +BitFieldAnd8 ( + IN UINT8 Operand, + IN UINTN StartBit, + IN UINTN EndBit, + IN UINT8 AndData + ) +{ + ASSERT (EndBit < 8); + ASSERT (StartBit <= EndBit); + return (UINT8)InternalBaseLibBitFieldAndUint (Operand, StartBit, EndBit, AndData); +} + +/** + Reads a bit field from an 8-bit value, performs a bitwise AND followed by a + bitwise OR, and returns the result. + + Performs a bitwise AND between the bit field specified by StartBit and EndBit + in Operand and the value specified by AndData, followed by a bitwise + OR with value specified by OrData. All other bits in Operand are + preserved. The new 8-bit value is returned. + + If 8-bit operations are not supported, then ASSERT(). + If StartBit is greater than 7, then ASSERT(). + If EndBit is greater than 7, then ASSERT(). + If EndBit is less than StartBit, then ASSERT(). + + @param Operand Operand on which to perform the bitfield operation. + @param StartBit The ordinal of the least significant bit in the bit field. + Range 0..7. + @param EndBit The ordinal of the most significant bit in the bit field. + Range 0..7. + @param AndData The value to AND with the read value from the value. + @param OrData The value to OR with the result of the AND operation. + + @return The new 8-bit value. + +**/ +UINT8 +EFIAPI +BitFieldAndThenOr8 ( + IN UINT8 Operand, + IN UINTN StartBit, + IN UINTN EndBit, + IN UINT8 AndData, + IN UINT8 OrData + ) +{ + ASSERT (EndBit < 8); + ASSERT (StartBit <= EndBit); + return BitFieldOr8 ( + BitFieldAnd8 (Operand, StartBit, EndBit, AndData), + StartBit, + EndBit, + OrData + ); +} + +/** + Returns a bit field from a 16-bit value. + + Returns the bitfield specified by the StartBit and the EndBit from Operand. + + If 16-bit operations are not supported, then ASSERT(). + If StartBit is greater than 15, then ASSERT(). + If EndBit is greater than 15, then ASSERT(). + If EndBit is less than StartBit, then ASSERT(). + + @param Operand Operand on which to perform the bitfield operation. + @param StartBit The ordinal of the least significant bit in the bit field. + Range 0..15. + @param EndBit The ordinal of the most significant bit in the bit field. + Range 0..15. + + @return The bit field read. + +**/ +UINT16 +EFIAPI +BitFieldRead16 ( + IN UINT16 Operand, + IN UINTN StartBit, + IN UINTN EndBit + ) +{ + ASSERT (EndBit < 16); + ASSERT (StartBit <= EndBit); + return (UINT16)InternalBaseLibBitFieldReadUint (Operand, StartBit, EndBit); +} + +/** + Writes a bit field to a 16-bit value, and returns the result. + + Writes Value to the bit field specified by the StartBit and the EndBit in + Operand. All other bits in Operand are preserved. The new 16-bit value is + returned. + + If 16-bit operations are not supported, then ASSERT(). + If StartBit is greater than 15, then ASSERT(). + If EndBit is greater than 15, then ASSERT(). + If EndBit is less than StartBit, then ASSERT(). + + @param Operand Operand on which to perform the bitfield operation. + @param StartBit The ordinal of the least significant bit in the bit field. + Range 0..15. + @param EndBit The ordinal of the most significant bit in the bit field. + Range 0..15. + @param Value The new value of the bit field. + + @return The new 16-bit value. + +**/ +UINT16 +EFIAPI +BitFieldWrite16 ( + IN UINT16 Operand, + IN UINTN StartBit, + IN UINTN EndBit, + IN UINT16 Value + ) +{ + ASSERT (EndBit < 16); + ASSERT (StartBit <= EndBit); + return BitFieldAndThenOr16 (Operand, StartBit, EndBit, 0, Value); +} + +/** + Reads a bit field from a 16-bit value, performs a bitwise OR, and returns the + result. + + Performs a bitwise OR between the bit field specified by StartBit + and EndBit in Operand and the value specified by OrData. All other bits in + Operand are preserved. The new 16-bit value is returned. + + If 16-bit operations are not supported, then ASSERT(). + If StartBit is greater than 15, then ASSERT(). + If EndBit is greater than 15, then ASSERT(). + If EndBit is less than StartBit, then ASSERT(). + + @param Operand Operand on which to perform the bitfield operation. + @param StartBit The ordinal of the least significant bit in the bit field. + Range 0..15. + @param EndBit The ordinal of the most significant bit in the bit field. + Range 0..15. + @param OrData The value to OR with the read value from the value. + + @return The new 16-bit value. + +**/ +UINT16 +EFIAPI +BitFieldOr16 ( + IN UINT16 Operand, + IN UINTN StartBit, + IN UINTN EndBit, + IN UINT16 OrData + ) +{ + ASSERT (EndBit < 16); + ASSERT (StartBit <= EndBit); + return (UINT16)InternalBaseLibBitFieldOrUint (Operand, StartBit, EndBit, OrData); +} + +/** + Reads a bit field from a 16-bit value, performs a bitwise AND, and returns + the result. + + Performs a bitwise AND between the bit field specified by StartBit and EndBit + in Operand and the value specified by AndData. All other bits in Operand are + preserved. The new 16-bit value is returned. + + If 16-bit operations are not supported, then ASSERT(). + If StartBit is greater than 15, then ASSERT(). + If EndBit is greater than 15, then ASSERT(). + If EndBit is less than StartBit, then ASSERT(). + + @param Operand Operand on which to perform the bitfield operation. + @param StartBit The ordinal of the least significant bit in the bit field. + Range 0..15. + @param EndBit The ordinal of the most significant bit in the bit field. + Range 0..15. + @param AndData The value to AND with the read value from the value. + + @return The new 16-bit value. + +**/ +UINT16 +EFIAPI +BitFieldAnd16 ( + IN UINT16 Operand, + IN UINTN StartBit, + IN UINTN EndBit, + IN UINT16 AndData + ) +{ + ASSERT (EndBit < 16); + ASSERT (StartBit <= EndBit); + return (UINT16)InternalBaseLibBitFieldAndUint (Operand, StartBit, EndBit, AndData); +} + +/** + Reads a bit field from a 16-bit value, performs a bitwise AND followed by a + bitwise OR, and returns the result. + + Performs a bitwise AND between the bit field specified by StartBit and EndBit + in Operand and the value specified by AndData, followed by a bitwise + OR with value specified by OrData. All other bits in Operand are + preserved. The new 16-bit value is returned. + + If 16-bit operations are not supported, then ASSERT(). + If StartBit is greater than 15, then ASSERT(). + If EndBit is greater than 15, then ASSERT(). + If EndBit is less than StartBit, then ASSERT(). + + @param Operand Operand on which to perform the bitfield operation. + @param StartBit The ordinal of the least significant bit in the bit field. + Range 0..15. + @param EndBit The ordinal of the most significant bit in the bit field. + Range 0..15. + @param AndData The value to AND with the read value from the value. + @param OrData The value to OR with the result of the AND operation. + + @return The new 16-bit value. + +**/ +UINT16 +EFIAPI +BitFieldAndThenOr16 ( + IN UINT16 Operand, + IN UINTN StartBit, + IN UINTN EndBit, + IN UINT16 AndData, + IN UINT16 OrData + ) +{ + ASSERT (EndBit < 16); + ASSERT (StartBit <= EndBit); + return BitFieldOr16 ( + BitFieldAnd16 (Operand, StartBit, EndBit, AndData), + StartBit, + EndBit, + OrData + ); +} + +/** + Returns a bit field from a 32-bit value. + + Returns the bitfield specified by the StartBit and the EndBit from Operand. + + If 32-bit operations are not supported, then ASSERT(). + If StartBit is greater than 31, then ASSERT(). + If EndBit is greater than 31, then ASSERT(). + If EndBit is less than StartBit, then ASSERT(). + + @param Operand Operand on which to perform the bitfield operation. + @param StartBit The ordinal of the least significant bit in the bit field. + Range 0..31. + @param EndBit The ordinal of the most significant bit in the bit field. + Range 0..31. + + @return The bit field read. + +**/ +UINT32 +EFIAPI +BitFieldRead32 ( + IN UINT32 Operand, + IN UINTN StartBit, + IN UINTN EndBit + ) +{ + ASSERT (EndBit < 32); + ASSERT (StartBit <= EndBit); + return (UINT32)InternalBaseLibBitFieldReadUint (Operand, StartBit, EndBit); +} + +/** + Writes a bit field to a 32-bit value, and returns the result. + + Writes Value to the bit field specified by the StartBit and the EndBit in + Operand. All other bits in Operand are preserved. The new 32-bit value is + returned. + + If 32-bit operations are not supported, then ASSERT(). + If StartBit is greater than 31, then ASSERT(). + If EndBit is greater than 31, then ASSERT(). + If EndBit is less than StartBit, then ASSERT(). + + @param Operand Operand on which to perform the bitfield operation. + @param StartBit The ordinal of the least significant bit in the bit field. + Range 0..31. + @param EndBit The ordinal of the most significant bit in the bit field. + Range 0..31. + @param Value The new value of the bit field. + + @return The new 32-bit value. + +**/ +UINT32 +EFIAPI +BitFieldWrite32 ( + IN UINT32 Operand, + IN UINTN StartBit, + IN UINTN EndBit, + IN UINT32 Value + ) +{ + ASSERT (EndBit < 32); + ASSERT (StartBit <= EndBit); + return BitFieldAndThenOr32 (Operand, StartBit, EndBit, 0, Value); +} + +/** + Reads a bit field from a 32-bit value, performs a bitwise OR, and returns the + result. + + Performs a bitwise OR between the bit field specified by StartBit + and EndBit in Operand and the value specified by OrData. All other bits in + Operand are preserved. The new 32-bit value is returned. + + If 32-bit operations are not supported, then ASSERT(). + If StartBit is greater than 31, then ASSERT(). + If EndBit is greater than 31, then ASSERT(). + If EndBit is less than StartBit, then ASSERT(). + + @param Operand Operand on which to perform the bitfield operation. + @param StartBit The ordinal of the least significant bit in the bit field. + Range 0..31. + @param EndBit The ordinal of the most significant bit in the bit field. + Range 0..31. + @param OrData The value to OR with the read value from the value. + + @return The new 32-bit value. + +**/ +UINT32 +EFIAPI +BitFieldOr32 ( + IN UINT32 Operand, + IN UINTN StartBit, + IN UINTN EndBit, + IN UINT32 OrData + ) +{ + ASSERT (EndBit < 32); + ASSERT (StartBit <= EndBit); + return (UINT32)InternalBaseLibBitFieldOrUint (Operand, StartBit, EndBit, OrData); +} + +/** + Reads a bit field from a 32-bit value, performs a bitwise AND, and returns + the result. + + Performs a bitwise AND between the bit field specified by StartBit and EndBit + in Operand and the value specified by AndData. All other bits in Operand are + preserved. The new 32-bit value is returned. + + If 32-bit operations are not supported, then ASSERT(). + If StartBit is greater than 31, then ASSERT(). + If EndBit is greater than 31, then ASSERT(). + If EndBit is less than StartBit, then ASSERT(). + + @param Operand Operand on which to perform the bitfield operation. + @param StartBit The ordinal of the least significant bit in the bit field. + Range 0..31. + @param EndBit The ordinal of the most significant bit in the bit field. + Range 0..31. + @param AndData The value to AND with the read value from the value. + + @return The new 32-bit value. + +**/ +UINT32 +EFIAPI +BitFieldAnd32 ( + IN UINT32 Operand, + IN UINTN StartBit, + IN UINTN EndBit, + IN UINT32 AndData + ) +{ + ASSERT (EndBit < 32); + ASSERT (StartBit <= EndBit); + return (UINT32)InternalBaseLibBitFieldAndUint (Operand, StartBit, EndBit, AndData); +} + +/** + Reads a bit field from a 32-bit value, performs a bitwise AND followed by a + bitwise OR, and returns the result. + + Performs a bitwise AND between the bit field specified by StartBit and EndBit + in Operand and the value specified by AndData, followed by a bitwise + OR with value specified by OrData. All other bits in Operand are + preserved. The new 32-bit value is returned. + + If 32-bit operations are not supported, then ASSERT(). + If StartBit is greater than 31, then ASSERT(). + If EndBit is greater than 31, then ASSERT(). + If EndBit is less than StartBit, then ASSERT(). + + @param Operand Operand on which to perform the bitfield operation. + @param StartBit The ordinal of the least significant bit in the bit field. + Range 0..31. + @param EndBit The ordinal of the most significant bit in the bit field. + Range 0..31. + @param AndData The value to AND with the read value from the value. + @param OrData The value to OR with the result of the AND operation. + + @return The new 32-bit value. + +**/ +UINT32 +EFIAPI +BitFieldAndThenOr32 ( + IN UINT32 Operand, + IN UINTN StartBit, + IN UINTN EndBit, + IN UINT32 AndData, + IN UINT32 OrData + ) +{ + ASSERT (EndBit < 32); + ASSERT (StartBit <= EndBit); + return BitFieldOr32 ( + BitFieldAnd32 (Operand, StartBit, EndBit, AndData), + StartBit, + EndBit, + OrData + ); +} + +/** + Returns a bit field from a 64-bit value. + + Returns the bitfield specified by the StartBit and the EndBit from Operand. + + If 64-bit operations are not supported, then ASSERT(). + If StartBit is greater than 63, then ASSERT(). + If EndBit is greater than 63, then ASSERT(). + If EndBit is less than StartBit, then ASSERT(). + + @param Operand Operand on which to perform the bitfield operation. + @param StartBit The ordinal of the least significant bit in the bit field. + Range 0..63. + @param EndBit The ordinal of the most significant bit in the bit field. + Range 0..63. + + @return The bit field read. + +**/ +UINT64 +EFIAPI +BitFieldRead64 ( + IN UINT64 Operand, + IN UINTN StartBit, + IN UINTN EndBit + ) +{ + ASSERT (EndBit < 64); + ASSERT (StartBit <= EndBit); + return RShiftU64 (Operand & ~LShiftU64 ((UINT64)-2, EndBit), StartBit); +} + +/** + Writes a bit field to a 64-bit value, and returns the result. + + Writes Value to the bit field specified by the StartBit and the EndBit in + Operand. All other bits in Operand are preserved. The new 64-bit value is + returned. + + If 64-bit operations are not supported, then ASSERT(). + If StartBit is greater than 63, then ASSERT(). + If EndBit is greater than 63, then ASSERT(). + If EndBit is less than StartBit, then ASSERT(). + + @param Operand Operand on which to perform the bitfield operation. + @param StartBit The ordinal of the least significant bit in the bit field. + Range 0..63. + @param EndBit The ordinal of the most significant bit in the bit field. + Range 0..63. + @param Value The new value of the bit field. + + @return The new 64-bit value. + +**/ +UINT64 +EFIAPI +BitFieldWrite64 ( + IN UINT64 Operand, + IN UINTN StartBit, + IN UINTN EndBit, + IN UINT64 Value + ) +{ + ASSERT (EndBit < 64); + ASSERT (StartBit <= EndBit); + return BitFieldAndThenOr64 (Operand, StartBit, EndBit, 0, Value); +} + +/** + Reads a bit field from a 64-bit value, performs a bitwise OR, and returns the + result. + + Performs a bitwise OR between the bit field specified by StartBit + and EndBit in Operand and the value specified by OrData. All other bits in + Operand are preserved. The new 64-bit value is returned. + + If 64-bit operations are not supported, then ASSERT(). + If StartBit is greater than 63, then ASSERT(). + If EndBit is greater than 63, then ASSERT(). + If EndBit is less than StartBit, then ASSERT(). + + @param Operand Operand on which to perform the bitfield operation. + @param StartBit The ordinal of the least significant bit in the bit field. + Range 0..63. + @param EndBit The ordinal of the most significant bit in the bit field. + Range 0..63. + @param OrData The value to OR with the read value from the value + + @return The new 64-bit value. + +**/ +UINT64 +EFIAPI +BitFieldOr64 ( + IN UINT64 Operand, + IN UINTN StartBit, + IN UINTN EndBit, + IN UINT64 OrData + ) +{ + UINT64 Value1; + UINT64 Value2; + + ASSERT (EndBit < 64); + ASSERT (StartBit <= EndBit); + + Value1 = LShiftU64 (OrData, StartBit); + Value2 = LShiftU64 ((UINT64) - 2, EndBit); + + return Operand | (Value1 & ~Value2); +} + +/** + Reads a bit field from a 64-bit value, performs a bitwise AND, and returns + the result. + + Performs a bitwise AND between the bit field specified by StartBit and EndBit + in Operand and the value specified by AndData. All other bits in Operand are + preserved. The new 64-bit value is returned. + + If 64-bit operations are not supported, then ASSERT(). + If StartBit is greater than 63, then ASSERT(). + If EndBit is greater than 63, then ASSERT(). + If EndBit is less than StartBit, then ASSERT(). + + @param Operand Operand on which to perform the bitfield operation. + @param StartBit The ordinal of the least significant bit in the bit field. + Range 0..63. + @param EndBit The ordinal of the most significant bit in the bit field. + Range 0..63. + @param AndData The value to AND with the read value from the value. + + @return The new 64-bit value. + +**/ +UINT64 +EFIAPI +BitFieldAnd64 ( + IN UINT64 Operand, + IN UINTN StartBit, + IN UINTN EndBit, + IN UINT64 AndData + ) +{ + UINT64 Value1; + UINT64 Value2; + + ASSERT (EndBit < 64); + ASSERT (StartBit <= EndBit); + + Value1 = LShiftU64 (~AndData, StartBit); + Value2 = LShiftU64 ((UINT64)-2, EndBit); + + return Operand & ~(Value1 & ~Value2); +} + +/** + Reads a bit field from a 64-bit value, performs a bitwise AND followed by a + bitwise OR, and returns the result. + + Performs a bitwise AND between the bit field specified by StartBit and EndBit + in Operand and the value specified by AndData, followed by a bitwise + OR with value specified by OrData. All other bits in Operand are + preserved. The new 64-bit value is returned. + + If 64-bit operations are not supported, then ASSERT(). + If StartBit is greater than 63, then ASSERT(). + If EndBit is greater than 63, then ASSERT(). + If EndBit is less than StartBit, then ASSERT(). + + @param Operand Operand on which to perform the bitfield operation. + @param StartBit The ordinal of the least significant bit in the bit field. + Range 0..63. + @param EndBit The ordinal of the most significant bit in the bit field. + Range 0..63. + @param AndData The value to AND with the read value from the value. + @param OrData The value to OR with the result of the AND operation. + + @return The new 64-bit value. + +**/ +UINT64 +EFIAPI +BitFieldAndThenOr64 ( + IN UINT64 Operand, + IN UINTN StartBit, + IN UINTN EndBit, + IN UINT64 AndData, + IN UINT64 OrData + ) +{ + ASSERT (EndBit < 64); + ASSERT (StartBit <= EndBit); + return BitFieldOr64 ( + BitFieldAnd64 (Operand, StartBit, EndBit, AndData), + StartBit, + EndBit, + OrData + ); +} diff --git a/UnixPkg/Library/UnixBaseLib/CheckSum.c b/UnixPkg/Library/UnixBaseLib/CheckSum.c new file mode 100644 index 0000000000..29688291bb --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/CheckSum.c @@ -0,0 +1,337 @@ +/** @file + Utility functions to generate checksum based on 2's complement + algorithm. + + 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 "BaseLibInternals.h" + +/** + Returns the sum of all elements in a buffer in unit of UINT8. + During calculation, the carry bits are dropped. + + This function calculates the sum of all elements in a buffer + in unit of UINT8. The carry bits in result of addition are dropped. + The result is returned as UINT8. If Length is Zero, then Zero is + returned. + + If Buffer is NULL, then ASSERT(). + If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). + + @param Buffer The pointer to the buffer to carry out the sum operation. + @param Length The size, in bytes, of Buffer. + + @return Sum The sum of Buffer with carry bits dropped during additions. + +**/ +UINT8 +EFIAPI +CalculateSum8 ( + IN CONST UINT8 *Buffer, + IN UINTN Length + ) +{ + UINT8 Sum; + UINTN Count; + + ASSERT (Buffer != NULL); + ASSERT (Length <= (MAX_ADDRESS - ((UINTN) Buffer) + 1)); + + for (Sum = 0, Count = 0; Count < Length; Count++) { + Sum = (UINT8) (Sum + *(Buffer + Count)); + } + + return Sum; +} + + +/** + Returns the two's complement checksum of all elements in a buffer + of 8-bit values. + + This function first calculates the sum of the 8-bit values in the + buffer specified by Buffer and Length. The carry bits in the result + of addition are dropped. Then, the two's complement of the sum is + returned. If Length is 0, then 0 is returned. + + If Buffer is NULL, then ASSERT(). + If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). + + @param Buffer The pointer to the buffer to carry out the checksum operation. + @param Length The size, in bytes, of Buffer. + + @return Checksum The 2's complement checksum of Buffer. + +**/ +UINT8 +EFIAPI +CalculateCheckSum8 ( + IN CONST UINT8 *Buffer, + IN UINTN Length + ) +{ + UINT8 CheckSum; + + CheckSum = CalculateSum8 (Buffer, Length); + + // + // Return the checksum based on 2's complement. + // + return (UINT8) (0x100 - CheckSum); +} + +/** + Returns the sum of all elements in a buffer of 16-bit values. During + calculation, the carry bits are dropped. + + This function calculates the sum of the 16-bit values in the buffer + specified by Buffer and Length. The carry bits in result of addition are dropped. + The 16-bit result is returned. If Length is 0, then 0 is returned. + + If Buffer is NULL, then ASSERT(). + If Buffer is not aligned on a 16-bit boundary, then ASSERT(). + If Length is not aligned on a 16-bit boundary, then ASSERT(). + If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). + + @param Buffer The pointer to the buffer to carry out the sum operation. + @param Length The size, in bytes, of Buffer. + + @return Sum The sum of Buffer with carry bits dropped during additions. + +**/ +UINT16 +EFIAPI +CalculateSum16 ( + IN CONST UINT16 *Buffer, + IN UINTN Length + ) +{ + UINT16 Sum; + UINTN Count; + UINTN Total; + + ASSERT (Buffer != NULL); + ASSERT (((UINTN) Buffer & 0x1) == 0); + ASSERT ((Length & 0x1) == 0); + ASSERT (Length <= (MAX_ADDRESS - ((UINTN) Buffer) + 1)); + + Total = Length / sizeof (*Buffer); + for (Sum = 0, Count = 0; Count < Total; Count++) { + Sum = (UINT16) (Sum + *(Buffer + Count)); + } + + return Sum; +} + + +/** + Returns the two's complement checksum of all elements in a buffer of + 16-bit values. + + This function first calculates the sum of the 16-bit values in the buffer + specified by Buffer and Length. The carry bits in the result of addition + are dropped. Then, the two's complement of the sum is returned. If Length + is 0, then 0 is returned. + + If Buffer is NULL, then ASSERT(). + If Buffer is not aligned on a 16-bit boundary, then ASSERT(). + If Length is not aligned on a 16-bit boundary, then ASSERT(). + If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). + + @param Buffer The pointer to the buffer to carry out the checksum operation. + @param Length The size, in bytes, of Buffer. + + @return Checksum The 2's complement checksum of Buffer. + +**/ +UINT16 +EFIAPI +CalculateCheckSum16 ( + IN CONST UINT16 *Buffer, + IN UINTN Length + ) +{ + UINT16 CheckSum; + + CheckSum = CalculateSum16 (Buffer, Length); + + // + // Return the checksum based on 2's complement. + // + return (UINT16) (0x10000 - CheckSum); +} + + +/** + Returns the sum of all elements in a buffer of 32-bit values. During + calculation, the carry bits are dropped. + + This function calculates the sum of the 32-bit values in the buffer + specified by Buffer and Length. The carry bits in result of addition are dropped. + The 32-bit result is returned. If Length is 0, then 0 is returned. + + If Buffer is NULL, then ASSERT(). + If Buffer is not aligned on a 32-bit boundary, then ASSERT(). + If Length is not aligned on a 32-bit boundary, then ASSERT(). + If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). + + @param Buffer The pointer to the buffer to carry out the sum operation. + @param Length The size, in bytes, of Buffer. + + @return Sum The sum of Buffer with carry bits dropped during additions. + +**/ +UINT32 +EFIAPI +CalculateSum32 ( + IN CONST UINT32 *Buffer, + IN UINTN Length + ) +{ + UINT32 Sum; + UINTN Count; + UINTN Total; + + ASSERT (Buffer != NULL); + ASSERT (((UINTN) Buffer & 0x3) == 0); + ASSERT ((Length & 0x3) == 0); + ASSERT (Length <= (MAX_ADDRESS - ((UINTN) Buffer) + 1)); + + Total = Length / sizeof (*Buffer); + for (Sum = 0, Count = 0; Count < Total; Count++) { + Sum = Sum + *(Buffer + Count); + } + + return Sum; +} + + +/** + Returns the two's complement checksum of all elements in a buffer of + 32-bit values. + + This function first calculates the sum of the 32-bit values in the buffer + specified by Buffer and Length. The carry bits in the result of addition + are dropped. Then, the two's complement of the sum is returned. If Length + is 0, then 0 is returned. + + If Buffer is NULL, then ASSERT(). + If Buffer is not aligned on a 32-bit boundary, then ASSERT(). + If Length is not aligned on a 32-bit boundary, then ASSERT(). + If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). + + @param Buffer The pointer to the buffer to carry out the checksum operation. + @param Length The size, in bytes, of Buffer. + + @return Checksum The 2's complement checksum of Buffer. + +**/ +UINT32 +EFIAPI +CalculateCheckSum32 ( + IN CONST UINT32 *Buffer, + IN UINTN Length + ) +{ + UINT32 CheckSum; + + CheckSum = CalculateSum32 (Buffer, Length); + + // + // Return the checksum based on 2's complement. + // + return (UINT32) ((UINT32)(-1) - CheckSum + 1); +} + + +/** + Returns the sum of all elements in a buffer of 64-bit values. During + calculation, the carry bits are dropped. + + This function calculates the sum of the 64-bit values in the buffer + specified by Buffer and Length. The carry bits in result of addition are dropped. + The 64-bit result is returned. If Length is 0, then 0 is returned. + + If Buffer is NULL, then ASSERT(). + If Buffer is not aligned on a 64-bit boundary, then ASSERT(). + If Length is not aligned on a 64-bit boundary, then ASSERT(). + If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). + + @param Buffer The pointer to the buffer to carry out the sum operation. + @param Length The size, in bytes, of Buffer. + + @return Sum The sum of Buffer with carry bits dropped during additions. + +**/ +UINT64 +EFIAPI +CalculateSum64 ( + IN CONST UINT64 *Buffer, + IN UINTN Length + ) +{ + UINT64 Sum; + UINTN Count; + UINTN Total; + + ASSERT (Buffer != NULL); + ASSERT (((UINTN) Buffer & 0x7) == 0); + ASSERT ((Length & 0x7) == 0); + ASSERT (Length <= (MAX_ADDRESS - ((UINTN) Buffer) + 1)); + + Total = Length / sizeof (*Buffer); + for (Sum = 0, Count = 0; Count < Total; Count++) { + Sum = Sum + *(Buffer + Count); + } + + return Sum; +} + + +/** + Returns the two's complement checksum of all elements in a buffer of + 64-bit values. + + This function first calculates the sum of the 64-bit values in the buffer + specified by Buffer and Length. The carry bits in the result of addition + are dropped. Then, the two's complement of the sum is returned. If Length + is 0, then 0 is returned. + + If Buffer is NULL, then ASSERT(). + If Buffer is not aligned on a 64-bit boundary, then ASSERT(). + If Length is not aligned on a 64-bit boundary, then ASSERT(). + If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). + + @param Buffer The pointer to the buffer to carry out the checksum operation. + @param Length The size, in bytes, of Buffer. + + @return Checksum The 2's complement checksum of Buffer. + +**/ +UINT64 +EFIAPI +CalculateCheckSum64 ( + IN CONST UINT64 *Buffer, + IN UINTN Length + ) +{ + UINT64 CheckSum; + + CheckSum = CalculateSum64 (Buffer, Length); + + // + // Return the checksum based on 2's complement. + // + return (UINT64) ((UINT64)(-1) - CheckSum + 1); +} + + diff --git a/UnixPkg/Library/UnixBaseLib/ChkStkGcc.c b/UnixPkg/Library/UnixBaseLib/ChkStkGcc.c new file mode 100644 index 0000000000..ecba3853b1 --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/ChkStkGcc.c @@ -0,0 +1,24 @@ +/** @file + Provides hack function for passng GCC build. + + Copyright (c) 2006 - 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. + +**/ + +#include "BaseLibInternals.h" + +/** + Hack function for passing GCC build. +**/ +VOID +__chkstk() +{ +} + diff --git a/UnixPkg/Library/UnixBaseLib/Cpu.c b/UnixPkg/Library/UnixBaseLib/Cpu.c new file mode 100644 index 0000000000..8bcbf25750 --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/Cpu.c @@ -0,0 +1,65 @@ +/** @file + Base Library CPU Functions for all architectures. + + 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. + +**/ + +#include "BaseLibInternals.h" + + +/** + Disables CPU interrupts and returns the interrupt state prior to the disable + operation. + + @retval TRUE CPU interrupts were enabled on entry to this call. + @retval FALSE CPU interrupts were disabled on entry to this call. + +**/ +BOOLEAN +EFIAPI +SaveAndDisableInterrupts ( + VOID + ) +{ + BOOLEAN InterruptState; + + InterruptState = GetInterruptState (); + DisableInterrupts (); + return InterruptState; +} + +/** + Set the current CPU interrupt state. + + Sets the current CPU interrupt state to the state specified by + InterruptState. If InterruptState is TRUE, then interrupts are enabled. If + InterruptState is FALSE, then interrupts are disabled. InterruptState is + returned. + + @param InterruptState TRUE if interrupts should be enabled. FALSE if + interrupts should be disabled. + + @return InterruptState + +**/ +BOOLEAN +EFIAPI +SetInterruptState ( + IN BOOLEAN InterruptState + ) +{ + if (InterruptState) { + EnableInterrupts (); + } else { + DisableInterrupts (); + } + return InterruptState; +} diff --git a/UnixPkg/Library/UnixBaseLib/CpuDeadLoop.c b/UnixPkg/Library/UnixBaseLib/CpuDeadLoop.c new file mode 100644 index 0000000000..3f9440547d --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/CpuDeadLoop.c @@ -0,0 +1,38 @@ +/** @file + Base Library CPU Functions for all architectures. + + Copyright (c) 2006 - 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. + +**/ + + + +#include +#include + +/** + Executes an infinite loop. + + Forces the CPU to execute an infinite loop. A debugger may be used to skip + past the loop and the code that follows the loop must execute properly. This + implies that the infinite loop must not cause the code that follow it to be + optimized away. + +**/ +VOID +EFIAPI +CpuDeadLoop ( + VOID + ) +{ + volatile UINTN Index; + + for (Index = 0; Index == 0;); +} diff --git a/UnixPkg/Library/UnixBaseLib/DivS64x64Remainder.c b/UnixPkg/Library/UnixBaseLib/DivS64x64Remainder.c new file mode 100644 index 0000000000..bb2fddcff8 --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/DivS64x64Remainder.c @@ -0,0 +1,53 @@ +/** @file + Math worker functions. + + Copyright (c) 2006 - 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. + +**/ + + + + +#include "BaseLibInternals.h" + +/** + Divides a 64-bit signed integer by a 64-bit signed integer and generates a + 64-bit signed result and a optional 64-bit signed remainder. + + This function divides the 64-bit signed value Dividend by the 64-bit signed + value Divisor and generates a 64-bit signed quotient. If Remainder is not + NULL, then the 64-bit signed remainder is returned in Remainder. This + function returns the 64-bit signed quotient. + + It is the caller's responsibility to not call this function with a Divisor of 0. + If Divisor is 0, then the quotient and remainder should be assumed to be + the largest negative integer. + + If Divisor is 0, then ASSERT(). + + @param Dividend A 64-bit signed value. + @param Divisor A 64-bit signed value. + @param Remainder A pointer to a 64-bit signed value. This parameter is + optional and may be NULL. + + @return Dividend / Divisor + +**/ +INT64 +EFIAPI +DivS64x64Remainder ( + IN INT64 Dividend, + IN INT64 Divisor, + OUT INT64 *Remainder OPTIONAL + ) +{ + ASSERT (Divisor != 0); + return InternalMathDivRemS64x64 (Dividend, Divisor, Remainder); +} diff --git a/UnixPkg/Library/UnixBaseLib/DivU64x32.c b/UnixPkg/Library/UnixBaseLib/DivU64x32.c new file mode 100644 index 0000000000..3e637ccfee --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/DivU64x32.c @@ -0,0 +1,45 @@ +/** @file + Math worker functions. + + Copyright (c) 2006 - 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. + +**/ + + + + +#include "BaseLibInternals.h" + +/** + Divides a 64-bit unsigned integer by a 32-bit unsigned integer and generates + a 64-bit unsigned result. + + This function divides the 64-bit unsigned value Dividend by the 32-bit + unsigned value Divisor and generates a 64-bit unsigned quotient. This + function returns the 64-bit unsigned quotient. + + If Divisor is 0, then ASSERT(). + + @param Dividend A 64-bit unsigned value. + @param Divisor A 32-bit unsigned value. + + @return Dividend / Divisor + +**/ +UINT64 +EFIAPI +DivU64x32 ( + IN UINT64 Dividend, + IN UINT32 Divisor + ) +{ + ASSERT (Divisor != 0); + return InternalMathDivU64x32 (Dividend, Divisor); +} diff --git a/UnixPkg/Library/UnixBaseLib/DivU64x32Remainder.c b/UnixPkg/Library/UnixBaseLib/DivU64x32Remainder.c new file mode 100644 index 0000000000..cf51f13647 --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/DivU64x32Remainder.c @@ -0,0 +1,49 @@ +/** @file + Math worker functions. + + Copyright (c) 2006 - 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. + +**/ + + + + +#include "BaseLibInternals.h" + +/** + Divides a 64-bit unsigned integer by a 32-bit unsigned integer and generates + a 64-bit unsigned result and an optional 32-bit unsigned remainder. + + This function divides the 64-bit unsigned value Dividend by the 32-bit + unsigned value Divisor and generates a 64-bit unsigned quotient. If Remainder + is not NULL, then the 32-bit unsigned remainder is returned in Remainder. + This function returns the 64-bit unsigned quotient. + + If Divisor is 0, then ASSERT(). + + @param Dividend A 64-bit unsigned value. + @param Divisor A 32-bit unsigned value. + @param Remainder A pointer to a 32-bit unsigned value. This parameter is + optional and may be NULL. + + @return Dividend / Divisor + +**/ +UINT64 +EFIAPI +DivU64x32Remainder ( + IN UINT64 Dividend, + IN UINT32 Divisor, + OUT UINT32 *Remainder OPTIONAL + ) +{ + ASSERT (Divisor != 0); + return InternalMathDivRemU64x32 (Dividend, Divisor, Remainder); +} diff --git a/UnixPkg/Library/UnixBaseLib/DivU64x64Remainder.c b/UnixPkg/Library/UnixBaseLib/DivU64x64Remainder.c new file mode 100644 index 0000000000..1366ca4c0a --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/DivU64x64Remainder.c @@ -0,0 +1,49 @@ +/** @file + Math worker functions. + + Copyright (c) 2006 - 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. + +**/ + + + + +#include "BaseLibInternals.h" + +/** + Divides a 64-bit unsigned integer by a 64-bit unsigned integer and generates + a 64-bit unsigned result and an optional 64-bit unsigned remainder. + + This function divides the 64-bit unsigned value Dividend by the 64-bit + unsigned value Divisor and generates a 64-bit unsigned quotient. If Remainder + is not NULL, then the 64-bit unsigned remainder is returned in Remainder. + This function returns the 64-bit unsigned quotient. + + If Divisor is 0, then ASSERT(). + + @param Dividend A 64-bit unsigned value. + @param Divisor A 64-bit unsigned value. + @param Remainder A pointer to a 64-bit unsigned value. This parameter is + optional and may be NULL. + + @return Dividend / Divisor + +**/ +UINT64 +EFIAPI +DivU64x64Remainder ( + IN UINT64 Dividend, + IN UINT64 Divisor, + OUT UINT64 *Remainder OPTIONAL + ) +{ + ASSERT (Divisor != 0); + return InternalMathDivRemU64x64 (Dividend, Divisor, Remainder); +} diff --git a/UnixPkg/Library/UnixBaseLib/GetPowerOfTwo32.c b/UnixPkg/Library/UnixBaseLib/GetPowerOfTwo32.c new file mode 100644 index 0000000000..913efb7a9f --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/GetPowerOfTwo32.c @@ -0,0 +1,44 @@ +/** @file + Math worker functions. + + Copyright (c) 2006 - 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. + +**/ + + + + +#include "BaseLibInternals.h" + +/** + Returns the value of the highest bit set in a 32-bit value. Equivalent to + 1 << log2(x). + + This function computes the value of the highest bit set in the 32-bit value + specified by Operand. If Operand is zero, then zero is returned. + + @param Operand The 32-bit operand to evaluate. + + @return 1 << HighBitSet32(Operand) + @retval 0 Operand is zero. + +**/ +UINT32 +EFIAPI +GetPowerOfTwo32 ( + IN UINT32 Operand + ) +{ + if (0 == Operand) { + return 0; + } + + return 1ul << HighBitSet32 (Operand); +} diff --git a/UnixPkg/Library/UnixBaseLib/GetPowerOfTwo64.c b/UnixPkg/Library/UnixBaseLib/GetPowerOfTwo64.c new file mode 100644 index 0000000000..4623c2a656 --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/GetPowerOfTwo64.c @@ -0,0 +1,44 @@ +/** @file + Math worker functions. + + Copyright (c) 2006 - 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. + +**/ + + + + +#include "BaseLibInternals.h" + +/** + Returns the value of the highest bit set in a 64-bit value. Equivalent to + 1 << log2(x). + + This function computes the value of the highest bit set in the 64-bit value + specified by Operand. If Operand is zero, then zero is returned. + + @param Operand The 64-bit operand to evaluate. + + @return 1 << HighBitSet64(Operand) + @retval 0 Operand is zero. + +**/ +UINT64 +EFIAPI +GetPowerOfTwo64 ( + IN UINT64 Operand + ) +{ + if (Operand == 0) { + return 0; + } + + return LShiftU64 (1, HighBitSet64 (Operand)); +} diff --git a/UnixPkg/Library/UnixBaseLib/HighBitSet32.c b/UnixPkg/Library/UnixBaseLib/HighBitSet32.c new file mode 100644 index 0000000000..8d055fe397 --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/HighBitSet32.c @@ -0,0 +1,47 @@ +/** @file + Math worker functions. + + Copyright (c) 2006 - 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. + +**/ + + + + +#include "BaseLibInternals.h" + +/** + Returns the bit position of the highest bit set in a 32-bit value. Equivalent + to log2(x). + + This function computes the bit position of the highest bit set in the 32-bit + value specified by Operand. If Operand is zero, then -1 is returned. + Otherwise, a value between 0 and 31 is returned. + + @param Operand The 32-bit operand to evaluate. + + @retval 0..31 Position of the highest bit set in Operand if found. + @retval -1 Operand is zero. + +**/ +INTN +EFIAPI +HighBitSet32 ( + IN UINT32 Operand + ) +{ + INTN BitIndex; + + if (Operand == 0) { + return - 1; + } + for (BitIndex = 31; (INT32)Operand > 0; BitIndex--, Operand <<= 1); + return BitIndex; +} diff --git a/UnixPkg/Library/UnixBaseLib/HighBitSet64.c b/UnixPkg/Library/UnixBaseLib/HighBitSet64.c new file mode 100644 index 0000000000..23abb735be --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/HighBitSet64.c @@ -0,0 +1,55 @@ +/** @file + Math worker functions. + + Copyright (c) 2006 - 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. + +**/ + + + + +#include "BaseLibInternals.h" + +/** + Returns the bit position of the highest bit set in a 64-bit value. Equivalent + to log2(x). + + This function computes the bit position of the highest bit set in the 64-bit + value specified by Operand. If Operand is zero, then -1 is returned. + Otherwise, a value between 0 and 63 is returned. + + @param Operand The 64-bit operand to evaluate. + + @retval 0..63 Position of the highest bit set in Operand if found. + @retval -1 Operand is zero. + +**/ +INTN +EFIAPI +HighBitSet64 ( + IN UINT64 Operand + ) +{ + if (Operand == (UINT32)Operand) { + // + // Operand is just a 32-bit integer + // + return HighBitSet32 ((UINT32)Operand); + } + + // + // Operand is really a 64-bit integer + // + if (sizeof (UINTN) == sizeof (UINT32)) { + return HighBitSet32 (((UINT32*)&Operand)[1]) + 32; + } else { + return HighBitSet32 ((UINT32)RShiftU64 (Operand, 32)) + 32; + } +} diff --git a/UnixPkg/Library/UnixBaseLib/LRotU32.c b/UnixPkg/Library/UnixBaseLib/LRotU32.c new file mode 100644 index 0000000000..d9bde78622 --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/LRotU32.c @@ -0,0 +1,42 @@ +/** @file + Math worker functions. + + Copyright (c) 2006 - 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. + +**/ + +#include "BaseLibInternals.h" + +/** + Rotates a 32-bit integer left between 0 and 31 bits, filling the low bits + with the high bits that were rotated. + + This function rotates the 32-bit value Operand to the left by Count bits. The + low Count bits are fill with the high Count bits of Operand. The rotated + value is returned. + + If Count is greater than 31, then ASSERT(). + + @param Operand The 32-bit operand to rotate left. + @param Count The number of bits to rotate left. + + @return Operand << Count + +**/ +UINT32 +EFIAPI +LRotU32 ( + IN UINT32 Operand, + IN UINTN Count + ) +{ + ASSERT (Count < 32); + return (Operand << Count) | (Operand >> (32 - Count)); +} diff --git a/UnixPkg/Library/UnixBaseLib/LRotU64.c b/UnixPkg/Library/UnixBaseLib/LRotU64.c new file mode 100644 index 0000000000..66b982a042 --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/LRotU64.c @@ -0,0 +1,42 @@ +/** @file + Math worker functions. + + Copyright (c) 2006 - 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. + +**/ + +#include "BaseLibInternals.h" + +/** + Rotates a 64-bit integer left between 0 and 63 bits, filling the low bits + with the high bits that were rotated. + + This function rotates the 64-bit value Operand to the left by Count bits. The + low Count bits are fill with the high Count bits of Operand. The rotated + value is returned. + + If Count is greater than 63, then ASSERT(). + + @param Operand The 64-bit operand to rotate left. + @param Count The number of bits to rotate left. + + @return Operand << Count + +**/ +UINT64 +EFIAPI +LRotU64 ( + IN UINT64 Operand, + IN UINTN Count + ) +{ + ASSERT (Count < 64); + return InternalMathLRotU64 (Operand, Count); +} diff --git a/UnixPkg/Library/UnixBaseLib/LShiftU64.c b/UnixPkg/Library/UnixBaseLib/LShiftU64.c new file mode 100644 index 0000000000..d13fd2185d --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/LShiftU64.c @@ -0,0 +1,41 @@ +/** @file + Math worker functions. + + Copyright (c) 2006 - 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. + +**/ + +#include "BaseLibInternals.h" + +/** + Shifts a 64-bit integer left between 0 and 63 bits. The low bits are filled + with zeros. The shifted value is returned. + + This function shifts the 64-bit value Operand to the left by Count bits. The + low Count bits are set to zero. The shifted value is returned. + + If Count is greater than 63, then ASSERT(). + + @param Operand The 64-bit operand to shift left. + @param Count The number of bits to shift left. + + @return Operand << Count. + +**/ +UINT64 +EFIAPI +LShiftU64 ( + IN UINT64 Operand, + IN UINTN Count + ) +{ + ASSERT (Count < 64); + return InternalMathLShiftU64 (Operand, Count); +} diff --git a/UnixPkg/Library/UnixBaseLib/LinkedList.c b/UnixPkg/Library/UnixBaseLib/LinkedList.c new file mode 100644 index 0000000000..726a402be7 --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/LinkedList.c @@ -0,0 +1,550 @@ +/** @file + Linked List Library Functions. + + 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. + +**/ + +#include "BaseLibInternals.h" + +/** + Worker function that locates the Node in the List. + + By searching the List, finds the location of the Node in List. At the same time, + verifies the validity of this list. + + If List is NULL, then ASSERT(). + If List->ForwardLink is NULL, then ASSERT(). + If List->backLink is NULL, then ASSERT(). + If Node is NULL, then ASSERT(). + If PcdVerifyNodeInList is TRUE and DoMembershipCheck is TRUE and Node + is in not a member of List, then return FALSE + If PcdMaximumLinkedListLenth is not zero, and List contains more than + PcdMaximumLinkedListLenth nodes, then ASSERT(). + + @param List A pointer to a node in a linked list. + @param Node A pointer to a node in a linked list. + @param VerifyNodeInList TRUE if a check should be made to see if Node is a + member of List. FALSE if no membership test should + be performed. + + @retval TRUE if PcdVerifyNodeInList is FALSE + @retval TRUE if DoMembershipCheck is FALSE + @retval TRUE if PcdVerifyNodeInList is TRUE and DoMembershipCheck is TRUE + and Node is a member of List. + @retval FALSE if PcdVerifyNodeInList is TRUE and DoMembershipCheck is TRUE + and Node is in not a member of List. + +**/ +BOOLEAN +EFIAPI +InternalBaseLibIsNodeInList ( + IN CONST LIST_ENTRY *List, + IN CONST LIST_ENTRY *Node, + IN BOOLEAN VerifyNodeInList + ) +{ + UINTN Count; + CONST LIST_ENTRY *Ptr; + + // + // Test the validity of List and Node + // + ASSERT (List != NULL); + ASSERT (List->ForwardLink != NULL); + ASSERT (List->BackLink != NULL); + ASSERT (Node != NULL); + + Count = 0; + Ptr = List; + + if (FeaturePcdGet (PcdVerifyNodeInList) && VerifyNodeInList) { + // + // Check to see if Node is a member of List. + // Exit early if the number of nodes in List >= PcdMaximumLinkedListLength + // + do { + Ptr = Ptr->ForwardLink; + if (PcdGet32 (PcdMaximumLinkedListLength) > 0) { + Count++; + // + // ASSERT() if the linked list is too long + // + ASSERT (Count < PcdGet32 (PcdMaximumLinkedListLength)); + + // + // Return if the linked list is too long + // + if (Count >= PcdGet32 (PcdMaximumLinkedListLength)) { + return (BOOLEAN)(Ptr == Node); + } + } + } while ((Ptr != List) && (Ptr != Node)); + + if (Ptr != Node) { + return FALSE; + } + } + + if (PcdGet32 (PcdMaximumLinkedListLength) > 0) { + // + // Count the total number of nodes in List. + // Exit early if the number of nodes in List >= PcdMaximumLinkedListLength + // + do { + Ptr = Ptr->ForwardLink; + Count++; + } while ((Ptr != List) && (Count < PcdGet32 (PcdMaximumLinkedListLength))); + + // + // ASSERT() if the linked list is too long + // + ASSERT (Count < PcdGet32 (PcdMaximumLinkedListLength)); + } + + return TRUE; +} + +/** + Initializes the head node of a doubly-linked list, and returns the pointer to + the head node of the doubly-linked list. + + Initializes the forward and backward links of a new linked list. After + initializing a linked list with this function, the other linked list + functions may be used to add and remove nodes from the linked list. It is up + to the caller of this function to allocate the memory for ListHead. + + If ListHead is NULL, then ASSERT(). + + @param ListHead A pointer to the head node of a new doubly-linked list. + + @return ListHead + +**/ +LIST_ENTRY * +EFIAPI +InitializeListHead ( + IN OUT LIST_ENTRY *ListHead + ) + +{ + ASSERT (ListHead != NULL); + + ListHead->ForwardLink = ListHead; + ListHead->BackLink = ListHead; + return ListHead; +} + +/** + Adds a node to the beginning of a doubly-linked list, and returns the pointer + to the head node of the doubly-linked list. + + Adds the node Entry at the beginning of the doubly-linked list denoted by + ListHead, and returns ListHead. + + If ListHead is NULL, then ASSERT(). + If Entry is NULL, then ASSERT(). + If ListHead was not initialized with INTIALIZE_LIST_HEAD_VARIABLE() or + InitializeListHead(), then ASSERT(). + If PcdMaximumLinkedListLenth is not zero, and prior to insertion the number + of nodes in ListHead, including the ListHead node, is greater than or + equal to PcdMaximumLinkedListLength, then ASSERT(). + + @param ListHead A pointer to the head node of a doubly-linked list. + @param Entry A pointer to a node that is to be inserted at the beginning + of a doubly-linked list. + + @return ListHead + +**/ +LIST_ENTRY * +EFIAPI +InsertHeadList ( + IN OUT LIST_ENTRY *ListHead, + IN OUT LIST_ENTRY *Entry + ) +{ + // + // ASSERT List not too long and Entry is not one of the nodes of List + // + ASSERT (InternalBaseLibIsNodeInList (ListHead, Entry, FALSE)); + + Entry->ForwardLink = ListHead->ForwardLink; + Entry->BackLink = ListHead; + Entry->ForwardLink->BackLink = Entry; + ListHead->ForwardLink = Entry; + return ListHead; +} + +/** + Adds a node to the end of a doubly-linked list, and returns the pointer to + the head node of the doubly-linked list. + + Adds the node Entry to the end of the doubly-linked list denoted by ListHead, + and returns ListHead. + + If ListHead is NULL, then ASSERT(). + If Entry is NULL, then ASSERT(). + If ListHead was not initialized with INTIALIZE_LIST_HEAD_VARIABLE() or + InitializeListHead(), then ASSERT(). + If PcdMaximumLinkedListLenth is not zero, and prior to insertion the number + of nodes in ListHead, including the ListHead node, is greater than or + equal to PcdMaximumLinkedListLength, then ASSERT(). + + @param ListHead A pointer to the head node of a doubly-linked list. + @param Entry A pointer to a node that is to be added at the end of the + doubly-linked list. + + @return ListHead + +**/ +LIST_ENTRY * +EFIAPI +InsertTailList ( + IN OUT LIST_ENTRY *ListHead, + IN OUT LIST_ENTRY *Entry + ) +{ + // + // ASSERT List not too long and Entry is not one of the nodes of List + // + ASSERT (InternalBaseLibIsNodeInList (ListHead, Entry, FALSE)); + + Entry->ForwardLink = ListHead; + Entry->BackLink = ListHead->BackLink; + Entry->BackLink->ForwardLink = Entry; + ListHead->BackLink = Entry; + return ListHead; +} + +/** + Retrieves the first node of a doubly-linked list. + + Returns the first node of a doubly-linked list. List must have been + initialized with INTIALIZE_LIST_HEAD_VARIABLE() or InitializeListHead(). + If List is empty, then List is returned. + + If List is NULL, then ASSERT(). + If List was not initialized with INTIALIZE_LIST_HEAD_VARIABLE() or + InitializeListHead(), then ASSERT(). + If PcdMaximumLinkedListLenth is not zero, and the number of nodes + in List, including the List node, is greater than or equal to + PcdMaximumLinkedListLength, then ASSERT(). + + @param List A pointer to the head node of a doubly-linked list. + + @return The first node of a doubly-linked list. + @retval NULL The list is empty. + +**/ +LIST_ENTRY * +EFIAPI +GetFirstNode ( + IN CONST LIST_ENTRY *List + ) +{ + // + // ASSERT List not too long + // + ASSERT (InternalBaseLibIsNodeInList (List, List, FALSE)); + + return List->ForwardLink; +} + +/** + Retrieves the next node of a doubly-linked list. + + Returns the node of a doubly-linked list that follows Node. + List must have been initialized with INTIALIZE_LIST_HEAD_VARIABLE() + or InitializeListHead(). If List is empty, then List is returned. + + If List is NULL, then ASSERT(). + If Node is NULL, then ASSERT(). + If List was not initialized with INTIALIZE_LIST_HEAD_VARIABLE() or + InitializeListHead(), then ASSERT(). + If PcdMaximumLinkedListLenth is not zero, and List contains more than + PcdMaximumLinkedListLenth nodes, then ASSERT(). + If PcdVerifyNodeInList is TRUE and Node is not a node in List, then ASSERT(). + + @param List A pointer to the head node of a doubly-linked list. + @param Node A pointer to a node in the doubly-linked list. + + @return A pointer to the next node if one exists. Otherwise List is returned. + +**/ +LIST_ENTRY * +EFIAPI +GetNextNode ( + IN CONST LIST_ENTRY *List, + IN CONST LIST_ENTRY *Node + ) +{ + // + // ASSERT List not too long and Node is one of the nodes of List + // + ASSERT (InternalBaseLibIsNodeInList (List, Node, TRUE)); + + return Node->ForwardLink; +} + +/** + Retrieves the previous node of a doubly-linked list. + + Returns the node of a doubly-linked list that precedes Node. + List must have been initialized with INTIALIZE_LIST_HEAD_VARIABLE() + or InitializeListHead(). If List is empty, then List is returned. + + If List is NULL, then ASSERT(). + If Node is NULL, then ASSERT(). + If List was not initialized with INTIALIZE_LIST_HEAD_VARIABLE() or + InitializeListHead(), then ASSERT(). + If PcdMaximumLinkedListLenth is not zero, and List contains more than + PcdMaximumLinkedListLenth nodes, then ASSERT(). + If PcdVerifyNodeInList is TRUE and Node is not a node in List, then ASSERT(). + + @param List A pointer to the head node of a doubly-linked list. + @param Node A pointer to a node in the doubly-linked list. + + @return A pointer to the previous node if one exists. Otherwise List is returned. + +**/ +LIST_ENTRY * +EFIAPI +GetPreviousNode ( + IN CONST LIST_ENTRY *List, + IN CONST LIST_ENTRY *Node + ) +{ + // + // ASSERT List not too long and Node is one of the nodes of List + // + ASSERT (InternalBaseLibIsNodeInList (List, Node, TRUE)); + + return Node->BackLink; +} + +/** + Checks to see if a doubly-linked list is empty or not. + + Checks to see if the doubly-linked list is empty. If the linked list contains + zero nodes, this function returns TRUE. Otherwise, it returns FALSE. + + If ListHead is NULL, then ASSERT(). + If ListHead was not initialized with INTIALIZE_LIST_HEAD_VARIABLE() or + InitializeListHead(), then ASSERT(). + If PcdMaximumLinkedListLenth is not zero, and the number of nodes + in List, including the List node, is greater than or equal to + PcdMaximumLinkedListLength, then ASSERT(). + + @param ListHead A pointer to the head node of a doubly-linked list. + + @retval TRUE The linked list is empty. + @retval FALSE The linked list is not empty. + +**/ +BOOLEAN +EFIAPI +IsListEmpty ( + IN CONST LIST_ENTRY *ListHead + ) +{ + // + // ASSERT List not too long + // + ASSERT (InternalBaseLibIsNodeInList (ListHead, ListHead, FALSE)); + + return (BOOLEAN)(ListHead->ForwardLink == ListHead); +} + +/** + Determines if a node in a doubly-linked list is the head node of a the same + doubly-linked list. This function is typically used to terminate a loop that + traverses all the nodes in a doubly-linked list starting with the head node. + + Returns TRUE if Node is equal to List. Returns FALSE if Node is one of the + nodes in the doubly-linked list specified by List. List must have been + initialized with INTIALIZE_LIST_HEAD_VARIABLE() or InitializeListHead(). + + If List is NULL, then ASSERT(). + If Node is NULL, then ASSERT(). + If List was not initialized with INTIALIZE_LIST_HEAD_VARIABLE() or InitializeListHead(), + then ASSERT(). + If PcdMaximumLinkedListLenth is not zero, and the number of nodes + in List, including the List node, is greater than or equal to + PcdMaximumLinkedListLength, then ASSERT(). + If PcdVerifyNodeInList is TRUE and Node is not a node in List and Node is not + equal to List, then ASSERT(). + + @param List A pointer to the head node of a doubly-linked list. + @param Node A pointer to a node in the doubly-linked list. + + @retval TRUE Node is one of the nodes in the doubly-linked list. + @retval FALSE Node is not one of the nodes in the doubly-linked list. + +**/ +BOOLEAN +EFIAPI +IsNull ( + IN CONST LIST_ENTRY *List, + IN CONST LIST_ENTRY *Node + ) +{ + // + // ASSERT List not too long and Node is one of the nodes of List + // + ASSERT (InternalBaseLibIsNodeInList (List, Node, TRUE)); + + return (BOOLEAN)(Node == List); +} + +/** + Determines if a node the last node in a doubly-linked list. + + Returns TRUE if Node is the last node in the doubly-linked list specified by + List. Otherwise, FALSE is returned. List must have been initialized with + INTIALIZE_LIST_HEAD_VARIABLE() or InitializeListHead(). + + If List is NULL, then ASSERT(). + If Node is NULL, then ASSERT(). + If List was not initialized with INTIALIZE_LIST_HEAD_VARIABLE() or + InitializeListHead(), then ASSERT(). + If PcdMaximumLinkedListLenth is not zero, and the number of nodes + in List, including the List node, is greater than or equal to + PcdMaximumLinkedListLength, then ASSERT(). + If PcdVerifyNodeInList is TRUE and Node is not a node in List, then ASSERT(). + + @param List A pointer to the head node of a doubly-linked list. + @param Node A pointer to a node in the doubly-linked list. + + @retval TRUE Node is the last node in the linked list. + @retval FALSE Node is not the last node in the linked list. + +**/ +BOOLEAN +EFIAPI +IsNodeAtEnd ( + IN CONST LIST_ENTRY *List, + IN CONST LIST_ENTRY *Node + ) +{ + // + // ASSERT List not too long and Node is one of the nodes of List + // + ASSERT (InternalBaseLibIsNodeInList (List, Node, TRUE)); + + return (BOOLEAN)(!IsNull (List, Node) && List->BackLink == Node); +} + +/** + Swaps the location of two nodes in a doubly-linked list, and returns the + first node after the swap. + + If FirstEntry is identical to SecondEntry, then SecondEntry is returned. + Otherwise, the location of the FirstEntry node is swapped with the location + of the SecondEntry node in a doubly-linked list. SecondEntry must be in the + same double linked list as FirstEntry and that double linked list must have + been initialized with INTIALIZE_LIST_HEAD_VARIABLE() or InitializeListHead(). + SecondEntry is returned after the nodes are swapped. + + If FirstEntry is NULL, then ASSERT(). + If SecondEntry is NULL, then ASSERT(). + If PcdVerifyNodeInList is TRUE and SecondEntry and FirstEntry are not in the + same linked list, then ASSERT(). + If PcdMaximumLinkedListLength is not zero, and the number of nodes in the + linked list containing the FirstEntry and SecondEntry nodes, including + the FirstEntry and SecondEntry nodes, is greater than or equal to + PcdMaximumLinkedListLength, then ASSERT(). + + @param FirstEntry A pointer to a node in a linked list. + @param SecondEntry A pointer to another node in the same linked list. + + @return SecondEntry. + +**/ +LIST_ENTRY * +EFIAPI +SwapListEntries ( + IN OUT LIST_ENTRY *FirstEntry, + IN OUT LIST_ENTRY *SecondEntry + ) +{ + LIST_ENTRY *Ptr; + + if (FirstEntry == SecondEntry) { + return SecondEntry; + } + + // + // ASSERT Entry1 and Entry2 are in the same linked list + // + ASSERT (InternalBaseLibIsNodeInList (FirstEntry, SecondEntry, TRUE)); + + // + // Ptr is the node pointed to by FirstEntry->ForwardLink + // + Ptr = RemoveEntryList (FirstEntry); + + // + // If FirstEntry immediately follows SecondEntry, FirstEntry will be placed + // immediately in front of SecondEntry + // + if (Ptr->BackLink == SecondEntry) { + return InsertTailList (SecondEntry, FirstEntry); + } + + // + // Ptr == SecondEntry means SecondEntry immediately follows FirstEntry, + // then there are no further steps necessary + // + if (Ptr == InsertHeadList (SecondEntry, FirstEntry)) { + return Ptr; + } + + // + // Move SecondEntry to the front of Ptr + // + RemoveEntryList (SecondEntry); + InsertTailList (Ptr, SecondEntry); + return SecondEntry; +} + +/** + Removes a node from a doubly-linked list, and returns the node that follows + the removed node. + + Removes the node Entry from a doubly-linked list. It is up to the caller of + this function to release the memory used by this node if that is required. On + exit, the node following Entry in the doubly-linked list is returned. If + Entry is the only node in the linked list, then the head node of the linked + list is returned. + + If Entry is NULL, then ASSERT(). + If Entry is the head node of an empty list, then ASSERT(). + If PcdMaximumLinkedListLength is not zero, and the number of nodes in the + linked list containing Entry, including the Entry node, is greater than + or equal to PcdMaximumLinkedListLength, then ASSERT(). + + @param Entry A pointer to a node in a linked list. + + @return Entry. + +**/ +LIST_ENTRY * +EFIAPI +RemoveEntryList ( + IN CONST LIST_ENTRY *Entry + ) +{ + ASSERT (!IsListEmpty (Entry)); + + Entry->ForwardLink->BackLink = Entry->BackLink; + Entry->BackLink->ForwardLink = Entry->ForwardLink; + return Entry->ForwardLink; +} diff --git a/UnixPkg/Library/UnixBaseLib/LongJump.c b/UnixPkg/Library/UnixBaseLib/LongJump.c new file mode 100644 index 0000000000..062be8f2da --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/LongJump.c @@ -0,0 +1,47 @@ +/** @file + Long Jump functions. + + Copyright (c) 2006 - 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. + +**/ + + + + +#include "BaseLibInternals.h" + +/** + Restores the CPU context that was saved with SetJump(). + + Restores the CPU context from the buffer specified by JumpBuffer. This + function never returns to the caller. Instead is resumes execution based on + the state of JumpBuffer. + + If JumpBuffer is NULL, then ASSERT(). + For IPF CPUs, if JumpBuffer is not aligned on a 16-byte boundary, then ASSERT(). + If Value is 0, then ASSERT(). + + @param JumpBuffer A pointer to CPU context buffer. + @param Value The value to return when the SetJump() context is + restored and must be non-zero. + +**/ +VOID +EFIAPI +LongJump ( + IN BASE_LIBRARY_JUMP_BUFFER *JumpBuffer, + IN UINTN Value + ) +{ + InternalAssertJumpBuffer (JumpBuffer); + ASSERT (Value != 0); + + InternalLongJump (JumpBuffer, Value); +} diff --git a/UnixPkg/Library/UnixBaseLib/LowBitSet32.c b/UnixPkg/Library/UnixBaseLib/LowBitSet32.c new file mode 100644 index 0000000000..64300367d6 --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/LowBitSet32.c @@ -0,0 +1,47 @@ +/** @file + Math worker functions. + + Copyright (c) 2006 - 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. + +**/ + + + + +#include "BaseLibInternals.h" + +/** + Returns the bit position of the lowest bit set in a 32-bit value. + + This function computes the bit position of the lowest bit set in the 32-bit + value specified by Operand. If Operand is zero, then -1 is returned. + Otherwise, a value between 0 and 31 is returned. + + @param Operand The 32-bit operand to evaluate. + + @retval 0..31 The lowest bit set in Operand was found. + @retval -1 Operand is zero. + +**/ +INTN +EFIAPI +LowBitSet32 ( + IN UINT32 Operand + ) +{ + INTN BitIndex; + + if (Operand == 0) { + return -1; + } + + for (BitIndex = 0; 0 == (Operand & 1); BitIndex++, Operand >>= 1); + return BitIndex; +} diff --git a/UnixPkg/Library/UnixBaseLib/LowBitSet64.c b/UnixPkg/Library/UnixBaseLib/LowBitSet64.c new file mode 100644 index 0000000000..2bc8bc3910 --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/LowBitSet64.c @@ -0,0 +1,50 @@ +/** @file + Math worker functions. + + Copyright (c) 2006 - 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. + +**/ + + + + +#include "BaseLibInternals.h" + +/** + Returns the bit position of the lowest bit set in a 64-bit value. + + This function computes the bit position of the lowest bit set in the 64-bit + value specified by Operand. If Operand is zero, then -1 is returned. + Otherwise, a value between 0 and 63 is returned. + + @param Operand The 64-bit operand to evaluate. + + @retval 0..63 The lowest bit set in Operand was found. + @retval -1 Operand is zero. + + +**/ +INTN +EFIAPI +LowBitSet64 ( + IN UINT64 Operand + ) +{ + INTN BitIndex; + + if (Operand == 0) { + return -1; + } + + for (BitIndex = 0; + (Operand & 1) == 0; + BitIndex++, Operand = RShiftU64 (Operand, 1)); + return BitIndex; +} diff --git a/UnixPkg/Library/UnixBaseLib/Math64.c b/UnixPkg/Library/UnixBaseLib/Math64.c new file mode 100644 index 0000000000..83d7684721 --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/Math64.c @@ -0,0 +1,368 @@ +/** @file + Leaf math worker functions that require 64-bit arithmetic support from the + compiler. + + 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. + +**/ + +#include "BaseLibInternals.h" + +/** + Shifts a 64-bit integer left between 0 and 63 bits. The low bits + are filled with zeros. The shifted value is returned. + + This function shifts the 64-bit value Operand to the left by Count bits. The + low Count bits are set to zero. The shifted value is returned. + + @param Operand The 64-bit operand to shift left. + @param Count The number of bits to shift left. + + @return Operand << Count. + +**/ +UINT64 +EFIAPI +InternalMathLShiftU64 ( + IN UINT64 Operand, + IN UINTN Count + ) +{ + return Operand << Count; +} + +/** + Shifts a 64-bit integer right between 0 and 63 bits. This high bits + are filled with zeros. The shifted value is returned. + + This function shifts the 64-bit value Operand to the right by Count bits. The + high Count bits are set to zero. The shifted value is returned. + + @param Operand The 64-bit operand to shift right. + @param Count The number of bits to shift right. + + @return Operand >> Count. + +**/ +UINT64 +EFIAPI +InternalMathRShiftU64 ( + IN UINT64 Operand, + IN UINTN Count + ) +{ + return Operand >> Count; +} + +/** + Shifts a 64-bit integer right between 0 and 63 bits. The high bits + are filled with original integer's bit 63. The shifted value is returned. + + This function shifts the 64-bit value Operand to the right by Count bits. The + high Count bits are set to bit 63 of Operand. The shifted value is returned. + + @param Operand The 64-bit operand to shift right. + @param Count The number of bits to shift right. + + @return Operand arithmetically shifted right by Count. + +**/ +UINT64 +EFIAPI +InternalMathARShiftU64 ( + IN UINT64 Operand, + IN UINTN Count + ) +{ + INTN TestValue; + + // + // Test if this compiler supports arithmetic shift + // + TestValue = (((-1) << (sizeof (-1) * 8 - 1)) >> (sizeof (-1) * 8 - 1)); + if (TestValue == -1) { + // + // Arithmetic shift is supported + // + return (UINT64)((INT64)Operand >> Count); + } + + // + // Arithmetic is not supported + // + return (Operand >> Count) | + ((INTN)Operand < 0 ? ~((UINTN)-1 >> Count) : 0); +} + + +/** + Rotates a 64-bit integer left between 0 and 63 bits, filling + the low bits with the high bits that were rotated. + + This function rotates the 64-bit value Operand to the left by Count bits. The + low Count bits are fill with the high Count bits of Operand. The rotated + value is returned. + + @param Operand The 64-bit operand to rotate left. + @param Count The number of bits to rotate left. + + @return Operand <<< Count. + +**/ +UINT64 +EFIAPI +InternalMathLRotU64 ( + IN UINT64 Operand, + IN UINTN Count + ) +{ + return (Operand << Count) | (Operand >> (64 - Count)); +} + +/** + Rotates a 64-bit integer right between 0 and 63 bits, filling + the high bits with the high low bits that were rotated. + + This function rotates the 64-bit value Operand to the right by Count bits. + The high Count bits are fill with the low Count bits of Operand. The rotated + value is returned. + + @param Operand The 64-bit operand to rotate right. + @param Count The number of bits to rotate right. + + @return Operand >>> Count. + +**/ +UINT64 +EFIAPI +InternalMathRRotU64 ( + IN UINT64 Operand, + IN UINTN Count + ) +{ + return (Operand >> Count) | (Operand << (64 - Count)); +} + +/** + Switches the endianess of a 64-bit integer. + + This function swaps the bytes in a 64-bit unsigned value to switch the value + from little endian to big endian or vice versa. The byte swapped value is + returned. + + @param Operand A 64-bit unsigned value. + + @return The byte swapped Operand. + +**/ +UINT64 +EFIAPI +InternalMathSwapBytes64 ( + IN UINT64 Operand + ) +{ + UINT64 LowerBytes; + UINT64 HigherBytes; + + LowerBytes = (UINT64) SwapBytes32 ((UINT32) Operand); + HigherBytes = (UINT64) SwapBytes32 ((UINT32) (Operand >> 32)); + + return (LowerBytes << 32 | HigherBytes); +} + +/** + Multiplies a 64-bit unsigned integer by a 32-bit unsigned integer + and generates a 64-bit unsigned result. + + This function multiplies the 64-bit unsigned value Multiplicand by the 32-bit + unsigned value Multiplier and generates a 64-bit unsigned result. This 64- + bit unsigned result is returned. + + @param Multiplicand A 64-bit unsigned value. + @param Multiplier A 32-bit unsigned value. + + @return Multiplicand * Multiplier + +**/ +UINT64 +EFIAPI +InternalMathMultU64x32 ( + IN UINT64 Multiplicand, + IN UINT32 Multiplier + ) +{ + return Multiplicand * Multiplier; +} + + +/** + Multiplies a 64-bit unsigned integer by a 64-bit unsigned integer + and generates a 64-bit unsigned result. + + This function multiplies the 64-bit unsigned value Multiplicand by the 64-bit + unsigned value Multiplier and generates a 64-bit unsigned result. This 64- + bit unsigned result is returned. + + @param Multiplicand A 64-bit unsigned value. + @param Multiplier A 64-bit unsigned value. + + @return Multiplicand * Multiplier. + +**/ +UINT64 +EFIAPI +InternalMathMultU64x64 ( + IN UINT64 Multiplicand, + IN UINT64 Multiplier + ) +{ + return Multiplicand * Multiplier; +} + +/** + Divides a 64-bit unsigned integer by a 32-bit unsigned integer and + generates a 64-bit unsigned result. + + This function divides the 64-bit unsigned value Dividend by the 32-bit + unsigned value Divisor and generates a 64-bit unsigned quotient. This + function returns the 64-bit unsigned quotient. + + @param Dividend A 64-bit unsigned value. + @param Divisor A 32-bit unsigned value. + + @return Dividend / Divisor. + +**/ +UINT64 +EFIAPI +InternalMathDivU64x32 ( + IN UINT64 Dividend, + IN UINT32 Divisor + ) +{ + return Dividend / Divisor; +} + +/** + Divides a 64-bit unsigned integer by a 32-bit unsigned integer and + generates a 32-bit unsigned remainder. + + This function divides the 64-bit unsigned value Dividend by the 32-bit + unsigned value Divisor and generates a 32-bit remainder. This function + returns the 32-bit unsigned remainder. + + @param Dividend A 64-bit unsigned value. + @param Divisor A 32-bit unsigned value. + + @return Dividend % Divisor. + +**/ +UINT32 +EFIAPI +InternalMathModU64x32 ( + IN UINT64 Dividend, + IN UINT32 Divisor + ) +{ + return (UINT32)(Dividend % Divisor); +} + +/** + Divides a 64-bit unsigned integer by a 32-bit unsigned integer and + generates a 64-bit unsigned result and an optional 32-bit unsigned remainder. + + This function divides the 64-bit unsigned value Dividend by the 32-bit + unsigned value Divisor and generates a 64-bit unsigned quotient. If Remainder + is not NULL, then the 32-bit unsigned remainder is returned in Remainder. + This function returns the 64-bit unsigned quotient. + + @param Dividend A 64-bit unsigned value. + @param Divisor A 32-bit unsigned value. + @param Remainder A pointer to a 32-bit unsigned value. This parameter is + optional and may be NULL. + + @return Dividend / Divisor. + +**/ +UINT64 +EFIAPI +InternalMathDivRemU64x32 ( + IN UINT64 Dividend, + IN UINT32 Divisor, + OUT UINT32 *Remainder OPTIONAL + ) +{ + if (Remainder != NULL) { + *Remainder = (UINT32)(Dividend % Divisor); + } + return Dividend / Divisor; +} + +/** + Divides a 64-bit unsigned integer by a 64-bit unsigned integer and + generates a 64-bit unsigned result and an optional 64-bit unsigned remainder. + + This function divides the 64-bit unsigned value Dividend by the 64-bit + unsigned value Divisor and generates a 64-bit unsigned quotient. If Remainder + is not NULL, then the 64-bit unsigned remainder is returned in Remainder. + This function returns the 64-bit unsigned quotient. + + @param Dividend A 64-bit unsigned value. + @param Divisor A 64-bit unsigned value. + @param Remainder A pointer to a 64-bit unsigned value. This parameter is + optional and may be NULL. + + @return Dividend / Divisor + +**/ +UINT64 +EFIAPI +InternalMathDivRemU64x64 ( + IN UINT64 Dividend, + IN UINT64 Divisor, + OUT UINT64 *Remainder OPTIONAL + ) +{ + if (Remainder != NULL) { + *Remainder = Dividend % Divisor; + } + return Dividend / Divisor; +} + +/** + Divides a 64-bit signed integer by a 64-bit signed integer and + generates a 64-bit signed result and an optional 64-bit signed remainder. + + This function divides the 64-bit signed value Dividend by the 64-bit + signed value Divisor and generates a 64-bit signed quotient. If Remainder + is not NULL, then the 64-bit signed remainder is returned in Remainder. + This function returns the 64-bit signed quotient. + + @param Dividend A 64-bit signed value. + @param Divisor A 64-bit signed value. + @param Remainder A pointer to a 64-bit signed value. This parameter is + optional and may be NULL. + + @return Dividend / Divisor. + +**/ +INT64 +EFIAPI +InternalMathDivRemS64x64 ( + IN INT64 Dividend, + IN INT64 Divisor, + OUT INT64 *Remainder OPTIONAL + ) +{ + if (Remainder != NULL) { + *Remainder = Dividend % Divisor; + } + return Dividend / Divisor; +} diff --git a/UnixPkg/Library/UnixBaseLib/ModU64x32.c b/UnixPkg/Library/UnixBaseLib/ModU64x32.c new file mode 100644 index 0000000000..29d7b779f7 --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/ModU64x32.c @@ -0,0 +1,45 @@ +/** @file + Math worker functions. + + Copyright (c) 2006 - 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. + +**/ + + + + +#include "BaseLibInternals.h" + +/** + Divides a 64-bit unsigned integer by a 32-bit unsigned integer and generates + a 32-bit unsigned remainder. + + This function divides the 64-bit unsigned value Dividend by the 32-bit + unsigned value Divisor and generates a 32-bit remainder. This function + returns the 32-bit unsigned remainder. + + If Divisor is 0, then ASSERT(). + + @param Dividend A 64-bit unsigned value. + @param Divisor A 32-bit unsigned value. + + @return Dividend % Divisor. + +**/ +UINT32 +EFIAPI +ModU64x32 ( + IN UINT64 Dividend, + IN UINT32 Divisor + ) +{ + ASSERT (Divisor != 0); + return InternalMathModU64x32 (Dividend, Divisor); +} diff --git a/UnixPkg/Library/UnixBaseLib/MultS64x64.c b/UnixPkg/Library/UnixBaseLib/MultS64x64.c new file mode 100644 index 0000000000..cbeaf02117 --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/MultS64x64.c @@ -0,0 +1,42 @@ +/** @file + Math worker functions. + + 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. + +**/ + + + + +#include "BaseLibInternals.h" + +/** + Multiplies a 64-bit signed integer by a 64-bit signed integer and generates a + 64-bit signed result. + + This function multiplies the 64-bit signed value Multiplicand by the 64-bit + signed value Multiplier and generates a 64-bit signed result. This 64-bit + signed result is returned. + + @param Multiplicand A 64-bit signed value. + @param Multiplier A 64-bit signed value. + + @return Multiplicand * Multiplier. + +**/ +INT64 +EFIAPI +MultS64x64 ( + IN INT64 Multiplicand, + IN INT64 Multiplier + ) +{ + return (INT64)MultU64x64 (Multiplicand, Multiplier); +} diff --git a/UnixPkg/Library/UnixBaseLib/MultU64x32.c b/UnixPkg/Library/UnixBaseLib/MultU64x32.c new file mode 100644 index 0000000000..a2c2436f1f --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/MultU64x32.c @@ -0,0 +1,46 @@ +/** @file + Math worker functions. + + 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. + +**/ + + + + +#include "BaseLibInternals.h" + +/** + Multiplies a 64-bit unsigned integer by a 32-bit unsigned integer and + generates a 64-bit unsigned result. + + This function multiplies the 64-bit unsigned value Multiplicand by the 32-bit + unsigned value Multiplier and generates a 64-bit unsigned result. This 64- + bit unsigned result is returned. + + @param Multiplicand A 64-bit unsigned value. + @param Multiplier A 32-bit unsigned value. + + @return Multiplicand * Multiplier. + +**/ +UINT64 +EFIAPI +MultU64x32 ( + IN UINT64 Multiplicand, + IN UINT32 Multiplier + ) +{ + UINT64 Result; + + Result = InternalMathMultU64x32 (Multiplicand, Multiplier); + + return Result; +} diff --git a/UnixPkg/Library/UnixBaseLib/MultU64x64.c b/UnixPkg/Library/UnixBaseLib/MultU64x64.c new file mode 100644 index 0000000000..a1a7629dac --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/MultU64x64.c @@ -0,0 +1,46 @@ +/** @file + Math worker functions. + + 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. + +**/ + + + + +#include "BaseLibInternals.h" + +/** + Multiplies a 64-bit unsigned integer by a 64-bit unsigned integer and + generates a 64-bit unsigned result. + + This function multiplies the 64-bit unsigned value Multiplicand by the 64-bit + unsigned value Multiplier and generates a 64-bit unsigned result. This 64- + bit unsigned result is returned. + + @param Multiplicand A 64-bit unsigned value. + @param Multiplier A 64-bit unsigned value. + + @return Multiplicand * Multiplier. + +**/ +UINT64 +EFIAPI +MultU64x64 ( + IN UINT64 Multiplicand, + IN UINT64 Multiplier + ) +{ + UINT64 Result; + + Result = InternalMathMultU64x64 (Multiplicand, Multiplier); + + return Result; +} diff --git a/UnixPkg/Library/UnixBaseLib/RRotU32.c b/UnixPkg/Library/UnixBaseLib/RRotU32.c new file mode 100644 index 0000000000..f4779f5043 --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/RRotU32.c @@ -0,0 +1,42 @@ +/** @file + Math worker functions. + + Copyright (c) 2006 - 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. + +**/ + +#include "BaseLibInternals.h" + +/** + Rotates a 32-bit integer right between 0 and 31 bits, filling the high bits + with the low bits that were rotated. + + This function rotates the 32-bit value Operand to the right by Count bits. + The high Count bits are fill with the low Count bits of Operand. The rotated + value is returned. + + If Count is greater than 31, then ASSERT(). + + @param Operand The 32-bit operand to rotate right. + @param Count The number of bits to rotate right. + + @return Operand >> Count. + +**/ +UINT32 +EFIAPI +RRotU32 ( + IN UINT32 Operand, + IN UINTN Count + ) +{ + ASSERT (Count < 32); + return (Operand >> Count) | (Operand << (32 - Count)); +} diff --git a/UnixPkg/Library/UnixBaseLib/RRotU64.c b/UnixPkg/Library/UnixBaseLib/RRotU64.c new file mode 100644 index 0000000000..45be7efdc3 --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/RRotU64.c @@ -0,0 +1,42 @@ +/** @file + Math worker functions. + + Copyright (c) 2006 - 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. + +**/ + +#include "BaseLibInternals.h" + +/** + Rotates a 64-bit integer right between 0 and 63 bits, filling the high bits + with the high low bits that were rotated. + + This function rotates the 64-bit value Operand to the right by Count bits. + The high Count bits are fill with the low Count bits of Operand. The rotated + value is returned. + + If Count is greater than 63, then ASSERT(). + + @param Operand The 64-bit operand to rotate right. + @param Count The number of bits to rotate right. + + @return Operand >> Count. + +**/ +UINT64 +EFIAPI +RRotU64 ( + IN UINT64 Operand, + IN UINTN Count + ) +{ + ASSERT (Count < 64); + return InternalMathRRotU64 (Operand, Count); +} diff --git a/UnixPkg/Library/UnixBaseLib/RShiftU64.c b/UnixPkg/Library/UnixBaseLib/RShiftU64.c new file mode 100644 index 0000000000..8a4834bb90 --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/RShiftU64.c @@ -0,0 +1,41 @@ +/** @file + Math worker functions. + + Copyright (c) 2006 - 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. + +**/ + +#include "BaseLibInternals.h" + +/** + Shifts a 64-bit integer right between 0 and 63 bits. This high bits are + filled with zeros. The shifted value is returned. + + This function shifts the 64-bit value Operand to the right by Count bits. The + high Count bits are set to zero. The shifted value is returned. + + If Count is greater than 63, then ASSERT(). + + @param Operand The 64-bit operand to shift right. + @param Count The number of bits to shift right. + + @return Operand >> Count. + +**/ +UINT64 +EFIAPI +RShiftU64 ( + IN UINT64 Operand, + IN UINTN Count + ) +{ + ASSERT (Count < 64); + return InternalMathRShiftU64 (Operand, Count); +} diff --git a/UnixPkg/Library/UnixBaseLib/SetJump.c b/UnixPkg/Library/UnixBaseLib/SetJump.c new file mode 100644 index 0000000000..b8fb35bb52 --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/SetJump.c @@ -0,0 +1,40 @@ +/** @file + Internal ASSERT () functions for SetJump. + + Copyright (c) 2006 - 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. + +**/ + + + + +#include "BaseLibInternals.h" + +/** + Worker function that checks ASSERT condition for JumpBuffer + + Checks ASSERT condition for JumpBuffer. + + If JumpBuffer is NULL, then ASSERT(). + For IPF CPUs, if JumpBuffer is not aligned on a 16-byte boundary, then ASSERT(). + + @param JumpBuffer A pointer to CPU context buffer. + +**/ +VOID +EFIAPI +InternalAssertJumpBuffer ( + IN BASE_LIBRARY_JUMP_BUFFER *JumpBuffer + ) +{ + ASSERT (JumpBuffer != NULL); + + ASSERT (((UINTN)JumpBuffer & (BASE_LIBRARY_JUMP_BUFFER_ALIGNMENT - 1)) == 0); +} diff --git a/UnixPkg/Library/UnixBaseLib/String.c b/UnixPkg/Library/UnixBaseLib/String.c new file mode 100644 index 0000000000..2279720951 --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/String.c @@ -0,0 +1,2109 @@ +/** @file + Unicode and ASCII string primatives. + + 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. + +**/ + +#include "BaseLibInternals.h" + +#define QUOTIENT_MAX_UINTN_DIVIDED_BY_10 ((UINTN) -1 / 10) +#define REMAINDER_MAX_UINTN_DIVIDED_BY_10 ((UINTN) -1 % 10) + +#define QUOTIENT_MAX_UINTN_DIVIDED_BY_16 ((UINTN) -1 / 16) +#define REMAINDER_MAX_UINTN_DIVIDED_BY_16 ((UINTN) -1 % 16) + +#define QUOTIENT_MAX_UINT64_DIVIDED_BY_10 ((UINT64) -1 / 10) +#define REMAINDER_MAX_UINT64_DIVIDED_BY_10 ((UINT64) -1 % 10) + +#define QUOTIENT_MAX_UINT64_DIVIDED_BY_16 ((UINT64) -1 / 16) +#define REMAINDER_MAX_UINT64_DIVIDED_BY_16 ((UINT64) -1 % 16) + +/** + Copies one Null-terminated Unicode string to another Null-terminated Unicode + string and returns the new Unicode string. + + This function copies the contents of the Unicode string Source to the Unicode + string Destination, and returns Destination. If Source and Destination + overlap, then the results are undefined. + + If Destination is NULL, then ASSERT(). + If Destination is not aligned on a 16-bit boundary, then ASSERT(). + If Source is NULL, then ASSERT(). + If Source is not aligned on a 16-bit boundary, then ASSERT(). + If Source and Destination overlap, then ASSERT(). + If PcdMaximumUnicodeStringLength is not zero, and Source contains more than + PcdMaximumUnicodeStringLength Unicode characters, not including the + Null-terminator, then ASSERT(). + + @param Destination A pointer to a Null-terminated Unicode string. + @param Source A pointer to a Null-terminated Unicode string. + + @return Destination. + +**/ +CHAR16 * +EFIAPI +StrCpy ( + OUT CHAR16 *Destination, + IN CONST CHAR16 *Source + ) +{ + CHAR16 *ReturnValue; + + // + // Destination cannot be NULL + // + ASSERT (Destination != NULL); + ASSERT (((UINTN) Destination & BIT0) == 0); + + // + // Destination and source cannot overlap + // + ASSERT ((UINTN)(Destination - Source) > StrLen (Source)); + ASSERT ((UINTN)(Source - Destination) > StrLen (Source)); + + ReturnValue = Destination; + while (*Source != 0) { + *(Destination++) = *(Source++); + } + *Destination = 0; + return ReturnValue; +} + +/** + Copies up to a specified length from one Null-terminated Unicode string to + another Null-terminated Unicode string and returns the new Unicode string. + + This function copies the contents of the Unicode string Source to the Unicode + string Destination, and returns Destination. At most, Length Unicode + characters are copied from Source to Destination. If Length is 0, then + Destination is returned unmodified. If Length is greater that the number of + Unicode characters in Source, then Destination is padded with Null Unicode + characters. If Source and Destination overlap, then the results are + undefined. + + If Length > 0 and Destination is NULL, then ASSERT(). + If Length > 0 and Destination is not aligned on a 16-bit boundary, then ASSERT(). + If Length > 0 and Source is NULL, then ASSERT(). + If Length > 0 and Source is not aligned on a 16-bit boundary, then ASSERT(). + If Source and Destination overlap, then ASSERT(). + If PcdMaximumUnicodeStringLength is not zero, and Length is greater than + PcdMaximumUnicodeStringLength, then ASSERT(). + If PcdMaximumUnicodeStringLength is not zero, and Source contains more than + PcdMaximumUnicodeStringLength Unicode characters, not including the Null-terminator, + then ASSERT(). + + @param Destination A pointer to a Null-terminated Unicode string. + @param Source A pointer to a Null-terminated Unicode string. + @param Length The maximum number of Unicode characters to copy. + + @return Destination. + +**/ +CHAR16 * +EFIAPI +StrnCpy ( + OUT CHAR16 *Destination, + IN CONST CHAR16 *Source, + IN UINTN Length + ) +{ + CHAR16 *ReturnValue; + + if (Length == 0) { + return Destination; + } + + // + // Destination cannot be NULL if Length is not zero + // + ASSERT (Destination != NULL); + ASSERT (((UINTN) Destination & BIT0) == 0); + + // + // Destination and source cannot overlap + // + ASSERT ((UINTN)(Destination - Source) > StrLen (Source)); + ASSERT ((UINTN)(Source - Destination) >= Length); + + if (PcdGet32 (PcdMaximumUnicodeStringLength) != 0) { + ASSERT (Length <= PcdGet32 (PcdMaximumUnicodeStringLength)); + } + + ReturnValue = Destination; + + while ((*Source != L'\0') && (Length > 0)) { + *(Destination++) = *(Source++); + Length--; + } + + ZeroMem (Destination, Length * sizeof (*Destination)); + return ReturnValue; +} + +/** + Returns the length of a Null-terminated Unicode string. + + This function returns the number of Unicode characters in the Null-terminated + Unicode string specified by String. + + If String is NULL, then ASSERT(). + If String is not aligned on a 16-bit boundary, then ASSERT(). + If PcdMaximumUnicodeStringLength is not zero, and String contains more than + PcdMaximumUnicodeStringLength Unicode characters, not including the + Null-terminator, then ASSERT(). + + @param String A pointer to a Null-terminated Unicode string. + + @return The length of String. + +**/ +UINTN +EFIAPI +StrLen ( + IN CONST CHAR16 *String + ) +{ + UINTN Length; + + ASSERT (String != NULL); + ASSERT (((UINTN) String & BIT0) == 0); + + for (Length = 0; *String != L'\0'; String++, Length++) { + // + // If PcdMaximumUnicodeStringLength is not zero, + // length should not more than PcdMaximumUnicodeStringLength + // + if (PcdGet32 (PcdMaximumUnicodeStringLength) != 0) { + ASSERT (Length < PcdGet32 (PcdMaximumUnicodeStringLength)); + } + } + return Length; +} + +/** + Returns the size of a Null-terminated Unicode string in bytes, including the + Null terminator. + + This function returns the size, in bytes, of the Null-terminated Unicode string + specified by String. + + If String is NULL, then ASSERT(). + If String is not aligned on a 16-bit boundary, then ASSERT(). + If PcdMaximumUnicodeStringLength is not zero, and String contains more than + PcdMaximumUnicodeStringLength Unicode characters, not including the + Null-terminator, then ASSERT(). + + @param String A pointer to a Null-terminated Unicode string. + + @return The size of String. + +**/ +UINTN +EFIAPI +StrSize ( + IN CONST CHAR16 *String + ) +{ + return (StrLen (String) + 1) * sizeof (*String); +} + +/** + Compares two Null-terminated Unicode strings, and returns the difference + between the first mismatched Unicode characters. + + This function compares the Null-terminated Unicode string FirstString to the + Null-terminated Unicode string SecondString. If FirstString is identical to + SecondString, then 0 is returned. Otherwise, the value returned is the first + mismatched Unicode character in SecondString subtracted from the first + mismatched Unicode character in FirstString. + + If FirstString is NULL, then ASSERT(). + If FirstString is not aligned on a 16-bit boundary, then ASSERT(). + If SecondString is NULL, then ASSERT(). + If SecondString is not aligned on a 16-bit boundary, then ASSERT(). + If PcdMaximumUnicodeStringLength is not zero, and FirstString contains more + than PcdMaximumUnicodeStringLength Unicode characters, not including the + Null-terminator, then ASSERT(). + If PcdMaximumUnicodeStringLength is not zero, and SecondString contains more + than PcdMaximumUnicodeStringLength Unicode characters, not including the + Null-terminator, then ASSERT(). + + @param FirstString A pointer to a Null-terminated Unicode string. + @param SecondString A pointer to a Null-terminated Unicode string. + + @retval 0 FirstString is identical to SecondString. + @return others FirstString is not identical to SecondString. + +**/ +INTN +EFIAPI +StrCmp ( + IN CONST CHAR16 *FirstString, + IN CONST CHAR16 *SecondString + ) +{ + // + // ASSERT both strings are less long than PcdMaximumUnicodeStringLength + // + ASSERT (StrSize (FirstString) != 0); + ASSERT (StrSize (SecondString) != 0); + + while ((*FirstString != L'\0') && (*FirstString == *SecondString)) { + FirstString++; + SecondString++; + } + return *FirstString - *SecondString; +} + +/** + Compares up to a specified length the contents of two Null-terminated Unicode strings, + and returns the difference between the first mismatched Unicode characters. + + This function compares the Null-terminated Unicode string FirstString to the + Null-terminated Unicode string SecondString. At most, Length Unicode + characters will be compared. If Length is 0, then 0 is returned. If + FirstString is identical to SecondString, then 0 is returned. Otherwise, the + value returned is the first mismatched Unicode character in SecondString + subtracted from the first mismatched Unicode character in FirstString. + + If Length > 0 and FirstString is NULL, then ASSERT(). + If Length > 0 and FirstString is not aligned on a 16-bit boundary, then ASSERT(). + If Length > 0 and SecondString is NULL, then ASSERT(). + If Length > 0 and SecondString is not aligned on a 16-bit boundary, then ASSERT(). + If PcdMaximumUnicodeStringLength is not zero, and Length is greater than + PcdMaximumUnicodeStringLength, then ASSERT(). + If PcdMaximumUnicodeStringLength is not zero, and FirstString contains more than + PcdMaximumUnicodeStringLength Unicode characters, not including the Null-terminator, + then ASSERT(). + If PcdMaximumUnicodeStringLength is not zero, and SecondString contains more than + PcdMaximumUnicodeStringLength Unicode characters, not including the Null-terminator, + then ASSERT(). + + @param FirstString A pointer to a Null-terminated Unicode string. + @param SecondString A pointer to a Null-terminated Unicode string. + @param Length The maximum number of Unicode characters to compare. + + @retval 0 FirstString is identical to SecondString. + @return others FirstString is not identical to SecondString. + +**/ +INTN +EFIAPI +StrnCmp ( + IN CONST CHAR16 *FirstString, + IN CONST CHAR16 *SecondString, + IN UINTN Length + ) +{ + if (Length == 0) { + return 0; + } + + // + // ASSERT both strings are less long than PcdMaximumUnicodeStringLength. + // Length tests are performed inside StrLen(). + // + ASSERT (StrSize (FirstString) != 0); + ASSERT (StrSize (SecondString) != 0); + + if (PcdGet32 (PcdMaximumUnicodeStringLength) != 0) { + ASSERT (Length <= PcdGet32 (PcdMaximumUnicodeStringLength)); + } + + while ((*FirstString != L'\0') && + (*FirstString == *SecondString) && + (Length > 1)) { + FirstString++; + SecondString++; + Length--; + } + + return *FirstString - *SecondString; +} + +/** + Concatenates one Null-terminated Unicode string to another Null-terminated + Unicode string, and returns the concatenated Unicode string. + + This function concatenates two Null-terminated Unicode strings. The contents + of Null-terminated Unicode string Source are concatenated to the end of + Null-terminated Unicode string Destination. The Null-terminated concatenated + Unicode String is returned. If Source and Destination overlap, then the + results are undefined. + + If Destination is NULL, then ASSERT(). + If Destination is not aligned on a 16-bit boundary, then ASSERT(). + If Source is NULL, then ASSERT(). + If Source is not aligned on a 16-bit boundary, then ASSERT(). + If Source and Destination overlap, then ASSERT(). + If PcdMaximumUnicodeStringLength is not zero, and Destination contains more + than PcdMaximumUnicodeStringLength Unicode characters, not including the + Null-terminator, then ASSERT(). + If PcdMaximumUnicodeStringLength is not zero, and Source contains more than + PcdMaximumUnicodeStringLength Unicode characters, not including the + Null-terminator, then ASSERT(). + If PcdMaximumUnicodeStringLength is not zero, and concatenating Destination + and Source results in a Unicode string with more than + PcdMaximumUnicodeStringLength Unicode characters, not including the + Null-terminator, then ASSERT(). + + @param Destination A pointer to a Null-terminated Unicode string. + @param Source A pointer to a Null-terminated Unicode string. + + @return Destination. + +**/ +CHAR16 * +EFIAPI +StrCat ( + IN OUT CHAR16 *Destination, + IN CONST CHAR16 *Source + ) +{ + StrCpy (Destination + StrLen (Destination), Source); + + // + // Size of the resulting string should never be zero. + // PcdMaximumUnicodeStringLength is tested inside StrLen(). + // + ASSERT (StrSize (Destination) != 0); + return Destination; +} + +/** + Concatenates up to a specified length one Null-terminated Unicode to the end + of another Null-terminated Unicode string, and returns the concatenated + Unicode string. + + This function concatenates two Null-terminated Unicode strings. The contents + of Null-terminated Unicode string Source are concatenated to the end of + Null-terminated Unicode string Destination, and Destination is returned. At + most, Length Unicode characters are concatenated from Source to the end of + Destination, and Destination is always Null-terminated. If Length is 0, then + Destination is returned unmodified. If Source and Destination overlap, then + the results are undefined. + + If Destination is NULL, then ASSERT(). + If Length > 0 and Destination is not aligned on a 16-bit boundary, then ASSERT(). + If Length > 0 and Source is NULL, then ASSERT(). + If Length > 0 and Source is not aligned on a 16-bit boundary, then ASSERT(). + If Source and Destination overlap, then ASSERT(). + If PcdMaximumUnicodeStringLength is not zero, and Length is greater than + PcdMaximumUnicodeStringLength, then ASSERT(). + If PcdMaximumUnicodeStringLength is not zero, and Destination contains more + than PcdMaximumUnicodeStringLength Unicode characters, not including the + Null-terminator, then ASSERT(). + If PcdMaximumUnicodeStringLength is not zero, and Source contains more than + PcdMaximumUnicodeStringLength Unicode characters, not including the + Null-terminator, then ASSERT(). + If PcdMaximumUnicodeStringLength is not zero, and concatenating Destination + and Source results in a Unicode string with more than PcdMaximumUnicodeStringLength + Unicode characters, not including the Null-terminator, then ASSERT(). + + @param Destination A pointer to a Null-terminated Unicode string. + @param Source A pointer to a Null-terminated Unicode string. + @param Length The maximum number of Unicode characters to concatenate from + Source. + + @return Destination. + +**/ +CHAR16 * +EFIAPI +StrnCat ( + IN OUT CHAR16 *Destination, + IN CONST CHAR16 *Source, + IN UINTN Length + ) +{ + UINTN DestinationLen; + + DestinationLen = StrLen (Destination); + StrnCpy (Destination + DestinationLen, Source, Length); + Destination[DestinationLen + Length] = L'\0'; + + // + // Size of the resulting string should never be zero. + // PcdMaximumUnicodeStringLength is tested inside StrLen(). + // + ASSERT (StrSize (Destination) != 0); + return Destination; +} + +/** + Returns the first occurrence of a Null-terminated Unicode sub-string + in a Null-terminated Unicode string. + + This function scans the contents of the Null-terminated Unicode string + specified by String and returns the first occurrence of SearchString. + If SearchString is not found in String, then NULL is returned. If + the length of SearchString is zero, then String is + returned. + + If String is NULL, then ASSERT(). + If String is not aligned on a 16-bit boundary, then ASSERT(). + If SearchString is NULL, then ASSERT(). + If SearchString is not aligned on a 16-bit boundary, then ASSERT(). + + If PcdMaximumUnicodeStringLength is not zero, and SearchString + or String contains more than PcdMaximumUnicodeStringLength Unicode + characters, not including the Null-terminator, then ASSERT(). + + @param String A pointer to a Null-terminated Unicode string. + @param SearchString A pointer to a Null-terminated Unicode string to search for. + + @retval NULL If the SearchString does not appear in String. + @return others If there is a match. + +**/ +CHAR16 * +EFIAPI +StrStr ( + IN CONST CHAR16 *String, + IN CONST CHAR16 *SearchString + ) +{ + CONST CHAR16 *FirstMatch; + CONST CHAR16 *SearchStringTmp; + + // + // ASSERT both strings are less long than PcdMaximumUnicodeStringLength. + // Length tests are performed inside StrLen(). + // + ASSERT (StrSize (String) != 0); + ASSERT (StrSize (SearchString) != 0); + + if (*SearchString == L'\0') { + return (CHAR16 *) String; + } + + while (*String != L'\0') { + SearchStringTmp = SearchString; + FirstMatch = String; + + while ((*String == *SearchStringTmp) + && (*String != L'\0')) { + String++; + SearchStringTmp++; + } + + if (*SearchStringTmp == L'\0') { + return (CHAR16 *) FirstMatch; + } + + if (*String == L'\0') { + return NULL; + } + + String = FirstMatch + 1; + } + + return NULL; +} + +/** + Check if a Unicode character is a decimal character. + + This internal function checks if a Unicode character is a + decimal character. The valid decimal character is from + L'0' to L'9'. + + @param Char The character to check against. + + @retval TRUE If the Char is a decmial character. + @retval FALSE If the Char is not a decmial character. + +**/ +BOOLEAN +EFIAPI +InternalIsDecimalDigitCharacter ( + IN CHAR16 Char + ) +{ + return (BOOLEAN) (Char >= L'0' && Char <= L'9'); +} + +/** + Convert a Unicode character to upper case only if + it maps to a valid small-case ASCII character. + + This internal function only deal with Unicode character + which maps to a valid small-case ASCII character, i.e. + L'a' to L'z'. For other Unicode character, the input character + is returned directly. + + @param Char The character to convert. + + @retval LowerCharacter If the Char is with range L'a' to L'z'. + @retval Unchanged Otherwise. + +**/ +CHAR16 +EFIAPI +InternalCharToUpper ( + IN CHAR16 Char + ) +{ + if (Char >= L'a' && Char <= L'z') { + return (CHAR16) (Char - (L'a' - L'A')); + } + + return Char; +} + +/** + Convert a Unicode character to numerical value. + + This internal function only deal with Unicode character + which maps to a valid hexadecimal ASII character, i.e. + L'0' to L'9', L'a' to L'f' or L'A' to L'F'. For other + Unicode character, the value returned does not make sense. + + @param Char The character to convert. + + @return The numerical value converted. + +**/ +UINTN +EFIAPI +InternalHexCharToUintn ( + IN CHAR16 Char + ) +{ + if (InternalIsDecimalDigitCharacter (Char)) { + return Char - L'0'; + } + + return (UINTN) (10 + InternalCharToUpper (Char) - L'A'); +} + +/** + Check if a Unicode character is a hexadecimal character. + + This internal function checks if a Unicode character is a + decimal character. The valid hexadecimal character is + L'0' to L'9', L'a' to L'f', or L'A' to L'F'. + + + @param Char The character to check against. + + @retval TRUE If the Char is a hexadecmial character. + @retval FALSE If the Char is not a hexadecmial character. + +**/ +BOOLEAN +EFIAPI +InternalIsHexaDecimalDigitCharacter ( + IN CHAR16 Char + ) +{ + + return (BOOLEAN) (InternalIsDecimalDigitCharacter (Char) || + (Char >= L'A' && Char <= L'F') || + (Char >= L'a' && Char <= L'f')); +} + +/** + Convert a Null-terminated Unicode decimal string to a value of + type UINTN. + + This function returns a value of type UINTN by interpreting the contents + of the Unicode string specified by String as a decimal number. The format + of the input Unicode string String is: + + [spaces] [decimal digits]. + + The valid decimal digit character is in the range [0-9]. The + function will ignore the pad space, which includes spaces or + tab characters, before [decimal digits]. The running zero in the + beginning of [decimal digits] will be ignored. Then, the function + stops at the first character that is a not a valid decimal character + or a Null-terminator, whichever one comes first. + + If String is NULL, then ASSERT(). + If String is not aligned in a 16-bit boundary, then ASSERT(). + If String has only pad spaces, then 0 is returned. + If String has no pad spaces or valid decimal digits, + then 0 is returned. + If the number represented by String overflows according + to the range defined by UINTN, then ASSERT(). + + If PcdMaximumUnicodeStringLength is not zero, and String contains + more than PcdMaximumUnicodeStringLength Unicode characters, not including + the Null-terminator, then ASSERT(). + + @param String A pointer to a Null-terminated Unicode string. + + @retval Value translated from String. + +**/ +UINTN +EFIAPI +StrDecimalToUintn ( + IN CONST CHAR16 *String + ) +{ + UINTN Result; + + // + // ASSERT String is less long than PcdMaximumUnicodeStringLength. + // Length tests are performed inside StrLen(). + // + ASSERT (StrSize (String) != 0); + + // + // Ignore the pad spaces (space or tab) + // + while ((*String == L' ') || (*String == L'\t')) { + String++; + } + + // + // Ignore leading Zeros after the spaces + // + while (*String == L'0') { + String++; + } + + Result = 0; + + while (InternalIsDecimalDigitCharacter (*String)) { + // + // If the number represented by String overflows according + // to the range defined by UINTN, then ASSERT(). + // + ASSERT ((Result < QUOTIENT_MAX_UINTN_DIVIDED_BY_10) || + ((Result == QUOTIENT_MAX_UINTN_DIVIDED_BY_10) && + (*String - L'0') <= REMAINDER_MAX_UINTN_DIVIDED_BY_10) + ); + + Result = Result * 10 + (*String - L'0'); + String++; + } + + return Result; +} + + +/** + Convert a Null-terminated Unicode decimal string to a value of + type UINT64. + + This function returns a value of type UINT64 by interpreting the contents + of the Unicode string specified by String as a decimal number. The format + of the input Unicode string String is: + + [spaces] [decimal digits]. + + The valid decimal digit character is in the range [0-9]. The + function will ignore the pad space, which includes spaces or + tab characters, before [decimal digits]. The running zero in the + beginning of [decimal digits] will be ignored. Then, the function + stops at the first character that is a not a valid decimal character + or a Null-terminator, whichever one comes first. + + If String is NULL, then ASSERT(). + If String is not aligned in a 16-bit boundary, then ASSERT(). + If String has only pad spaces, then 0 is returned. + If String has no pad spaces or valid decimal digits, + then 0 is returned. + If the number represented by String overflows according + to the range defined by UINT64, then ASSERT(). + + If PcdMaximumUnicodeStringLength is not zero, and String contains + more than PcdMaximumUnicodeStringLength Unicode characters, not including + the Null-terminator, then ASSERT(). + + @param String A pointer to a Null-terminated Unicode string. + + @retval Value translated from String. + +**/ +UINT64 +EFIAPI +StrDecimalToUint64 ( + IN CONST CHAR16 *String + ) +{ + UINT64 Result; + + // + // ASSERT String is less long than PcdMaximumUnicodeStringLength. + // Length tests are performed inside StrLen(). + // + ASSERT (StrSize (String) != 0); + + // + // Ignore the pad spaces (space or tab) + // + while ((*String == L' ') || (*String == L'\t')) { + String++; + } + + // + // Ignore leading Zeros after the spaces + // + while (*String == L'0') { + String++; + } + + Result = 0; + + while (InternalIsDecimalDigitCharacter (*String)) { + // + // If the number represented by String overflows according + // to the range defined by UINTN, then ASSERT(). + // + ASSERT ((Result < QUOTIENT_MAX_UINT64_DIVIDED_BY_10) || + ((Result == QUOTIENT_MAX_UINT64_DIVIDED_BY_10) && + (*String - L'0') <= REMAINDER_MAX_UINT64_DIVIDED_BY_10) + ); + + Result = MultU64x32 (Result, 10) + (*String - L'0'); + String++; + } + + return Result; +} + +/** + Convert a Null-terminated Unicode hexadecimal string to a value of type UINTN. + + This function returns a value of type UINTN by interpreting the contents + of the Unicode string specified by String as a hexadecimal number. + The format of the input Unicode string String is: + + [spaces][zeros][x][hexadecimal digits]. + + The valid hexadecimal digit character is in the range [0-9], [a-f] and [A-F]. + The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefix. + If "x" appears in the input string, it must be prefixed with at least one 0. + The function will ignore the pad space, which includes spaces or tab characters, + before [zeros], [x] or [hexadecimal digit]. The running zero before [x] or + [hexadecimal digit] will be ignored. Then, the decoding starts after [x] or the + first valid hexadecimal digit. Then, the function stops at the first character that is + a not a valid hexadecimal character or NULL, whichever one comes first. + + If String is NULL, then ASSERT(). + If String is not aligned in a 16-bit boundary, then ASSERT(). + If String has only pad spaces, then zero is returned. + If String has no leading pad spaces, leading zeros or valid hexadecimal digits, + then zero is returned. + If the number represented by String overflows according to the range defined by + UINTN, then ASSERT(). + + If PcdMaximumUnicodeStringLength is not zero, and String contains more than + PcdMaximumUnicodeStringLength Unicode characters, not including the Null-terminator, + then ASSERT(). + + @param String A pointer to a Null-terminated Unicode string. + + @retval Value translated from String. + +**/ +UINTN +EFIAPI +StrHexToUintn ( + IN CONST CHAR16 *String + ) +{ + UINTN Result; + + // + // ASSERT String is less long than PcdMaximumUnicodeStringLength. + // Length tests are performed inside StrLen(). + // + ASSERT (StrSize (String) != 0); + + // + // Ignore the pad spaces (space or tab) + // + while ((*String == L' ') || (*String == L'\t')) { + String++; + } + + // + // Ignore leading Zeros after the spaces + // + while (*String == L'0') { + String++; + } + + if (InternalCharToUpper (*String) == L'X') { + if (*(String - 1) != L'0') { + return 0; + } + // + // Skip the 'X' + // + String++; + } + + Result = 0; + + while (InternalIsHexaDecimalDigitCharacter (*String)) { + // + // If the Hex Number represented by String overflows according + // to the range defined by UINTN, then ASSERT(). + // + ASSERT ((Result < QUOTIENT_MAX_UINTN_DIVIDED_BY_16) || + ((Result == QUOTIENT_MAX_UINTN_DIVIDED_BY_16) && + (InternalHexCharToUintn (*String) <= REMAINDER_MAX_UINTN_DIVIDED_BY_16)) + ); + + Result = (Result << 4) + InternalHexCharToUintn (*String); + String++; + } + + return Result; +} + + +/** + Convert a Null-terminated Unicode hexadecimal string to a value of type UINT64. + + This function returns a value of type UINT64 by interpreting the contents + of the Unicode string specified by String as a hexadecimal number. + The format of the input Unicode string String is + + [spaces][zeros][x][hexadecimal digits]. + + The valid hexadecimal digit character is in the range [0-9], [a-f] and [A-F]. + The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefix. + If "x" appears in the input string, it must be prefixed with at least one 0. + The function will ignore the pad space, which includes spaces or tab characters, + before [zeros], [x] or [hexadecimal digit]. The running zero before [x] or + [hexadecimal digit] will be ignored. Then, the decoding starts after [x] or the + first valid hexadecimal digit. Then, the function stops at the first character that is + a not a valid hexadecimal character or NULL, whichever one comes first. + + If String is NULL, then ASSERT(). + If String is not aligned in a 16-bit boundary, then ASSERT(). + If String has only pad spaces, then zero is returned. + If String has no leading pad spaces, leading zeros or valid hexadecimal digits, + then zero is returned. + If the number represented by String overflows according to the range defined by + UINT64, then ASSERT(). + + If PcdMaximumUnicodeStringLength is not zero, and String contains more than + PcdMaximumUnicodeStringLength Unicode characters, not including the Null-terminator, + then ASSERT(). + + @param String A pointer to a Null-terminated Unicode string. + + @retval Value translated from String. + +**/ +UINT64 +EFIAPI +StrHexToUint64 ( + IN CONST CHAR16 *String + ) +{ + UINT64 Result; + + // + // ASSERT String is less long than PcdMaximumUnicodeStringLength. + // Length tests are performed inside StrLen(). + // + ASSERT (StrSize (String) != 0); + + // + // Ignore the pad spaces (space or tab) + // + while ((*String == L' ') || (*String == L'\t')) { + String++; + } + + // + // Ignore leading Zeros after the spaces + // + while (*String == L'0') { + String++; + } + + if (InternalCharToUpper (*String) == L'X') { + ASSERT (*(String - 1) == L'0'); + if (*(String - 1) != L'0') { + return 0; + } + // + // Skip the 'X' + // + String++; + } + + Result = 0; + + while (InternalIsHexaDecimalDigitCharacter (*String)) { + // + // If the Hex Number represented by String overflows according + // to the range defined by UINTN, then ASSERT(). + // + ASSERT ((Result < QUOTIENT_MAX_UINT64_DIVIDED_BY_16)|| + ((Result == QUOTIENT_MAX_UINT64_DIVIDED_BY_16) && + (InternalHexCharToUintn (*String) <= REMAINDER_MAX_UINT64_DIVIDED_BY_16)) + ); + + Result = LShiftU64 (Result, 4); + Result = Result + InternalHexCharToUintn (*String); + String++; + } + + return Result; +} + +/** + Check if a ASCII character is a decimal character. + + This internal function checks if a Unicode character is a + decimal character. The valid decimal character is from + '0' to '9'. + + @param Char The character to check against. + + @retval TRUE If the Char is a decmial character. + @retval FALSE If the Char is not a decmial character. + +**/ +BOOLEAN +EFIAPI +InternalAsciiIsDecimalDigitCharacter ( + IN CHAR8 Char + ) +{ + return (BOOLEAN) (Char >= '0' && Char <= '9'); +} + +/** + Check if a ASCII character is a hexadecimal character. + + This internal function checks if a ASCII character is a + decimal character. The valid hexadecimal character is + L'0' to L'9', L'a' to L'f', or L'A' to L'F'. + + + @param Char The character to check against. + + @retval TRUE If the Char is a hexadecmial character. + @retval FALSE If the Char is not a hexadecmial character. + +**/ +BOOLEAN +EFIAPI +InternalAsciiIsHexaDecimalDigitCharacter ( + IN CHAR8 Char + ) +{ + + return (BOOLEAN) (InternalAsciiIsDecimalDigitCharacter (Char) || + (Char >= 'A' && Char <= 'F') || + (Char >= 'a' && Char <= 'f')); +} + +/** + Convert a Null-terminated Unicode string to a Null-terminated + ASCII string and returns the ASCII string. + + This function converts the content of the Unicode string Source + to the ASCII string Destination by copying the lower 8 bits of + each Unicode character. It returns Destination. + + If any Unicode characters in Source contain non-zero value in + the upper 8 bits, then ASSERT(). + + If Destination is NULL, then ASSERT(). + If Source is NULL, then ASSERT(). + If Source is not aligned on a 16-bit boundary, then ASSERT(). + If Source and Destination overlap, then ASSERT(). + + If PcdMaximumUnicodeStringLength is not zero, and Source contains + more than PcdMaximumUnicodeStringLength Unicode characters, not including + the Null-terminator, then ASSERT(). + + If PcdMaximumAsciiStringLength is not zero, and Source contains more + than PcdMaximumAsciiStringLength Unicode characters, not including the + Null-terminator, then ASSERT(). + + @param Source A pointer to a Null-terminated Unicode string. + @param Destination A pointer to a Null-terminated ASCII string. + + @return Destination. + +**/ +CHAR8 * +EFIAPI +UnicodeStrToAsciiStr ( + IN CONST CHAR16 *Source, + OUT CHAR8 *Destination + ) +{ + CHAR8 *ReturnValue; + + ASSERT (Destination != NULL); + + // + // ASSERT if Source is long than PcdMaximumUnicodeStringLength. + // Length tests are performed inside StrLen(). + // + ASSERT (StrSize (Source) != 0); + + // + // Source and Destination should not overlap + // + ASSERT ((UINTN) ((CHAR16 *) Destination - Source) > StrLen (Source)); + ASSERT ((UINTN) ((CHAR8 *) Source - Destination) > StrLen (Source)); + + + ReturnValue = Destination; + while (*Source != '\0') { + // + // If any Unicode characters in Source contain + // non-zero value in the upper 8 bits, then ASSERT(). + // + ASSERT (*Source < 0x100); + *(Destination++) = (CHAR8) *(Source++); + } + + *Destination = '\0'; + + // + // ASSERT Original Destination is less long than PcdMaximumAsciiStringLength. + // Length tests are performed inside AsciiStrLen(). + // + ASSERT (AsciiStrSize (ReturnValue) != 0); + + return ReturnValue; +} + + +/** + Copies one Null-terminated ASCII string to another Null-terminated ASCII + string and returns the new ASCII string. + + This function copies the contents of the ASCII string Source to the ASCII + string Destination, and returns Destination. If Source and Destination + overlap, then the results are undefined. + + If Destination is NULL, then ASSERT(). + If Source is NULL, then ASSERT(). + If Source and Destination overlap, then ASSERT(). + If PcdMaximumAsciiStringLength is not zero and Source contains more than + PcdMaximumAsciiStringLength ASCII characters, not including the Null-terminator, + then ASSERT(). + + @param Destination A pointer to a Null-terminated ASCII string. + @param Source A pointer to a Null-terminated ASCII string. + + @return Destination + +**/ +CHAR8 * +EFIAPI +AsciiStrCpy ( + OUT CHAR8 *Destination, + IN CONST CHAR8 *Source + ) +{ + CHAR8 *ReturnValue; + + // + // Destination cannot be NULL + // + ASSERT (Destination != NULL); + + // + // Destination and source cannot overlap + // + ASSERT ((UINTN)(Destination - Source) > AsciiStrLen (Source)); + ASSERT ((UINTN)(Source - Destination) > AsciiStrLen (Source)); + + ReturnValue = Destination; + while (*Source != 0) { + *(Destination++) = *(Source++); + } + *Destination = 0; + return ReturnValue; +} + +/** + Copies up to a specified length one Null-terminated ASCII string to another + Null-terminated ASCII string and returns the new ASCII string. + + This function copies the contents of the ASCII string Source to the ASCII + string Destination, and returns Destination. At most, Length ASCII characters + are copied from Source to Destination. If Length is 0, then Destination is + returned unmodified. If Length is greater that the number of ASCII characters + in Source, then Destination is padded with Null ASCII characters. If Source + and Destination overlap, then the results are undefined. + + If Destination is NULL, then ASSERT(). + If Source is NULL, then ASSERT(). + If Source and Destination overlap, then ASSERT(). + If PcdMaximumAsciiStringLength is not zero, and Length is greater than + PcdMaximumAsciiStringLength, then ASSERT(). + If PcdMaximumAsciiStringLength is not zero, and Source contains more than + PcdMaximumAsciiStringLength ASCII characters, not including the Null-terminator, + then ASSERT(). + + @param Destination A pointer to a Null-terminated ASCII string. + @param Source A pointer to a Null-terminated ASCII string. + @param Length The maximum number of ASCII characters to copy. + + @return Destination + +**/ +CHAR8 * +EFIAPI +AsciiStrnCpy ( + OUT CHAR8 *Destination, + IN CONST CHAR8 *Source, + IN UINTN Length + ) +{ + CHAR8 *ReturnValue; + + if (Length == 0) { + return Destination; + } + + // + // Destination cannot be NULL + // + ASSERT (Destination != NULL); + + // + // Destination and source cannot overlap + // + ASSERT ((UINTN)(Destination - Source) > AsciiStrLen (Source)); + ASSERT ((UINTN)(Source - Destination) >= Length); + + if (PcdGet32 (PcdMaximumAsciiStringLength) != 0) { + ASSERT (Length <= PcdGet32 (PcdMaximumAsciiStringLength)); + } + + ReturnValue = Destination; + + while (*Source != 0 && Length > 0) { + *(Destination++) = *(Source++); + Length--; + } + + ZeroMem (Destination, Length * sizeof (*Destination)); + return ReturnValue; +} + +/** + Returns the length of a Null-terminated ASCII string. + + This function returns the number of ASCII characters in the Null-terminated + ASCII string specified by String. + + If Length > 0 and Destination is NULL, then ASSERT(). + If Length > 0 and Source is NULL, then ASSERT(). + If PcdMaximumAsciiStringLength is not zero and String contains more than + PcdMaximumAsciiStringLength ASCII characters, not including the Null-terminator, + then ASSERT(). + + @param String A pointer to a Null-terminated ASCII string. + + @return The length of String. + +**/ +UINTN +EFIAPI +AsciiStrLen ( + IN CONST CHAR8 *String + ) +{ + UINTN Length; + + ASSERT (String != NULL); + + for (Length = 0; *String != '\0'; String++, Length++) { + // + // If PcdMaximumUnicodeStringLength is not zero, + // length should not more than PcdMaximumUnicodeStringLength + // + if (PcdGet32 (PcdMaximumAsciiStringLength) != 0) { + ASSERT (Length < PcdGet32 (PcdMaximumAsciiStringLength)); + } + } + return Length; +} + +/** + Returns the size of a Null-terminated ASCII string in bytes, including the + Null terminator. + + This function returns the size, in bytes, of the Null-terminated ASCII string + specified by String. + + If String is NULL, then ASSERT(). + If PcdMaximumAsciiStringLength is not zero and String contains more than + PcdMaximumAsciiStringLength ASCII characters, not including the Null-terminator, + then ASSERT(). + + @param String A pointer to a Null-terminated ASCII string. + + @return The size of String. + +**/ +UINTN +EFIAPI +AsciiStrSize ( + IN CONST CHAR8 *String + ) +{ + return (AsciiStrLen (String) + 1) * sizeof (*String); +} + +/** + Compares two Null-terminated ASCII strings, and returns the difference + between the first mismatched ASCII characters. + + This function compares the Null-terminated ASCII string FirstString to the + Null-terminated ASCII string SecondString. If FirstString is identical to + SecondString, then 0 is returned. Otherwise, the value returned is the first + mismatched ASCII character in SecondString subtracted from the first + mismatched ASCII character in FirstString. + + If FirstString is NULL, then ASSERT(). + If SecondString is NULL, then ASSERT(). + If PcdMaximumAsciiStringLength is not zero and FirstString contains more than + PcdMaximumAsciiStringLength ASCII characters, not including the Null-terminator, + then ASSERT(). + If PcdMaximumAsciiStringLength is not zero and SecondString contains more + than PcdMaximumAsciiStringLength ASCII characters, not including the + Null-terminator, then ASSERT(). + + @param FirstString A pointer to a Null-terminated ASCII string. + @param SecondString A pointer to a Null-terminated ASCII string. + + @retval ==0 FirstString is identical to SecondString. + @retval !=0 FirstString is not identical to SecondString. + +**/ +INTN +EFIAPI +AsciiStrCmp ( + IN CONST CHAR8 *FirstString, + IN CONST CHAR8 *SecondString + ) +{ + // + // ASSERT both strings are less long than PcdMaximumAsciiStringLength + // + ASSERT (AsciiStrSize (FirstString)); + ASSERT (AsciiStrSize (SecondString)); + + while ((*FirstString != '\0') && (*FirstString == *SecondString)) { + FirstString++; + SecondString++; + } + + return *FirstString - *SecondString; +} + +/** + Converts a lowercase Ascii character to upper one. + + If Chr is lowercase Ascii character, then converts it to upper one. + + If Value >= 0xA0, then ASSERT(). + If (Value & 0x0F) >= 0x0A, then ASSERT(). + + @param Chr one Ascii character + + @return The uppercase value of Ascii character + +**/ +CHAR8 +EFIAPI +InternalBaseLibAsciiToUpper ( + IN CHAR8 Chr + ) +{ + return (UINT8) ((Chr >= 'a' && Chr <= 'z') ? Chr - ('a' - 'A') : Chr); +} + +/** + Convert a ASCII character to numerical value. + + This internal function only deal with Unicode character + which maps to a valid hexadecimal ASII character, i.e. + '0' to '9', 'a' to 'f' or 'A' to 'F'. For other + ASCII character, the value returned does not make sense. + + @param Char The character to convert. + + @return The numerical value converted. + +**/ +UINTN +EFIAPI +InternalAsciiHexCharToUintn ( + IN CHAR8 Char + ) +{ + if (InternalIsDecimalDigitCharacter (Char)) { + return Char - '0'; + } + + return (UINTN) (10 + InternalBaseLibAsciiToUpper (Char) - 'A'); +} + + +/** + Performs a case insensitive comparison of two Null-terminated ASCII strings, + and returns the difference between the first mismatched ASCII characters. + + This function performs a case insensitive comparison of the Null-terminated + ASCII string FirstString to the Null-terminated ASCII string SecondString. If + FirstString is identical to SecondString, then 0 is returned. Otherwise, the + value returned is the first mismatched lower case ASCII character in + SecondString subtracted from the first mismatched lower case ASCII character + in FirstString. + + If FirstString is NULL, then ASSERT(). + If SecondString is NULL, then ASSERT(). + If PcdMaximumAsciiStringLength is not zero and FirstString contains more than + PcdMaximumAsciiStringLength ASCII characters, not including the Null-terminator, + then ASSERT(). + If PcdMaximumAsciiStringLength is not zero and SecondString contains more + than PcdMaximumAsciiStringLength ASCII characters, not including the + Null-terminator, then ASSERT(). + + @param FirstString A pointer to a Null-terminated ASCII string. + @param SecondString A pointer to a Null-terminated ASCII string. + + @retval ==0 FirstString is identical to SecondString using case insensitive + comparisons. + @retval !=0 FirstString is not identical to SecondString using case + insensitive comparisons. + +**/ +INTN +EFIAPI +AsciiStriCmp ( + IN CONST CHAR8 *FirstString, + IN CONST CHAR8 *SecondString + ) +{ + CHAR8 UpperFirstString; + CHAR8 UpperSecondString; + + // + // ASSERT both strings are less long than PcdMaximumAsciiStringLength + // + ASSERT (AsciiStrSize (FirstString)); + ASSERT (AsciiStrSize (SecondString)); + + UpperFirstString = InternalBaseLibAsciiToUpper (*FirstString); + UpperSecondString = InternalBaseLibAsciiToUpper (*SecondString); + while ((*FirstString != '\0') && (UpperFirstString == UpperSecondString)) { + FirstString++; + SecondString++; + UpperFirstString = InternalBaseLibAsciiToUpper (*FirstString); + UpperSecondString = InternalBaseLibAsciiToUpper (*SecondString); + } + + return UpperFirstString - UpperSecondString; +} + +/** + Compares two Null-terminated ASCII strings with maximum lengths, and returns + the difference between the first mismatched ASCII characters. + + This function compares the Null-terminated ASCII string FirstString to the + Null-terminated ASCII string SecondString. At most, Length ASCII characters + will be compared. If Length is 0, then 0 is returned. If FirstString is + identical to SecondString, then 0 is returned. Otherwise, the value returned + is the first mismatched ASCII character in SecondString subtracted from the + first mismatched ASCII character in FirstString. + + If Length > 0 and FirstString is NULL, then ASSERT(). + If Length > 0 and SecondString is NULL, then ASSERT(). + If PcdMaximumAsciiStringLength is not zero, and Length is greater than + PcdMaximumAsciiStringLength, then ASSERT(). + If PcdMaximumAsciiStringLength is not zero, and FirstString contains more than + PcdMaximumAsciiStringLength ASCII characters, not including the Null-terminator, + then ASSERT(). + If PcdMaximumAsciiStringLength is not zero, and SecondString contains more than + PcdMaximumAsciiStringLength ASCII characters, not including the Null-terminator, + then ASSERT(). + + @param FirstString A pointer to a Null-terminated ASCII string. + @param SecondString A pointer to a Null-terminated ASCII string. + @param Length The maximum number of ASCII characters for compare. + + @retval ==0 FirstString is identical to SecondString. + @retval !=0 FirstString is not identical to SecondString. + +**/ +INTN +EFIAPI +AsciiStrnCmp ( + IN CONST CHAR8 *FirstString, + IN CONST CHAR8 *SecondString, + IN UINTN Length + ) +{ + if (Length == 0) { + return 0; + } + + // + // ASSERT both strings are less long than PcdMaximumAsciiStringLength + // + ASSERT (AsciiStrSize (FirstString)); + ASSERT (AsciiStrSize (SecondString)); + + if (PcdGet32 (PcdMaximumAsciiStringLength) != 0) { + ASSERT (Length <= PcdGet32 (PcdMaximumAsciiStringLength)); + } + + while ((*FirstString != '\0') && + (*FirstString == *SecondString) && + (Length > 1)) { + FirstString++; + SecondString++; + Length--; + } + return *FirstString - *SecondString; +} + +/** + Concatenates one Null-terminated ASCII string to another Null-terminated + ASCII string, and returns the concatenated ASCII string. + + This function concatenates two Null-terminated ASCII strings. The contents of + Null-terminated ASCII string Source are concatenated to the end of Null- + terminated ASCII string Destination. The Null-terminated concatenated ASCII + String is returned. + + If Destination is NULL, then ASSERT(). + If Source is NULL, then ASSERT(). + If PcdMaximumAsciiStringLength is not zero and Destination contains more than + PcdMaximumAsciiStringLength ASCII characters, not including the Null-terminator, + then ASSERT(). + If PcdMaximumAsciiStringLength is not zero and Source contains more than + PcdMaximumAsciiStringLength ASCII characters, not including the Null-terminator, + then ASSERT(). + If PcdMaximumAsciiStringLength is not zero and concatenating Destination and + Source results in a ASCII string with more than PcdMaximumAsciiStringLength + ASCII characters, then ASSERT(). + + @param Destination A pointer to a Null-terminated ASCII string. + @param Source A pointer to a Null-terminated ASCII string. + + @return Destination + +**/ +CHAR8 * +EFIAPI +AsciiStrCat ( + IN OUT CHAR8 *Destination, + IN CONST CHAR8 *Source + ) +{ + AsciiStrCpy (Destination + AsciiStrLen (Destination), Source); + + // + // Size of the resulting string should never be zero. + // PcdMaximumUnicodeStringLength is tested inside StrLen(). + // + ASSERT (AsciiStrSize (Destination) != 0); + return Destination; +} + +/** + Concatenates up to a specified length one Null-terminated ASCII string to + the end of another Null-terminated ASCII string, and returns the + concatenated ASCII string. + + This function concatenates two Null-terminated ASCII strings. The contents + of Null-terminated ASCII string Source are concatenated to the end of Null- + terminated ASCII string Destination, and Destination is returned. At most, + Length ASCII characters are concatenated from Source to the end of + Destination, and Destination is always Null-terminated. If Length is 0, then + Destination is returned unmodified. If Source and Destination overlap, then + the results are undefined. + + If Length > 0 and Destination is NULL, then ASSERT(). + If Length > 0 and Source is NULL, then ASSERT(). + If Source and Destination overlap, then ASSERT(). + If PcdMaximumAsciiStringLength is not zero, and Length is greater than + PcdMaximumAsciiStringLength, then ASSERT(). + If PcdMaximumAsciiStringLength is not zero, and Destination contains more than + PcdMaximumAsciiStringLength ASCII characters, not including the Null-terminator, + then ASSERT(). + If PcdMaximumAsciiStringLength is not zero, and Source contains more than + PcdMaximumAsciiStringLength ASCII characters, not including the Null-terminator, + then ASSERT(). + If PcdMaximumAsciiStringLength is not zero, and concatenating Destination and + Source results in a ASCII string with more than PcdMaximumAsciiStringLength + ASCII characters, not including the Null-terminator, then ASSERT(). + + @param Destination A pointer to a Null-terminated ASCII string. + @param Source A pointer to a Null-terminated ASCII string. + @param Length The maximum number of ASCII characters to concatenate from + Source. + + @return Destination + +**/ +CHAR8 * +EFIAPI +AsciiStrnCat ( + IN OUT CHAR8 *Destination, + IN CONST CHAR8 *Source, + IN UINTN Length + ) +{ + UINTN DestinationLen; + + DestinationLen = AsciiStrLen (Destination); + AsciiStrnCpy (Destination + DestinationLen, Source, Length); + Destination[DestinationLen + Length] = '\0'; + + // + // Size of the resulting string should never be zero. + // PcdMaximumUnicodeStringLength is tested inside StrLen(). + // + ASSERT (AsciiStrSize (Destination) != 0); + return Destination; +} + +/** + Returns the first occurrence of a Null-terminated ASCII sub-string + in a Null-terminated ASCII string. + + This function scans the contents of the ASCII string specified by String + and returns the first occurrence of SearchString. If SearchString is not + found in String, then NULL is returned. If the length of SearchString is zero, + then String is returned. + + If String is NULL, then ASSERT(). + If SearchString is NULL, then ASSERT(). + + If PcdMaximumAsciiStringLength is not zero, and SearchString or + String contains more than PcdMaximumAsciiStringLength Unicode characters + not including the Null-terminator, then ASSERT(). + + @param String A pointer to a Null-terminated ASCII string. + @param SearchString A pointer to a Null-terminated ASCII string to search for. + + @retval NULL If the SearchString does not appear in String. + @retval others If there is a match return the first occurrence of SearchingString. + If the length of SearchString is zero,return String. + +**/ +CHAR8 * +EFIAPI +AsciiStrStr ( + IN CONST CHAR8 *String, + IN CONST CHAR8 *SearchString + ) +{ + CONST CHAR8 *FirstMatch; + CONST CHAR8 *SearchStringTmp; + + // + // ASSERT both strings are less long than PcdMaximumAsciiStringLength + // + ASSERT (AsciiStrSize (String) != 0); + ASSERT (AsciiStrSize (SearchString) != 0); + + if (*SearchString == '\0') { + return (CHAR8 *) String; + } + + while (*String != '\0') { + SearchStringTmp = SearchString; + FirstMatch = String; + + while ((*String == *SearchStringTmp) + && (*String != '\0')) { + String++; + SearchStringTmp++; + } + + if (*SearchStringTmp == '\0') { + return (CHAR8 *) FirstMatch; + } + + if (*String == '\0') { + return NULL; + } + + String = FirstMatch + 1; + } + + return NULL; +} + +/** + Convert a Null-terminated ASCII decimal string to a value of type + UINTN. + + This function returns a value of type UINTN by interpreting the contents + of the ASCII string String as a decimal number. The format of the input + ASCII string String is: + + [spaces] [decimal digits]. + + The valid decimal digit character is in the range [0-9]. The function will + ignore the pad space, which includes spaces or tab characters, before the digits. + The running zero in the beginning of [decimal digits] will be ignored. Then, the + function stops at the first character that is a not a valid decimal character or + Null-terminator, whichever on comes first. + + If String has only pad spaces, then 0 is returned. + If String has no pad spaces or valid decimal digits, then 0 is returned. + If the number represented by String overflows according to the range defined by + UINTN, then ASSERT(). + If String is NULL, then ASSERT(). + If PcdMaximumAsciiStringLength is not zero, and String contains more than + PcdMaximumAsciiStringLength ASCII characters not including the Null-terminator, + then ASSERT(). + + @param String A pointer to a Null-terminated ASCII string. + + @retval Value translated from String. + +**/ +UINTN +EFIAPI +AsciiStrDecimalToUintn ( + IN CONST CHAR8 *String + ) +{ + UINTN Result; + + // + // ASSERT Strings is less long than PcdMaximumAsciiStringLength + // + ASSERT (AsciiStrSize (String) != 0); + + // + // Ignore the pad spaces (space or tab) + // + while ((*String == ' ') || (*String == '\t' )) { + String++; + } + + // + // Ignore leading Zeros after the spaces + // + while (*String == '0') { + String++; + } + + Result = 0; + + while (InternalAsciiIsDecimalDigitCharacter (*String)) { + // + // If the number represented by String overflows according + // to the range defined by UINTN, then ASSERT(). + // + ASSERT ((Result < QUOTIENT_MAX_UINTN_DIVIDED_BY_10) || + ((Result == QUOTIENT_MAX_UINTN_DIVIDED_BY_10) && + (*String - '0') <= REMAINDER_MAX_UINTN_DIVIDED_BY_10) + ); + + Result = Result * 10 + (*String - '0'); + String++; + } + + return Result; +} + + +/** + Convert a Null-terminated ASCII decimal string to a value of type + UINT64. + + This function returns a value of type UINT64 by interpreting the contents + of the ASCII string String as a decimal number. The format of the input + ASCII string String is: + + [spaces] [decimal digits]. + + The valid decimal digit character is in the range [0-9]. The function will + ignore the pad space, which includes spaces or tab characters, before the digits. + The running zero in the beginning of [decimal digits] will be ignored. Then, the + function stops at the first character that is a not a valid decimal character or + Null-terminator, whichever on comes first. + + If String has only pad spaces, then 0 is returned. + If String has no pad spaces or valid decimal digits, then 0 is returned. + If the number represented by String overflows according to the range defined by + UINT64, then ASSERT(). + If String is NULL, then ASSERT(). + If PcdMaximumAsciiStringLength is not zero, and String contains more than + PcdMaximumAsciiStringLength ASCII characters not including the Null-terminator, + then ASSERT(). + + @param String A pointer to a Null-terminated ASCII string. + + @retval Value translated from String. + +**/ +UINT64 +EFIAPI +AsciiStrDecimalToUint64 ( + IN CONST CHAR8 *String + ) +{ + UINT64 Result; + + // + // ASSERT Strings is less long than PcdMaximumAsciiStringLength + // + ASSERT (AsciiStrSize (String) != 0); + + // + // Ignore the pad spaces (space or tab) + // + while ((*String == ' ') || (*String == '\t' )) { + String++; + } + + // + // Ignore leading Zeros after the spaces + // + while (*String == '0') { + String++; + } + + Result = 0; + + while (InternalAsciiIsDecimalDigitCharacter (*String)) { + // + // If the number represented by String overflows according + // to the range defined by UINTN, then ASSERT(). + // + ASSERT ((Result < QUOTIENT_MAX_UINT64_DIVIDED_BY_10) || + ((Result == QUOTIENT_MAX_UINT64_DIVIDED_BY_10) && + (*String - '0') <= REMAINDER_MAX_UINT64_DIVIDED_BY_10) + ); + + Result = MultU64x32 (Result, 10) + (*String - '0'); + String++; + } + + return Result; +} + +/** + Convert a Null-terminated ASCII hexadecimal string to a value of type UINTN. + + This function returns a value of type UINTN by interpreting the contents of + the ASCII string String as a hexadecimal number. The format of the input ASCII + string String is: + + [spaces][zeros][x][hexadecimal digits]. + + The valid hexadecimal digit character is in the range [0-9], [a-f] and [A-F]. + The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefix. If "x" + appears in the input string, it must be prefixed with at least one 0. The function + will ignore the pad space, which includes spaces or tab characters, before [zeros], + [x] or [hexadecimal digits]. The running zero before [x] or [hexadecimal digits] + will be ignored. Then, the decoding starts after [x] or the first valid hexadecimal + digit. Then, the function stops at the first character that is a not a valid + hexadecimal character or Null-terminator, whichever on comes first. + + If String has only pad spaces, then 0 is returned. + If String has no leading pad spaces, leading zeros or valid hexadecimal digits, then + 0 is returned. + + If the number represented by String overflows according to the range defined by UINTN, + then ASSERT(). + If String is NULL, then ASSERT(). + If PcdMaximumAsciiStringLength is not zero, + and String contains more than PcdMaximumAsciiStringLength ASCII characters not including + the Null-terminator, then ASSERT(). + + @param String A pointer to a Null-terminated ASCII string. + + @retval Value translated from String. + +**/ +UINTN +EFIAPI +AsciiStrHexToUintn ( + IN CONST CHAR8 *String + ) +{ + UINTN Result; + + // + // ASSERT Strings is less long than PcdMaximumAsciiStringLength + // + ASSERT (AsciiStrSize (String) != 0); + + // + // Ignore the pad spaces (space or tab) + // + while ((*String == ' ') || (*String == '\t' )) { + String++; + } + + // + // Ignore leading Zeros after the spaces + // + while (*String == '0') { + String++; + } + + if (InternalBaseLibAsciiToUpper (*String) == 'X') { + ASSERT (*(String - 1) == '0'); + if (*(String - 1) != '0') { + return 0; + } + // + // Skip the 'X' + // + String++; + } + + Result = 0; + + while (InternalAsciiIsHexaDecimalDigitCharacter (*String)) { + // + // If the Hex Number represented by String overflows according + // to the range defined by UINTN, then ASSERT(). + // + ASSERT ((Result < QUOTIENT_MAX_UINTN_DIVIDED_BY_16) || + ((Result == QUOTIENT_MAX_UINTN_DIVIDED_BY_16) && + (InternalAsciiHexCharToUintn (*String) <= REMAINDER_MAX_UINTN_DIVIDED_BY_16)) + ); + + Result = (Result << 4) + InternalAsciiHexCharToUintn (*String); + String++; + } + + return Result; +} + + +/** + Convert a Null-terminated ASCII hexadecimal string to a value of type UINT64. + + This function returns a value of type UINT64 by interpreting the contents of + the ASCII string String as a hexadecimal number. The format of the input ASCII + string String is: + + [spaces][zeros][x][hexadecimal digits]. + + The valid hexadecimal digit character is in the range [0-9], [a-f] and [A-F]. + The prefix "0x" is optional. Both "x" and "X" is allowed in "0x" prefix. If "x" + appears in the input string, it must be prefixed with at least one 0. The function + will ignore the pad space, which includes spaces or tab characters, before [zeros], + [x] or [hexadecimal digits]. The running zero before [x] or [hexadecimal digits] + will be ignored. Then, the decoding starts after [x] or the first valid hexadecimal + digit. Then, the function stops at the first character that is a not a valid + hexadecimal character or Null-terminator, whichever on comes first. + + If String has only pad spaces, then 0 is returned. + If String has no leading pad spaces, leading zeros or valid hexadecimal digits, then + 0 is returned. + + If the number represented by String overflows according to the range defined by UINT64, + then ASSERT(). + If String is NULL, then ASSERT(). + If PcdMaximumAsciiStringLength is not zero, + and String contains more than PcdMaximumAsciiStringLength ASCII characters not including + the Null-terminator, then ASSERT(). + + @param String A pointer to a Null-terminated ASCII string. + + @retval Value translated from String. + +**/ +UINT64 +EFIAPI +AsciiStrHexToUint64 ( + IN CONST CHAR8 *String + ) +{ + UINT64 Result; + + // + // ASSERT Strings is less long than PcdMaximumAsciiStringLength + // + ASSERT (AsciiStrSize (String) != 0); + + // + // Ignore the pad spaces (space or tab) and leading Zeros + // + // + // Ignore the pad spaces (space or tab) + // + while ((*String == ' ') || (*String == '\t' )) { + String++; + } + + // + // Ignore leading Zeros after the spaces + // + while (*String == '0') { + String++; + } + + if (InternalBaseLibAsciiToUpper (*String) == 'X') { + ASSERT (*(String - 1) == '0'); + if (*(String - 1) != '0') { + return 0; + } + // + // Skip the 'X' + // + String++; + } + + Result = 0; + + while (InternalAsciiIsHexaDecimalDigitCharacter (*String)) { + // + // If the Hex Number represented by String overflows according + // to the range defined by UINTN, then ASSERT(). + // + ASSERT ((Result < QUOTIENT_MAX_UINT64_DIVIDED_BY_16) || + ((Result == QUOTIENT_MAX_UINT64_DIVIDED_BY_16) && + (InternalAsciiHexCharToUintn (*String) <= REMAINDER_MAX_UINT64_DIVIDED_BY_16)) + ); + + Result = LShiftU64 (Result, 4); + Result = Result + InternalAsciiHexCharToUintn (*String); + String++; + } + + return Result; +} + + +/** + Convert one Null-terminated ASCII string to a Null-terminated + Unicode string and returns the Unicode string. + + This function converts the contents of the ASCII string Source to the Unicode + string Destination, and returns Destination. The function terminates the + Unicode string Destination by appending a Null-terminator character at the end. + The caller is responsible to make sure Destination points to a buffer with size + equal or greater than ((AsciiStrLen (Source) + 1) * sizeof (CHAR16)) in bytes. + + If Destination is NULL, then ASSERT(). + If Destination is not aligned on a 16-bit boundary, then ASSERT(). + If Source is NULL, then ASSERT(). + If Source and Destination overlap, then ASSERT(). + If PcdMaximumAsciiStringLength is not zero, and Source contains more than + PcdMaximumAsciiStringLength ASCII characters not including the Null-terminator, + then ASSERT(). + If PcdMaximumUnicodeStringLength is not zero, and Source contains more than + PcdMaximumUnicodeStringLength ASCII characters not including the + Null-terminator, then ASSERT(). + + @param Source A pointer to a Null-terminated ASCII string. + @param Destination A pointer to a Null-terminated Unicode string. + + @return Destination. + +**/ +CHAR16 * +EFIAPI +AsciiStrToUnicodeStr ( + IN CONST CHAR8 *Source, + OUT CHAR16 *Destination + ) +{ + CHAR16 *ReturnValue; + + ASSERT (Destination != NULL); + + // + // ASSERT Source is less long than PcdMaximumAsciiStringLength + // + ASSERT (AsciiStrSize (Source) != 0); + + // + // Source and Destination should not overlap + // + ASSERT ((UINTN) ((CHAR8 *) Destination - Source) > AsciiStrLen (Source)); + ASSERT ((UINTN) (Source - (CHAR8 *) Destination) > (AsciiStrLen (Source) * sizeof (CHAR16))); + + + ReturnValue = Destination; + while (*Source != '\0') { + *(Destination++) = (CHAR16) *(Source++); + } + // + // End the Destination with a NULL. + // + *Destination = '\0'; + + // + // ASSERT Original Destination is less long than PcdMaximumUnicodeStringLength + // + ASSERT (StrSize (ReturnValue) != 0); + + return ReturnValue; +} + +/** + Converts an 8-bit value to an 8-bit BCD value. + + Converts the 8-bit value specified by Value to BCD. The BCD value is + returned. + + If Value >= 100, then ASSERT(). + + @param Value The 8-bit value to convert to BCD. Range 0..99. + + @return The BCD value. + +**/ +UINT8 +EFIAPI +DecimalToBcd8 ( + IN UINT8 Value + ) +{ + ASSERT (Value < 100); + return (UINT8) (((Value / 10) << 4) | (Value % 10)); +} + +/** + Converts an 8-bit BCD value to an 8-bit value. + + Converts the 8-bit BCD value specified by Value to an 8-bit value. The 8-bit + value is returned. + + If Value >= 0xA0, then ASSERT(). + If (Value & 0x0F) >= 0x0A, then ASSERT(). + + @param Value The 8-bit BCD value to convert to an 8-bit value. + + @return The 8-bit value is returned. + +**/ +UINT8 +EFIAPI +BcdToDecimal8 ( + IN UINT8 Value + ) +{ + ASSERT (Value < 0xa0); + ASSERT ((Value & 0xf) < 0xa); + return (UINT8) ((Value >> 4) * 10 + (Value & 0xf)); +} diff --git a/UnixPkg/Library/UnixBaseLib/SwapBytes16.c b/UnixPkg/Library/UnixBaseLib/SwapBytes16.c new file mode 100644 index 0000000000..64a674a0cd --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/SwapBytes16.c @@ -0,0 +1,39 @@ +/** @file + Math worker functions. + + Copyright (c) 2006 - 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. + +**/ + + + + +#include "BaseLibInternals.h" + +/** + Switches the endianess of a 16-bit integer. + + This function swaps the bytes in a 16-bit unsigned value to switch the value + from little endian to big endian or vice versa. The byte swapped value is + returned. + + @param Value A 16-bit unsigned value. + + @return The byte swapped Value. + +**/ +UINT16 +EFIAPI +SwapBytes16 ( + IN UINT16 Value + ) +{ + return (UINT16) ((Value<< 8) | (Value>> 8)); +} diff --git a/UnixPkg/Library/UnixBaseLib/SwapBytes32.c b/UnixPkg/Library/UnixBaseLib/SwapBytes32.c new file mode 100644 index 0000000000..7e30d25132 --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/SwapBytes32.c @@ -0,0 +1,45 @@ +/** @file + Math worker functions. + + Copyright (c) 2006 - 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. + +**/ + + + + +#include "BaseLibInternals.h" + +/** + Switches the endianess of a 32-bit integer. + + This function swaps the bytes in a 32-bit unsigned value to switch the value + from little endian to big endian or vice versa. The byte swapped value is + returned. + + @param Value A 32-bit unsigned value. + + @return The byte swapped Value. + +**/ +UINT32 +EFIAPI +SwapBytes32 ( + IN UINT32 Value + ) +{ + UINT32 LowerBytes; + UINT32 HigherBytes; + + LowerBytes = (UINT32) SwapBytes16 ((UINT16) Value); + HigherBytes = (UINT32) SwapBytes16 ((UINT16) (Value >> 16)); + + return (LowerBytes << 16 | HigherBytes); +} diff --git a/UnixPkg/Library/UnixBaseLib/SwapBytes64.c b/UnixPkg/Library/UnixBaseLib/SwapBytes64.c new file mode 100644 index 0000000000..6a6ce8388f --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/SwapBytes64.c @@ -0,0 +1,39 @@ +/** @file + Math worker functions. + + Copyright (c) 2006 - 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. + +**/ + + + + +#include "BaseLibInternals.h" + +/** + Switches the endianess of a 64-bit integer. + + This function swaps the bytes in a 64-bit unsigned value to switch the value + from little endian to big endian or vice versa. The byte swapped value is + returned. + + @param Value A 64-bit unsigned value. + + @return The byte swapped Value. + +**/ +UINT64 +EFIAPI +SwapBytes64 ( + IN UINT64 Value + ) +{ + return InternalMathSwapBytes64 (Value); +} diff --git a/UnixPkg/Library/UnixBaseLib/SwitchStack.c b/UnixPkg/Library/UnixBaseLib/SwitchStack.c new file mode 100644 index 0000000000..36811175af --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/SwitchStack.c @@ -0,0 +1,76 @@ +/** @file + Switch Stack functions. + + Copyright (c) 2006 - 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. + +**/ + +#include "BaseLibInternals.h" + +/** + Transfers control to a function starting with a new stack. + + Transfers control to the function specified by EntryPoint using the + new stack specified by NewStack and passing in the parameters specified + by Context1 and Context2. Context1 and Context2 are optional and may + be NULL. The function EntryPoint must never return. This function + supports a variable number of arguments following the NewStack parameter. + These additional arguments are ignored on IA-32, x64, and EBC. + IPF CPUs expect one additional parameter of type VOID * that specifies + the new backing store pointer. + + If EntryPoint is NULL, then ASSERT(). + If NewStack is NULL, then ASSERT(). + + @param EntryPoint A pointer to function to call with the new stack. + @param Context1 A pointer to the context to pass into the EntryPoint + function. + @param Context2 A pointer to the context to pass into the EntryPoint + function. + @param NewStack A pointer to the new stack to use for the EntryPoint + function. + @param ... This variable argument list is ignored for IA32, x64, and EBC. + For IPF, this variable argument list is expected to contain + a single parameter of type VOID * that specifies the new backing + store pointer. + + +**/ +VOID +EFIAPI +SwitchStack ( + IN SWITCH_STACK_ENTRY_POINT EntryPoint, + IN VOID *Context1, OPTIONAL + IN VOID *Context2, OPTIONAL + IN VOID *NewStack, + ... + ) +{ + VA_LIST Marker; + + ASSERT (EntryPoint != NULL); + ASSERT (NewStack != NULL); + + // + // New stack must be aligned with CPU_STACK_ALIGNMENT + // + ASSERT (((UINTN)NewStack & (CPU_STACK_ALIGNMENT - 1)) == 0); + + VA_START (Marker, NewStack); + + InternalSwitchStack (EntryPoint, Context1, Context2, NewStack, Marker); + + VA_END (Marker); + + // + // InternalSwitchStack () will never return + // + ASSERT (FALSE); +} diff --git a/UnixPkg/Library/UnixBaseLib/Unaligned.c b/UnixPkg/Library/UnixBaseLib/Unaligned.c new file mode 100644 index 0000000000..68dafa6452 --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/Unaligned.c @@ -0,0 +1,222 @@ +/** @file + Unaligned access functions of BaseLib. + + 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. + +**/ + + +#include "BaseLibInternals.h" + + +/** + Reads a 16-bit value from memory that may be unaligned. + + This function returns the 16-bit value pointed to by Buffer. The function + guarantees that the read operation does not produce an alignment fault. + + If the Buffer is NULL, then ASSERT(). + + @param Buffer A pointer to a 16-bit value that may be unaligned. + + @return The 16-bit value read from Buffer. + +**/ +UINT16 +EFIAPI +ReadUnaligned16 ( + IN CONST UINT16 *Buffer + ) +{ + ASSERT (Buffer != NULL); + + return *Buffer; +} + +/** + Writes a 16-bit value to memory that may be unaligned. + + This function writes the 16-bit value specified by Value to Buffer. Value is + returned. The function guarantees that the write operation does not produce + an alignment fault. + + If the Buffer is NULL, then ASSERT(). + + @param Buffer A pointer to a 16-bit value that may be unaligned. + @param Value 16-bit value to write to Buffer. + + @return The 16-bit value to write to Buffer. + +**/ +UINT16 +EFIAPI +WriteUnaligned16 ( + OUT UINT16 *Buffer, + IN UINT16 Value + ) +{ + ASSERT (Buffer != NULL); + + return *Buffer = Value; +} + +/** + Reads a 24-bit value from memory that may be unaligned. + + This function returns the 24-bit value pointed to by Buffer. The function + guarantees that the read operation does not produce an alignment fault. + + If the Buffer is NULL, then ASSERT(). + + @param Buffer A pointer to a 24-bit value that may be unaligned. + + @return The 24-bit value read from Buffer. + +**/ +UINT32 +EFIAPI +ReadUnaligned24 ( + IN CONST UINT32 *Buffer + ) +{ + ASSERT (Buffer != NULL); + + return *Buffer & 0xffffff; +} + +/** + Writes a 24-bit value to memory that may be unaligned. + + This function writes the 24-bit value specified by Value to Buffer. Value is + returned. The function guarantees that the write operation does not produce + an alignment fault. + + If the Buffer is NULL, then ASSERT(). + + @param Buffer A pointer to a 24-bit value that may be unaligned. + @param Value 24-bit value to write to Buffer. + + @return The 24-bit value to write to Buffer. + +**/ +UINT32 +EFIAPI +WriteUnaligned24 ( + OUT UINT32 *Buffer, + IN UINT32 Value + ) +{ + ASSERT (Buffer != NULL); + + *Buffer = BitFieldWrite32 (*Buffer, 0, 23, Value); + return Value; +} + +/** + Reads a 32-bit value from memory that may be unaligned. + + This function returns the 32-bit value pointed to by Buffer. The function + guarantees that the read operation does not produce an alignment fault. + + If the Buffer is NULL, then ASSERT(). + + @param Buffer A pointer to a 32-bit value that may be unaligned. + + @return The 32-bit value read from Buffer. + +**/ +UINT32 +EFIAPI +ReadUnaligned32 ( + IN CONST UINT32 *Buffer + ) +{ + ASSERT (Buffer != NULL); + + return *Buffer; +} + +/** + Writes a 32-bit value to memory that may be unaligned. + + This function writes the 32-bit value specified by Value to Buffer. Value is + returned. The function guarantees that the write operation does not produce + an alignment fault. + + If the Buffer is NULL, then ASSERT(). + + @param Buffer A pointer to a 32-bit value that may be unaligned. + @param Value The 32-bit value to write to Buffer. + + @return The 32-bit value to write to Buffer. + +**/ +UINT32 +EFIAPI +WriteUnaligned32 ( + OUT UINT32 *Buffer, + IN UINT32 Value + ) +{ + ASSERT (Buffer != NULL); + + return *Buffer = Value; +} + +/** + Reads a 64-bit value from memory that may be unaligned. + + This function returns the 64-bit value pointed to by Buffer. The function + guarantees that the read operation does not produce an alignment fault. + + If the Buffer is NULL, then ASSERT(). + + @param Buffer A pointer to a 64-bit value that may be unaligned. + + @return The 64-bit value read from Buffer. + +**/ +UINT64 +EFIAPI +ReadUnaligned64 ( + IN CONST UINT64 *Buffer + ) +{ + ASSERT (Buffer != NULL); + + return *Buffer; +} + +/** + Writes a 64-bit value to memory that may be unaligned. + + This function writes the 64-bit value specified by Value to Buffer. Value is + returned. The function guarantees that the write operation does not produce + an alignment fault. + + If the Buffer is NULL, then ASSERT(). + + @param Buffer A pointer to a 64-bit value that may be unaligned. + @param Value The 64-bit value to write to Buffer. + + @return The 64-bit value to write to Buffer. + +**/ +UINT64 +EFIAPI +WriteUnaligned64 ( + OUT UINT64 *Buffer, + IN UINT64 Value + ) +{ + ASSERT (Buffer != NULL); + + return *Buffer = Value; +} diff --git a/UnixPkg/Library/UnixBaseLib/UnixBaseLib.inf b/UnixPkg/Library/UnixBaseLib/UnixBaseLib.inf new file mode 100644 index 0000000000..957fd89082 --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/UnixBaseLib.inf @@ -0,0 +1,201 @@ +## @file +# Base Library implementation for X64 UnixPkg. X64 code writes CR3 so to +# not change MdeModulePkg DxeIpl we need a UnixPkg copy of the BaseLib. +# +# Currently I'm debugging UnixPkg with SVR V ABI so there are some +# temp changes for that too. +# +# +# Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.
+# Portions 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. +# +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = BaseLib + FILE_GUID = 27d67720-ea68-48ae-93da-a3a074c90e30 + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = BaseLib + +# +# VALID_ARCHITECTURES = IA32 X64 IPF EBC ARM +# + +[Sources] + CheckSum.c + SwitchStack.c + SwapBytes64.c + SwapBytes32.c + SwapBytes16.c + LongJump.c + SetJump.c + RShiftU64.c + RRotU64.c + RRotU32.c + MultU64x64.c + MultU64x32.c + MultS64x64.c + ModU64x32.c + LShiftU64.c + LRotU64.c + LRotU32.c + LowBitSet64.c + LowBitSet32.c + HighBitSet64.c + HighBitSet32.c + GetPowerOfTwo64.c + GetPowerOfTwo32.c + DivU64x64Remainder.c + DivU64x32Remainder.c + DivU64x32.c + DivS64x64Remainder.c + ARShiftU64.c + BitField.c + CpuDeadLoop.c + Cpu.c + LinkedList.c + String.c + BaseLibInternals.h + + +[Sources.X64] + X64/Thunk16.asm + X64/CpuPause.asm + X64/EnableDisableInterrupts.asm + X64/DisableInterrupts.asm + X64/EnableInterrupts.asm + X64/FlushCacheLine.asm + X64/Invd.asm + X64/Wbinvd.asm + X64/DisablePaging64.asm + X64/Mwait.asm + X64/Monitor.asm + X64/ReadPmc.asm + X64/ReadTsc.asm + X64/WriteMm7.asm + X64/WriteMm6.asm + X64/WriteMm5.asm + X64/WriteMm4.asm + X64/WriteMm3.asm + X64/WriteMm2.asm + X64/WriteMm1.asm + X64/WriteMm0.asm + X64/ReadMm7.asm + X64/ReadMm6.asm + X64/ReadMm5.asm + X64/ReadMm4.asm + X64/ReadMm3.asm + X64/ReadMm2.asm + X64/ReadMm1.asm + X64/ReadMm0.asm + X64/FxRestore.asm + X64/FxSave.asm + X64/WriteLdtr.asm + X64/ReadLdtr.asm + X64/WriteIdtr.asm + X64/ReadIdtr.asm + X64/WriteGdtr.asm + X64/ReadGdtr.asm + X64/ReadTr.asm + X64/ReadSs.asm + X64/ReadGs.asm + X64/ReadFs.asm + X64/ReadEs.asm + X64/ReadDs.asm + X64/ReadCs.asm + X64/WriteDr7.asm + X64/WriteDr6.asm + X64/WriteDr5.asm + X64/WriteDr4.asm + X64/WriteDr3.asm + X64/WriteDr2.asm + X64/WriteDr1.asm + X64/WriteDr0.asm + X64/ReadDr7.asm + X64/ReadDr6.asm + X64/ReadDr5.asm + X64/ReadDr4.asm + X64/ReadDr3.asm + X64/ReadDr2.asm + X64/ReadDr1.asm + X64/ReadDr0.asm + X64/WriteCr4.asm + X64/WriteCr3.asm + X64/WriteCr2.asm + X64/WriteCr0.asm + X64/ReadCr4.asm + X64/ReadCr3.asm + X64/ReadCr2.asm + X64/ReadCr0.asm + X64/ReadEflags.asm + X64/CpuIdEx.asm + X64/CpuId.asm + X64/LongJump.asm + X64/SetJump.asm + X64/SwitchStack.asm + X64/EnableCache.asm + X64/DisableCache.asm + + X64/CpuBreakpoint.c | MSFT + X64/WriteMsr64.c | MSFT + X64/ReadMsr64.c | MSFT + + X64/CpuBreakpoint.asm | INTEL + X64/WriteMsr64.asm | INTEL + X64/ReadMsr64.asm | INTEL + + X64/Non-existing.c + Math64.c + Unaligned.c + X86WriteIdtr.c + X86WriteGdtr.c + X86Thunk.c + X86ReadIdtr.c + X86ReadGdtr.c + X86Msr.c + X86MemoryFence.c | MSFT + X86MemoryFence.c | INTEL + X86GetInterruptState.c + X86FxSave.c + X86FxRestore.c + X86EnablePaging64.c + X86EnablePaging32.c + X86DisablePaging64.c + X86DisablePaging32.c + X64/GccInline.c | GCC + X64/Thunk16.S | GCC + X64/SwitchStack.S | GCC + X64/SetJump.S | GCC + X64/LongJump.S | GCC + X64/EnableDisableInterrupts.S | GCC + X64/DisablePaging64.S | GCC + X64/CpuId.S | GCC + X64/CpuIdEx.S | GCC + X64/EnableCache.S | GCC + X64/DisableCache.S | GCC + ChkStkGcc.c | GCC + + +[Packages] + MdePkg/MdePkg.dec + +[LibraryClasses] + PcdLib + DebugLib + BaseMemoryLib + +[Pcd] + gEfiMdePkgTokenSpaceGuid.PcdMaximumLinkedListLength + gEfiMdePkgTokenSpaceGuid.PcdMaximumAsciiStringLength + gEfiMdePkgTokenSpaceGuid.PcdMaximumUnicodeStringLength + gEfiMdePkgTokenSpaceGuid.PcdVerifyNodeInList diff --git a/UnixPkg/Library/UnixBaseLib/X64/CpuBreakpoint.S b/UnixPkg/Library/UnixBaseLib/X64/CpuBreakpoint.S new file mode 100644 index 0000000000..51cf9c0784 --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/X64/CpuBreakpoint.S @@ -0,0 +1,25 @@ +#------------------------------------------------------------------------------ +# +# Copyright (c) 2006 - 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. +# +# Module Name: +# +# CpuBreakpoint.S +# +# Abstract: +# +# Implementation of CpuBreakpoint() on x86_64 +# +#------------------------------------------------------------------------------ + +ASM_GLOBAL ASM_PFX(CpuBreakpoint) +ASM_PFX(CpuBreakpoint): + int $0x3 + ret diff --git a/UnixPkg/Library/UnixBaseLib/X64/CpuBreakpoint.asm b/UnixPkg/Library/UnixBaseLib/X64/CpuBreakpoint.asm new file mode 100644 index 0000000000..25dd9b48e8 --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/X64/CpuBreakpoint.asm @@ -0,0 +1,37 @@ +;------------------------------------------------------------------------------ ; +; 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: +; +; CpuBreakpoint.Asm +; +; Abstract: +; +; CpuBreakpoint function +; +; Notes: +; +;------------------------------------------------------------------------------ + + .code + +;------------------------------------------------------------------------------ +; VOID +; EFIAPI +; CpuBreakpoint ( +; VOID +; ); +;------------------------------------------------------------------------------ +CpuBreakpoint PROC + int 3 + ret +CpuBreakpoint ENDP + + END diff --git a/UnixPkg/Library/UnixBaseLib/X64/CpuBreakpoint.c b/UnixPkg/Library/UnixBaseLib/X64/CpuBreakpoint.c new file mode 100644 index 0000000000..d654f84571 --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/X64/CpuBreakpoint.c @@ -0,0 +1,39 @@ +/** @file + CpuBreakpoint function. + + Copyright (c) 2006 - 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. + +**/ + + +/** + Microsoft Visual Studio 7.1 Function Prototypes for I/O Intrinsics. +**/ + +void __debugbreak (); + +#pragma intrinsic(__debugbreak) + +/** + Generates a breakpoint on the CPU. + + Generates a breakpoint on the CPU. The breakpoint must be implemented such + that code can resume normal execution after the breakpoint. + +**/ +VOID +EFIAPI +CpuBreakpoint ( + VOID + ) +{ + __debugbreak (); +} + diff --git a/UnixPkg/Library/UnixBaseLib/X64/CpuId.S b/UnixPkg/Library/UnixBaseLib/X64/CpuId.S new file mode 100644 index 0000000000..c3d2597205 --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/X64/CpuId.S @@ -0,0 +1,60 @@ +#------------------------------------------------------------------------------ +# +# Copyright (c) 2006 - 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. +# +# Module Name: +# +# CpuId.S +# +# Abstract: +# +# AsmCpuid function +# +# Notes: +# +#------------------------------------------------------------------------------ + +#------------------------------------------------------------------------------ +# VOID +# EFIAPI +# AsmCpuid ( +# IN UINT32 RegisterInEax, +# OUT UINT32 *RegisterOutEax OPTIONAL, +# OUT UINT32 *RegisterOutEbx OPTIONAL, +# OUT UINT32 *RegisterOutEcx OPTIONAL, +# OUT UINT32 *RegisterOutEdx OPTIONAL +# ) +#------------------------------------------------------------------------------ +ASM_GLOBAL ASM_PFX(AsmCpuid) +ASM_PFX(AsmCpuid): + push %rbx + mov %ecx, %eax + push %rax # save Index on stack + push %rdx + cpuid + test %r9, %r9 + jz L1 + mov %ecx, (%r9) +L1: + pop %rcx + jrcxz L2 + mov %eax, (%rcx) +L2: + mov %r8, %rcx + jrcxz L3 + mov %ebx, (%rcx) +L3: + mov 0x38(%rsp), %rcx + jrcxz L4 + mov %edx, (%rcx) +L4: + pop %rax # restore Index to rax as return value + pop %rbx + ret diff --git a/UnixPkg/Library/UnixBaseLib/X64/CpuId.asm b/UnixPkg/Library/UnixBaseLib/X64/CpuId.asm new file mode 100644 index 0000000000..c6182c1611 --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/X64/CpuId.asm @@ -0,0 +1,62 @@ +;------------------------------------------------------------------------------ +; +; Copyright (c) 2006 - 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. +; +; Module Name: +; +; CpuId.Asm +; +; Abstract: +; +; AsmCpuid function +; +; Notes: +; +;------------------------------------------------------------------------------ + + .code + +;------------------------------------------------------------------------------ +; VOID +; EFIAPI +; AsmCpuid ( +; IN UINT32 RegisterInEax, +; OUT UINT32 *RegisterOutEax OPTIONAL, +; OUT UINT32 *RegisterOutEbx OPTIONAL, +; OUT UINT32 *RegisterOutEcx OPTIONAL, +; OUT UINT32 *RegisterOutEdx OPTIONAL +; ) +;------------------------------------------------------------------------------ +AsmCpuid PROC USES rbx + mov eax, ecx + push rax ; save Index on stack + push rdx + cpuid + test r9, r9 + jz @F + mov [r9], ecx +@@: + pop rcx + jrcxz @F + mov [rcx], eax +@@: + mov rcx, r8 + jrcxz @F + mov [rcx], ebx +@@: + mov rcx, [rsp + 38h] + jrcxz @F + mov [rcx], edx +@@: + pop rax ; restore Index to rax as return value + ret +AsmCpuid ENDP + + END diff --git a/UnixPkg/Library/UnixBaseLib/X64/CpuIdEx.S b/UnixPkg/Library/UnixBaseLib/X64/CpuIdEx.S new file mode 100644 index 0000000000..d47f53c84c --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/X64/CpuIdEx.S @@ -0,0 +1,62 @@ +#------------------------------------------------------------------------------ +# +# Copyright (c) 2006 - 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. +# +# Module Name: +# +# CpuIdEx.S +# +# Abstract: +# +# AsmCpuidEx function +# +# Notes: +# +#------------------------------------------------------------------------------ + +#------------------------------------------------------------------------------ +# UINT32 +# EFIAPI +# AsmCpuidEx ( +# IN UINT32 RegisterInEax, +# IN UINT32 RegisterInEcx, +# OUT UINT32 *RegisterOutEax OPTIONAL, +# OUT UINT32 *RegisterOutEbx OPTIONAL, +# OUT UINT32 *RegisterOutEcx OPTIONAL, +# OUT UINT32 *RegisterOutEdx OPTIONAL +# ) +#------------------------------------------------------------------------------ +ASM_GLOBAL ASM_PFX(AsmCpuidEx) +ASM_PFX(AsmCpuidEx): + push %rbx + movl %ecx,%eax + movl %edx,%ecx + push %rax # save Index on stack + cpuid + mov 0x38(%rsp), %r10 + test %r10, %r10 + jz L1 + mov %ecx,(%r10) +L1: + mov %r8, %rcx + jrcxz L2 + movl %eax,(%rcx) +L2: + mov %r9, %rcx + jrcxz L3 + mov %ebx, (%rcx) +L3: + mov 0x40(%rsp), %rcx + jrcxz L4 + mov %edx, (%rcx) +L4: + pop %rax # restore Index to rax as return value + pop %rbx + ret diff --git a/UnixPkg/Library/UnixBaseLib/X64/CpuIdEx.asm b/UnixPkg/Library/UnixBaseLib/X64/CpuIdEx.asm new file mode 100644 index 0000000000..b41ba8e2fe --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/X64/CpuIdEx.asm @@ -0,0 +1,64 @@ +;------------------------------------------------------------------------------ +; +; Copyright (c) 2006 - 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. +; +; Module Name: +; +; CpuIdEx.Asm +; +; Abstract: +; +; AsmCpuidEx function +; +; Notes: +; +;------------------------------------------------------------------------------ + + .code + +;------------------------------------------------------------------------------ +; UINT32 +; EFIAPI +; AsmCpuidEx ( +; IN UINT32 RegisterInEax, +; IN UINT32 RegisterInEcx, +; OUT UINT32 *RegisterOutEax OPTIONAL, +; OUT UINT32 *RegisterOutEbx OPTIONAL, +; OUT UINT32 *RegisterOutEcx OPTIONAL, +; OUT UINT32 *RegisterOutEdx OPTIONAL +; ) +;------------------------------------------------------------------------------ +AsmCpuidEx PROC USES rbx + mov eax, ecx + mov ecx, edx + push rax ; save Index on stack + cpuid + mov r10, [rsp + 38h] + test r10, r10 + jz @F + mov [r10], ecx +@@: + mov rcx, r8 + jrcxz @F + mov [rcx], eax +@@: + mov rcx, r9 + jrcxz @F + mov [rcx], ebx +@@: + mov rcx, [rsp + 40h] + jrcxz @F + mov [rcx], edx +@@: + pop rax ; restore Index to rax as return value + ret +AsmCpuidEx ENDP + + END diff --git a/UnixPkg/Library/UnixBaseLib/X64/CpuPause.asm b/UnixPkg/Library/UnixBaseLib/X64/CpuPause.asm new file mode 100644 index 0000000000..a84465fe0a --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/X64/CpuPause.asm @@ -0,0 +1,37 @@ +;------------------------------------------------------------------------------ ; +; 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: +; +; CpuPause.Asm +; +; Abstract: +; +; CpuPause function +; +; Notes: +; +;------------------------------------------------------------------------------ + + .code + +;------------------------------------------------------------------------------ +; VOID +; EFIAPI +; CpuPause ( +; VOID +; ); +;------------------------------------------------------------------------------ +CpuPause PROC + pause + ret +CpuPause ENDP + + END diff --git a/UnixPkg/Library/UnixBaseLib/X64/DisableCache.S b/UnixPkg/Library/UnixBaseLib/X64/DisableCache.S new file mode 100644 index 0000000000..970f2f3618 --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/X64/DisableCache.S @@ -0,0 +1,39 @@ +#------------------------------------------------------------------------------ +# +# Copyright (c) 2006 - 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. +# +# Module Name: +# +# DisableCache.S +# +# Abstract: +# +# Set the CD bit of CR0 to 1, clear the NW bit of CR0 to 0, and flush all caches with a +# WBINVD instruction. +# +# Notes: +# +#------------------------------------------------------------------------------ + +#------------------------------------------------------------------------------ +# VOID +# EFIAPI +# AsmDisableCache ( +# VOID +# ); +#------------------------------------------------------------------------------ +ASM_GLOBAL ASM_PFX(AsmDisableCache) +ASM_PFX(AsmDisableCache): + movq %cr0, %rax + btsq $30, %rax + btrq $29, %rax + movq %rax, %cr0 + wbinvd + ret diff --git a/UnixPkg/Library/UnixBaseLib/X64/DisableCache.asm b/UnixPkg/Library/UnixBaseLib/X64/DisableCache.asm new file mode 100644 index 0000000000..9fd5bd79bd --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/X64/DisableCache.asm @@ -0,0 +1,43 @@ +;------------------------------------------------------------------------------ +; +; Copyright (c) 2006 - 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. +; +; Module Name: +; +; DisableCache.Asm +; +; Abstract: +; +; Set the CD bit of CR0 to 1, clear the NW bit of CR0 to 0, and flush all caches with a +; WBINVD instruction. +; +; Notes: +; +;------------------------------------------------------------------------------ + + .code + +;------------------------------------------------------------------------------ +; VOID +; EFIAPI +; AsmDisableCache ( +; VOID +; ); +;------------------------------------------------------------------------------ +AsmDisableCache PROC + mov rax, cr0 + bts rax, 30 + btr rax, 29 + mov cr0, rax + wbinvd + ret +AsmDisableCache ENDP + + END diff --git a/UnixPkg/Library/UnixBaseLib/X64/DisableInterrupts.asm b/UnixPkg/Library/UnixBaseLib/X64/DisableInterrupts.asm new file mode 100644 index 0000000000..4e54e0d889 --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/X64/DisableInterrupts.asm @@ -0,0 +1,38 @@ +;------------------------------------------------------------------------------ +; +; 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: +; +; DisableInterrupts.Asm +; +; Abstract: +; +; DisableInterrupts function +; +; Notes: +; +;------------------------------------------------------------------------------ + + .code + +;------------------------------------------------------------------------------ +; VOID +; EFIAPI +; DisableInterrupts ( +; VOID +; ); +;------------------------------------------------------------------------------ +DisableInterrupts PROC + cli + ret +DisableInterrupts ENDP + + END diff --git a/UnixPkg/Library/UnixBaseLib/X64/DisablePaging64.S b/UnixPkg/Library/UnixBaseLib/X64/DisablePaging64.S new file mode 100644 index 0000000000..676e9e175a --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/X64/DisablePaging64.S @@ -0,0 +1,82 @@ +#------------------------------------------------------------------------------ +# +# 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: +# +# DisablePaging64.S +# +# Abstract: +# +# AsmDisablePaging64 function +# +# Notes: +# +#------------------------------------------------------------------------------ + + + +#------------------------------------------------------------------------------ +# VOID +# EFIAPI +# InternalX86DisablePaging64 ( +# IN UINT16 Cs, +# IN UINT32 EntryPoint, +# IN UINT32 Context1, OPTIONAL +# IN UINT32 Context2, OPTIONAL +# IN UINT32 NewStack +# ); +#------------------------------------------------------------------------------ + +ASM_GLOBAL ASM_PFX(InternalX86DisablePaging64) +ASM_PFX(InternalX86DisablePaging64): + cli + lea L1(%rip), %rsi # rsi <- The start address of transition code + mov 0x28(%rsp), %edi # rdi <- New stack + lea _mTransitionEnd(%rip), %rax # rax <- end of transition code + sub %rsi, %rax # rax <- The size of transition piece code + add $4, %rax # round rax up to the next 4 byte boundary + and $0xfc, %al + sub %rax, %rdi # rdi <- use stack to hold transition code + mov %edi, %r10d # r10 <- The start address of transicition code below 4G + push %rcx # save rcx to stack + mov %rax, %rcx # rcx <- The size of transition piece code + rep + movsb # copy transition code to (new stack - 64byte) below 4G + pop %rcx # restore rcx + + mov %r8d, %esi + mov %r9d, %edi + mov %r10d, %eax + sub $4, %eax + push %rcx # push Cs to stack + push %r10 # push address of transition code on stack + .byte 0x48, 0xcb # retq: Use far return to load CS register from stack + # (Use raw byte code since some GNU assemblers generates incorrect code for "retq") +L1: + mov %eax,%esp # set up new stack + mov %cr0,%rax + btr $0x1f,%eax # clear CR0.PG + mov %rax,%cr0 # disable paging + + mov %edx,%ebx # save EntryPoint to ebx, for rdmsr will overwrite edx + mov $0xc0000080,%ecx + rdmsr + and $0xfe,%ah # clear LME + wrmsr + mov %cr4,%rax + and $0xdf,%al # clear PAE + mov %rax,%cr4 + push %rdi # push Context2 + push %rsi # push Context1 + callq *%rbx # transfer control to EntryPoint + jmp . # no one should get here + +_mTransitionEnd : diff --git a/UnixPkg/Library/UnixBaseLib/X64/DisablePaging64.asm b/UnixPkg/Library/UnixBaseLib/X64/DisablePaging64.asm new file mode 100644 index 0000000000..32dcd5aa1f --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/X64/DisablePaging64.asm @@ -0,0 +1,84 @@ +;------------------------------------------------------------------------------ +; +; Copyright (c) 2006 - 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. +; +; Module Name: +; +; DisablePaging64.Asm +; +; Abstract: +; +; AsmDisablePaging64 function +; +; Notes: +; +;------------------------------------------------------------------------------ + + .code + +;------------------------------------------------------------------------------ +; VOID +; EFIAPI +; InternalX86DisablePaging64 ( +; IN UINT16 Cs, +; IN UINT32 EntryPoint, +; IN UINT32 Context1, OPTIONAL +; IN UINT32 Context2, OPTIONAL +; IN UINT32 NewStack +; ); +;------------------------------------------------------------------------------ +InternalX86DisablePaging64 PROC + cli + lea rsi, @F ; rsi <- The start address of transition code + mov edi, [rsp + 28h] ; rdi <- New stack + lea rax, mTransitionEnd ; rax <- end of transition code + sub rax, rsi ; rax <- The size of transition piece code + add rax, 4 ; Round RAX up to the next 4 byte boundary + and al, 0fch + sub rdi, rax ; rdi <- Use stack to hold transition code + mov r10d, edi ; r10 <- The start address of transicition code below 4G + push rcx ; save rcx to stack + mov rcx, rax ; rcx <- The size of transition piece code + rep movsb ; copy transition code to top of new stack which must be below 4GB + pop rcx ; restore rcx + + mov esi, r8d + mov edi, r9d + mov eax, r10d ; eax <- start of the transition code on the stack + sub eax, 4 ; eax <- One slot below transition code on the stack + push rcx ; push Cs to stack + push r10 ; push address of tansition code on stack + DB 48h ; prefix to composite "retq" with next "retf" + retf ; Use far return to load CS register from stack + +; Start of transition code +@@: + mov esp, eax ; set up new stack + mov rax, cr0 + btr eax, 31 ; Clear CR0.PG + mov cr0, rax ; disable paging and caches + + mov ebx, edx ; save EntryPoint to rbx, for rdmsr will overwrite rdx + mov ecx, 0c0000080h + rdmsr + and ah, NOT 1 ; clear LME + wrmsr + mov rax, cr4 + and al, NOT (1 SHL 5) ; clear PAE + mov cr4, rax + push rdi ; push Context2 + push rsi ; push Context1 + call rbx ; transfer control to EntryPoint + hlt ; no one should get here +InternalX86DisablePaging64 ENDP + +mTransitionEnd LABEL BYTE + + END diff --git a/UnixPkg/Library/UnixBaseLib/X64/EnableCache.S b/UnixPkg/Library/UnixBaseLib/X64/EnableCache.S new file mode 100644 index 0000000000..9d739603c9 --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/X64/EnableCache.S @@ -0,0 +1,39 @@ +#------------------------------------------------------------------------------ +# +# Copyright (c) 2006 - 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. +# +# Module Name: +# +# EnableCache.S +# +# Abstract: +# +# Flush all caches with a WBINVD instruction, clear the CD bit of CR0 to 0, and clear +# the NW bit of CR0 to 0 +# +# Notes: +# +#------------------------------------------------------------------------------ + +#------------------------------------------------------------------------------ +# VOID +# EFIAPI +# AsmEnableCache ( +# VOID +# ); +#------------------------------------------------------------------------------ +ASM_GLOBAL ASM_PFX(AsmEnableCache) +ASM_PFX(AsmEnableCache): + wbinvd + movq %cr0, %rax + btrq $30, %rax + btrq $29, %rax + movq %rax, %cr0 + ret diff --git a/UnixPkg/Library/UnixBaseLib/X64/EnableCache.asm b/UnixPkg/Library/UnixBaseLib/X64/EnableCache.asm new file mode 100644 index 0000000000..88b71d706f --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/X64/EnableCache.asm @@ -0,0 +1,43 @@ +;------------------------------------------------------------------------------ +; +; Copyright (c) 2006 - 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. +; +; Module Name: +; +; EnableCache.Asm +; +; Abstract: +; +; Flush all caches with a WBINVD instruction, clear the CD bit of CR0 to 0, and clear +; the NW bit of CR0 to 0 +; +; Notes: +; +;------------------------------------------------------------------------------ + + .code + +;------------------------------------------------------------------------------ +; VOID +; EFIAPI +; AsmEnableCache ( +; VOID +; ); +;------------------------------------------------------------------------------ +AsmEnableCache PROC + wbinvd + mov rax, cr0 + btr rax, 29 + btr rax, 30 + mov cr0, rax + ret +AsmEnableCache ENDP + + END diff --git a/UnixPkg/Library/UnixBaseLib/X64/EnableDisableInterrupts.S b/UnixPkg/Library/UnixBaseLib/X64/EnableDisableInterrupts.S new file mode 100644 index 0000000000..f2ff61ecfd --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/X64/EnableDisableInterrupts.S @@ -0,0 +1,36 @@ +#------------------------------------------------------------------------------ +# +# 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: +# +# EnableDisableInterrupts.S +# +# Abstract: +# +# EnableDisableInterrupts function +# +# Notes: +# +#------------------------------------------------------------------------------ + + +#------------------------------------------------------------------------------ +# VOID +# EFIAPI +# EnableDisableInterrupts ( +# VOID +# ); +#------------------------------------------------------------------------------ +ASM_GLOBAL ASM_PFX(EnableDisableInterrupts) +ASM_PFX(EnableDisableInterrupts): + sti + cli + ret diff --git a/UnixPkg/Library/UnixBaseLib/X64/EnableDisableInterrupts.asm b/UnixPkg/Library/UnixBaseLib/X64/EnableDisableInterrupts.asm new file mode 100644 index 0000000000..f6b2d9c97a --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/X64/EnableDisableInterrupts.asm @@ -0,0 +1,39 @@ +;------------------------------------------------------------------------------ +; +; 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: +; +; EnableDisableInterrupts.Asm +; +; Abstract: +; +; EnableDisableInterrupts function +; +; Notes: +; +;------------------------------------------------------------------------------ + + .code + +;------------------------------------------------------------------------------ +; VOID +; EFIAPI +; EnableDisableInterrupts ( +; VOID +; ); +;------------------------------------------------------------------------------ +EnableDisableInterrupts PROC + sti + cli + ret +EnableDisableInterrupts ENDP + + END diff --git a/UnixPkg/Library/UnixBaseLib/X64/EnableInterrupts.asm b/UnixPkg/Library/UnixBaseLib/X64/EnableInterrupts.asm new file mode 100644 index 0000000000..e776c27c4b --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/X64/EnableInterrupts.asm @@ -0,0 +1,38 @@ +;------------------------------------------------------------------------------ +; +; 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: +; +; EnableInterrupts.Asm +; +; Abstract: +; +; EnableInterrupts function +; +; Notes: +; +;------------------------------------------------------------------------------ + + .code + +;------------------------------------------------------------------------------ +; VOID +; EFIAPI +; EnableInterrupts ( +; VOID +; ); +;------------------------------------------------------------------------------ +EnableInterrupts PROC + sti + ret +EnableInterrupts ENDP + + END diff --git a/UnixPkg/Library/UnixBaseLib/X64/FlushCacheLine.asm b/UnixPkg/Library/UnixBaseLib/X64/FlushCacheLine.asm new file mode 100644 index 0000000000..e30f9a90b9 --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/X64/FlushCacheLine.asm @@ -0,0 +1,39 @@ +;------------------------------------------------------------------------------ +; +; 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: +; +; FlushCacheLine.Asm +; +; Abstract: +; +; AsmFlushCacheLine function +; +; Notes: +; +;------------------------------------------------------------------------------ + + .code + +;------------------------------------------------------------------------------ +; VOID * +; EFIAPI +; AsmFlushCacheLine ( +; IN VOID *LinearAddress +; ); +;------------------------------------------------------------------------------ +AsmFlushCacheLine PROC + clflush [rcx] + mov rax, rcx + ret +AsmFlushCacheLine ENDP + + END diff --git a/UnixPkg/Library/UnixBaseLib/X64/FxRestore.asm b/UnixPkg/Library/UnixBaseLib/X64/FxRestore.asm new file mode 100644 index 0000000000..8496331ac5 --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/X64/FxRestore.asm @@ -0,0 +1,38 @@ +;------------------------------------------------------------------------------ +; +; 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: +; +; FxRestore.Asm +; +; Abstract: +; +; AsmFxRestore function +; +; Notes: +; +;------------------------------------------------------------------------------ + + .code + +;------------------------------------------------------------------------------ +; VOID +; EFIAPI +; InternalX86FxRestore ( +; IN CONST IA32_FX_BUFFER *Buffer +; ); +;------------------------------------------------------------------------------ +InternalX86FxRestore PROC + fxrstor [rcx] + ret +InternalX86FxRestore ENDP + + END diff --git a/UnixPkg/Library/UnixBaseLib/X64/FxSave.asm b/UnixPkg/Library/UnixBaseLib/X64/FxSave.asm new file mode 100644 index 0000000000..d41e9351b3 --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/X64/FxSave.asm @@ -0,0 +1,38 @@ +;------------------------------------------------------------------------------ +; +; 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: +; +; FxSave.Asm +; +; Abstract: +; +; AsmFxSave function +; +; Notes: +; +;------------------------------------------------------------------------------ + + .code + +;------------------------------------------------------------------------------ +; VOID +; EFIAPI +; InternalX86FxSave ( +; OUT IA32_FX_BUFFER *Buffer +; ); +;------------------------------------------------------------------------------ +InternalX86FxSave PROC + fxsave [rcx] + ret +InternalX86FxSave ENDP + + END diff --git a/UnixPkg/Library/UnixBaseLib/X64/GccInline.c b/UnixPkg/Library/UnixBaseLib/X64/GccInline.c new file mode 100644 index 0000000000..731172aacc --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/X64/GccInline.c @@ -0,0 +1,1801 @@ +/** @file + GCC inline implementation of BaseLib processor specific functions. + + Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.
+ Portions 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 "BaseLibInternals.h" + + + + +/** + Used to serialize load and store operations. + + All loads and stores that proceed calls to this function are guaranteed to be + globally visible when this function returns. + +**/ +VOID +EFIAPI +MemoryFence ( + VOID + ) +{ + // This is a little bit of overkill and it is more about the compiler that it is + // actually processor synchronization. This is like the _ReadWriteBarrier + // Microsoft specific intrinsic + __asm__ __volatile__ ("":::"memory"); +} + + +/** + Enables CPU interrupts. + + Enables CPU interrupts. + +**/ +VOID +EFIAPI +EnableInterrupts ( + VOID + ) +{ + __asm__ __volatile__ ("sti"::: "memory"); +} + + +/** + Disables CPU interrupts. + + Disables CPU interrupts. + +**/ +VOID +EFIAPI +DisableInterrupts ( + VOID + ) +{ + __asm__ __volatile__ ("cli"::: "memory"); +} + + + + +/** + Requests CPU to pause for a short period of time. + + Requests CPU to pause for a short period of time. Typically used in MP + systems to prevent memory starvation while waiting for a spin lock. + +**/ +VOID +EFIAPI +CpuPause ( + VOID + ) +{ + __asm__ __volatile__ ("pause"); +} + + +/** + Generates a breakpoint on the CPU. + + Generates a breakpoint on the CPU. The breakpoint must be implemented such + that code can resume normal execution after the breakpoint. + +**/ +VOID +EFIAPI +CpuBreakpoint ( + VOID + ) +{ + __asm__ __volatile__ ("int $3"); +} + + + +/** + Returns a 64-bit Machine Specific Register(MSR). + + Reads and returns the 64-bit MSR specified by Index. No parameter checking is + performed on Index, and some Index values may cause CPU exceptions. The + caller must either guarantee that Index is valid, or the caller must set up + exception handlers to catch the exceptions. This function is only available + on IA-32 and X64. + + @param Index The 32-bit MSR index to read. + + @return The value of the MSR identified by Index. + +**/ +UINT64 +EFIAPI +AsmReadMsr64 ( + IN UINT32 Index + ) +{ + UINT32 LowData; + UINT32 HighData; + + __asm__ __volatile__ ( + "rdmsr" + : "=a" (LowData), // %0 + "=d" (HighData) // %1 + : "c" (Index) // %2 + ); + + return (((UINT64)HighData) << 32) | LowData; +} + +/** + Writes a 64-bit value to a Machine Specific Register(MSR), and returns the + value. + + Writes the 64-bit value specified by Value to the MSR specified by Index. The + 64-bit value written to the MSR is returned. No parameter checking is + performed on Index or Value, and some of these may cause CPU exceptions. The + caller must either guarantee that Index and Value are valid, or the caller + must establish proper exception handlers. This function is only available on + IA-32 and X64. + + @param Index The 32-bit MSR index to write. + @param Value The 64-bit value to write to the MSR. + + @return Value + +**/ +UINT64 +EFIAPI +AsmWriteMsr64 ( + IN UINT32 Index, + IN UINT64 Value + ) +{ + UINT32 LowData; + UINT32 HighData; + + LowData = (UINT32)(Value); + HighData = (UINT32)(Value >> 32); + + __asm__ __volatile__ ( + "wrmsr" + : + : "c" (Index), + "a" (LowData), + "d" (HighData) + ); + + return Value; +} + + + +/** + Reads the current value of the EFLAGS register. + + Reads and returns the current value of the EFLAGS register. This function is + only available on IA-32 and X64. This returns a 32-bit value on IA-32 and a + 64-bit value on X64. + + @return EFLAGS on IA-32 or RFLAGS on X64. + +**/ +UINTN +EFIAPI +AsmReadEflags ( + VOID + ) +{ + UINTN Eflags; + + __asm__ __volatile__ ( + "pushfq \n\t" + "pop %0 " + : "=r" (Eflags) // %0 + ); + + return Eflags; +} + + + +/** + Reads the current value of the Control Register 0 (CR0). + + Reads and returns the current value of CR0. This function is only available + on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on + X64. + + @return The value of the Control Register 0 (CR0). + +**/ +UINTN +EFIAPI +AsmReadCr0 ( + VOID + ) +{ + UINTN Data; + + __asm__ __volatile__ ( + "mov %%cr0,%0" + : "=r" (Data) // %0 + ); + + return Data; +} + + +/** + Reads the current value of the Control Register 2 (CR2). + + Reads and returns the current value of CR2. This function is only available + on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on + X64. + + @return The value of the Control Register 2 (CR2). + +**/ +UINTN +EFIAPI +AsmReadCr2 ( + VOID + ) +{ + UINTN Data; + + __asm__ __volatile__ ( + "mov %%cr2, %0" + : "=r" (Data) // %0 + ); + + return Data; +} + +/** + Reads the current value of the Control Register 3 (CR3). + + Reads and returns the current value of CR3. This function is only available + on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on + X64. + + @return The value of the Control Register 3 (CR3). + +**/ +UINTN +EFIAPI +AsmReadCr3 ( + VOID + ) +{ + UINTN Data; + + __asm__ __volatile__ ( + "mov %%cr3, %0" + : "=r" (Data) // %0 + ); + + return Data; +} + + +/** + Reads the current value of the Control Register 4 (CR4). + + Reads and returns the current value of CR4. This function is only available + on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on + X64. + + @return The value of the Control Register 4 (CR4). + +**/ +UINTN +EFIAPI +AsmReadCr4 ( + VOID + ) +{ + UINTN Data; + + __asm__ __volatile__ ( + "mov %%cr4, %0" + : "=r" (Data) // %0 + ); + + return Data; +} + + +/** + Writes a value to Control Register 0 (CR0). + + Writes and returns a new value to CR0. This function is only available on + IA-32 and X64. This writes a 32-bit value on IA-32 and a 64-bit value on X64. + + @param Cr0 The value to write to CR0. + + @return The value written to CR0. + +**/ +UINTN +EFIAPI +AsmWriteCr0 ( + UINTN Cr0 + ) +{ + __asm__ __volatile__ ( + "mov %0, %%cr0" + : + : "r" (Cr0) + ); + return Cr0; +} + + +/** + Writes a value to Control Register 2 (CR2). + + Writes and returns a new value to CR2. This function is only available on + IA-32 and X64. This writes a 32-bit value on IA-32 and a 64-bit value on X64. + + @param Cr2 The value to write to CR2. + + @return The value written to CR2. + +**/ +UINTN +EFIAPI +AsmWriteCr2 ( + UINTN Cr2 + ) +{ + __asm__ __volatile__ ( + "mov %0, %%cr2" + : + : "r" (Cr2) + ); + return Cr2; +} + + +/** + Writes a value to Control Register 3 (CR3). + + Writes and returns a new value to CR3. This function is only available on + IA-32 and X64. This writes a 32-bit value on IA-32 and a 64-bit value on X64. + + @param Cr3 The value to write to CR3. + + @return The value written to CR3. + +**/ +UINTN +EFIAPI +AsmWriteCr3 ( + UINTN Cr3 + ) +{ + return Cr3; +} + + +/** + Writes a value to Control Register 4 (CR4). + + Writes and returns a new value to CR4. This function is only available on + IA-32 and X64. This writes a 32-bit value on IA-32 and a 64-bit value on X64. + + @param Cr4 The value to write to CR4. + + @return The value written to CR4. + +**/ +UINTN +EFIAPI +AsmWriteCr4 ( + UINTN Cr4 + ) +{ + __asm__ __volatile__ ( + "mov %0, %%cr4" + : + : "r" (Cr4) + ); + return Cr4; +} + + +/** + Reads the current value of Debug Register 0 (DR0). + + Reads and returns the current value of DR0. This function is only available + on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on + X64. + + @return The value of Debug Register 0 (DR0). + +**/ +UINTN +EFIAPI +AsmReadDr0 ( + VOID + ) +{ + UINTN Data; + + __asm__ __volatile__ ( + "mov %%dr0, %0" + : "=r" (Data) + ); + + return Data; +} + + +/** + Reads the current value of Debug Register 1 (DR1). + + Reads and returns the current value of DR1. This function is only available + on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on + X64. + + @return The value of Debug Register 1 (DR1). + +**/ +UINTN +EFIAPI +AsmReadDr1 ( + VOID + ) +{ + UINTN Data; + + __asm__ __volatile__ ( + "mov %%dr1, %0" + : "=r" (Data) + ); + + return Data; +} + + +/** + Reads the current value of Debug Register 2 (DR2). + + Reads and returns the current value of DR2. This function is only available + on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on + X64. + + @return The value of Debug Register 2 (DR2). + +**/ +UINTN +EFIAPI +AsmReadDr2 ( + VOID + ) +{ + UINTN Data; + + __asm__ __volatile__ ( + "mov %%dr2, %0" + : "=r" (Data) + ); + + return Data; +} + + +/** + Reads the current value of Debug Register 3 (DR3). + + Reads and returns the current value of DR3. This function is only available + on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on + X64. + + @return The value of Debug Register 3 (DR3). + +**/ +UINTN +EFIAPI +AsmReadDr3 ( + VOID + ) +{ + UINTN Data; + + __asm__ __volatile__ ( + "mov %%dr3, %0" + : "=r" (Data) + ); + + return Data; +} + + +/** + Reads the current value of Debug Register 4 (DR4). + + Reads and returns the current value of DR4. This function is only available + on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on + X64. + + @return The value of Debug Register 4 (DR4). + +**/ +UINTN +EFIAPI +AsmReadDr4 ( + VOID + ) +{ + UINTN Data; + + __asm__ __volatile__ ( + "mov %%dr4, %0" + : "=r" (Data) + ); + + return Data; +} + + +/** + Reads the current value of Debug Register 5 (DR5). + + Reads and returns the current value of DR5. This function is only available + on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on + X64. + + @return The value of Debug Register 5 (DR5). + +**/ +UINTN +EFIAPI +AsmReadDr5 ( + VOID + ) +{ + UINTN Data; + + __asm__ __volatile__ ( + "mov %%dr5, %0" + : "=r" (Data) + ); + + return Data; +} + + +/** + Reads the current value of Debug Register 6 (DR6). + + Reads and returns the current value of DR6. This function is only available + on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on + X64. + + @return The value of Debug Register 6 (DR6). + +**/ +UINTN +EFIAPI +AsmReadDr6 ( + VOID + ) +{ + UINTN Data; + + __asm__ __volatile__ ( + "mov %%dr6, %0" + : "=r" (Data) + ); + + return Data; +} + + +/** + Reads the current value of Debug Register 7 (DR7). + + Reads and returns the current value of DR7. This function is only available + on IA-32 and X64. This returns a 32-bit value on IA-32 and a 64-bit value on + X64. + + @return The value of Debug Register 7 (DR7). + +**/ +UINTN +EFIAPI +AsmReadDr7 ( + VOID + ) +{ + UINTN Data; + + __asm__ __volatile__ ( + "mov %%dr7, %0" + : "=r" (Data) + ); + + return Data; +} + + +/** + Writes a value to Debug Register 0 (DR0). + + Writes and returns a new value to DR0. This function is only available on + IA-32 and X64. This writes a 32-bit value on IA-32 and a 64-bit value on X64. + + @param Dr0 The value to write to Dr0. + + @return The value written to Debug Register 0 (DR0). + +**/ +UINTN +EFIAPI +AsmWriteDr0 ( + UINTN Dr0 + ) +{ + __asm__ __volatile__ ( + "mov %0, %%dr0" + : + : "r" (Dr0) + ); + return Dr0; +} + + +/** + Writes a value to Debug Register 1 (DR1). + + Writes and returns a new value to DR1. This function is only available on + IA-32 and X64. This writes a 32-bit value on IA-32 and a 64-bit value on X64. + + @param Dr1 The value to write to Dr1. + + @return The value written to Debug Register 1 (DR1). + +**/ +UINTN +EFIAPI +AsmWriteDr1 ( + UINTN Dr1 + ) +{ + __asm__ __volatile__ ( + "mov %0, %%dr1" + : + : "r" (Dr1) + ); + return Dr1; +} + + +/** + Writes a value to Debug Register 2 (DR2). + + Writes and returns a new value to DR2. This function is only available on + IA-32 and X64. This writes a 32-bit value on IA-32 and a 64-bit value on X64. + + @param Dr2 The value to write to Dr2. + + @return The value written to Debug Register 2 (DR2). + +**/ +UINTN +EFIAPI +AsmWriteDr2 ( + UINTN Dr2 + ) +{ + __asm__ __volatile__ ( + "mov %0, %%dr2" + : + : "r" (Dr2) + ); + return Dr2; +} + + +/** + Writes a value to Debug Register 3 (DR3). + + Writes and returns a new value to DR3. This function is only available on + IA-32 and X64. This writes a 32-bit value on IA-32 and a 64-bit value on X64. + + @param Dr3 The value to write to Dr3. + + @return The value written to Debug Register 3 (DR3). + +**/ +UINTN +EFIAPI +AsmWriteDr3 ( + UINTN Dr3 + ) +{ + __asm__ __volatile__ ( + "mov %0, %%dr3" + : + : "r" (Dr3) + ); + return Dr3; +} + + +/** + Writes a value to Debug Register 4 (DR4). + + Writes and returns a new value to DR4. This function is only available on + IA-32 and X64. This writes a 32-bit value on IA-32 and a 64-bit value on X64. + + @param Dr4 The value to write to Dr4. + + @return The value written to Debug Register 4 (DR4). + +**/ +UINTN +EFIAPI +AsmWriteDr4 ( + UINTN Dr4 + ) +{ + __asm__ __volatile__ ( + "mov %0, %%dr4" + : + : "r" (Dr4) + ); + return Dr4; +} + + +/** + Writes a value to Debug Register 5 (DR5). + + Writes and returns a new value to DR5. This function is only available on + IA-32 and X64. This writes a 32-bit value on IA-32 and a 64-bit value on X64. + + @param Dr5 The value to write to Dr5. + + @return The value written to Debug Register 5 (DR5). + +**/ +UINTN +EFIAPI +AsmWriteDr5 ( + UINTN Dr5 + ) +{ + __asm__ __volatile__ ( + "mov %0, %%dr5" + : + : "r" (Dr5) + ); + return Dr5; +} + + +/** + Writes a value to Debug Register 6 (DR6). + + Writes and returns a new value to DR6. This function is only available on + IA-32 and X64. This writes a 32-bit value on IA-32 and a 64-bit value on X64. + + @param Dr6 The value to write to Dr6. + + @return The value written to Debug Register 6 (DR6). + +**/ +UINTN +EFIAPI +AsmWriteDr6 ( + UINTN Dr6 + ) +{ + __asm__ __volatile__ ( + "mov %0, %%dr6" + : + : "r" (Dr6) + ); + return Dr6; +} + + +/** + Writes a value to Debug Register 7 (DR7). + + Writes and returns a new value to DR7. This function is only available on + IA-32 and X64. This writes a 32-bit value on IA-32 and a 64-bit value on X64. + + @param Dr7 The value to write to Dr7. + + @return The value written to Debug Register 7 (DR7). + +**/ +UINTN +EFIAPI +AsmWriteDr7 ( + UINTN Dr7 + ) +{ + __asm__ __volatile__ ( + "mov %0, %%dr7" + : + : "r" (Dr7) + ); + return Dr7; +} + + +/** + Reads the current value of Code Segment Register (CS). + + Reads and returns the current value of CS. This function is only available on + IA-32 and X64. + + @return The current value of CS. + +**/ +UINT16 +EFIAPI +AsmReadCs ( + VOID + ) +{ + UINT16 Data; + + __asm__ __volatile__ ( + "mov %%cs, %0" + :"=a" (Data) + ); + + return Data; +} + + +/** + Reads the current value of Data Segment Register (DS). + + Reads and returns the current value of DS. This function is only available on + IA-32 and X64. + + @return The current value of DS. + +**/ +UINT16 +EFIAPI +AsmReadDs ( + VOID + ) +{ + UINT16 Data; + + __asm__ __volatile__ ( + "mov %%ds, %0" + :"=a" (Data) + ); + + return Data; +} + + +/** + Reads the current value of Extra Segment Register (ES). + + Reads and returns the current value of ES. This function is only available on + IA-32 and X64. + + @return The current value of ES. + +**/ +UINT16 +EFIAPI +AsmReadEs ( + VOID + ) +{ + UINT16 Data; + + __asm__ __volatile__ ( + "mov %%es, %0" + :"=a" (Data) + ); + + return Data; +} + + +/** + Reads the current value of FS Data Segment Register (FS). + + Reads and returns the current value of FS. This function is only available on + IA-32 and X64. + + @return The current value of FS. + +**/ +UINT16 +EFIAPI +AsmReadFs ( + VOID + ) +{ + UINT16 Data; + + __asm__ __volatile__ ( + "mov %%fs, %0" + :"=a" (Data) + ); + + return Data; +} + + +/** + Reads the current value of GS Data Segment Register (GS). + + Reads and returns the current value of GS. This function is only available on + IA-32 and X64. + + @return The current value of GS. + +**/ +UINT16 +EFIAPI +AsmReadGs ( + VOID + ) +{ + UINT16 Data; + + __asm__ __volatile__ ( + "mov %%gs, %0" + :"=a" (Data) + ); + + return Data; +} + + +/** + Reads the current value of Stack Segment Register (SS). + + Reads and returns the current value of SS. This function is only available on + IA-32 and X64. + + @return The current value of SS. + +**/ +UINT16 +EFIAPI +AsmReadSs ( + VOID + ) +{ + UINT16 Data; + + __asm__ __volatile__ ( + "mov %%ds, %0" + :"=a" (Data) + ); + + return Data; +} + + +/** + Reads the current value of Task Register (TR). + + Reads and returns the current value of TR. This function is only available on + IA-32 and X64. + + @return The current value of TR. + +**/ +UINT16 +EFIAPI +AsmReadTr ( + VOID + ) +{ + UINT16 Data; + + __asm__ __volatile__ ( + "str %0" + : "=r" (Data) + ); + + return Data; +} + + +/** + Reads the current Global Descriptor Table Register(GDTR) descriptor. + + Reads and returns the current GDTR descriptor and returns it in Gdtr. This + function is only available on IA-32 and X64. + + @param Gdtr The pointer to a GDTR descriptor. + +**/ +VOID +EFIAPI +InternalX86ReadGdtr ( + OUT IA32_DESCRIPTOR *Gdtr + ) +{ + __asm__ __volatile__ ( + "sgdt %0" + : "=m" (*Gdtr) + ); +} + + +/** + Writes the current Global Descriptor Table Register (GDTR) descriptor. + + Writes and the current GDTR descriptor specified by Gdtr. This function is + only available on IA-32 and X64. + + @param Gdtr The pointer to a GDTR descriptor. + +**/ +VOID +EFIAPI +InternalX86WriteGdtr ( + IN CONST IA32_DESCRIPTOR *Gdtr + ) +{ + __asm__ __volatile__ ( + "lgdt %0" + : + : "m" (*Gdtr) + ); + +} + + +/** + Reads the current Interrupt Descriptor Table Register(GDTR) descriptor. + + Reads and returns the current IDTR descriptor and returns it in Idtr. This + function is only available on IA-32 and X64. + + @param Idtr The pointer to a IDTR descriptor. + +**/ +VOID +EFIAPI +InternalX86ReadIdtr ( + OUT IA32_DESCRIPTOR *Idtr + ) +{ + __asm__ __volatile__ ( + "sidt %0" + : "=m" (*Idtr) + ); +} + + +/** + Writes the current Interrupt Descriptor Table Register(GDTR) descriptor. + + Writes the current IDTR descriptor and returns it in Idtr. This function is + only available on IA-32 and X64. + + @param Idtr The pointer to a IDTR descriptor. + +**/ +VOID +EFIAPI +InternalX86WriteIdtr ( + IN CONST IA32_DESCRIPTOR *Idtr + ) +{ + __asm__ __volatile__ ( + "lidt %0" + : + : "m" (*Idtr) + ); +} + + +/** + Reads the current Local Descriptor Table Register(LDTR) selector. + + Reads and returns the current 16-bit LDTR descriptor value. This function is + only available on IA-32 and X64. + + @return The current selector of LDT. + +**/ +UINT16 +EFIAPI +AsmReadLdtr ( + VOID + ) +{ + UINT16 Data; + + __asm__ __volatile__ ( + "sldt %0" + : "=g" (Data) // %0 + ); + + return Data; +} + + +/** + Writes the current Local Descriptor Table Register (GDTR) selector. + + Writes and the current LDTR descriptor specified by Ldtr. This function is + only available on IA-32 and X64. + + @param Ldtr 16-bit LDTR selector value. + +**/ +VOID +EFIAPI +AsmWriteLdtr ( + IN UINT16 Ldtr + ) +{ + __asm__ __volatile__ ( + "lldtw %0" + : + : "g" (Ldtr) // %0 + ); +} + + +/** + Save the current floating point/SSE/SSE2 context to a buffer. + + Saves the current floating point/SSE/SSE2 state to the buffer specified by + Buffer. Buffer must be aligned on a 16-byte boundary. This function is only + available on IA-32 and X64. + + @param Buffer The pointer to a buffer to save the floating point/SSE/SSE2 context. + +**/ +VOID +EFIAPI +InternalX86FxSave ( + OUT IA32_FX_BUFFER *Buffer + ) +{ + __asm__ __volatile__ ( + "fxsave %0" + : + : "m" (*Buffer) // %0 + ); +} + + +/** + Restores the current floating point/SSE/SSE2 context from a buffer. + + Restores the current floating point/SSE/SSE2 state from the buffer specified + by Buffer. Buffer must be aligned on a 16-byte boundary. This function is + only available on IA-32 and X64. + + @param Buffer The pointer to a buffer to save the floating point/SSE/SSE2 context. + +**/ +VOID +EFIAPI +InternalX86FxRestore ( + IN CONST IA32_FX_BUFFER *Buffer + ) +{ + __asm__ __volatile__ ( + "fxrstor %0" + : + : "m" (*Buffer) // %0 + ); +} + + +/** + Reads the current value of 64-bit MMX Register #0 (MM0). + + Reads and returns the current value of MM0. This function is only available + on IA-32 and X64. + + @return The current value of MM0. + +**/ +UINT64 +EFIAPI +AsmReadMm0 ( + VOID + ) +{ + UINT64 Data; + + __asm__ __volatile__ ( + "movd %%mm0, %0 \n\t" + : "=r" (Data) // %0 + ); + + return Data; +} + + +/** + Reads the current value of 64-bit MMX Register #1 (MM1). + + Reads and returns the current value of MM1. This function is only available + on IA-32 and X64. + + @return The current value of MM1. + +**/ +UINT64 +EFIAPI +AsmReadMm1 ( + VOID + ) +{ + UINT64 Data; + + __asm__ __volatile__ ( + "movd %%mm1, %0 \n\t" + : "=r" (Data) // %0 + ); + + return Data; +} + + +/** + Reads the current value of 64-bit MMX Register #2 (MM2). + + Reads and returns the current value of MM2. This function is only available + on IA-32 and X64. + + @return The current value of MM2. + +**/ +UINT64 +EFIAPI +AsmReadMm2 ( + VOID + ) +{ + UINT64 Data; + + __asm__ __volatile__ ( + "movd %%mm2, %0 \n\t" + : "=r" (Data) // %0 + ); + + return Data; +} + + +/** + Reads the current value of 64-bit MMX Register #3 (MM3). + + Reads and returns the current value of MM3. This function is only available + on IA-32 and X64. + + @return The current value of MM3. + +**/ +UINT64 +EFIAPI +AsmReadMm3 ( + VOID + ) +{ + UINT64 Data; + + __asm__ __volatile__ ( + "movd %%mm3, %0 \n\t" + : "=r" (Data) // %0 + ); + + return Data; +} + + +/** + Reads the current value of 64-bit MMX Register #4 (MM4). + + Reads and returns the current value of MM4. This function is only available + on IA-32 and X64. + + @return The current value of MM4. + +**/ +UINT64 +EFIAPI +AsmReadMm4 ( + VOID + ) +{ + UINT64 Data; + + __asm__ __volatile__ ( + "movd %%mm4, %0 \n\t" + : "=r" (Data) // %0 + ); + + return Data; +} + + +/** + Reads the current value of 64-bit MMX Register #5 (MM5). + + Reads and returns the current value of MM5. This function is only available + on IA-32 and X64. + + @return The current value of MM5. + +**/ +UINT64 +EFIAPI +AsmReadMm5 ( + VOID + ) +{ + UINT64 Data; + + __asm__ __volatile__ ( + "movd %%mm5, %0 \n\t" + : "=r" (Data) // %0 + ); + + return Data; +} + + +/** + Reads the current value of 64-bit MMX Register #6 (MM6). + + Reads and returns the current value of MM6. This function is only available + on IA-32 and X64. + + @return The current value of MM6. + +**/ +UINT64 +EFIAPI +AsmReadMm6 ( + VOID + ) +{ + UINT64 Data; + + __asm__ __volatile__ ( + "movd %%mm6, %0 \n\t" + : "=r" (Data) // %0 + ); + + return Data; +} + + +/** + Reads the current value of 64-bit MMX Register #7 (MM7). + + Reads and returns the current value of MM7. This function is only available + on IA-32 and X64. + + @return The current value of MM7. + +**/ +UINT64 +EFIAPI +AsmReadMm7 ( + VOID + ) +{ + UINT64 Data; + + __asm__ __volatile__ ( + "movd %%mm7, %0 \n\t" + : "=r" (Data) // %0 + ); + + return Data; +} + + +/** + Writes the current value of 64-bit MMX Register #0 (MM0). + + Writes the current value of MM0. This function is only available on IA32 and + X64. + + @param Value The 64-bit value to write to MM0. + +**/ +VOID +EFIAPI +AsmWriteMm0 ( + IN UINT64 Value + ) +{ + __asm__ __volatile__ ( + "movd %0, %%mm0" // %0 + : + : "m" (Value) + ); +} + + +/** + Writes the current value of 64-bit MMX Register #1 (MM1). + + Writes the current value of MM1. This function is only available on IA32 and + X64. + + @param Value The 64-bit value to write to MM1. + +**/ +VOID +EFIAPI +AsmWriteMm1 ( + IN UINT64 Value + ) +{ + __asm__ __volatile__ ( + "movd %0, %%mm1" // %0 + : + : "m" (Value) + ); +} + + +/** + Writes the current value of 64-bit MMX Register #2 (MM2). + + Writes the current value of MM2. This function is only available on IA32 and + X64. + + @param Value The 64-bit value to write to MM2. + +**/ +VOID +EFIAPI +AsmWriteMm2 ( + IN UINT64 Value + ) +{ + __asm__ __volatile__ ( + "movd %0, %%mm2" // %0 + : + : "m" (Value) + ); +} + + +/** + Writes the current value of 64-bit MMX Register #3 (MM3). + + Writes the current value of MM3. This function is only available on IA32 and + X64. + + @param Value The 64-bit value to write to MM3. + +**/ +VOID +EFIAPI +AsmWriteMm3 ( + IN UINT64 Value + ) +{ + __asm__ __volatile__ ( + "movd %0, %%mm3" // %0 + : + : "m" (Value) + ); +} + + +/** + Writes the current value of 64-bit MMX Register #4 (MM4). + + Writes the current value of MM4. This function is only available on IA32 and + X64. + + @param Value The 64-bit value to write to MM4. + +**/ +VOID +EFIAPI +AsmWriteMm4 ( + IN UINT64 Value + ) +{ + __asm__ __volatile__ ( + "movd %0, %%mm4" // %0 + : + : "m" (Value) + ); +} + + +/** + Writes the current value of 64-bit MMX Register #5 (MM5). + + Writes the current value of MM5. This function is only available on IA32 and + X64. + + @param Value The 64-bit value to write to MM5. + +**/ +VOID +EFIAPI +AsmWriteMm5 ( + IN UINT64 Value + ) +{ + __asm__ __volatile__ ( + "movd %0, %%mm5" // %0 + : + : "m" (Value) + ); +} + + +/** + Writes the current value of 64-bit MMX Register #6 (MM6). + + Writes the current value of MM6. This function is only available on IA32 and + X64. + + @param Value The 64-bit value to write to MM6. + +**/ +VOID +EFIAPI +AsmWriteMm6 ( + IN UINT64 Value + ) +{ + __asm__ __volatile__ ( + "movd %0, %%mm6" // %0 + : + : "m" (Value) + ); +} + + +/** + Writes the current value of 64-bit MMX Register #7 (MM7). + + Writes the current value of MM7. This function is only available on IA32 and + X64. + + @param Value The 64-bit value to write to MM7. + +**/ +VOID +EFIAPI +AsmWriteMm7 ( + IN UINT64 Value + ) +{ + __asm__ __volatile__ ( + "movd %0, %%mm7" // %0 + : + : "m" (Value) + ); +} + + +/** + Reads the current value of Time Stamp Counter (TSC). + + Reads and returns the current value of TSC. This function is only available + on IA-32 and X64. + + @return The current value of TSC + +**/ +UINT64 +EFIAPI +AsmReadTsc ( + VOID + ) +{ + UINT32 LowData; + UINT32 HiData; + + __asm__ __volatile__ ( + "rdtsc" + : "=a" (LowData), + "=d" (HiData) + ); + + return (((UINT64)HiData) << 32) | LowData; +} + + +/** + Reads the current value of a Performance Counter (PMC). + + Reads and returns the current value of performance counter specified by + Index. This function is only available on IA-32 and X64. + + @param Index The 32-bit Performance Counter index to read. + + @return The value of the PMC specified by Index. + +**/ +UINT64 +EFIAPI +AsmReadPmc ( + IN UINT32 Index + ) +{ + UINT32 LowData; + UINT32 HiData; + + __asm__ __volatile__ ( + "rdpmc" + : "=a" (LowData), + "=d" (HiData) + : "c" (Index) + ); + + return (((UINT64)HiData) << 32) | LowData; +} + + +/** + Sets up a monitor buffer that is used by AsmMwait(). + + Executes a MONITOR instruction with the register state specified by Eax, Ecx + and Edx. Returns Eax. This function is only available on IA-32 and X64. + + @param Eax The value to load into EAX or RAX before executing the MONITOR + instruction. + @param Ecx The value to load into ECX or RCX before executing the MONITOR + instruction. + @param Edx The value to load into EDX or RDX before executing the MONITOR + instruction. + + @return Eax + +**/ +UINTN +EFIAPI +AsmMonitor ( + IN UINTN Eax, + IN UINTN Ecx, + IN UINTN Edx + ) +{ + __asm__ __volatile__ ( + "monitor" + : + : "a" (Eax), + "c" (Ecx), + "d" (Edx) + ); + + return Eax; +} + + +/** + Executes an MWAIT instruction. + + Executes an MWAIT instruction with the register state specified by Eax and + Ecx. Returns Eax. This function is only available on IA-32 and X64. + + @param Eax The value to load into EAX or RAX before executing the MONITOR + instruction. + @param Ecx The value to load into ECX or RCX before executing the MONITOR + instruction. + + @return Eax + +**/ +UINTN +EFIAPI +AsmMwait ( + IN UINTN Eax, + IN UINTN Ecx + ) +{ + __asm__ __volatile__ ( + "mwait" + : + : "a" (Eax), + "c" (Ecx) + ); + + return Eax; +} + + +/** + Executes a WBINVD instruction. + + Executes a WBINVD instruction. This function is only available on IA-32 and + X64. + +**/ +VOID +EFIAPI +AsmWbinvd ( + VOID + ) +{ + __asm__ __volatile__ ("wbinvd":::"memory"); +} + + +/** + Executes a INVD instruction. + + Executes a INVD instruction. This function is only available on IA-32 and + X64. + +**/ +VOID +EFIAPI +AsmInvd ( + VOID + ) +{ + __asm__ __volatile__ ("invd":::"memory"); + +} + + +/** + Flushes a cache line from all the instruction and data caches within the + coherency domain of the CPU. + + Flushed the cache line specified by LinearAddress, and returns LinearAddress. + This function is only available on IA-32 and X64. + + @param LinearAddress The address of the cache line to flush. If the CPU is + in a physical addressing mode, then LinearAddress is a + physical address. If the CPU is in a virtual + addressing mode, then LinearAddress is a virtual + address. + + @return LinearAddress +**/ +VOID * +EFIAPI +AsmFlushCacheLine ( + IN VOID *LinearAddress + ) +{ + __asm__ __volatile__ ( + "clflush (%0)" + : + : "r" (LinearAddress) + : "memory" + ); + + return LinearAddress; +} + + diff --git a/UnixPkg/Library/UnixBaseLib/X64/Invd.asm b/UnixPkg/Library/UnixBaseLib/X64/Invd.asm new file mode 100644 index 0000000000..ed6f95da55 --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/X64/Invd.asm @@ -0,0 +1,38 @@ +;------------------------------------------------------------------------------ +; +; 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: +; +; Invd.Asm +; +; Abstract: +; +; AsmInvd function +; +; Notes: +; +;------------------------------------------------------------------------------ + + .code + +;------------------------------------------------------------------------------ +; VOID +; EFIAPI +; AsmInvd ( +; VOID +; ); +;------------------------------------------------------------------------------ +AsmInvd PROC + invd + ret +AsmInvd ENDP + + END diff --git a/UnixPkg/Library/UnixBaseLib/X64/LongJump.S b/UnixPkg/Library/UnixBaseLib/X64/LongJump.S new file mode 100644 index 0000000000..d17592cf37 --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/X64/LongJump.S @@ -0,0 +1,88 @@ +#------------------------------------------------------------------------------ +# +# Copyright (c) 2006 - 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. +# +# Module Name: +# +# LongJump.S +# +# Abstract: +# +# Implementation of _LongJump() on x64. +# +#------------------------------------------------------------------------------ + +#------------------------------------------------------------------------------ +# VOID +# EFIAPI +# InternalLongJump ( +# IN BASE_LIBRARY_JUMP_BUFFER *JumpBuffer, // %rcx +# IN UINTN Value // %rdx +# ); +#------------------------------------------------------------------------------ +ASM_GLOBAL ASM_PFX(EfiInternalLongJump) +ASM_PFX(EfiInternalLongJump): + mov (%rcx), %rbx + mov 0x8(%rcx), %rsp + mov 0x10(%rcx), %rbp + mov 0x18(%rcx), %rdi + mov 0x20(%rcx), %rsi + mov 0x28(%rcx), %r12 + mov 0x30(%rcx), %r13 + mov 0x38(%rcx), %r14 + mov 0x40(%rcx), %r15 + # load non-volatile fp registers + ldmxcsr 0x50(%rcx) + movdqu 0x58(%rcx), %xmm6 + movdqu 0x68(%rcx), %xmm7 + movdqu 0x78(%rcx), %xmm8 + movdqu 0x88(%rcx), %xmm9 + movdqu 0x98(%rcx), %xmm10 + movdqu 0xA8(%rcx), %xmm11 + movdqu 0xB8(%rcx), %xmm12 + movdqu 0xC8(%rcx), %xmm13 + movdqu 0xD8(%rcx), %xmm14 + movdqu 0xE8(%rcx), %xmm15 + mov %rdx, %rax # set return value + jmp *0x48(%rcx) + +#------------------------------------------------------------------------------ +# VOID +# EFIAPI +# UnixInternalLongJump ( +# IN BASE_LIBRARY_JUMP_BUFFER *JumpBuffer, // %rdi +# IN UINTN Value // %rsi +# ); +#------------------------------------------------------------------------------ +ASM_GLOBAL ASM_PFX(InternalLongJump) +ASM_PFX(InternalLongJump): + mov (%rdi), %rbx + mov 0x8(%rdi), %rsp + mov 0x10(%rdi), %rbp + mov 0x18(%rdi), %rdi + mov 0x20(%rdi), %rsi + mov 0x28(%rdi), %r12 + mov 0x30(%rdi), %r13 + mov 0x38(%rdi), %r14 + mov 0x40(%rdi), %r15 + # load non-volatile fp registers + ldmxcsr 0x50(%rdi) + movdqu 0x58(%rdi), %xmm6 + movdqu 0x68(%rdi), %xmm7 + movdqu 0x78(%rdi), %xmm8 + movdqu 0x88(%rdi), %xmm9 + movdqu 0x98(%rdi), %xmm10 + movdqu 0xA8(%rdi), %xmm11 + movdqu 0xB8(%rdi), %xmm12 + movdqu 0xC8(%rdi), %xmm13 + movdqu 0xD8(%rdi), %xmm14 + movdqu 0xE8(%rdi), %xmm15 + mov %rsi, %rax # set return value + jmp *0x48(%rdi) diff --git a/UnixPkg/Library/UnixBaseLib/X64/LongJump.asm b/UnixPkg/Library/UnixBaseLib/X64/LongJump.asm new file mode 100644 index 0000000000..eaf32ea2e6 --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/X64/LongJump.asm @@ -0,0 +1,58 @@ +;------------------------------------------------------------------------------ +; +; 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: +; +; LongJump.Asm +; +; Abstract: +; +; Implementation of _LongJump() on x64. +; +;------------------------------------------------------------------------------ + + .code + +;------------------------------------------------------------------------------ +; VOID +; EFIAPI +; InternalLongJump ( +; IN BASE_LIBRARY_JUMP_BUFFER *JumpBuffer, +; IN UINTN Value +; ); +;------------------------------------------------------------------------------ +InternalLongJump PROC + mov rbx, [rcx] + mov rsp, [rcx + 8] + mov rbp, [rcx + 10h] + mov rdi, [rcx + 18h] + mov rsi, [rcx + 20h] + mov r12, [rcx + 28h] + mov r13, [rcx + 30h] + mov r14, [rcx + 38h] + mov r15, [rcx + 40h] + ; load non-volatile fp registers + ldmxcsr [rcx + 50h] + movdqu xmm6, [rcx + 58h] + movdqu xmm7, [rcx + 68h] + movdqu xmm8, [rcx + 78h] + movdqu xmm9, [rcx + 88h] + movdqu xmm10, [rcx + 98h] + movdqu xmm11, [rcx + 0A8h] + movdqu xmm12, [rcx + 0B8h] + movdqu xmm13, [rcx + 0C8h] + movdqu xmm14, [rcx + 0D8h] + movdqu xmm15, [rcx + 0E8h] + mov rax, rdx ; set return value + jmp qword ptr [rcx + 48h] +InternalLongJump ENDP + + END diff --git a/UnixPkg/Library/UnixBaseLib/X64/Monitor.asm b/UnixPkg/Library/UnixBaseLib/X64/Monitor.asm new file mode 100644 index 0000000000..8ae6e7320c --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/X64/Monitor.asm @@ -0,0 +1,43 @@ +;------------------------------------------------------------------------------ +; +; 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: +; +; Monitor.Asm +; +; Abstract: +; +; AsmMonitor function +; +; Notes: +; +;------------------------------------------------------------------------------ + + .code + +;------------------------------------------------------------------------------ +; UINT64 +; EFIAPI +; AsmMonitor ( +; IN UINTN Eax, +; IN UINTN Ecx, +; IN UINTN Edx +; ); +;------------------------------------------------------------------------------ +AsmMonitor PROC + mov eax, ecx + mov ecx, edx + mov edx, r8d + DB 0fh, 1, 0c8h ; monitor + ret +AsmMonitor ENDP + + END diff --git a/UnixPkg/Library/UnixBaseLib/X64/Mwait.asm b/UnixPkg/Library/UnixBaseLib/X64/Mwait.asm new file mode 100644 index 0000000000..02ec8633e5 --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/X64/Mwait.asm @@ -0,0 +1,41 @@ +;------------------------------------------------------------------------------ +; +; 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: +; +; Mwait.Asm +; +; Abstract: +; +; AsmMwait function +; +; Notes: +; +;------------------------------------------------------------------------------ + + .code + +;------------------------------------------------------------------------------ +; UINT64 +; EFIAPI +; AsmMwait ( +; IN UINTN Eax, +; IN UINTN Ecx +; ); +;------------------------------------------------------------------------------ +AsmMwait PROC + mov eax, ecx + mov ecx, edx + DB 0fh, 1, 0c9h ; mwait + ret +AsmMwait ENDP + + END diff --git a/UnixPkg/Library/UnixBaseLib/X64/Non-existing.c b/UnixPkg/Library/UnixBaseLib/X64/Non-existing.c new file mode 100644 index 0000000000..5ceb64bd79 --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/X64/Non-existing.c @@ -0,0 +1,153 @@ +/** @file + Non-existing BaseLib functions on x64 + + Copyright (c) 2006 - 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. + +**/ + +#include +#include + +/** + Enables the 32-bit paging mode on the CPU. + + Enables the 32-bit paging mode on the CPU. CR0, CR3, CR4, and the page tables + must be properly initialized prior to calling this service. This function + assumes the current execution mode is 32-bit protected mode. This function is + only available on IA-32. After the 32-bit paging mode is enabled, control is + transferred to the function specified by EntryPoint using the new stack + specified by NewStack and passing in the parameters specified by Context1 and + Context2. Context1 and Context2 are optional and may be NULL. The function + EntryPoint must never return. + + There are a number of constraints that must be followed before calling this + function: + 1) Interrupts must be disabled. + 2) The caller must be in 32-bit protected mode with flat descriptors. This + means all descriptors must have a base of 0 and a limit of 4GB. + 3) CR0 and CR4 must be compatible with 32-bit protected mode with flat + descriptors. + 4) CR3 must point to valid page tables that will be used once the transition + is complete, and those page tables must guarantee that the pages for this + function and the stack are identity mapped. + + @param EntryPoint A pointer to function to call with the new stack after + paging is enabled. + @param Context1 A pointer to the context to pass into the EntryPoint + function as the first parameter after paging is enabled. + @param Context2 A pointer to the context to pass into the EntryPoint + function as the second parameter after paging is enabled. + @param NewStack A pointer to the new stack to use for the EntryPoint + function after paging is enabled. + +**/ +VOID +EFIAPI +InternalX86EnablePaging32 ( + IN SWITCH_STACK_ENTRY_POINT EntryPoint, + IN VOID *Context1, OPTIONAL + IN VOID *Context2, OPTIONAL + IN VOID *NewStack + ) +{ + // + // This function cannot work on x64 platform + // + ASSERT (FALSE); +} + +/** + Disables the 32-bit paging mode on the CPU. + + Disables the 32-bit paging mode on the CPU and returns to 32-bit protected + mode. This function assumes the current execution mode is 32-paged protected + mode. This function is only available on IA-32. After the 32-bit paging mode + is disabled, control is transferred to the function specified by EntryPoint + using the new stack specified by NewStack and passing in the parameters + specified by Context1 and Context2. Context1 and Context2 are optional and + may be NULL. The function EntryPoint must never return. + + There are a number of constraints that must be followed before calling this + function: + 1) Interrupts must be disabled. + 2) The caller must be in 32-bit paged mode. + 3) CR0, CR3, and CR4 must be compatible with 32-bit paged mode. + 4) CR3 must point to valid page tables that guarantee that the pages for + this function and the stack are identity mapped. + + @param EntryPoint A pointer to function to call with the new stack after + paging is disabled. + @param Context1 A pointer to the context to pass into the EntryPoint + function as the first parameter after paging is disabled. + @param Context2 A pointer to the context to pass into the EntryPoint + function as the second parameter after paging is + disabled. + @param NewStack A pointer to the new stack to use for the EntryPoint + function after paging is disabled. + +**/ +VOID +EFIAPI +InternalX86DisablePaging32 ( + IN SWITCH_STACK_ENTRY_POINT EntryPoint, + IN VOID *Context1, OPTIONAL + IN VOID *Context2, OPTIONAL + IN VOID *NewStack + ) +{ + // + // This function cannot work on x64 platform + // + ASSERT (FALSE); +} + + +/** + Enables the 64-bit paging mode on the CPU. + + Enables the 64-bit paging mode on the CPU. CR0, CR3, CR4, and the page tables + must be properly initialized prior to calling this service. This function + assumes the current execution mode is 32-bit protected mode with flat + descriptors. This function is only available on IA-32. After the 64-bit + paging mode is enabled, control is transferred to the function specified by + EntryPoint using the new stack specified by NewStack and passing in the + parameters specified by Context1 and Context2. Context1 and Context2 are + optional and may be 0. The function EntryPoint must never return. + + @param Cs The 16-bit selector to load in the CS before EntryPoint + is called. The descriptor in the GDT that this selector + references must be setup for long mode. + @param EntryPoint The 64-bit virtual address of the function to call with + the new stack after paging is enabled. + @param Context1 The 64-bit virtual address of the context to pass into + the EntryPoint function as the first parameter after + paging is enabled. + @param Context2 The 64-bit virtual address of the context to pass into + the EntryPoint function as the second parameter after + paging is enabled. + @param NewStack The 64-bit virtual address of the new stack to use for + the EntryPoint function after paging is enabled. + +**/ +VOID +EFIAPI +InternalX86EnablePaging64 ( + IN UINT16 Cs, + IN UINT64 EntryPoint, + IN UINT64 Context1, OPTIONAL + IN UINT64 Context2, OPTIONAL + IN UINT64 NewStack + ) +{ + // + // This function cannot work on x64 platform. + // + ASSERT (FALSE); +} diff --git a/UnixPkg/Library/UnixBaseLib/X64/ReadCr0.asm b/UnixPkg/Library/UnixBaseLib/X64/ReadCr0.asm new file mode 100644 index 0000000000..c3ff5b0772 --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/X64/ReadCr0.asm @@ -0,0 +1,38 @@ +;------------------------------------------------------------------------------ +; +; 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: +; +; ReadCr0.Asm +; +; Abstract: +; +; AsmReadCr0 function +; +; Notes: +; +;------------------------------------------------------------------------------ + + .code + +;------------------------------------------------------------------------------ +; UINTN +; EFIAPI +; AsmReadCr0 ( +; VOID +; ); +;------------------------------------------------------------------------------ +AsmReadCr0 PROC + mov rax, cr0 + ret +AsmReadCr0 ENDP + + END diff --git a/UnixPkg/Library/UnixBaseLib/X64/ReadCr2.asm b/UnixPkg/Library/UnixBaseLib/X64/ReadCr2.asm new file mode 100644 index 0000000000..f1473b9ad4 --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/X64/ReadCr2.asm @@ -0,0 +1,38 @@ +;------------------------------------------------------------------------------ +; +; 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: +; +; ReadCr2.Asm +; +; Abstract: +; +; AsmReadCr2 function +; +; Notes: +; +;------------------------------------------------------------------------------ + + .code + +;------------------------------------------------------------------------------ +; UINTN +; EFIAPI +; AsmReadCr2 ( +; VOID +; ); +;------------------------------------------------------------------------------ +AsmReadCr2 PROC + mov rax, cr2 + ret +AsmReadCr2 ENDP + + END diff --git a/UnixPkg/Library/UnixBaseLib/X64/ReadCr3.asm b/UnixPkg/Library/UnixBaseLib/X64/ReadCr3.asm new file mode 100644 index 0000000000..432468e731 --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/X64/ReadCr3.asm @@ -0,0 +1,38 @@ +;------------------------------------------------------------------------------ +; +; 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: +; +; ReadCr3.Asm +; +; Abstract: +; +; AsmReadCr3 function +; +; Notes: +; +;------------------------------------------------------------------------------ + + .code + +;------------------------------------------------------------------------------ +; UINTN +; EFIAPI +; AsmReadCr3 ( +; VOID +; ); +;------------------------------------------------------------------------------ +AsmReadCr3 PROC + mov rax, cr3 + ret +AsmReadCr3 ENDP + + END diff --git a/UnixPkg/Library/UnixBaseLib/X64/ReadCr4.asm b/UnixPkg/Library/UnixBaseLib/X64/ReadCr4.asm new file mode 100644 index 0000000000..17d44996ea --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/X64/ReadCr4.asm @@ -0,0 +1,38 @@ +;------------------------------------------------------------------------------ +; +; 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: +; +; ReadCr4.Asm +; +; Abstract: +; +; AsmReadCr4 function +; +; Notes: +; +;------------------------------------------------------------------------------ + + .code + +;------------------------------------------------------------------------------ +; UINTN +; EFIAPI +; AsmReadCr4 ( +; VOID +; ); +;------------------------------------------------------------------------------ +AsmReadCr4 PROC + mov rax, cr4 + ret +AsmReadCr4 ENDP + + END diff --git a/UnixPkg/Library/UnixBaseLib/X64/ReadCs.asm b/UnixPkg/Library/UnixBaseLib/X64/ReadCs.asm new file mode 100644 index 0000000000..ac3040cd1b --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/X64/ReadCs.asm @@ -0,0 +1,38 @@ +;------------------------------------------------------------------------------ +; +; 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: +; +; ReadCs.Asm +; +; Abstract: +; +; AsmReadCs function +; +; Notes: +; +;------------------------------------------------------------------------------ + + .code + +;------------------------------------------------------------------------------ +; UINT16 +; EFIAPI +; AsmReadCs ( +; VOID +; ); +;------------------------------------------------------------------------------ +AsmReadCs PROC + mov eax, cs + ret +AsmReadCs ENDP + + END diff --git a/UnixPkg/Library/UnixBaseLib/X64/ReadDr0.asm b/UnixPkg/Library/UnixBaseLib/X64/ReadDr0.asm new file mode 100644 index 0000000000..8ac85ade8e --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/X64/ReadDr0.asm @@ -0,0 +1,38 @@ +;------------------------------------------------------------------------------ +; +; 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: +; +; ReadDr0.Asm +; +; Abstract: +; +; AsmReadDr0 function +; +; Notes: +; +;------------------------------------------------------------------------------ + + .code + +;------------------------------------------------------------------------------ +; UINTN +; EFIAPI +; AsmReadDr0 ( +; VOID +; ); +;------------------------------------------------------------------------------ +AsmReadDr0 PROC + mov rax, dr0 + ret +AsmReadDr0 ENDP + + END diff --git a/UnixPkg/Library/UnixBaseLib/X64/ReadDr1.asm b/UnixPkg/Library/UnixBaseLib/X64/ReadDr1.asm new file mode 100644 index 0000000000..8b042e2d2e --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/X64/ReadDr1.asm @@ -0,0 +1,38 @@ +;------------------------------------------------------------------------------ +; +; 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: +; +; ReadDr1.Asm +; +; Abstract: +; +; AsmReadDr1 function +; +; Notes: +; +;------------------------------------------------------------------------------ + + .code + +;------------------------------------------------------------------------------ +; UINTN +; EFIAPI +; AsmReadDr1 ( +; VOID +; ); +;------------------------------------------------------------------------------ +AsmReadDr1 PROC + mov rax, dr1 + ret +AsmReadDr1 ENDP + + END diff --git a/UnixPkg/Library/UnixBaseLib/X64/ReadDr2.asm b/UnixPkg/Library/UnixBaseLib/X64/ReadDr2.asm new file mode 100644 index 0000000000..9361756584 --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/X64/ReadDr2.asm @@ -0,0 +1,38 @@ +;------------------------------------------------------------------------------ +; +; 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: +; +; ReadDr2.Asm +; +; Abstract: +; +; AsmReadDr2 function +; +; Notes: +; +;------------------------------------------------------------------------------ + + .code + +;------------------------------------------------------------------------------ +; UINTN +; EFIAPI +; AsmReadDr2 ( +; VOID +; ); +;------------------------------------------------------------------------------ +AsmReadDr2 PROC + mov rax, dr2 + ret +AsmReadDr2 ENDP + + END diff --git a/UnixPkg/Library/UnixBaseLib/X64/ReadDr3.asm b/UnixPkg/Library/UnixBaseLib/X64/ReadDr3.asm new file mode 100644 index 0000000000..a25fc9d97a --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/X64/ReadDr3.asm @@ -0,0 +1,38 @@ +;------------------------------------------------------------------------------ +; +; 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: +; +; ReadDr3.Asm +; +; Abstract: +; +; AsmReadDr3 function +; +; Notes: +; +;------------------------------------------------------------------------------ + + .code + +;------------------------------------------------------------------------------ +; UINTN +; EFIAPI +; AsmReadDr3 ( +; VOID +; ); +;------------------------------------------------------------------------------ +AsmReadDr3 PROC + mov rax, dr3 + ret +AsmReadDr3 ENDP + + END diff --git a/UnixPkg/Library/UnixBaseLib/X64/ReadDr4.asm b/UnixPkg/Library/UnixBaseLib/X64/ReadDr4.asm new file mode 100644 index 0000000000..dc6c5e9826 --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/X64/ReadDr4.asm @@ -0,0 +1,42 @@ +;------------------------------------------------------------------------------ +; +; 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: +; +; ReadDr4.Asm +; +; Abstract: +; +; AsmReadDr4 function +; +; Notes: +; +;------------------------------------------------------------------------------ + + .code + +;------------------------------------------------------------------------------ +; UINTN +; EFIAPI +; AsmReadDr4 ( +; VOID +; ); +;------------------------------------------------------------------------------ +AsmReadDr4 PROC + ; + ; There's no obvious reason to access this register, since it's aliased to + ; DR7 when DE=0 or an exception generated when DE=1 + ; + DB 0fh, 21h, 0e0h + ret +AsmReadDr4 ENDP + + END diff --git a/UnixPkg/Library/UnixBaseLib/X64/ReadDr5.asm b/UnixPkg/Library/UnixBaseLib/X64/ReadDr5.asm new file mode 100644 index 0000000000..7e313522f6 --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/X64/ReadDr5.asm @@ -0,0 +1,42 @@ +;------------------------------------------------------------------------------ +; +; 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: +; +; ReadDr5.Asm +; +; Abstract: +; +; AsmReadDr5 function +; +; Notes: +; +;------------------------------------------------------------------------------ + + .code + +;------------------------------------------------------------------------------ +; UINTN +; EFIAPI +; AsmReadDr5 ( +; VOID +; ); +;------------------------------------------------------------------------------ +AsmReadDr5 PROC + ; + ; There's no obvious reason to access this register, since it's aliased to + ; DR7 when DE=0 or an exception generated when DE=1 + ; + DB 0fh, 21h, 0e8h + ret +AsmReadDr5 ENDP + + END diff --git a/UnixPkg/Library/UnixBaseLib/X64/ReadDr6.asm b/UnixPkg/Library/UnixBaseLib/X64/ReadDr6.asm new file mode 100644 index 0000000000..ee6b9ec695 --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/X64/ReadDr6.asm @@ -0,0 +1,38 @@ +;------------------------------------------------------------------------------ +; +; 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: +; +; ReadDr6.Asm +; +; Abstract: +; +; AsmReadDr6 function +; +; Notes: +; +;------------------------------------------------------------------------------ + + .code + +;------------------------------------------------------------------------------ +; UINTN +; EFIAPI +; AsmReadDr6 ( +; VOID +; ); +;------------------------------------------------------------------------------ +AsmReadDr6 PROC + mov rax, dr6 + ret +AsmReadDr6 ENDP + + END diff --git a/UnixPkg/Library/UnixBaseLib/X64/ReadDr7.asm b/UnixPkg/Library/UnixBaseLib/X64/ReadDr7.asm new file mode 100644 index 0000000000..7173057e9e --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/X64/ReadDr7.asm @@ -0,0 +1,38 @@ +;------------------------------------------------------------------------------ +; +; 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: +; +; ReadDr7.Asm +; +; Abstract: +; +; AsmReadDr7 function +; +; Notes: +; +;------------------------------------------------------------------------------ + + .code + +;------------------------------------------------------------------------------ +; UINTN +; EFIAPI +; AsmReadDr7 ( +; VOID +; ); +;------------------------------------------------------------------------------ +AsmReadDr7 PROC + mov rax, dr7 + ret +AsmReadDr7 ENDP + + END diff --git a/UnixPkg/Library/UnixBaseLib/X64/ReadDs.asm b/UnixPkg/Library/UnixBaseLib/X64/ReadDs.asm new file mode 100644 index 0000000000..d67512c3de --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/X64/ReadDs.asm @@ -0,0 +1,38 @@ +;------------------------------------------------------------------------------ +; +; 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: +; +; ReadDs.Asm +; +; Abstract: +; +; AsmReadDs function +; +; Notes: +; +;------------------------------------------------------------------------------ + + .code + +;------------------------------------------------------------------------------ +; UINT16 +; EFIAPI +; AsmReadDs ( +; VOID +; ); +;------------------------------------------------------------------------------ +AsmReadDs PROC + mov eax, ds + ret +AsmReadDs ENDP + + END diff --git a/UnixPkg/Library/UnixBaseLib/X64/ReadEflags.asm b/UnixPkg/Library/UnixBaseLib/X64/ReadEflags.asm new file mode 100644 index 0000000000..b3ecc7cc16 --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/X64/ReadEflags.asm @@ -0,0 +1,39 @@ +;------------------------------------------------------------------------------ +; +; 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: +; +; ReadEflags.Asm +; +; Abstract: +; +; AsmReadEflags function +; +; Notes: +; +;------------------------------------------------------------------------------ + + .code + +;------------------------------------------------------------------------------ +; UINTN +; EFIAPI +; AsmReadEflags ( +; VOID +; ); +;------------------------------------------------------------------------------ +AsmReadEflags PROC + pushfq + pop rax + ret +AsmReadEflags ENDP + + END diff --git a/UnixPkg/Library/UnixBaseLib/X64/ReadEs.asm b/UnixPkg/Library/UnixBaseLib/X64/ReadEs.asm new file mode 100644 index 0000000000..76cffdcb5c --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/X64/ReadEs.asm @@ -0,0 +1,38 @@ +;------------------------------------------------------------------------------ +; +; 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: +; +; ReadEs.Asm +; +; Abstract: +; +; AsmReadEs function +; +; Notes: +; +;------------------------------------------------------------------------------ + + .code + +;------------------------------------------------------------------------------ +; UINT16 +; EFIAPI +; AsmReadEs ( +; VOID +; ); +;------------------------------------------------------------------------------ +AsmReadEs PROC + mov eax, es + ret +AsmReadEs ENDP + + END diff --git a/UnixPkg/Library/UnixBaseLib/X64/ReadFs.asm b/UnixPkg/Library/UnixBaseLib/X64/ReadFs.asm new file mode 100644 index 0000000000..e91aa14aa6 --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/X64/ReadFs.asm @@ -0,0 +1,38 @@ +;------------------------------------------------------------------------------ +; +; 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: +; +; ReadFs.Asm +; +; Abstract: +; +; AsmReadFs function +; +; Notes: +; +;------------------------------------------------------------------------------ + + .code + +;------------------------------------------------------------------------------ +; UINT16 +; EFIAPI +; AsmReadFs ( +; VOID +; ); +;------------------------------------------------------------------------------ +AsmReadFs PROC + mov eax, fs + ret +AsmReadFs ENDP + + END diff --git a/UnixPkg/Library/UnixBaseLib/X64/ReadGdtr.asm b/UnixPkg/Library/UnixBaseLib/X64/ReadGdtr.asm new file mode 100644 index 0000000000..ebc60bd999 --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/X64/ReadGdtr.asm @@ -0,0 +1,38 @@ +;------------------------------------------------------------------------------ +; +; 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: +; +; ReadGdtr.Asm +; +; Abstract: +; +; AsmReadGdtr function +; +; Notes: +; +;------------------------------------------------------------------------------ + + .code + +;------------------------------------------------------------------------------ +; VOID +; EFIAPI +; InternalX86ReadGdtr ( +; OUT IA32_DESCRIPTOR *Gdtr +; ); +;------------------------------------------------------------------------------ +InternalX86ReadGdtr PROC + sgdt fword ptr [rcx] + ret +InternalX86ReadGdtr ENDP + + END diff --git a/UnixPkg/Library/UnixBaseLib/X64/ReadGs.asm b/UnixPkg/Library/UnixBaseLib/X64/ReadGs.asm new file mode 100644 index 0000000000..f185c38761 --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/X64/ReadGs.asm @@ -0,0 +1,38 @@ +;------------------------------------------------------------------------------ +; +; 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: +; +; ReadGs.Asm +; +; Abstract: +; +; AsmReadGs function +; +; Notes: +; +;------------------------------------------------------------------------------ + + .code + +;------------------------------------------------------------------------------ +; UINT16 +; EFIAPI +; AsmReadGs ( +; VOID +; ); +;------------------------------------------------------------------------------ +AsmReadGs PROC + mov eax, gs + ret +AsmReadGs ENDP + + END diff --git a/UnixPkg/Library/UnixBaseLib/X64/ReadIdtr.asm b/UnixPkg/Library/UnixBaseLib/X64/ReadIdtr.asm new file mode 100644 index 0000000000..4d53feb9d8 --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/X64/ReadIdtr.asm @@ -0,0 +1,38 @@ +;------------------------------------------------------------------------------ +; +; 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: +; +; ReadIdtr.Asm +; +; Abstract: +; +; AsmReadIdtr function +; +; Notes: +; +;------------------------------------------------------------------------------ + + .code + +;------------------------------------------------------------------------------ +; VOID +; EFIAPI +; InternalX86ReadIdtr ( +; OUT IA32_DESCRIPTOR *Idtr +; ); +;------------------------------------------------------------------------------ +InternalX86ReadIdtr PROC + sidt fword ptr [rcx] + ret +InternalX86ReadIdtr ENDP + + END diff --git a/UnixPkg/Library/UnixBaseLib/X64/ReadLdtr.asm b/UnixPkg/Library/UnixBaseLib/X64/ReadLdtr.asm new file mode 100644 index 0000000000..dbe517e353 --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/X64/ReadLdtr.asm @@ -0,0 +1,38 @@ +;------------------------------------------------------------------------------ +; +; 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: +; +; ReadLdtr.Asm +; +; Abstract: +; +; AsmReadLdtr function +; +; Notes: +; +;------------------------------------------------------------------------------ + + .code + +;------------------------------------------------------------------------------ +; UINT16 +; EFIAPI +; AsmReadLdtr ( +; VOID +; ); +;------------------------------------------------------------------------------ +AsmReadLdtr PROC + sldt eax + ret +AsmReadLdtr ENDP + + END diff --git a/UnixPkg/Library/UnixBaseLib/X64/ReadMm0.asm b/UnixPkg/Library/UnixBaseLib/X64/ReadMm0.asm new file mode 100644 index 0000000000..99212c747d --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/X64/ReadMm0.asm @@ -0,0 +1,41 @@ +;------------------------------------------------------------------------------ +; +; 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: +; +; ReadMm0.Asm +; +; Abstract: +; +; AsmReadMm0 function +; +; Notes: +; +;------------------------------------------------------------------------------ + + .code + +;------------------------------------------------------------------------------ +; UINT64 +; EFIAPI +; AsmReadMm0 ( +; VOID +; ); +;------------------------------------------------------------------------------ +AsmReadMm0 PROC + ; + ; 64-bit MASM doesn't support MMX instructions, so use opcode here + ; + DB 48h, 0fh, 7eh, 0c0h + ret +AsmReadMm0 ENDP + + END diff --git a/UnixPkg/Library/UnixBaseLib/X64/ReadMm1.asm b/UnixPkg/Library/UnixBaseLib/X64/ReadMm1.asm new file mode 100644 index 0000000000..7a9ae7c1ce --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/X64/ReadMm1.asm @@ -0,0 +1,41 @@ +;------------------------------------------------------------------------------ +; +; 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: +; +; ReadMm1.Asm +; +; Abstract: +; +; AsmReadMm1 function +; +; Notes: +; +;------------------------------------------------------------------------------ + + .code + +;------------------------------------------------------------------------------ +; UINT64 +; EFIAPI +; AsmReadMm1 ( +; VOID +; ); +;------------------------------------------------------------------------------ +AsmReadMm1 PROC + ; + ; 64-bit MASM doesn't support MMX instructions, so use opcode here + ; + DB 48h, 0fh, 7eh, 0c8h + ret +AsmReadMm1 ENDP + + END diff --git a/UnixPkg/Library/UnixBaseLib/X64/ReadMm2.asm b/UnixPkg/Library/UnixBaseLib/X64/ReadMm2.asm new file mode 100644 index 0000000000..337ac73dde --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/X64/ReadMm2.asm @@ -0,0 +1,41 @@ +;------------------------------------------------------------------------------ +; +; 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: +; +; ReadMm2.Asm +; +; Abstract: +; +; AsmReadMm2 function +; +; Notes: +; +;------------------------------------------------------------------------------ + + .code + +;------------------------------------------------------------------------------ +; UINT64 +; EFIAPI +; AsmReadMm2 ( +; VOID +; ); +;------------------------------------------------------------------------------ +AsmReadMm2 PROC + ; + ; 64-bit MASM doesn't support MMX instructions, so use opcode here + ; + DB 48h, 0fh, 7eh, 0d0h + ret +AsmReadMm2 ENDP + + END diff --git a/UnixPkg/Library/UnixBaseLib/X64/ReadMm3.asm b/UnixPkg/Library/UnixBaseLib/X64/ReadMm3.asm new file mode 100644 index 0000000000..266e29a9d1 --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/X64/ReadMm3.asm @@ -0,0 +1,41 @@ +;------------------------------------------------------------------------------ +; +; 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: +; +; ReadMm3.Asm +; +; Abstract: +; +; AsmReadMm3 function +; +; Notes: +; +;------------------------------------------------------------------------------ + + .code + +;------------------------------------------------------------------------------ +; UINT64 +; EFIAPI +; AsmReadMm3 ( +; VOID +; ); +;------------------------------------------------------------------------------ +AsmReadMm3 PROC + ; + ; 64-bit MASM doesn't support MMX instructions, so use opcode here + ; + DB 48h, 0fh, 7eh, 0d8h + ret +AsmReadMm3 ENDP + + END diff --git a/UnixPkg/Library/UnixBaseLib/X64/ReadMm4.asm b/UnixPkg/Library/UnixBaseLib/X64/ReadMm4.asm new file mode 100644 index 0000000000..9cc7435807 --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/X64/ReadMm4.asm @@ -0,0 +1,41 @@ +;------------------------------------------------------------------------------ +; +; 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: +; +; ReadMm4.Asm +; +; Abstract: +; +; AsmReadMm4 function +; +; Notes: +; +;------------------------------------------------------------------------------ + + .code + +;------------------------------------------------------------------------------ +; UINT64 +; EFIAPI +; AsmReadMm4 ( +; VOID +; ); +;------------------------------------------------------------------------------ +AsmReadMm4 PROC + ; + ; 64-bit MASM doesn't support MMX instructions, so use opcode here + ; + DB 48h, 0fh, 7eh, 0e0h + ret +AsmReadMm4 ENDP + + END diff --git a/UnixPkg/Library/UnixBaseLib/X64/ReadMm5.asm b/UnixPkg/Library/UnixBaseLib/X64/ReadMm5.asm new file mode 100644 index 0000000000..b66522535f --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/X64/ReadMm5.asm @@ -0,0 +1,41 @@ +;------------------------------------------------------------------------------ +; +; 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: +; +; ReadMm5.Asm +; +; Abstract: +; +; AsmReadMm5 function +; +; Notes: +; +;------------------------------------------------------------------------------ + + .code + +;------------------------------------------------------------------------------ +; UINT64 +; EFIAPI +; AsmReadMm5 ( +; VOID +; ); +;------------------------------------------------------------------------------ +AsmReadMm5 PROC + ; + ; 64-bit MASM doesn't support MMX instructions, so use opcode here + ; + DB 48h, 0fh, 7eh, 0e8h + ret +AsmReadMm5 ENDP + + END diff --git a/UnixPkg/Library/UnixBaseLib/X64/ReadMm6.asm b/UnixPkg/Library/UnixBaseLib/X64/ReadMm6.asm new file mode 100644 index 0000000000..1e3ebc5d8e --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/X64/ReadMm6.asm @@ -0,0 +1,41 @@ +;------------------------------------------------------------------------------ +; +; 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: +; +; ReadMm6.Asm +; +; Abstract: +; +; AsmReadMm6 function +; +; Notes: +; +;------------------------------------------------------------------------------ + + .code + +;------------------------------------------------------------------------------ +; UINT64 +; EFIAPI +; AsmReadMm6 ( +; VOID +; ); +;------------------------------------------------------------------------------ +AsmReadMm6 PROC + ; + ; 64-bit MASM doesn't support MMX instructions, so use opcode here + ; + DB 48h, 0fh, 7eh, 0f0h + ret +AsmReadMm6 ENDP + + END diff --git a/UnixPkg/Library/UnixBaseLib/X64/ReadMm7.asm b/UnixPkg/Library/UnixBaseLib/X64/ReadMm7.asm new file mode 100644 index 0000000000..8228672135 --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/X64/ReadMm7.asm @@ -0,0 +1,41 @@ +;------------------------------------------------------------------------------ +; +; 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: +; +; ReadMm7.Asm +; +; Abstract: +; +; AsmReadMm7 function +; +; Notes: +; +;------------------------------------------------------------------------------ + + .code + +;------------------------------------------------------------------------------ +; UINT64 +; EFIAPI +; AsmReadMm7 ( +; VOID +; ); +;------------------------------------------------------------------------------ +AsmReadMm7 PROC + ; + ; 64-bit MASM doesn't support MMX instructions, so use opcode here + ; + DB 48h, 0fh, 7eh, 0f8h + ret +AsmReadMm7 ENDP + + END diff --git a/UnixPkg/Library/UnixBaseLib/X64/ReadMsr64.asm b/UnixPkg/Library/UnixBaseLib/X64/ReadMsr64.asm new file mode 100644 index 0000000000..878ed18245 --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/X64/ReadMsr64.asm @@ -0,0 +1,40 @@ +;------------------------------------------------------------------------------ +; +; 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: +; +; ReadMsr64.Asm +; +; Abstract: +; +; AsmReadMsr64 function +; +; Notes: +; +;------------------------------------------------------------------------------ + + .code + +;------------------------------------------------------------------------------ +; UINT64 +; EFIAPI +; AsmReadMsr64 ( +; IN UINT32 Index +; ); +;------------------------------------------------------------------------------ +AsmReadMsr64 PROC + rdmsr ; edx & eax are zero extended + shl rdx, 20h + or rax, rdx + ret +AsmReadMsr64 ENDP + + END diff --git a/UnixPkg/Library/UnixBaseLib/X64/ReadMsr64.c b/UnixPkg/Library/UnixBaseLib/X64/ReadMsr64.c new file mode 100644 index 0000000000..343e9246b0 --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/X64/ReadMsr64.c @@ -0,0 +1,39 @@ +/** @file + CpuBreakpoint function. + + Copyright (c) 2006 - 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. + +**/ + +/** + Microsoft Visual Studio 7.1 Function Prototypes for I/O Intrinsics. +**/ + +unsigned __int64 __readmsr (int register); + +#pragma intrinsic(__readmsr) + +/** + Read data to MSR. + + @param Index Register index of MSR. + + @return Value read from MSR. + +**/ +UINT64 +EFIAPI +AsmReadMsr64 ( + IN UINT32 Index + ) +{ + return __readmsr (Index); +} + diff --git a/UnixPkg/Library/UnixBaseLib/X64/ReadPmc.asm b/UnixPkg/Library/UnixBaseLib/X64/ReadPmc.asm new file mode 100644 index 0000000000..1b74f67e72 --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/X64/ReadPmc.asm @@ -0,0 +1,40 @@ +;------------------------------------------------------------------------------ +; +; 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: +; +; ReadPmc.Asm +; +; Abstract: +; +; AsmReadPmc function +; +; Notes: +; +;------------------------------------------------------------------------------ + + .code + +;------------------------------------------------------------------------------ +; UINT64 +; EFIAPI +; AsmReadPmc ( +; IN UINT32 PmcIndex +; ); +;------------------------------------------------------------------------------ +AsmReadPmc PROC + rdpmc + shl rdx, 20h + or rax, rdx + ret +AsmReadPmc ENDP + + END diff --git a/UnixPkg/Library/UnixBaseLib/X64/ReadSs.asm b/UnixPkg/Library/UnixBaseLib/X64/ReadSs.asm new file mode 100644 index 0000000000..8f308c49af --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/X64/ReadSs.asm @@ -0,0 +1,38 @@ +;------------------------------------------------------------------------------ +; +; 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: +; +; ReadSs.Asm +; +; Abstract: +; +; AsmReadSs function +; +; Notes: +; +;------------------------------------------------------------------------------ + + .code + +;------------------------------------------------------------------------------ +; UINT16 +; EFIAPI +; AsmReadSs ( +; VOID +; ); +;------------------------------------------------------------------------------ +AsmReadSs PROC + mov eax, ss + ret +AsmReadSs ENDP + + END diff --git a/UnixPkg/Library/UnixBaseLib/X64/ReadTr.asm b/UnixPkg/Library/UnixBaseLib/X64/ReadTr.asm new file mode 100644 index 0000000000..a114f53146 --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/X64/ReadTr.asm @@ -0,0 +1,38 @@ +;------------------------------------------------------------------------------ +; +; 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: +; +; ReadTr.Asm +; +; Abstract: +; +; AsmReadTr function +; +; Notes: +; +;------------------------------------------------------------------------------ + + .code + +;------------------------------------------------------------------------------ +; UINT16 +; EFIAPI +; AsmReadTr ( +; VOID +; ); +;------------------------------------------------------------------------------ +AsmReadTr PROC + str eax + ret +AsmReadTr ENDP + + END diff --git a/UnixPkg/Library/UnixBaseLib/X64/ReadTsc.asm b/UnixPkg/Library/UnixBaseLib/X64/ReadTsc.asm new file mode 100644 index 0000000000..d792bfb204 --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/X64/ReadTsc.asm @@ -0,0 +1,40 @@ +;------------------------------------------------------------------------------ +; +; 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: +; +; ReadTsc.Asm +; +; Abstract: +; +; AsmReadTsc function +; +; Notes: +; +;------------------------------------------------------------------------------ + + .code + +;------------------------------------------------------------------------------ +; UINT64 +; EFIAPI +; AsmReadTsc ( +; VOID +; ); +;------------------------------------------------------------------------------ +AsmReadTsc PROC + rdtsc + shl rdx, 20h + or rax, rdx + ret +AsmReadTsc ENDP + + END diff --git a/UnixPkg/Library/UnixBaseLib/X64/SetJump.S b/UnixPkg/Library/UnixBaseLib/X64/SetJump.S new file mode 100644 index 0000000000..b5fd38ab6a --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/X64/SetJump.S @@ -0,0 +1,82 @@ +#------------------------------------------------------------------------------ +# +# Copyright (c) 2006 - 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. +# +# Module Name: +# +# SetJump.S +# +# Abstract: +# +# Implementation of SetJump() on x86_64 +# +#------------------------------------------------------------------------------ + +ASM_GLOBAL ASM_PFX(EfiSetJump) +ASM_PFX(EfiSetJump): + push %rcx + add $0xffffffffffffffe0,%rsp + call ASM_PFX(InternalAssertJumpBuffer) + add $0x20,%rsp + pop %rcx + pop %rdx + mov %rbx,(%rcx) + mov %rsp,0x8(%rcx) + mov %rbp,0x10(%rcx) + mov %rdi,0x18(%rcx) + mov %rsi,0x20(%rcx) + mov %r12,0x28(%rcx) + mov %r13,0x30(%rcx) + mov %r14,0x38(%rcx) + mov %r15,0x40(%rcx) + mov %rdx,0x48(%rcx) + # save non-volatile fp registers + stmxcsr 0x50(%rcx) + movdqu %xmm6, 0x58(%rcx) + movdqu %xmm7, 0x68(%rcx) + movdqu %xmm8, 0x78(%rcx) + movdqu %xmm9, 0x88(%rcx) + movdqu %xmm10, 0x98(%rcx) + movdqu %xmm11, 0xA8(%rcx) + movdqu %xmm12, 0xB8(%rcx) + movdqu %xmm13, 0xC8(%rcx) + movdqu %xmm14, 0xD8(%rcx) + movdqu %xmm15, 0xE8(%rcx) + xor %rax,%rax + jmpq *%rdx + + +ASM_GLOBAL ASM_PFX(SetJump) +ASM_PFX(SetJump): + pop %rdx + mov %rbx,(%rdi) # Rbx + mov %rsp,0x8(%rdi) + mov %rbp,0x10(%rdi) + mov %rcx,0x18(%rdi) + mov %rsi,0x20(%rdi) + mov %r12,0x28(%rdi) + mov %r13,0x30(%rdi) + mov %r14,0x38(%rdi) + mov %r15,0x40(%rdi) + mov %rdx,0x48(%rdi) + # save non-volatile fp registers + stmxcsr 0x50(%rdi) + movdqu %xmm6, 0x58(%rdi) + movdqu %xmm7, 0x68(%rdi) + movdqu %xmm8, 0x78(%rdi) + movdqu %xmm9, 0x88(%rdi) + movdqu %xmm10, 0x98(%rdi) + movdqu %xmm11, 0xA8(%rdi) + movdqu %xmm12, 0xB8(%rdi) + movdqu %xmm13, 0xC8(%rdi) + movdqu %xmm14, 0xD8(%rdi) + movdqu %xmm15, 0xE8(%rdi) + xor %rax,%rax + jmpq *%rdx diff --git a/UnixPkg/Library/UnixBaseLib/X64/SetJump.asm b/UnixPkg/Library/UnixBaseLib/X64/SetJump.asm new file mode 100644 index 0000000000..efdbb9a1fc --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/X64/SetJump.asm @@ -0,0 +1,66 @@ +;------------------------------------------------------------------------------ +; +; 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: +; +; SetJump.Asm +; +; Abstract: +; +; Implementation of SetJump() on x64. +; +;------------------------------------------------------------------------------ + + .code + +EXTERNDEF InternalAssertJumpBuffer:PROC + +;------------------------------------------------------------------------------ +; UINTN +; EFIAPI +; SetJump ( +; OUT BASE_LIBRARY_JUMP_BUFFER *JumpBuffer +; ); +;------------------------------------------------------------------------------ +SetJump PROC + push rcx + add rsp, -20h + call InternalAssertJumpBuffer + add rsp, 20h + pop rcx + pop rdx + mov [rcx], rbx + mov [rcx + 8], rsp + mov [rcx + 10h], rbp + mov [rcx + 18h], rdi + mov [rcx + 20h], rsi + mov [rcx + 28h], r12 + mov [rcx + 30h], r13 + mov [rcx + 38h], r14 + mov [rcx + 40h], r15 + mov [rcx + 48h], rdx + ; save non-volatile fp registers + stmxcsr [rcx + 50h] + movdqu [rcx + 58h], xmm6 + movdqu [rcx + 68h], xmm7 + movdqu [rcx + 78h], xmm8 + movdqu [rcx + 88h], xmm9 + movdqu [rcx + 98h], xmm10 + movdqu [rcx + 0A8h], xmm11 + movdqu [rcx + 0B8h], xmm12 + movdqu [rcx + 0C8h], xmm13 + movdqu [rcx + 0D8h], xmm14 + movdqu [rcx + 0E8h], xmm15 + xor rax, rax + jmp rdx +SetJump ENDP + + END diff --git a/UnixPkg/Library/UnixBaseLib/X64/SwitchStack.S b/UnixPkg/Library/UnixBaseLib/X64/SwitchStack.S new file mode 100644 index 0000000000..b6dff5ed77 --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/X64/SwitchStack.S @@ -0,0 +1,79 @@ +#------------------------------------------------------------------------------ +# +# Copyright (c) 2006 - 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. +# +# Module Name: +# +# SwitchStack.S +# +# Abstract: +# +#------------------------------------------------------------------------------ + + +#------------------------------------------------------------------------------ +# Routine Description: +# +# Routine for switching stacks with 2 parameters +# +# Arguments: +# +# (rcx) EntryPoint - Entry point with new stack. +# (rdx) Context1 - Parameter1 for entry point. +# (r8) Context2 - Parameter2 for entry point. +# (r9) NewStack - The pointer to new stack. +# +# Returns: +# +# None +# +#------------------------------------------------------------------------------ +ASM_GLOBAL ASM_PFX(EfiInternalSwitchStack) +ASM_PFX(EfiInternalSwitchStack): + mov %rcx, %rax + mov %rdx, %rcx + mov %r8, %rdx + # + # Reserve space for register parameters (rcx, rdx, r8 & r9) on the stack, + # in case the callee wishes to spill them. + # + lea -0x20(%r9), %rsp + call *%rax + + + +#------------------------------------------------------------------------------ +# Routine Description: +# +# Routine for switching stacks with 2 parameters (Unix ABI) +# +# Arguments: +# +# (rdi) EntryPoint - Entry point with new stack. +# (rsi) Context1 - Parameter1 for entry point. +# (rdx) Context2 - Parameter2 for entry point. +# (rcx) NewStack - The pointer to new stack. +# +# Returns: +# +# None +# +#------------------------------------------------------------------------------ +ASM_GLOBAL ASM_PFX(InternalSwitchStack) +ASM_PFX(InternalSwitchStack): + mov %rdi, %rax + mov %rsi, %rdi + mov %rdx, %rsi + # + # Reserve space for register parameters (rcx, rdx, r8 & r9) on the stack, + # in case the callee wishes to spill them. + # + lea -0x20(%rcx), %rsp + call *%rax diff --git a/UnixPkg/Library/UnixBaseLib/X64/SwitchStack.asm b/UnixPkg/Library/UnixBaseLib/X64/SwitchStack.asm new file mode 100644 index 0000000000..0f802b0174 --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/X64/SwitchStack.asm @@ -0,0 +1,51 @@ +;------------------------------------------------------------------------------ +; +; Copyright (c) 2006 - 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. +; +; Module Name: +; +; SwitchStack.Asm +; +; Abstract: +; +;------------------------------------------------------------------------------ + + .code + +;------------------------------------------------------------------------------ +; Routine Description: +; +; Routine for switching stacks with 2 parameters +; +; Arguments: +; +; (rcx) EntryPoint - Entry point with new stack. +; (rdx) Context1 - Parameter1 for entry point. +; (r8) Context2 - Parameter2 for entry point. +; (r9) NewStack - The pointer to new stack. +; +; Returns: +; +; None +; +;------------------------------------------------------------------------------ +InternalSwitchStack PROC + mov rax, rcx + mov rcx, rdx + mov rdx, r8 + ; + ; Reserve space for register parameters (rcx, rdx, r8 & r9) on the stack, + ; in case the callee wishes to spill them. + ; + lea rsp, [r9 - 20h] + call rax +InternalSwitchStack ENDP + + END diff --git a/UnixPkg/Library/UnixBaseLib/X64/Thunk16.S b/UnixPkg/Library/UnixBaseLib/X64/Thunk16.S new file mode 100644 index 0000000000..fa9b3d6035 --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/X64/Thunk16.S @@ -0,0 +1,325 @@ +#------------------------------------------------------------------------------ +# +# 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: +# +# Thunk16.S +# +# Abstract: +# +# Real mode thunk +# +#------------------------------------------------------------------------------ + +#include + +ASM_GLOBAL ASM_PFX(m16Start) +ASM_GLOBAL ASM_PFX(m16Size) +ASM_GLOBAL ASM_PFX(mThunk16Attr) +ASM_GLOBAL ASM_PFX(m16Gdt) +ASM_GLOBAL ASM_PFX(m16GdtrBase) +ASM_GLOBAL ASM_PFX(mTransition) +ASM_GLOBAL ASM_PFX(InternalAsmThunk16) + +# define the structure of IA32_REGS +.set _EDI, 0 #size 4 +.set _ESI, 4 #size 4 +.set _EBP, 8 #size 4 +.set _ESP, 12 #size 4 +.set _EBX, 16 #size 4 +.set _EDX, 20 #size 4 +.set _ECX, 24 #size 4 +.set _EAX, 28 #size 4 +.set _DS, 32 #size 2 +.set _ES, 34 #size 2 +.set _FS, 36 #size 2 +.set _GS, 38 #size 2 +.set _EFLAGS, 40 #size 8 +.set _EIP, 48 #size 4 +.set _CS, 52 #size 2 +.set _SS, 54 #size 2 +.set IA32_REGS_SIZE, 56 + + .data + +ASM_PFX(m16Size): .word ASM_PFX(InternalAsmThunk16) - ASM_PFX(m16Start) +ASM_PFX(mThunk16Attr): .word _ThunkAttr - ASM_PFX(m16Start) +ASM_PFX(m16Gdt): .word ASM_PFX(NullSeg) - ASM_PFX(m16Start) +ASM_PFX(m16GdtrBase): .word _16GdtrBase - ASM_PFX(m16Start) +ASM_PFX(mTransition): .word _EntryPoint - ASM_PFX(m16Start) + + .text + +ASM_PFX(m16Start): + +SavedGdt: .space 10 + +#------------------------------------------------------------------------------ +# _BackFromUserCode() takes control in real mode after 'retf' has been executed +# by user code. It will be shadowed to somewhere in memory below 1MB. +#------------------------------------------------------------------------------ +ASM_GLOBAL ASM_PFX(BackFromUserCode) +ASM_PFX(BackFromUserCode): + # + # The order of saved registers on the stack matches the order they appears + # in IA32_REGS structure. This facilitates wrapper function to extract them + # into that structure. + # + # Some instructions for manipulation of segment registers have to be written + # in opcode since 64-bit MASM prevents accesses to those registers. + # + .byte 0x16 # push ss + .byte 0xe # push cs + .byte 0x66 + call L_Base # push eip +L_Base: + .byte 0x66 + pushq $0 # reserved high order 32 bits of EFlags + .byte 0x66, 0x9c # pushfd actually + cli # disable interrupts + push %gs + push %fs + .byte 6 # push es + .byte 0x1e # push ds + .byte 0x66,0x60 # pushad + .byte 0x66,0xba # mov edx, imm32 +_ThunkAttr: .space 4 + testb $THUNK_ATTRIBUTE_DISABLE_A20_MASK_INT_15, %dl + jz L_1 + movl $0x15cd2401,%eax # mov ax, 2401h & int 15h + cli # disable interrupts + jnc L_2 +L_1: + testb $THUNK_ATTRIBUTE_DISABLE_A20_MASK_KBD_CTRL, %dl + jz L_2 + inb $0x92,%al + orb $2,%al + outb %al, $0x92 # deactivate A20M# +L_2: + movl %ss,%eax + lea IA32_REGS_SIZE(%esp), %bp + # + # rsi in the following 2 instructions is indeed bp in 16-bit code + # + movw %bp, (_ESP - IA32_REGS_SIZE)(%rsi) + .byte 0x66 + movl (_EIP - IA32_REGS_SIZE)(%rsi), %ebx + shlw $4,%ax # shl eax, 4 + addw %ax,%bp # add ebp, eax + movw %cs,%ax + shlw $4,%ax + lea (L_64BitCode - L_Base)(%ebx, %eax), %ax + .byte 0x66,0x2e,0x89,0x87 # mov cs:[bx + (L_64Eip - L_Base)], eax + .word L_64Eip - L_Base + .byte 0x66,0xb8 # mov eax, imm32 +SavedCr4: .space 4 + movq %rax, %cr4 + # + # rdi in the instruction below is indeed bx in 16-bit code + # + .byte 0x66,0x2e # 2eh is "cs:" segment override + lgdt (SavedGdt - L_Base)(%rdi) + .byte 0x66 + movl $0xc0000080,%ecx + rdmsr + orb $1,%ah + wrmsr + .byte 0x66,0xb8 # mov eax, imm32 +SavedCr0: .space 4 + movq %rax, %cr0 + .byte 0x66,0xea # jmp far cs:L_64Bit +L_64Eip: .space 4 +SavedCs: .space 2 +L_64BitCode: + .byte 0x90 + .byte 0x67,0xbc # mov esp, imm32 +SavedSp: .space 4 # restore stack + nop + ret + +_EntryPoint: .long ASM_PFX(ToUserCode) - ASM_PFX(m16Start) + .word CODE16 +_16Gdtr: .word GDT_SIZE - 1 +_16GdtrBase: .quad ASM_PFX(NullSeg) +_16Idtr: .word 0x3ff + .long 0 + +#------------------------------------------------------------------------------ +# _ToUserCode() takes control in real mode before passing control to user code. +# It will be shadowed to somewhere in memory below 1MB. +#------------------------------------------------------------------------------ +ASM_GLOBAL ASM_PFX(ToUserCode) +ASM_PFX(ToUserCode): + movl %edx,%ss # set new segment selectors + movl %edx,%ds + movl %edx,%es + movl %edx,%fs + movl %edx,%gs + .byte 0x66 + movl $0xc0000080,%ecx + movq %rax, %cr0 + rdmsr + andb $0xfe, %ah # $0b11111110 + wrmsr + movq %rbp, %cr4 + movl %esi,%ss # set up 16-bit stack segment + movw %bx,%sp # set up 16-bit stack pointer + .byte 0x66 # make the following call 32-bit + call L_Base1 # push eip +L_Base1: + popw %bp # ebp <- address of L_Base1 + pushq (IA32_REGS_SIZE + 2)(%esp) + lea 0x0c(%rsi), %eax + pushq %rax + lret # execution begins at next instruction +L_RealMode: + .byte 0x66,0x2e # CS and operand size override + lidt (_16Idtr - L_Base1)(%rsi) + .byte 0x66,0x61 # popad + .byte 0x1f # pop ds + .byte 0x7 # pop es + .byte 0x0f, 0xa1 # pop fs + .byte 0x0f, 0xa9 # pop gs + .byte 0x66, 0x9d # popfd + leaw 4(%esp),%sp # skip high order 32 bits of EFlags + .byte 0x66 # make the following retf 32-bit + lret # transfer control to user code + +.set CODE16, ASM_PFX(_16Code) - . +.set DATA16, ASM_PFX(_16Data) - . +.set DATA32, ASM_PFX(_32Data) - . + +ASM_PFX(NullSeg): .quad 0 +ASM_PFX(_16Code): + .word -1 + .word 0 + .byte 0 + .byte 0x9b + .byte 0x8f # 16-bit segment, 4GB limit + .byte 0 +ASM_PFX(_16Data): + .word -1 + .word 0 + .byte 0 + .byte 0x93 + .byte 0x8f # 16-bit segment, 4GB limit + .byte 0 +ASM_PFX(_32Data): + .word -1 + .word 0 + .byte 0 + .byte 0x93 + .byte 0xcf # 16-bit segment, 4GB limit + .byte 0 + +.set GDT_SIZE, . - ASM_PFX(NullSeg) + +#------------------------------------------------------------------------------ +# IA32_REGISTER_SET * +# EFIAPI +# InternalAsmThunk16 ( +# IN IA32_REGISTER_SET *RegisterSet, +# IN OUT VOID *Transition +# ); +#------------------------------------------------------------------------------ + +ASM_GLOBAL ASM_PFX(InternalAsmThunk16) +ASM_PFX(InternalAsmThunk16): + pushq %rbp + pushq %rbx + pushq %rsi + pushq %rdi + + movl %ds, %ebx + pushq %rbx # Save ds segment register on the stack + movl %es, %ebx + pushq %rbx # Save es segment register on the stack + movl %ss, %ebx + pushq %rbx # Save ss segment register on the stack + + .byte 0x0f, 0xa0 #push fs + .byte 0x0f, 0xa8 #push gs + movq %rcx, %rsi + movzwl _SS(%rsi), %r8d + movl _ESP(%rsi), %edi + lea -(IA32_REGS_SIZE + 4)(%edi), %rdi + imul $16, %r8d, %eax + movl %edi,%ebx # ebx <- stack for 16-bit code + pushq $(IA32_REGS_SIZE / 4) + addl %eax,%edi # edi <- linear address of 16-bit stack + popq %rcx + rep + movsl # copy RegSet + lea (SavedCr4 - ASM_PFX(m16Start))(%rdx), %ecx + movl %edx,%eax # eax <- transition code address + andl $0xf,%edx + shll $12,%eax # segment address in high order 16 bits + lea (ASM_PFX(BackFromUserCode) - ASM_PFX(m16Start))(%rdx), %ax + stosl # [edi] <- return address of user code + sgdt 0x60(%rsp) # save GDT stack in argument space + movzwq 0x60(%rsp), %r10 # r10 <- GDT limit + lea ((ASM_PFX(InternalAsmThunk16) - SavedCr4) + 0xf)(%rcx), %r11 + andq $0xfffffffffffffff0, %r11 # r11 <- 16-byte aligned shadowed GDT table in real mode buffer + + movw %r10w, (SavedGdt - SavedCr4)(%rcx) # save the limit of shadowed GDT table + movq %r11, (SavedGdt - SavedCr4 + 0x2)(%rcx) # save the base address of shadowed GDT table + + movq 0x62(%rsp) ,%rsi # rsi <- the original GDT base address + xchg %r10, %rcx # save rcx to r10 and initialize rcx to be the limit of GDT table + incq %rcx # rcx <- the size of memory to copy + xchg %r11, %rdi # save rdi to r11 and initialize rdi to the base address of shadowed GDT table + rep + movsb # perform memory copy to shadow GDT table + movq %r10, %rcx # restore the orignal rcx before memory copy + movq %r11, %rdi # restore the original rdi before memory copy + + sidt 0x50(%rsp) + movq %cr0, %rax + movl %eax, (SavedCr0 - SavedCr4)(%rcx) + andl $0x7ffffffe,%eax # clear PE, PG bits + movq %cr4, %rbp + movl %ebp, (%rcx) # save CR4 in SavedCr4 + andl $0x300,%ebp # clear all but PCE and OSFXSR bits + movl %r8d, %esi # esi <- 16-bit stack segment + .byte 0x6a, DATA32 + popq %rdx + lgdt (_16Gdtr - SavedCr4)(%rcx) + movl %edx,%ss + pushfq + lea -8(%rdx), %edx + lea L_RetFromRealMode(%rip), %r8 + pushq %r8 + movl %cs, %r8d + movw %r8w, (SavedCs - SavedCr4)(%rcx) + movl %esp, (SavedSp - SavedCr4)(%rcx) + .byte 0xff, 0x69 # jmp (_EntryPoint - SavedCr4)(%rcx) + .byte _EntryPoint - SavedCr4 +L_RetFromRealMode: + popfq + lgdt 0x60(%rsp) # restore protected mode GDTR + lidt 0x50(%rsp) # restore protected mode IDTR + lea -IA32_REGS_SIZE(%rbp), %eax + .byte 0x0f, 0xa9 # pop gs + .byte 0x0f, 0xa1 # pop fs + + popq %rbx + movl %ebx, %ss + popq %rbx + movl %ebx, %es + popq %rbx + movl %ebx, %ds + + popq %rdi + popq %rsi + popq %rbx + popq %rbp + + ret diff --git a/UnixPkg/Library/UnixBaseLib/X64/Thunk16.asm b/UnixPkg/Library/UnixBaseLib/X64/Thunk16.asm new file mode 100644 index 0000000000..459966a43f --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/X64/Thunk16.asm @@ -0,0 +1,314 @@ + +#include "BaseLibInternals.h" + +;------------------------------------------------------------------------------ +; +; Copyright (c) 2006 - 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. +; +; Module Name: +; +; Thunk.asm +; +; Abstract: +; +; Real mode thunk +; +;------------------------------------------------------------------------------ + +EXTERNDEF m16Start:BYTE +EXTERNDEF m16Size:WORD +EXTERNDEF mThunk16Attr:WORD +EXTERNDEF m16Gdt:WORD +EXTERNDEF m16GdtrBase:WORD +EXTERNDEF mTransition:WORD + +IA32_REGS STRUC 4t +_EDI DD ? +_ESI DD ? +_EBP DD ? +_ESP DD ? +_EBX DD ? +_EDX DD ? +_ECX DD ? +_EAX DD ? +_DS DW ? +_ES DW ? +_FS DW ? +_GS DW ? +_EFLAGS DQ ? +_EIP DD ? +_CS DW ? +_SS DW ? +IA32_REGS ENDS + + .const + +m16Size DW InternalAsmThunk16 - m16Start +mThunk16Attr DW _ThunkAttr - m16Start +m16Gdt DW _NullSeg - m16Start +m16GdtrBase DW _16GdtrBase - m16Start +mTransition DW _EntryPoint - m16Start + + .code + +m16Start LABEL BYTE + +SavedGdt LABEL FWORD + DW ? + DQ ? + +;------------------------------------------------------------------------------ +; _BackFromUserCode() takes control in real mode after 'retf' has been executed +; by user code. It will be shadowed to somewhere in memory below 1MB. +;------------------------------------------------------------------------------ +_BackFromUserCode PROC + ; + ; The order of saved registers on the stack matches the order they appears + ; in IA32_REGS structure. This facilitates wrapper function to extract them + ; into that structure. + ; + ; Some instructions for manipulation of segment registers have to be written + ; in opcode since 64-bit MASM prevents accesses to those registers. + ; + DB 16h ; push ss + DB 0eh ; push cs + DB 66h + call @Base ; push eip +@Base: + DB 66h + push 0 ; reserved high order 32 bits of EFlags + pushf ; pushfd actually + cli ; disable interrupts + push gs + push fs + DB 6 ; push es + DB 1eh ; push ds + DB 66h, 60h ; pushad + DB 66h, 0bah ; mov edx, imm32 +_ThunkAttr DD ? + test dl, THUNK_ATTRIBUTE_DISABLE_A20_MASK_INT_15 + jz @1 + mov eax, 15cd2401h ; mov ax, 2401h & int 15h + cli ; disable interrupts + jnc @2 +@1: + test dl, THUNK_ATTRIBUTE_DISABLE_A20_MASK_KBD_CTRL + jz @2 + in al, 92h + or al, 2 + out 92h, al ; deactivate A20M# +@2: + mov eax, ss + lea bp, [esp + sizeof (IA32_REGS)] + ; + ; rsi in the following 2 instructions is indeed bp in 16-bit code + ; + mov word ptr (IA32_REGS ptr [rsi - sizeof (IA32_REGS)])._ESP, bp + DB 66h + mov ebx, (IA32_REGS ptr [rsi - sizeof (IA32_REGS)])._EIP + shl ax, 4 ; shl eax, 4 + add bp, ax ; add ebp, eax + mov ax, cs + shl ax, 4 + lea ax, [eax + ebx + (@64BitCode - @Base)] + DB 66h, 2eh, 89h, 87h ; mov cs:[bx + (@64Eip - @Base)], eax + DW @64Eip - @Base + DB 66h, 0b8h ; mov eax, imm32 +SavedCr4 DD ? + mov cr4, rax + ; + ; rdi in the instruction below is indeed bx in 16-bit code + ; + DB 66h, 2eh ; 2eh is "cs:" segment override + lgdt fword ptr [rdi + (SavedGdt - @Base)] + DB 66h + mov ecx, 0c0000080h + rdmsr + or ah, 1 + wrmsr + DB 66h, 0b8h ; mov eax, imm32 +SavedCr0 DD ? + mov cr0, rax + DB 66h, 0eah ; jmp far cs:@64Bit +@64Eip DD ? +SavedCs DW ? +@64BitCode: + db 090h + db 067h, 0bch ; mov esp, imm32 +SavedSp DD ? ; restore stack + nop + ret +_BackFromUserCode ENDP + +_EntryPoint DD _ToUserCode - m16Start + DW CODE16 +_16Gdtr LABEL FWORD + DW GDT_SIZE - 1 +_16GdtrBase DQ _NullSeg +_16Idtr FWORD (1 SHL 10) - 1 + +;------------------------------------------------------------------------------ +; _ToUserCode() takes control in real mode before passing control to user code. +; It will be shadowed to somewhere in memory below 1MB. +;------------------------------------------------------------------------------ +_ToUserCode PROC + mov ss, edx ; set new segment selectors + mov ds, edx + mov es, edx + mov fs, edx + mov gs, edx + DB 66h + mov ecx, 0c0000080h + mov cr0, rax ; real mode starts at next instruction + rdmsr + and ah, NOT 1 + wrmsr + mov cr4, rbp + mov ss, esi ; set up 16-bit stack segment + mov sp, bx ; set up 16-bit stack pointer + DB 66h ; make the following call 32-bit + call @Base ; push eip +@Base: + pop bp ; ebp <- address of @Base + push [esp + sizeof (IA32_REGS) + 2] + lea eax, [rsi + (@RealMode - @Base)] ; rsi is "bp" in 16-bit code + push rax + retf ; execution begins at next instruction +@RealMode: + DB 66h, 2eh ; CS and operand size override + lidt fword ptr [rsi + (_16Idtr - @Base)] + DB 66h, 61h ; popad + DB 1fh ; pop ds + DB 07h ; pop es + pop fs + pop gs + popf ; popfd + lea sp, [esp + 4] ; skip high order 32 bits of EFlags + DB 66h ; make the following retf 32-bit + retf ; transfer control to user code +_ToUserCode ENDP + +CODE16 = _16Code - $ +DATA16 = _16Data - $ +DATA32 = _32Data - $ + +_NullSeg DQ 0 +_16Code LABEL QWORD + DW -1 + DW 0 + DB 0 + DB 9bh + DB 8fh ; 16-bit segment, 4GB limit + DB 0 +_16Data LABEL QWORD + DW -1 + DW 0 + DB 0 + DB 93h + DB 8fh ; 16-bit segment, 4GB limit + DB 0 +_32Data LABEL QWORD + DW -1 + DW 0 + DB 0 + DB 93h + DB 0cfh ; 16-bit segment, 4GB limit + DB 0 + +GDT_SIZE = $ - _NullSeg + +;------------------------------------------------------------------------------ +; IA32_REGISTER_SET * +; EFIAPI +; InternalAsmThunk16 ( +; IN IA32_REGISTER_SET *RegisterSet, +; IN OUT VOID *Transition +; ); +;------------------------------------------------------------------------------ +InternalAsmThunk16 PROC USES rbp rbx rsi rdi + mov rbx, ds + push rbx ; Save ds segment register on the stack + mov rbx, es + push rbx ; Save es segment register on the stack + mov rbx, ss + push rbx ; Save ss segment register on the stack + + push fs + push gs + mov rsi, rcx + movzx r8d, (IA32_REGS ptr [rsi])._SS + mov edi, (IA32_REGS ptr [rsi])._ESP + lea rdi, [edi - (sizeof (IA32_REGS) + 4)] + imul eax, r8d, 16 ; eax <- r8d(stack segment) * 16 + mov ebx, edi ; ebx <- stack for 16-bit code + push sizeof (IA32_REGS) / 4 + add edi, eax ; edi <- linear address of 16-bit stack + pop rcx + rep movsd ; copy RegSet + lea ecx, [rdx + (SavedCr4 - m16Start)] + mov eax, edx ; eax <- transition code address + and edx, 0fh + shl eax, 12 ; segment address in high order 16 bits + lea ax, [rdx + (_BackFromUserCode - m16Start)] ; offset address + stosd ; [edi] <- return address of user code + + sgdt fword ptr [rsp + 60h] ; save GDT stack in argument space + movzx r10, word ptr [rsp + 60h] ; r10 <- GDT limit + lea r11, [rcx + (InternalAsmThunk16 - SavedCr4) + 0xf] + and r11, 0xfffffff0 ; r11 <- 16-byte aligned shadowed GDT table in real mode buffer + + mov word ptr [rcx + (SavedGdt - SavedCr4)], r10w ; save the limit of shadowed GDT table + mov qword ptr [rcx + (SavedGdt - SavedCr4) + 2], r11 ; save the base address of shadowed GDT table + + mov rsi, qword ptr [rsp + 62h] ; rsi <- the original GDT base address + xchg rcx, r10 ; save rcx to r10 and initialize rcx to be the limit of GDT table + inc rcx ; rcx <- the size of memory to copy + xchg rdi, r11 ; save rdi to r11 and initialize rdi to the base address of shadowed GDT table + rep movsb ; perform memory copy to shadow GDT table + mov rcx, r10 ; restore the orignal rcx before memory copy + mov rdi, r11 ; restore the original rdi before memory copy + + sidt fword ptr [rsp + 50h] ; save IDT stack in argument space + mov rax, cr0 + mov [rcx + (SavedCr0 - SavedCr4)], eax + and eax, 7ffffffeh ; clear PE, PG bits + mov rbp, cr4 + mov [rcx], ebp ; save CR4 in SavedCr4 + and ebp, 300h ; clear all but PCE and OSFXSR bits + mov esi, r8d ; esi <- 16-bit stack segment + DB 6ah, DATA32 ; push DATA32 + pop rdx ; rdx <- 32-bit data segment selector + lgdt fword ptr [rcx + (_16Gdtr - SavedCr4)] + mov ss, edx + pushfq + lea edx, [rdx + DATA16 - DATA32] + lea r8, @RetFromRealMode + push r8 + mov r8d, cs + mov [rcx + (SavedCs - SavedCr4)], r8w + mov [rcx + (SavedSp - SavedCr4)], esp + jmp fword ptr [rcx + (_EntryPoint - SavedCr4)] +@RetFromRealMode: + popfq + lgdt fword ptr [rsp + 60h] ; restore protected mode GDTR + lidt fword ptr [rsp + 50h] ; restore protected mode IDTR + lea eax, [rbp - sizeof (IA32_REGS)] + pop gs + pop fs + pop rbx + mov ss, rbx + pop rbx + mov es, rbx + pop rbx + mov ds, rbx + ret +InternalAsmThunk16 ENDP + + END diff --git a/UnixPkg/Library/UnixBaseLib/X64/Wbinvd.S b/UnixPkg/Library/UnixBaseLib/X64/Wbinvd.S new file mode 100644 index 0000000000..52702d55ad --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/X64/Wbinvd.S @@ -0,0 +1,35 @@ +#------------------------------------------------------------------------------ +# +# 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: +# +# Wbinvd.S +# +# Abstract: +# +# AsmWbinvd function +# +# Notes: +# +#------------------------------------------------------------------------------ + + +#------------------------------------------------------------------------------ +# VOID +# EFIAPI +# AsmWbinvd ( +# VOID +# ); +#------------------------------------------------------------------------------ +ASM_GLOBAL ASM_PFX(AsmWbinvd) +ASM_PFX(AsmWbinvd): + wbinvd + ret diff --git a/UnixPkg/Library/UnixBaseLib/X64/Wbinvd.asm b/UnixPkg/Library/UnixBaseLib/X64/Wbinvd.asm new file mode 100644 index 0000000000..b0807e088f --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/X64/Wbinvd.asm @@ -0,0 +1,38 @@ +;------------------------------------------------------------------------------ +; +; 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: +; +; Wbinvd.Asm +; +; Abstract: +; +; AsmWbinvd function +; +; Notes: +; +;------------------------------------------------------------------------------ + + .code + +;------------------------------------------------------------------------------ +; VOID +; EFIAPI +; AsmWbinvd ( +; VOID +; ); +;------------------------------------------------------------------------------ +AsmWbinvd PROC + wbinvd + ret +AsmWbinvd ENDP + + END diff --git a/UnixPkg/Library/UnixBaseLib/X64/WriteCr0.asm b/UnixPkg/Library/UnixBaseLib/X64/WriteCr0.asm new file mode 100644 index 0000000000..98fef9cd61 --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/X64/WriteCr0.asm @@ -0,0 +1,39 @@ +;------------------------------------------------------------------------------ +; +; 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: +; +; WriteCr0.Asm +; +; Abstract: +; +; AsmWriteCr0 function +; +; Notes: +; +;------------------------------------------------------------------------------ + + .code + +;------------------------------------------------------------------------------ +; UINTN +; EFIAPI +; AsmWriteCr0 ( +; UINTN Cr0 +; ); +;------------------------------------------------------------------------------ +AsmWriteCr0 PROC + mov cr0, rcx + mov rax, rcx + ret +AsmWriteCr0 ENDP + + END diff --git a/UnixPkg/Library/UnixBaseLib/X64/WriteCr2.asm b/UnixPkg/Library/UnixBaseLib/X64/WriteCr2.asm new file mode 100644 index 0000000000..3d77d6aef2 --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/X64/WriteCr2.asm @@ -0,0 +1,39 @@ +;------------------------------------------------------------------------------ +; +; 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: +; +; WriteCr2.Asm +; +; Abstract: +; +; AsmWriteCr2 function +; +; Notes: +; +;------------------------------------------------------------------------------ + + .code + +;------------------------------------------------------------------------------ +; UINTN +; EFIAPI +; AsmWriteCr2 ( +; UINTN Cr2 +; ); +;------------------------------------------------------------------------------ +AsmWriteCr2 PROC + mov cr2, rcx + mov rax, rcx + ret +AsmWriteCr2 ENDP + + END diff --git a/UnixPkg/Library/UnixBaseLib/X64/WriteCr3.asm b/UnixPkg/Library/UnixBaseLib/X64/WriteCr3.asm new file mode 100644 index 0000000000..9b39938150 --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/X64/WriteCr3.asm @@ -0,0 +1,39 @@ +;------------------------------------------------------------------------------ +; +; 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: +; +; WriteCr3.Asm +; +; Abstract: +; +; AsmWriteCr3 function +; +; Notes: +; +;------------------------------------------------------------------------------ + + .code + +;------------------------------------------------------------------------------ +; UINTN +; EFIAPI +; AsmWriteCr3 ( +; UINTN Cr3 +; ); +;------------------------------------------------------------------------------ +AsmWriteCr3 PROC + mov cr3, rcx + mov rax, rcx + ret +AsmWriteCr3 ENDP + + END diff --git a/UnixPkg/Library/UnixBaseLib/X64/WriteCr4.asm b/UnixPkg/Library/UnixBaseLib/X64/WriteCr4.asm new file mode 100644 index 0000000000..145584257e --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/X64/WriteCr4.asm @@ -0,0 +1,39 @@ +;------------------------------------------------------------------------------ +; +; 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: +; +; WriteCr4.Asm +; +; Abstract: +; +; AsmWriteCr4 function +; +; Notes: +; +;------------------------------------------------------------------------------ + + .code + +;------------------------------------------------------------------------------ +; UINTN +; EFIAPI +; AsmWriteCr4 ( +; UINTN Cr4 +; ); +;------------------------------------------------------------------------------ +AsmWriteCr4 PROC + mov cr4, rcx + mov rax, rcx + ret +AsmWriteCr4 ENDP + + END diff --git a/UnixPkg/Library/UnixBaseLib/X64/WriteDr0.asm b/UnixPkg/Library/UnixBaseLib/X64/WriteDr0.asm new file mode 100644 index 0000000000..dafe9ab169 --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/X64/WriteDr0.asm @@ -0,0 +1,39 @@ +;------------------------------------------------------------------------------ +; +; 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: +; +; WriteDr0.Asm +; +; Abstract: +; +; AsmWriteDr0 function +; +; Notes: +; +;------------------------------------------------------------------------------ + + .code + +;------------------------------------------------------------------------------ +; UINTN +; EFIAPI +; AsmWriteDr0 ( +; IN UINTN Value +; ); +;------------------------------------------------------------------------------ +AsmWriteDr0 PROC + mov dr0, rcx + mov rax, rcx + ret +AsmWriteDr0 ENDP + + END diff --git a/UnixPkg/Library/UnixBaseLib/X64/WriteDr1.asm b/UnixPkg/Library/UnixBaseLib/X64/WriteDr1.asm new file mode 100644 index 0000000000..7167f5e5c2 --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/X64/WriteDr1.asm @@ -0,0 +1,39 @@ +;------------------------------------------------------------------------------ +; +; 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: +; +; WriteDr1.Asm +; +; Abstract: +; +; AsmWriteDr1 function +; +; Notes: +; +;------------------------------------------------------------------------------ + + .code + +;------------------------------------------------------------------------------ +; UINTN +; EFIAPI +; AsmWriteDr1 ( +; IN UINTN Value +; ); +;------------------------------------------------------------------------------ +AsmWriteDr1 PROC + mov dr1, rcx + mov rax, rcx + ret +AsmWriteDr1 ENDP + + END diff --git a/UnixPkg/Library/UnixBaseLib/X64/WriteDr2.asm b/UnixPkg/Library/UnixBaseLib/X64/WriteDr2.asm new file mode 100644 index 0000000000..c14ba34b15 --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/X64/WriteDr2.asm @@ -0,0 +1,39 @@ +;------------------------------------------------------------------------------ +; +; 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: +; +; WriteDr2.Asm +; +; Abstract: +; +; AsmWriteDr2 function +; +; Notes: +; +;------------------------------------------------------------------------------ + + .code + +;------------------------------------------------------------------------------ +; UINTN +; EFIAPI +; AsmWriteDr2 ( +; IN UINTN Value +; ); +;------------------------------------------------------------------------------ +AsmWriteDr2 PROC + mov dr2, rcx + mov rax, rcx + ret +AsmWriteDr2 ENDP + + END diff --git a/UnixPkg/Library/UnixBaseLib/X64/WriteDr3.asm b/UnixPkg/Library/UnixBaseLib/X64/WriteDr3.asm new file mode 100644 index 0000000000..8873916c4e --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/X64/WriteDr3.asm @@ -0,0 +1,39 @@ +;------------------------------------------------------------------------------ +; +; 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: +; +; WriteDr3.Asm +; +; Abstract: +; +; AsmWriteDr3 function +; +; Notes: +; +;------------------------------------------------------------------------------ + + .code + +;------------------------------------------------------------------------------ +; UINTN +; EFIAPI +; AsmWriteDr3 ( +; IN UINTN Value +; ); +;------------------------------------------------------------------------------ +AsmWriteDr3 PROC + mov dr3, rcx + mov rax, rcx + ret +AsmWriteDr3 ENDP + + END diff --git a/UnixPkg/Library/UnixBaseLib/X64/WriteDr4.asm b/UnixPkg/Library/UnixBaseLib/X64/WriteDr4.asm new file mode 100644 index 0000000000..4803525dd9 --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/X64/WriteDr4.asm @@ -0,0 +1,43 @@ +;------------------------------------------------------------------------------ +; +; 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: +; +; WriteDr4.Asm +; +; Abstract: +; +; AsmWriteDr4 function +; +; Notes: +; +;------------------------------------------------------------------------------ + + .code + +;------------------------------------------------------------------------------ +; UINTN +; EFIAPI +; AsmWriteDr4 ( +; IN UINTN Value +; ); +;------------------------------------------------------------------------------ +AsmWriteDr4 PROC + ; + ; There's no obvious reason to access this register, since it's aliased to + ; DR6 when DE=0 or an exception generated when DE=1 + ; + DB 0fh, 23h, 0e1h + mov rax, rcx + ret +AsmWriteDr4 ENDP + + END diff --git a/UnixPkg/Library/UnixBaseLib/X64/WriteDr5.asm b/UnixPkg/Library/UnixBaseLib/X64/WriteDr5.asm new file mode 100644 index 0000000000..2cdb328771 --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/X64/WriteDr5.asm @@ -0,0 +1,43 @@ +;------------------------------------------------------------------------------ +; +; Copyright (c) 2006 - 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. +; +; Module Name: +; +; WriteDr5.Asm +; +; Abstract: +; +; AsmWriteDr5 function +; +; Notes: +; +;------------------------------------------------------------------------------ + + .code + +;------------------------------------------------------------------------------ +; UINTN +; EFIAPI +; AsmWriteDr5 ( +; IN UINTN Value +; ); +;------------------------------------------------------------------------------ +AsmWriteDr5 PROC + ; + ; There's no obvious reason to access this register, since it's aliased to + ; DR7 when DE=0 or an exception generated when DE=1 + ; + DB 0fh, 23h, 0e9h + mov rax, rcx + ret +AsmWriteDr5 ENDP + + END diff --git a/UnixPkg/Library/UnixBaseLib/X64/WriteDr6.asm b/UnixPkg/Library/UnixBaseLib/X64/WriteDr6.asm new file mode 100644 index 0000000000..22c9c871c4 --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/X64/WriteDr6.asm @@ -0,0 +1,39 @@ +;------------------------------------------------------------------------------ +; +; 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: +; +; WriteDr6.Asm +; +; Abstract: +; +; AsmWriteDr6 function +; +; Notes: +; +;------------------------------------------------------------------------------ + + .code + +;------------------------------------------------------------------------------ +; UINTN +; EFIAPI +; AsmWriteDr6 ( +; IN UINTN Value +; ); +;------------------------------------------------------------------------------ +AsmWriteDr6 PROC + mov dr6, rcx + mov rax, rcx + ret +AsmWriteDr6 ENDP + + END diff --git a/UnixPkg/Library/UnixBaseLib/X64/WriteDr7.asm b/UnixPkg/Library/UnixBaseLib/X64/WriteDr7.asm new file mode 100644 index 0000000000..b55afd39af --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/X64/WriteDr7.asm @@ -0,0 +1,39 @@ +;------------------------------------------------------------------------------ +; +; 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: +; +; WriteDr7.Asm +; +; Abstract: +; +; AsmWriteDr7 function +; +; Notes: +; +;------------------------------------------------------------------------------ + + .code + +;------------------------------------------------------------------------------ +; UINTN +; EFIAPI +; AsmWriteDr7 ( +; IN UINTN Value +; ); +;------------------------------------------------------------------------------ +AsmWriteDr7 PROC + mov dr7, rcx + mov rax, rcx + ret +AsmWriteDr7 ENDP + + END diff --git a/UnixPkg/Library/UnixBaseLib/X64/WriteGdtr.asm b/UnixPkg/Library/UnixBaseLib/X64/WriteGdtr.asm new file mode 100644 index 0000000000..0cc8b7ad7a --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/X64/WriteGdtr.asm @@ -0,0 +1,38 @@ +;------------------------------------------------------------------------------ +; +; 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: +; +; WriteGdtr.Asm +; +; Abstract: +; +; AsmWriteGdtr function +; +; Notes: +; +;------------------------------------------------------------------------------ + + .code + +;------------------------------------------------------------------------------ +; VOID +; EFIAPI +; InternalX86WriteGdtr ( +; IN CONST IA32_DESCRIPTOR *Idtr +; ); +;------------------------------------------------------------------------------ +InternalX86WriteGdtr PROC + lgdt fword ptr [rcx] + ret +InternalX86WriteGdtr ENDP + + END diff --git a/UnixPkg/Library/UnixBaseLib/X64/WriteIdtr.asm b/UnixPkg/Library/UnixBaseLib/X64/WriteIdtr.asm new file mode 100644 index 0000000000..01ca1c0b59 --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/X64/WriteIdtr.asm @@ -0,0 +1,41 @@ +;------------------------------------------------------------------------------ +; +; 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. +; +; Module Name: +; +; WriteIdtr.Asm +; +; Abstract: +; +; AsmWriteIdtr function +; +; Notes: +; +;------------------------------------------------------------------------------ + + .code + +;------------------------------------------------------------------------------ +; VOID +; EFIAPI +; InternalX86WriteIdtr ( +; IN CONST IA32_DESCRIPTOR *Idtr +; ); +;------------------------------------------------------------------------------ +InternalX86WriteIdtr PROC + pushfq + cli + lidt fword ptr [rcx] + popfq + ret +InternalX86WriteIdtr ENDP + + END diff --git a/UnixPkg/Library/UnixBaseLib/X64/WriteLdtr.asm b/UnixPkg/Library/UnixBaseLib/X64/WriteLdtr.asm new file mode 100644 index 0000000000..af6786389b --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/X64/WriteLdtr.asm @@ -0,0 +1,38 @@ +;------------------------------------------------------------------------------ +; +; 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: +; +; WriteLdtr.Asm +; +; Abstract: +; +; AsmWriteLdtr function +; +; Notes: +; +;------------------------------------------------------------------------------ + + .code + +;------------------------------------------------------------------------------ +; VOID +; EFIAPI +; AsmWriteLdtr ( +; IN UINT16 Ldtr +; ); +;------------------------------------------------------------------------------ +AsmWriteLdtr PROC + lldt cx + ret +AsmWriteLdtr ENDP + + END diff --git a/UnixPkg/Library/UnixBaseLib/X64/WriteMm0.asm b/UnixPkg/Library/UnixBaseLib/X64/WriteMm0.asm new file mode 100644 index 0000000000..f40db0339d --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/X64/WriteMm0.asm @@ -0,0 +1,41 @@ +;------------------------------------------------------------------------------ +; +; 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: +; +; WriteMm0.Asm +; +; Abstract: +; +; AsmWriteMm0 function +; +; Notes: +; +;------------------------------------------------------------------------------ + + .code + +;------------------------------------------------------------------------------ +; VOID +; EFIAPI +; AsmWriteMm0 ( +; IN UINT64 Value +; ); +;------------------------------------------------------------------------------ +AsmWriteMm0 PROC + ; + ; 64-bit MASM doesn't support MMX instructions, so use opcode here + ; + DB 48h, 0fh, 6eh, 0c1h + ret +AsmWriteMm0 ENDP + + END diff --git a/UnixPkg/Library/UnixBaseLib/X64/WriteMm1.asm b/UnixPkg/Library/UnixBaseLib/X64/WriteMm1.asm new file mode 100644 index 0000000000..ec17208ec4 --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/X64/WriteMm1.asm @@ -0,0 +1,41 @@ +;------------------------------------------------------------------------------ +; +; 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: +; +; WriteMm1.Asm +; +; Abstract: +; +; AsmWriteMm1 function +; +; Notes: +; +;------------------------------------------------------------------------------ + + .code + +;------------------------------------------------------------------------------ +; VOID +; EFIAPI +; AsmWriteMm1 ( +; IN UINT64 Value +; ); +;------------------------------------------------------------------------------ +AsmWriteMm1 PROC + ; + ; 64-bit MASM doesn't support MMX instructions, so use opcode here + ; + DB 48h, 0fh, 6eh, 0c9h + ret +AsmWriteMm1 ENDP + + END diff --git a/UnixPkg/Library/UnixBaseLib/X64/WriteMm2.asm b/UnixPkg/Library/UnixBaseLib/X64/WriteMm2.asm new file mode 100644 index 0000000000..38c0d5ed26 --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/X64/WriteMm2.asm @@ -0,0 +1,41 @@ +;------------------------------------------------------------------------------ +; +; 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: +; +; WriteMm2.Asm +; +; Abstract: +; +; AsmWriteMm2 function +; +; Notes: +; +;------------------------------------------------------------------------------ + + .code + +;------------------------------------------------------------------------------ +; VOID +; EFIAPI +; AsmWriteMm2 ( +; IN UINT64 Value +; ); +;------------------------------------------------------------------------------ +AsmWriteMm2 PROC + ; + ; 64-bit MASM doesn't support MMX instructions, so use opcode here + ; + DB 48h, 0fh, 6eh, 0d1h + ret +AsmWriteMm2 ENDP + + END diff --git a/UnixPkg/Library/UnixBaseLib/X64/WriteMm3.asm b/UnixPkg/Library/UnixBaseLib/X64/WriteMm3.asm new file mode 100644 index 0000000000..5f5bbdd482 --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/X64/WriteMm3.asm @@ -0,0 +1,41 @@ +;------------------------------------------------------------------------------ +; +; 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: +; +; WriteMm3.Asm +; +; Abstract: +; +; AsmWriteMm3 function +; +; Notes: +; +;------------------------------------------------------------------------------ + + .code + +;------------------------------------------------------------------------------ +; VOID +; EFIAPI +; AsmWriteMm3 ( +; IN UINT64 Value +; ); +;------------------------------------------------------------------------------ +AsmWriteMm3 PROC + ; + ; 64-bit MASM doesn't support MMX instructions, so use opcode here + ; + DB 48h, 0fh, 6eh, 0d9h + ret +AsmWriteMm3 ENDP + + END diff --git a/UnixPkg/Library/UnixBaseLib/X64/WriteMm4.asm b/UnixPkg/Library/UnixBaseLib/X64/WriteMm4.asm new file mode 100644 index 0000000000..7f533137f8 --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/X64/WriteMm4.asm @@ -0,0 +1,41 @@ +;------------------------------------------------------------------------------ +; +; 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: +; +; WriteMm4.Asm +; +; Abstract: +; +; AsmWriteMm4 function +; +; Notes: +; +;------------------------------------------------------------------------------ + + .code + +;------------------------------------------------------------------------------ +; VOID +; EFIAPI +; AsmWriteMm4 ( +; IN UINT64 Value +; ); +;------------------------------------------------------------------------------ +AsmWriteMm4 PROC + ; + ; 64-bit MASM doesn't support MMX instructions, so use opcode here + ; + DB 48h, 0fh, 6eh, 0e1h + ret +AsmWriteMm4 ENDP + + END diff --git a/UnixPkg/Library/UnixBaseLib/X64/WriteMm5.asm b/UnixPkg/Library/UnixBaseLib/X64/WriteMm5.asm new file mode 100644 index 0000000000..ea30bc14a4 --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/X64/WriteMm5.asm @@ -0,0 +1,41 @@ +;------------------------------------------------------------------------------ +; +; 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: +; +; WriteMm5.Asm +; +; Abstract: +; +; AsmWriteMm5 function +; +; Notes: +; +;------------------------------------------------------------------------------ + + .code + +;------------------------------------------------------------------------------ +; VOID +; EFIAPI +; AsmWriteMm5 ( +; IN UINT64 Value +; ); +;------------------------------------------------------------------------------ +AsmWriteMm5 PROC + ; + ; 64-bit MASM doesn't support MMX instructions, so use opcode here + ; + DB 48h, 0fh, 6eh, 0e9h + ret +AsmWriteMm5 ENDP + + END diff --git a/UnixPkg/Library/UnixBaseLib/X64/WriteMm6.asm b/UnixPkg/Library/UnixBaseLib/X64/WriteMm6.asm new file mode 100644 index 0000000000..aa926ae710 --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/X64/WriteMm6.asm @@ -0,0 +1,41 @@ +;------------------------------------------------------------------------------ +; +; 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: +; +; WriteMm6.Asm +; +; Abstract: +; +; AsmWriteMm6 function +; +; Notes: +; +;------------------------------------------------------------------------------ + + .code + +;------------------------------------------------------------------------------ +; VOID +; EFIAPI +; AsmWriteMm6 ( +; IN UINT64 Value +; ); +;------------------------------------------------------------------------------ +AsmWriteMm6 PROC + ; + ; 64-bit MASM doesn't support MMX instructions, so use opcode here + ; + DB 48h, 0fh, 6eh, 0f1h + ret +AsmWriteMm6 ENDP + + END diff --git a/UnixPkg/Library/UnixBaseLib/X64/WriteMm7.asm b/UnixPkg/Library/UnixBaseLib/X64/WriteMm7.asm new file mode 100644 index 0000000000..652e041452 --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/X64/WriteMm7.asm @@ -0,0 +1,41 @@ +;------------------------------------------------------------------------------ +; +; 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: +; +; WriteMm7.Asm +; +; Abstract: +; +; AsmWriteMm7 function +; +; Notes: +; +;------------------------------------------------------------------------------ + + .code + +;------------------------------------------------------------------------------ +; VOID +; EFIAPI +; AsmWriteMm7 ( +; IN UINT64 Value +; ); +;------------------------------------------------------------------------------ +AsmWriteMm7 PROC + ; + ; 64-bit MASM doesn't support MMX instructions, so use opcode here + ; + DB 48h, 0fh, 6eh, 0f9h + ret +AsmWriteMm7 ENDP + + END diff --git a/UnixPkg/Library/UnixBaseLib/X64/WriteMsr64.asm b/UnixPkg/Library/UnixBaseLib/X64/WriteMsr64.asm new file mode 100644 index 0000000000..19ef572845 --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/X64/WriteMsr64.asm @@ -0,0 +1,41 @@ +;------------------------------------------------------------------------------ +; +; 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: +; +; WriteMsr64.Asm +; +; Abstract: +; +; AsmWriteMsr64 function +; +; Notes: +; +;------------------------------------------------------------------------------ + + .code + +;------------------------------------------------------------------------------ +; UINT64 +; EFIAPI +; AsmWriteMsr64 ( +; IN UINT32 Index, +; IN UINT64 Value +; ); +;------------------------------------------------------------------------------ +AsmWriteMsr64 PROC + mov rax, rdx ; meanwhile, rax <- return value + shr rdx, 20h ; edx:eax contains the value to write + wrmsr + ret +AsmWriteMsr64 ENDP + + END diff --git a/UnixPkg/Library/UnixBaseLib/X64/WriteMsr64.c b/UnixPkg/Library/UnixBaseLib/X64/WriteMsr64.c new file mode 100644 index 0000000000..58f0754246 --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/X64/WriteMsr64.c @@ -0,0 +1,42 @@ +/** @file + CpuBreakpoint function. + + 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. + +**/ + +/** + Microsoft Visual Studio 7.1 Function Prototypes for I/O Intrinsics. +**/ + +void __writemsr (unsigned long Register, unsigned __int64 Value); + +#pragma intrinsic(__writemsr) + +/** + Write data to MSR. + + @param Index The register index of MSR. + @param Value Data wants to be written. + + @return Value written to MSR. + +**/ +UINT64 +EFIAPI +AsmWriteMsr64 ( + IN UINT32 Index, + IN UINT64 Value + ) +{ + __writemsr (Index, Value); + return Value; +} + diff --git a/UnixPkg/Library/UnixBaseLib/X86DisablePaging32.c b/UnixPkg/Library/UnixBaseLib/X86DisablePaging32.c new file mode 100644 index 0000000000..cf14c84383 --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/X86DisablePaging32.c @@ -0,0 +1,66 @@ +/** @file + IA-32/x64 AsmDisablePaging32() + + Copyright (c) 2006 - 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. + +**/ + + + + +#include "BaseLibInternals.h" + +/** + Disables the 32-bit paging mode on the CPU. + + Disables the 32-bit paging mode on the CPU and returns to 32-bit protected + mode. This function assumes the current execution mode is 32-paged protected + mode. This function is only available on IA-32. After the 32-bit paging mode + is disabled, control is transferred to the function specified by EntryPoint + using the new stack specified by NewStack and passing in the parameters + specified by Context1 and Context2. Context1 and Context2 are optional and + may be NULL. The function EntryPoint must never return. + + If the current execution mode is not 32-bit paged mode, then ASSERT(). + If EntryPoint is NULL, then ASSERT(). + If NewStack is NULL, then ASSERT(). + + There are a number of constraints that must be followed before calling this + function: + 1) Interrupts must be disabled. + 2) The caller must be in 32-bit paged mode. + 3) CR0, CR3, and CR4 must be compatible with 32-bit paged mode. + 4) CR3 must point to valid page tables that guarantee that the pages for + this function and the stack are identity mapped. + + @param EntryPoint A pointer to function to call with the new stack after + paging is disabled. + @param Context1 A pointer to the context to pass into the EntryPoint + function as the first parameter after paging is disabled. + @param Context2 A pointer to the context to pass into the EntryPoint + function as the second parameter after paging is + disabled. + @param NewStack A pointer to the new stack to use for the EntryPoint + function after paging is disabled. + +**/ +VOID +EFIAPI +AsmDisablePaging32 ( + IN SWITCH_STACK_ENTRY_POINT EntryPoint, + IN VOID *Context1, OPTIONAL + IN VOID *Context2, OPTIONAL + IN VOID *NewStack + ) +{ + ASSERT (EntryPoint != NULL); + ASSERT (NewStack != NULL); + InternalX86DisablePaging32 (EntryPoint, Context1, Context2, NewStack); +} diff --git a/UnixPkg/Library/UnixBaseLib/X86DisablePaging64.c b/UnixPkg/Library/UnixBaseLib/X86DisablePaging64.c new file mode 100644 index 0000000000..add86cc6eb --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/X86DisablePaging64.c @@ -0,0 +1,63 @@ +/** @file + IA-32/x64 AsmDisablePaging64() + + Copyright (c) 2006 - 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. + +**/ + + + + +#include "BaseLibInternals.h" + +/** + Disables the 64-bit paging mode on the CPU. + + Disables the 64-bit paging mode on the CPU and returns to 32-bit protected + mode. This function assumes the current execution mode is 64-paging mode. + This function is only available on x64. After the 64-bit paging mode is + disabled, control is transferred to the function specified by EntryPoint + using the new stack specified by NewStack and passing in the parameters + specified by Context1 and Context2. Context1 and Context2 are optional and + may be 0. The function EntryPoint must never return. + + If the current execution mode is not 64-bit paged mode, then ASSERT(). + If EntryPoint is 0, then ASSERT(). + If NewStack is 0, then ASSERT(). + + @param Cs The 16-bit selector to load in the CS before EntryPoint + is called. The descriptor in the GDT that this selector + references must be setup for 32-bit protected mode. + @param EntryPoint The 64-bit virtual address of the function to call with + the new stack after paging is disabled. + @param Context1 The 64-bit virtual address of the context to pass into + the EntryPoint function as the first parameter after + paging is disabled. + @param Context2 The 64-bit virtual address of the context to pass into + the EntryPoint function as the second parameter after + paging is disabled. + @param NewStack The 64-bit virtual address of the new stack to use for + the EntryPoint function after paging is disabled. + +**/ +VOID +EFIAPI +AsmDisablePaging64 ( + IN UINT16 Cs, + IN UINT32 EntryPoint, + IN UINT32 Context1, OPTIONAL + IN UINT32 Context2, OPTIONAL + IN UINT32 NewStack + ) +{ + ASSERT (EntryPoint != 0); + ASSERT (NewStack != 0); + InternalX86DisablePaging64 (Cs, EntryPoint, Context1, Context2, NewStack); +} diff --git a/UnixPkg/Library/UnixBaseLib/X86EnablePaging32.c b/UnixPkg/Library/UnixBaseLib/X86EnablePaging32.c new file mode 100644 index 0000000000..cb0ea29a4a --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/X86EnablePaging32.c @@ -0,0 +1,69 @@ +/** @file + IA-32/x64 AsmEnablePaging32() + + Copyright (c) 2006 - 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. + +**/ + + + + +#include "BaseLibInternals.h" + +/** + Enables the 32-bit paging mode on the CPU. + + Enables the 32-bit paging mode on the CPU. CR0, CR3, CR4, and the page tables + must be properly initialized prior to calling this service. This function + assumes the current execution mode is 32-bit protected mode. This function is + only available on IA-32. After the 32-bit paging mode is enabled, control is + transferred to the function specified by EntryPoint using the new stack + specified by NewStack and passing in the parameters specified by Context1 and + Context2. Context1 and Context2 are optional and may be NULL. The function + EntryPoint must never return. + + If the current execution mode is not 32-bit protected mode, then ASSERT(). + If EntryPoint is NULL, then ASSERT(). + If NewStack is NULL, then ASSERT(). + + There are a number of constraints that must be followed before calling this + function: + 1) Interrupts must be disabled. + 2) The caller must be in 32-bit protected mode with flat descriptors. This + means all descriptors must have a base of 0 and a limit of 4GB. + 3) CR0 and CR4 must be compatible with 32-bit protected mode with flat + descriptors. + 4) CR3 must point to valid page tables that will be used once the transition + is complete, and those page tables must guarantee that the pages for this + function and the stack are identity mapped. + + @param EntryPoint A pointer to function to call with the new stack after + paging is enabled. + @param Context1 A pointer to the context to pass into the EntryPoint + function as the first parameter after paging is enabled. + @param Context2 A pointer to the context to pass into the EntryPoint + function as the second parameter after paging is enabled. + @param NewStack A pointer to the new stack to use for the EntryPoint + function after paging is enabled. + +**/ +VOID +EFIAPI +AsmEnablePaging32 ( + IN SWITCH_STACK_ENTRY_POINT EntryPoint, + IN VOID *Context1, OPTIONAL + IN VOID *Context2, OPTIONAL + IN VOID *NewStack + ) +{ + ASSERT (EntryPoint != NULL); + ASSERT (NewStack != NULL); + InternalX86EnablePaging32 (EntryPoint, Context1, Context2, NewStack); +} diff --git a/UnixPkg/Library/UnixBaseLib/X86EnablePaging64.c b/UnixPkg/Library/UnixBaseLib/X86EnablePaging64.c new file mode 100644 index 0000000000..28f9f2733e --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/X86EnablePaging64.c @@ -0,0 +1,65 @@ +/** @file + IA-32/x64 AsmEnablePaging64() + + Copyright (c) 2006 - 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. + +**/ + + + + +#include "BaseLibInternals.h" + +/** + Enables the 64-bit paging mode on the CPU. + + Enables the 64-bit paging mode on the CPU. CR0, CR3, CR4, and the page tables + must be properly initialized prior to calling this service. This function + assumes the current execution mode is 32-bit protected mode with flat + descriptors. This function is only available on IA-32. After the 64-bit + paging mode is enabled, control is transferred to the function specified by + EntryPoint using the new stack specified by NewStack and passing in the + parameters specified by Context1 and Context2. Context1 and Context2 are + optional and may be 0. The function EntryPoint must never return. + + If the current execution mode is not 32-bit protected mode with flat + descriptors, then ASSERT(). + If EntryPoint is 0, then ASSERT(). + If NewStack is 0, then ASSERT(). + + @param Cs The 16-bit selector to load in the CS before EntryPoint + is called. The descriptor in the GDT that this selector + references must be setup for long mode. + @param EntryPoint The 64-bit virtual address of the function to call with + the new stack after paging is enabled. + @param Context1 The 64-bit virtual address of the context to pass into + the EntryPoint function as the first parameter after + paging is enabled. + @param Context2 The 64-bit virtual address of the context to pass into + the EntryPoint function as the second parameter after + paging is enabled. + @param NewStack The 64-bit virtual address of the new stack to use for + the EntryPoint function after paging is enabled. + +**/ +VOID +EFIAPI +AsmEnablePaging64 ( + IN UINT16 Cs, + IN UINT64 EntryPoint, + IN UINT64 Context1, OPTIONAL + IN UINT64 Context2, OPTIONAL + IN UINT64 NewStack + ) +{ + ASSERT (EntryPoint != 0); + ASSERT (NewStack != 0); + InternalX86EnablePaging64 (Cs, EntryPoint, Context1, Context2, NewStack); +} diff --git a/UnixPkg/Library/UnixBaseLib/X86FxRestore.c b/UnixPkg/Library/UnixBaseLib/X86FxRestore.c new file mode 100644 index 0000000000..d93cc91df3 --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/X86FxRestore.c @@ -0,0 +1,49 @@ +/** @file + IA-32/x64 AsmFxRestore() + + 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. + +**/ + + + + +#include "BaseLibInternals.h" + +/** + Restores the current floating point/SSE/SSE2 context from a buffer. + + Restores the current floating point/SSE/SSE2 state from the buffer specified + by Buffer. Buffer must be aligned on a 16-byte boundary. This function is + only available on IA-32 and x64. + + If Buffer is NULL, then ASSERT(). + If Buffer is not aligned on a 16-byte boundary, then ASSERT(). + If Buffer was not saved with AsmFxSave(), then ASSERT(). + + @param Buffer A pointer to a buffer to save the floating point/SSE/SSE2 context. + +**/ +VOID +EFIAPI +AsmFxRestore ( + IN CONST IA32_FX_BUFFER *Buffer + ) +{ + ASSERT (Buffer != NULL); + ASSERT (0 == ((UINTN)Buffer & 0xf)); + + // + // Check the flag recorded by AsmFxSave() + // + ASSERT (0xAA5555AA == *(UINT32 *) (&Buffer[sizeof (IA32_FX_BUFFER) - 4])); + + InternalX86FxRestore (Buffer); +} diff --git a/UnixPkg/Library/UnixBaseLib/X86FxSave.c b/UnixPkg/Library/UnixBaseLib/X86FxSave.c new file mode 100644 index 0000000000..2dc935079e --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/X86FxSave.c @@ -0,0 +1,48 @@ +/** @file + IA-32/x64 AsmFxSave() + + 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. + +**/ + + + + +#include "BaseLibInternals.h" + +/** + Save the current floating point/SSE/SSE2 context to a buffer. + + Saves the current floating point/SSE/SSE2 state to the buffer specified by + Buffer. Buffer must be aligned on a 16-byte boundary. This function is only + available on IA-32 and x64. + + If Buffer is NULL, then ASSERT(). + If Buffer is not aligned on a 16-byte boundary, then ASSERT(). + + @param Buffer A pointer to a buffer to save the floating point/SSE/SSE2 context. + +**/ +VOID +EFIAPI +AsmFxSave ( + OUT IA32_FX_BUFFER *Buffer + ) +{ + ASSERT (Buffer != NULL); + ASSERT (0 == ((UINTN)Buffer & 0xf)); + + InternalX86FxSave (Buffer); + + // + // Mark one flag at end of Buffer, it will be check by AsmFxRestor() + // + *(UINT32 *) (&Buffer[sizeof (IA32_FX_BUFFER) - 4]) = 0xAA5555AA; +} diff --git a/UnixPkg/Library/UnixBaseLib/X86GetInterruptState.c b/UnixPkg/Library/UnixBaseLib/X86GetInterruptState.c new file mode 100644 index 0000000000..ed3f495f9c --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/X86GetInterruptState.c @@ -0,0 +1,41 @@ +/** @file + IA-32/x64 GetInterruptState() + + Copyright (c) 2006 - 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. + +**/ + + +#include "BaseLibInternals.h" + + +/** + Retrieves the current CPU interrupt state. + + Returns TRUE is interrupts are currently enabled. Otherwise + returns FALSE. + + @retval TRUE CPU interrupts are enabled. + @retval FALSE CPU interrupts are disabled. + +**/ +BOOLEAN +EFIAPI +GetInterruptState ( + VOID + ) +{ + IA32_EFLAGS32 EFlags; + + EFlags.UintN = AsmReadEflags (); + return (BOOLEAN)(1 == EFlags.Bits.IF); +} + + diff --git a/UnixPkg/Library/UnixBaseLib/X86MemoryFence.c b/UnixPkg/Library/UnixBaseLib/X86MemoryFence.c new file mode 100644 index 0000000000..77e1c5a4dd --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/X86MemoryFence.c @@ -0,0 +1,32 @@ +/** @file + IA-32/x64 MemoryFence(). + + Copyright (c) 2006 - 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. + +**/ + + + + +/** + Used to serialize load and store operations. + + All loads and stores that proceed calls to this function are guaranteed to be + globally visible when this function returns. + +**/ +VOID +EFIAPI +MemoryFence ( + VOID + ) +{ + return; +} diff --git a/UnixPkg/Library/UnixBaseLib/X86Msr.c b/UnixPkg/Library/UnixBaseLib/X86Msr.c new file mode 100644 index 0000000000..6a6bd9e766 --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/X86Msr.c @@ -0,0 +1,650 @@ +/** @file + IA-32/x64 MSR functions. + + Copyright (c) 2006 - 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. + +**/ + + +#include "BaseLibInternals.h" + + +/** + Returns the lower 32-bits of a Machine Specific Register(MSR). + + Reads and returns the lower 32-bits of the MSR specified by Index. + No parameter checking is performed on Index, and some Index values may cause + CPU exceptions. The caller must either guarantee that Index is valid, or the + caller must set up exception handlers to catch the exceptions. This function + is only available on IA-32 and x64. + + @param Index The 32-bit MSR index to read. + + @return The lower 32 bits of the MSR identified by Index. + +**/ +UINT32 +EFIAPI +AsmReadMsr32 ( + IN UINT32 Index + ) +{ + return (UINT32)AsmReadMsr64 (Index); +} + +/** + Writes a 32-bit value to a Machine Specific Register(MSR), and returns the value. + The upper 32-bits of the MSR are set to zero. + + Writes the 32-bit value specified by Value to the MSR specified by Index. The + upper 32-bits of the MSR write are set to zero. The 32-bit value written to + the MSR is returned. No parameter checking is performed on Index or Value, + and some of these may cause CPU exceptions. The caller must either guarantee + that Index and Value are valid, or the caller must establish proper exception + handlers. This function is only available on IA-32 and x64. + + @param Index The 32-bit MSR index to write. + @param Value The 32-bit value to write to the MSR. + + @return Value + +**/ +UINT32 +EFIAPI +AsmWriteMsr32 ( + IN UINT32 Index, + IN UINT32 Value + ) +{ + return (UINT32)AsmWriteMsr64 (Index, Value); +} + +/** + Reads a 64-bit MSR, performs a bitwise OR on the lower 32-bits, and + writes the result back to the 64-bit MSR. + + Reads the 64-bit MSR specified by Index, performs a bitwise OR + between the lower 32-bits of the read result and the value specified by + OrData, and writes the result to the 64-bit MSR specified by Index. The lower + 32-bits of the value written to the MSR is returned. No parameter checking is + performed on Index or OrData, and some of these may cause CPU exceptions. The + caller must either guarantee that Index and OrData are valid, or the caller + must establish proper exception handlers. This function is only available on + IA-32 and x64. + + @param Index The 32-bit MSR index to write. + @param OrData The value to OR with the read value from the MSR. + + @return The lower 32-bit value written to the MSR. + +**/ +UINT32 +EFIAPI +AsmMsrOr32 ( + IN UINT32 Index, + IN UINT32 OrData + ) +{ + return (UINT32)AsmMsrOr64 (Index, OrData); +} + +/** + Reads a 64-bit MSR, performs a bitwise AND on the lower 32-bits, and writes + the result back to the 64-bit MSR. + + Reads the 64-bit MSR specified by Index, performs a bitwise AND between the + lower 32-bits of the read result and the value specified by AndData, and + writes the result to the 64-bit MSR specified by Index. The lower 32-bits of + the value written to the MSR is returned. No parameter checking is performed + on Index or AndData, and some of these may cause CPU exceptions. The caller + must either guarantee that Index and AndData are valid, or the caller must + establish proper exception handlers. This function is only available on IA-32 + and x64. + + @param Index The 32-bit MSR index to write. + @param AndData The value to AND with the read value from the MSR. + + @return The lower 32-bit value written to the MSR. + +**/ +UINT32 +EFIAPI +AsmMsrAnd32 ( + IN UINT32 Index, + IN UINT32 AndData + ) +{ + return (UINT32)AsmMsrAnd64 (Index, AndData); +} + +/** + Reads a 64-bit MSR, performs a bitwise AND followed by a bitwise OR + on the lower 32-bits, and writes the result back to the 64-bit MSR. + + Reads the 64-bit MSR specified by Index, performs a bitwise AND between the + lower 32-bits of the read result and the value specified by AndData + preserving the upper 32-bits, performs a bitwise OR between the + result of the AND operation and the value specified by OrData, and writes the + result to the 64-bit MSR specified by Address. The lower 32-bits of the value + written to the MSR is returned. No parameter checking is performed on Index, + AndData, or OrData, and some of these may cause CPU exceptions. The caller + must either guarantee that Index, AndData, and OrData are valid, or the + caller must establish proper exception handlers. This function is only + available on IA-32 and x64. + + @param Index The 32-bit MSR index to write. + @param AndData The value to AND with the read value from the MSR. + @param OrData The value to OR with the result of the AND operation. + + @return The lower 32-bit value written to the MSR. + +**/ +UINT32 +EFIAPI +AsmMsrAndThenOr32 ( + IN UINT32 Index, + IN UINT32 AndData, + IN UINT32 OrData + ) +{ + return (UINT32)AsmMsrAndThenOr64 (Index, AndData, OrData); +} + +/** + Reads a bit field of an MSR. + + Reads the bit field in the lower 32-bits of a 64-bit MSR. The bit field is + specified by the StartBit and the EndBit. The value of the bit field is + returned. The caller must either guarantee that Index is valid, or the caller + must set up exception handlers to catch the exceptions. This function is only + available on IA-32 and x64. + + If StartBit is greater than 31, then ASSERT(). + If EndBit is greater than 31, then ASSERT(). + If EndBit is less than StartBit, then ASSERT(). + + @param Index The 32-bit MSR index to read. + @param StartBit The ordinal of the least significant bit in the bit field. + Range 0..31. + @param EndBit The ordinal of the most significant bit in the bit field. + Range 0..31. + + @return The bit field read from the MSR. + +**/ +UINT32 +EFIAPI +AsmMsrBitFieldRead32 ( + IN UINT32 Index, + IN UINTN StartBit, + IN UINTN EndBit + ) +{ + return BitFieldRead32 (AsmReadMsr32 (Index), StartBit, EndBit); +} + +/** + Writes a bit field to an MSR. + + Writes Value to a bit field in the lower 32-bits of a 64-bit MSR. The bit + field is specified by the StartBit and the EndBit. All other bits in the + destination MSR are preserved. The lower 32-bits of the MSR written is + returned. The caller must either guarantee that Index and the data written + is valid, or the caller must set up exception handlers to catch the exceptions. + This function is only available on IA-32 and x64. + + If StartBit is greater than 31, then ASSERT(). + If EndBit is greater than 31, then ASSERT(). + If EndBit is less than StartBit, then ASSERT(). + + @param Index The 32-bit MSR index to write. + @param StartBit The ordinal of the least significant bit in the bit field. + Range 0..31. + @param EndBit The ordinal of the most significant bit in the bit field. + Range 0..31. + @param Value The new value of the bit field. + + @return The lower 32-bit of the value written to the MSR. + +**/ +UINT32 +EFIAPI +AsmMsrBitFieldWrite32 ( + IN UINT32 Index, + IN UINTN StartBit, + IN UINTN EndBit, + IN UINT32 Value + ) +{ + ASSERT (EndBit < sizeof (Value) * 8); + ASSERT (StartBit <= EndBit); + return (UINT32)AsmMsrBitFieldWrite64 (Index, StartBit, EndBit, Value); +} + +/** + Reads a bit field in a 64-bit MSR, performs a bitwise OR, and writes the + result back to the bit field in the 64-bit MSR. + + Reads the 64-bit MSR specified by Index, performs a bitwise OR + between the read result and the value specified by OrData, and writes the + result to the 64-bit MSR specified by Index. The lower 32-bits of the value + written to the MSR are returned. Extra left bits in OrData are stripped. The + caller must either guarantee that Index and the data written is valid, or + the caller must set up exception handlers to catch the exceptions. This + function is only available on IA-32 and x64. + + If StartBit is greater than 31, then ASSERT(). + If EndBit is greater than 31, then ASSERT(). + If EndBit is less than StartBit, then ASSERT(). + + @param Index The 32-bit MSR index to write. + @param StartBit The ordinal of the least significant bit in the bit field. + Range 0..31. + @param EndBit The ordinal of the most significant bit in the bit field. + Range 0..31. + @param OrData The value to OR with the read value from the MSR. + + @return The lower 32-bit of the value written to the MSR. + +**/ +UINT32 +EFIAPI +AsmMsrBitFieldOr32 ( + IN UINT32 Index, + IN UINTN StartBit, + IN UINTN EndBit, + IN UINT32 OrData + ) +{ + ASSERT (EndBit < sizeof (OrData) * 8); + ASSERT (StartBit <= EndBit); + return (UINT32)AsmMsrBitFieldOr64 (Index, StartBit, EndBit, OrData); +} + +/** + Reads a bit field in a 64-bit MSR, performs a bitwise AND, and writes the + result back to the bit field in the 64-bit MSR. + + Reads the 64-bit MSR specified by Index, performs a bitwise AND between the + read result and the value specified by AndData, and writes the result to the + 64-bit MSR specified by Index. The lower 32-bits of the value written to the + MSR are returned. Extra left bits in AndData are stripped. The caller must + either guarantee that Index and the data written is valid, or the caller must + set up exception handlers to catch the exceptions. This function is only + available on IA-32 and x64. + + If StartBit is greater than 31, then ASSERT(). + If EndBit is greater than 31, then ASSERT(). + If EndBit is less than StartBit, then ASSERT(). + + @param Index The 32-bit MSR index to write. + @param StartBit The ordinal of the least significant bit in the bit field. + Range 0..31. + @param EndBit The ordinal of the most significant bit in the bit field. + Range 0..31. + @param AndData The value to AND with the read value from the MSR. + + @return The lower 32-bit of the value written to the MSR. + +**/ +UINT32 +EFIAPI +AsmMsrBitFieldAnd32 ( + IN UINT32 Index, + IN UINTN StartBit, + IN UINTN EndBit, + IN UINT32 AndData + ) +{ + ASSERT (EndBit < sizeof (AndData) * 8); + ASSERT (StartBit <= EndBit); + return (UINT32)AsmMsrBitFieldAnd64 (Index, StartBit, EndBit, AndData); +} + +/** + Reads a bit field in a 64-bit MSR, performs a bitwise AND followed by a + bitwise OR, and writes the result back to the bit field in the + 64-bit MSR. + + Reads the 64-bit MSR specified by Index, performs a bitwise AND followed by a + bitwise OR between the read result and the value specified by + AndData, and writes the result to the 64-bit MSR specified by Index. The + lower 32-bits of the value written to the MSR are returned. Extra left bits + in both AndData and OrData are stripped. The caller must either guarantee + that Index and the data written is valid, or the caller must set up exception + handlers to catch the exceptions. This function is only available on IA-32 + and x64. + + If StartBit is greater than 31, then ASSERT(). + If EndBit is greater than 31, then ASSERT(). + If EndBit is less than StartBit, then ASSERT(). + + @param Index The 32-bit MSR index to write. + @param StartBit The ordinal of the least significant bit in the bit field. + Range 0..31. + @param EndBit The ordinal of the most significant bit in the bit field. + Range 0..31. + @param AndData The value to AND with the read value from the MSR. + @param OrData The value to OR with the result of the AND operation. + + @return The lower 32-bit of the value written to the MSR. + +**/ +UINT32 +EFIAPI +AsmMsrBitFieldAndThenOr32 ( + IN UINT32 Index, + IN UINTN StartBit, + IN UINTN EndBit, + IN UINT32 AndData, + IN UINT32 OrData + ) +{ + ASSERT (EndBit < sizeof (AndData) * 8); + ASSERT (StartBit <= EndBit); + return (UINT32)AsmMsrBitFieldAndThenOr64 ( + Index, + StartBit, + EndBit, + AndData, + OrData + ); +} + +/** + Reads a 64-bit MSR, performs a bitwise OR, and writes the result + back to the 64-bit MSR. + + Reads the 64-bit MSR specified by Index, performs a bitwise OR + between the read result and the value specified by OrData, and writes the + result to the 64-bit MSR specified by Index. The value written to the MSR is + returned. No parameter checking is performed on Index or OrData, and some of + these may cause CPU exceptions. The caller must either guarantee that Index + and OrData are valid, or the caller must establish proper exception handlers. + This function is only available on IA-32 and x64. + + @param Index The 32-bit MSR index to write. + @param OrData The value to OR with the read value from the MSR. + + @return The value written back to the MSR. + +**/ +UINT64 +EFIAPI +AsmMsrOr64 ( + IN UINT32 Index, + IN UINT64 OrData + ) +{ + return AsmWriteMsr64 (Index, AsmReadMsr64 (Index) | OrData); +} + +/** + Reads a 64-bit MSR, performs a bitwise AND, and writes the result back to the + 64-bit MSR. + + Reads the 64-bit MSR specified by Index, performs a bitwise AND between the + read result and the value specified by OrData, and writes the result to the + 64-bit MSR specified by Index. The value written to the MSR is returned. No + parameter checking is performed on Index or OrData, and some of these may + cause CPU exceptions. The caller must either guarantee that Index and OrData + are valid, or the caller must establish proper exception handlers. This + function is only available on IA-32 and x64. + + @param Index The 32-bit MSR index to write. + @param AndData The value to AND with the read value from the MSR. + + @return The value written back to the MSR. + +**/ +UINT64 +EFIAPI +AsmMsrAnd64 ( + IN UINT32 Index, + IN UINT64 AndData + ) +{ + return AsmWriteMsr64 (Index, AsmReadMsr64 (Index) & AndData); +} + +/** + Reads a 64-bit MSR, performs a bitwise AND followed by a bitwise + OR, and writes the result back to the 64-bit MSR. + + Reads the 64-bit MSR specified by Index, performs a bitwise AND between read + result and the value specified by AndData, performs a bitwise OR + between the result of the AND operation and the value specified by OrData, + and writes the result to the 64-bit MSR specified by Index. The value written + to the MSR is returned. No parameter checking is performed on Index, AndData, + or OrData, and some of these may cause CPU exceptions. The caller must either + guarantee that Index, AndData, and OrData are valid, or the caller must + establish proper exception handlers. This function is only available on IA-32 + and x64. + + @param Index The 32-bit MSR index to write. + @param AndData The value to AND with the read value from the MSR. + @param OrData The value to OR with the result of the AND operation. + + @return The value written back to the MSR. + +**/ +UINT64 +EFIAPI +AsmMsrAndThenOr64 ( + IN UINT32 Index, + IN UINT64 AndData, + IN UINT64 OrData + ) +{ + return AsmWriteMsr64 (Index, (AsmReadMsr64 (Index) & AndData) | OrData); +} + +/** + Reads a bit field of an MSR. + + Reads the bit field in the 64-bit MSR. The bit field is specified by the + StartBit and the EndBit. The value of the bit field is returned. The caller + must either guarantee that Index is valid, or the caller must set up + exception handlers to catch the exceptions. This function is only available + on IA-32 and x64. + + If StartBit is greater than 63, then ASSERT(). + If EndBit is greater than 63, then ASSERT(). + If EndBit is less than StartBit, then ASSERT(). + + @param Index The 32-bit MSR index to read. + @param StartBit The ordinal of the least significant bit in the bit field. + Range 0..63. + @param EndBit The ordinal of the most significant bit in the bit field. + Range 0..63. + + @return The value read from the MSR. + +**/ +UINT64 +EFIAPI +AsmMsrBitFieldRead64 ( + IN UINT32 Index, + IN UINTN StartBit, + IN UINTN EndBit + ) +{ + return BitFieldRead64 (AsmReadMsr64 (Index), StartBit, EndBit); +} + +/** + Writes a bit field to an MSR. + + Writes Value to a bit field in a 64-bit MSR. The bit field is specified by + the StartBit and the EndBit. All other bits in the destination MSR are + preserved. The MSR written is returned. The caller must either guarantee + that Index and the data written is valid, or the caller must set up exception + handlers to catch the exceptions. This function is only available on IA-32 and x64. + + If StartBit is greater than 63, then ASSERT(). + If EndBit is greater than 63, then ASSERT(). + If EndBit is less than StartBit, then ASSERT(). + + @param Index The 32-bit MSR index to write. + @param StartBit The ordinal of the least significant bit in the bit field. + Range 0..63. + @param EndBit The ordinal of the most significant bit in the bit field. + Range 0..63. + @param Value The new value of the bit field. + + @return The value written back to the MSR. + +**/ +UINT64 +EFIAPI +AsmMsrBitFieldWrite64 ( + IN UINT32 Index, + IN UINTN StartBit, + IN UINTN EndBit, + IN UINT64 Value + ) +{ + return AsmWriteMsr64 ( + Index, + BitFieldWrite64 (AsmReadMsr64 (Index), StartBit, EndBit, Value) + ); +} + +/** + Reads a bit field in a 64-bit MSR, performs a bitwise OR, and + writes the result back to the bit field in the 64-bit MSR. + + Reads the 64-bit MSR specified by Index, performs a bitwise OR + between the read result and the value specified by OrData, and writes the + result to the 64-bit MSR specified by Index. The value written to the MSR is + returned. Extra left bits in OrData are stripped. The caller must either + guarantee that Index and the data written is valid, or the caller must set up + exception handlers to catch the exceptions. This function is only available + on IA-32 and x64. + + If StartBit is greater than 63, then ASSERT(). + If EndBit is greater than 63, then ASSERT(). + If EndBit is less than StartBit, then ASSERT(). + + @param Index The 32-bit MSR index to write. + @param StartBit The ordinal of the least significant bit in the bit field. + Range 0..63. + @param EndBit The ordinal of the most significant bit in the bit field. + Range 0..63. + @param OrData The value to OR with the read value from the bit field. + + @return The value written back to the MSR. + +**/ +UINT64 +EFIAPI +AsmMsrBitFieldOr64 ( + IN UINT32 Index, + IN UINTN StartBit, + IN UINTN EndBit, + IN UINT64 OrData + ) +{ + return AsmWriteMsr64 ( + Index, + BitFieldOr64 (AsmReadMsr64 (Index), StartBit, EndBit, OrData) + ); +} + +/** + Reads a bit field in a 64-bit MSR, performs a bitwise AND, and writes the + result back to the bit field in the 64-bit MSR. + + Reads the 64-bit MSR specified by Index, performs a bitwise AND between the + read result and the value specified by AndData, and writes the result to the + 64-bit MSR specified by Index. The value written to the MSR is returned. + Extra left bits in AndData are stripped. The caller must either guarantee + that Index and the data written is valid, or the caller must set up exception + handlers to catch the exceptions. This function is only available on IA-32 + and x64. + + If StartBit is greater than 63, then ASSERT(). + If EndBit is greater than 63, then ASSERT(). + If EndBit is less than StartBit, then ASSERT(). + + @param Index The 32-bit MSR index to write. + @param StartBit The ordinal of the least significant bit in the bit field. + Range 0..63. + @param EndBit The ordinal of the most significant bit in the bit field. + Range 0..63. + @param AndData The value to AND with the read value from the bit field. + + @return The value written back to the MSR. + +**/ +UINT64 +EFIAPI +AsmMsrBitFieldAnd64 ( + IN UINT32 Index, + IN UINTN StartBit, + IN UINTN EndBit, + IN UINT64 AndData + ) +{ + return AsmWriteMsr64 ( + Index, + BitFieldAnd64 (AsmReadMsr64 (Index), StartBit, EndBit, AndData) + ); +} + +/** + Reads a bit field in a 64-bit MSR, performs a bitwise AND followed by a + bitwise OR, and writes the result back to the bit field in the + 64-bit MSR. + + Reads the 64-bit MSR specified by Index, performs a bitwise AND followed by + a bitwise OR between the read result and the value specified by + AndData, and writes the result to the 64-bit MSR specified by Index. The + value written to the MSR is returned. Extra left bits in both AndData and + OrData are stripped. The caller must either guarantee that Index and the data + written is valid, or the caller must set up exception handlers to catch the + exceptions. This function is only available on IA-32 and x64. + + If StartBit is greater than 63, then ASSERT(). + If EndBit is greater than 63, then ASSERT(). + If EndBit is less than StartBit, then ASSERT(). + + @param Index The 32-bit MSR index to write. + @param StartBit The ordinal of the least significant bit in the bit field. + Range 0..63. + @param EndBit The ordinal of the most significant bit in the bit field. + Range 0..63. + @param AndData The value to AND with the read value from the bit field. + @param OrData The value to OR with the result of the AND operation. + + @return The value written back to the MSR. + +**/ +UINT64 +EFIAPI +AsmMsrBitFieldAndThenOr64 ( + IN UINT32 Index, + IN UINTN StartBit, + IN UINTN EndBit, + IN UINT64 AndData, + IN UINT64 OrData + ) +{ + return AsmWriteMsr64 ( + Index, + BitFieldAndThenOr64 ( + AsmReadMsr64 (Index), + StartBit, + EndBit, + AndData, + OrData + ) + ); +} diff --git a/UnixPkg/Library/UnixBaseLib/X86ReadGdtr.c b/UnixPkg/Library/UnixBaseLib/X86ReadGdtr.c new file mode 100644 index 0000000000..ecd2b802cf --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/X86ReadGdtr.c @@ -0,0 +1,39 @@ +/** @file + IA-32/x64 AsmReadGdtr() + + Copyright (c) 2006 - 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. + +**/ + + + + +#include "BaseLibInternals.h" + +/** + Reads the current Global Descriptor Table Register(GDTR) descriptor. + + Reads and returns the current GDTR descriptor and returns it in Gdtr. This + function is only available on IA-32 and x64. + + If Gdtr is NULL, then ASSERT(). + + @param Gdtr The pointer to a GDTR descriptor. + +**/ +VOID +EFIAPI +AsmReadGdtr ( + OUT IA32_DESCRIPTOR *Gdtr + ) +{ + ASSERT (Gdtr != NULL); + InternalX86ReadGdtr (Gdtr); +} diff --git a/UnixPkg/Library/UnixBaseLib/X86ReadIdtr.c b/UnixPkg/Library/UnixBaseLib/X86ReadIdtr.c new file mode 100644 index 0000000000..392b6e3400 --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/X86ReadIdtr.c @@ -0,0 +1,39 @@ +/** @file + IA-32/x64 AsmReadIdtr() + + Copyright (c) 2006 - 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. + +**/ + + + + +#include "BaseLibInternals.h" + +/** + Reads the current Interrupt Descriptor Table Register(IDTR) descriptor. + + Reads and returns the current IDTR descriptor and returns it in Idtr. This + function is only available on IA-32 and x64. + + If Idtr is NULL, then ASSERT(). + + @param Idtr The pointer to a IDTR descriptor. + +**/ +VOID +EFIAPI +AsmReadIdtr ( + OUT IA32_DESCRIPTOR *Idtr + ) +{ + ASSERT (Idtr != NULL); + InternalX86ReadIdtr (Idtr); +} diff --git a/UnixPkg/Library/UnixBaseLib/X86Thunk.c b/UnixPkg/Library/UnixBaseLib/X86Thunk.c new file mode 100644 index 0000000000..014287b3c2 --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/X86Thunk.c @@ -0,0 +1,291 @@ +/** @file + Real Mode Thunk Functions for IA32 and x64. + + Copyright (c) 2006 - 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. + +**/ + + +#include "BaseLibInternals.h" + + +// +// Byte packed structure for a segment descriptor in a GDT/LDT +// +typedef union { + struct { + UINT32 LimitLow:16; + UINT32 BaseLow:16; + UINT32 BaseMid:8; + UINT32 Type:4; + UINT32 S:1; + UINT32 DPL:2; + UINT32 P:1; + UINT32 LimitHigh:4; + UINT32 AVL:1; + UINT32 L:1; + UINT32 DB:1; + UINT32 G:1; + UINT32 BaseHigh:8; + } Bits; + UINT64 Uint64; +} IA32_SEGMENT_DESCRIPTOR; + +extern CONST UINT8 m16Start; +extern CONST UINT16 m16Size; +extern CONST UINT16 mThunk16Attr; +extern CONST UINT16 m16Gdt; +extern CONST UINT16 m16GdtrBase; +extern CONST UINT16 mTransition; + +/** + Invokes 16-bit code in big real mode and returns the updated register set. + + This function transfers control to the 16-bit code specified by CS:EIP using + the stack specified by SS:ESP in RegisterSet. The updated registers are saved + on the real mode stack and the starting address of the save area is returned. + + @param RegisterSet Values of registers before invocation of 16-bit code. + @param Transition The pointer to the transition code under 1MB. + + @return The pointer to a IA32_REGISTER_SET structure containing the updated + register values. + +**/ +IA32_REGISTER_SET * +EFIAPI +InternalAsmThunk16 ( + IN IA32_REGISTER_SET *RegisterSet, + IN OUT VOID *Transition + ); + +/** + Retrieves the properties for 16-bit thunk functions. + + Computes the size of the buffer and stack below 1MB required to use the + AsmPrepareThunk16(), AsmThunk16() and AsmPrepareAndThunk16() functions. This + buffer size is returned in RealModeBufferSize, and the stack size is returned + in ExtraStackSize. If parameters are passed to the 16-bit real mode code, + then the actual minimum stack size is ExtraStackSize plus the maximum number + of bytes that need to be passed to the 16-bit real mode code. + + If RealModeBufferSize is NULL, then ASSERT(). + If ExtraStackSize is NULL, then ASSERT(). + + @param RealModeBufferSize A pointer to the size of the buffer below 1MB + required to use the 16-bit thunk functions. + @param ExtraStackSize A pointer to the extra size of stack below 1MB + that the 16-bit thunk functions require for + temporary storage in the transition to and from + 16-bit real mode. + +**/ +VOID +EFIAPI +AsmGetThunk16Properties ( + OUT UINT32 *RealModeBufferSize, + OUT UINT32 *ExtraStackSize + ) +{ + ASSERT (RealModeBufferSize != NULL); + ASSERT (ExtraStackSize != NULL); + + *RealModeBufferSize = m16Size; + + // + // Extra 4 bytes for return address, and another 4 bytes for mode transition + // + *ExtraStackSize = sizeof (IA32_DWORD_REGS) + 8; +} + +/** + Prepares all structures a code required to use AsmThunk16(). + + Prepares all structures and code required to use AsmThunk16(). + + This interface is limited to be used in either physical mode or virtual modes with paging enabled where the + virtual to physical mappings for ThunkContext.RealModeBuffer is mapped 1:1. + + If ThunkContext is NULL, then ASSERT(). + + @param ThunkContext A pointer to the context structure that describes the + 16-bit real mode code to call. + +**/ +VOID +EFIAPI +AsmPrepareThunk16 ( + OUT THUNK_CONTEXT *ThunkContext + ) +{ + IA32_SEGMENT_DESCRIPTOR *RealModeGdt; + + ASSERT (ThunkContext != NULL); + ASSERT ((UINTN)ThunkContext->RealModeBuffer < 0x100000); + ASSERT (ThunkContext->RealModeBufferSize >= m16Size); + ASSERT ((UINTN)ThunkContext->RealModeBuffer + m16Size <= 0x100000); + + CopyMem (ThunkContext->RealModeBuffer, &m16Start, m16Size); + + // + // Point RealModeGdt to the GDT to be used in transition + // + // RealModeGdt[0]: Reserved as NULL descriptor + // RealModeGdt[1]: Code Segment + // RealModeGdt[2]: Data Segment + // RealModeGdt[3]: Call Gate + // + RealModeGdt = (IA32_SEGMENT_DESCRIPTOR*)( + (UINTN)ThunkContext->RealModeBuffer + m16Gdt); + + // + // Update Code & Data Segment Descriptor + // + RealModeGdt[1].Bits.BaseLow = + (UINT32)(UINTN)ThunkContext->RealModeBuffer & ~0xf; + RealModeGdt[1].Bits.BaseMid = + (UINT32)(UINTN)ThunkContext->RealModeBuffer >> 16; + + // + // Update transition code entry point offset + // + *(UINT32*)((UINTN)ThunkContext->RealModeBuffer + mTransition) += + (UINT32)(UINTN)ThunkContext->RealModeBuffer & 0xf; + + // + // Update Segment Limits for both Code and Data Segment Descriptors + // + if ((ThunkContext->ThunkAttributes & THUNK_ATTRIBUTE_BIG_REAL_MODE) == 0) { + // + // Set segment limits to 64KB + // + RealModeGdt[1].Bits.LimitHigh = 0; + RealModeGdt[1].Bits.G = 0; + RealModeGdt[2].Bits.LimitHigh = 0; + RealModeGdt[2].Bits.G = 0; + } + + // + // Update GDTBASE for this thunk context + // + *(VOID**)((UINTN)ThunkContext->RealModeBuffer + m16GdtrBase) = RealModeGdt; + + // + // Update Thunk Attributes + // + *(UINT32*)((UINTN)ThunkContext->RealModeBuffer + mThunk16Attr) = + ThunkContext->ThunkAttributes; +} + +/** + Transfers control to a 16-bit real mode entry point and returns the results. + + Transfers control to a 16-bit real mode entry point and returns the results. + AsmPrepareThunk16() must be called with ThunkContext before this function is used. + This function must be called with interrupts disabled. + + The register state from the RealModeState field of ThunkContext is restored just prior + to calling the 16-bit real mode entry point. This includes the EFLAGS field of RealModeState, + which is used to set the interrupt state when a 16-bit real mode entry point is called. + Control is transferred to the 16-bit real mode entry point specified by the CS and Eip fields of RealModeState. + The stack is initialized to the SS and ESP fields of RealModeState. Any parameters passed to + the 16-bit real mode code must be populated by the caller at SS:ESP prior to calling this function. + The 16-bit real mode entry point is invoked with a 16-bit CALL FAR instruction, + so when accessing stack contents, the 16-bit real mode code must account for the 16-bit segment + and 16-bit offset of the return address that were pushed onto the stack. The 16-bit real mode entry + point must exit with a RETF instruction. The register state is captured into RealModeState immediately + after the RETF instruction is executed. + + If EFLAGS specifies interrupts enabled, or any of the 16-bit real mode code enables interrupts, + or any of the 16-bit real mode code makes a SW interrupt, then the caller is responsible for making sure + the IDT at address 0 is initialized to handle any HW or SW interrupts that may occur while in 16-bit real mode. + + If EFLAGS specifies interrupts enabled, or any of the 16-bit real mode code enables interrupts, + then the caller is responsible for making sure the 8259 PIC is in a state compatible with 16-bit real mode. + This includes the base vectors, the interrupt masks, and the edge/level trigger mode. + + If THUNK_ATTRIBUTE_BIG_REAL_MODE is set in the ThunkAttributes field of ThunkContext, then the user code + is invoked in big real mode. Otherwise, the user code is invoked in 16-bit real mode with 64KB segment limits. + + If neither THUNK_ATTRIBUTE_DISABLE_A20_MASK_INT_15 nor THUNK_ATTRIBUTE_DISABLE_A20_MASK_KBD_CTRL are set in + ThunkAttributes, then it is assumed that the user code did not enable the A20 mask, and no attempt is made to + disable the A20 mask. + + If THUNK_ATTRIBUTE_DISABLE_A20_MASK_INT_15 is set and THUNK_ATTRIBUTE_DISABLE_A20_MASK_KBD_CTRL is clear in + ThunkAttributes, then attempt to use the INT 15 service to disable the A20 mask. If this INT 15 call fails, + then attempt to disable the A20 mask by directly accessing the 8042 keyboard controller I/O ports. + + If THUNK_ATTRIBUTE_DISABLE_A20_MASK_INT_15 is clear and THUNK_ATTRIBUTE_DISABLE_A20_MASK_KBD_CTRL is set in + ThunkAttributes, then attempt to disable the A20 mask by directly accessing the 8042 keyboard controller I/O ports. + + If ThunkContext is NULL, then ASSERT(). + If AsmPrepareThunk16() was not previously called with ThunkContext, then ASSERT(). + If both THUNK_ATTRIBUTE_DISABLE_A20_MASK_INT_15 and THUNK_ATTRIBUTE_DISABLE_A20_MASK_KBD_CTRL are set in + ThunkAttributes, then ASSERT(). + + This interface is limited to be used in either physical mode or virtual modes with paging enabled where the + virtual to physical mappings for ThunkContext.RealModeBuffer is mapped 1:1. + + @param ThunkContext A pointer to the context structure that describes the + 16-bit real mode code to call. + +**/ +VOID +EFIAPI +AsmThunk16 ( + IN OUT THUNK_CONTEXT *ThunkContext + ) +{ + IA32_REGISTER_SET *UpdatedRegs; + + ASSERT (ThunkContext != NULL); + ASSERT ((UINTN)ThunkContext->RealModeBuffer < 0x100000); + ASSERT (ThunkContext->RealModeBufferSize >= m16Size); + ASSERT ((UINTN)ThunkContext->RealModeBuffer + m16Size <= 0x100000); + ASSERT (((ThunkContext->ThunkAttributes & (THUNK_ATTRIBUTE_DISABLE_A20_MASK_INT_15 | THUNK_ATTRIBUTE_DISABLE_A20_MASK_KBD_CTRL)) != \ + (THUNK_ATTRIBUTE_DISABLE_A20_MASK_INT_15 | THUNK_ATTRIBUTE_DISABLE_A20_MASK_KBD_CTRL))); + + UpdatedRegs = InternalAsmThunk16 ( + ThunkContext->RealModeState, + ThunkContext->RealModeBuffer + ); + + CopyMem (ThunkContext->RealModeState, UpdatedRegs, sizeof (*UpdatedRegs)); +} + +/** + Prepares all structures and code for a 16-bit real mode thunk, transfers + control to a 16-bit real mode entry point, and returns the results. + + Prepares all structures and code for a 16-bit real mode thunk, transfers + control to a 16-bit real mode entry point, and returns the results. If the + caller only need to perform a single 16-bit real mode thunk, then this + service should be used. If the caller intends to make more than one 16-bit + real mode thunk, then it is more efficient if AsmPrepareThunk16() is called + once and AsmThunk16() can be called for each 16-bit real mode thunk. + + This interface is limited to be used in either physical mode or virtual modes with paging enabled where the + virtual to physical mappings for ThunkContext.RealModeBuffer is mapped 1:1. + + See AsmPrepareThunk16() and AsmThunk16() for the detailed description and ASSERT() conditions. + + @param ThunkContext A pointer to the context structure that describes the + 16-bit real mode code to call. + +**/ +VOID +EFIAPI +AsmPrepareAndThunk16 ( + IN OUT THUNK_CONTEXT *ThunkContext + ) +{ + AsmPrepareThunk16 (ThunkContext); + AsmThunk16 (ThunkContext); +} diff --git a/UnixPkg/Library/UnixBaseLib/X86WriteGdtr.c b/UnixPkg/Library/UnixBaseLib/X86WriteGdtr.c new file mode 100644 index 0000000000..54383d5d56 --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/X86WriteGdtr.c @@ -0,0 +1,39 @@ +/** @file + IA-32/x64 AsmWriteGdtr() + + Copyright (c) 2006 - 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. + +**/ + + + + +#include "BaseLibInternals.h" + +/** + Writes the current Global Descriptor Table Register (GDTR) descriptor. + + Writes and the current GDTR descriptor specified by Gdtr. This function is + only available on IA-32 and x64. + + If Gdtr is NULL, then ASSERT(). + + @param Gdtr The pointer to a GDTR descriptor. + +**/ +VOID +EFIAPI +AsmWriteGdtr ( + IN CONST IA32_DESCRIPTOR *Gdtr + ) +{ + ASSERT (Gdtr != NULL); + InternalX86WriteGdtr (Gdtr); +} diff --git a/UnixPkg/Library/UnixBaseLib/X86WriteIdtr.c b/UnixPkg/Library/UnixBaseLib/X86WriteIdtr.c new file mode 100644 index 0000000000..d187bc2d07 --- /dev/null +++ b/UnixPkg/Library/UnixBaseLib/X86WriteIdtr.c @@ -0,0 +1,39 @@ +/** @file + IA-32/x64 AsmWriteIdtr() + + Copyright (c) 2006 - 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. + +**/ + + + + +#include "BaseLibInternals.h" + +/** + Writes the current Interrupt Descriptor Table Register(IDTR) descriptor. + + Writes the current IDTR descriptor and returns it in Idtr. This function is + only available on IA-32 and x64. + + If Idtr is NULL, then ASSERT(). + + @param Idtr The pointer to a IDTR descriptor. + +**/ +VOID +EFIAPI +AsmWriteIdtr ( + IN CONST IA32_DESCRIPTOR *Idtr + ) +{ + ASSERT (Idtr != NULL); + InternalX86WriteIdtr (Idtr); +} -- 2.39.2