From e8338d8180d0dfcb025a4c8cc5cf542ea9d37e09 Mon Sep 17 00:00:00 2001 From: vit9696 Date: Sun, 7 Oct 2018 04:12:17 +0300 Subject: [PATCH] Import pico libs --- Include/IndustryStandard/CpuId.h | 215 +++++ Include/IndustryStandard/GenericIch.h | 70 ++ Include/Library/OcAcpiLib.h | 62 ++ Include/Library/OcCpuLib.h | 66 ++ Include/Library/OcDevicePathLib.h | 107 +++ Include/Library/OcFileLib.h | 226 +++++ Include/Library/OcMiscLib.h | 136 +++ Include/Library/OcPrintLib.h | 165 ++++ Include/Library/OcProtocolLib.h | 112 +++ Include/Library/OcStringLib.h | 403 +++++++++ Include/Library/OcTimerLib.h | 30 + Include/Library/OcVariableLib.h | 96 +++ Include/Macros.h | 99 +++ Include/Protocol/OcLog.h | 120 +++ Library/OcAcpiLib/AcpiFindLegacyRsdPtr.c | 71 ++ Library/OcAcpiLib/AcpiFindRsdPtr.c | 62 ++ Library/OcAcpiLib/AcpiLocateTable.c | 88 ++ Library/OcAcpiLib/OcAcpiLib.inf | 42 + Library/OcCpuLib/OcCpuLib.c | 270 ++++++ Library/OcCpuLib/OcCpuLib.inf | 40 + Library/OcCpuLib/ProcessorInfo.h | 207 +++++ Library/OcDebugLogLib/OcDebugLogLib.c | 245 ++++++ Library/OcDebugLogLib/OcDebugLogLib.inf | 45 + Library/OcDevicePathLib/OcDevicePathLib.c | 321 +++++++ Library/OcDevicePathLib/OcDevicePathLib.inf | 43 + Library/OcFileLib/FileExists.c | 149 ++++ Library/OcFileLib/GetFileInfo.c | 164 ++++ Library/OcFileLib/GetNextDirEntry.c | 95 ++ Library/OcFileLib/GetVolumeLabel.c | 103 +++ Library/OcFileLib/OcFileLib.inf | 54 ++ Library/OcFileLib/OcFileLibInternal.h | 18 + Library/OcFileLib/OpenDirectory.c | 115 +++ Library/OcFileLib/OpenFileSystem.c | 73 ++ Library/OcFileLib/ReadFile.c | 242 ++++++ Library/OcFileLib/ReadFvFile.c | 187 ++++ Library/OcFileLib/WriteFile.c | 186 ++++ Library/OcMiscLib/Base64Decode.c | 271 ++++++ Library/OcMiscLib/ConvertDataToString.c | 174 ++++ Library/OcMiscLib/LegacyRegionLock.c | 84 ++ Library/OcMiscLib/LegacyRegionUnLock.c | 85 ++ Library/OcMiscLib/LogBootOrder.c | 109 +++ Library/OcMiscLib/LogHexDump.c | 102 +++ Library/OcMiscLib/OcMiscLib.inf | 55 ++ Library/OcMiscLib/SetPlatformData.c | 125 +++ Library/OcPrintLib/GuidTable.c | 105 +++ Library/OcPrintLib/GuidTable.h | 25 + Library/OcPrintLib/OcPrintLib.c | 814 ++++++++++++++++++ Library/OcPrintLib/OcPrintLib.inf | 87 ++ Library/OcPrintLib/StringTable.c | 61 ++ Library/OcProtocolLib/OcProtocolLib.inf | 48 ++ .../OcProtocolLib/RegisterProtocolCallback.c | 68 ++ Library/OcProtocolLib/SafeHandleProtocol.c | 52 ++ .../SafeInstallProtocolInterface.c | 79 ++ Library/OcProtocolLib/SafeLocateProtocol.c | 54 ++ Library/OcProtocolLib/SignalProtocolEvent.c | 50 ++ Library/OcStringLib/OcAsciiLib.c | 469 ++++++++++ Library/OcStringLib/OcStringLib.inf | 48 ++ Library/OcStringLib/OcUnicodeLib.c | 523 +++++++++++ Library/OcTimerLib/OcTimerLib.c | 134 +++ Library/OcTimerLib/OcTimerLib.inf | 41 + Library/OcVariableLib/CheckVariable.c | 56 ++ Library/OcVariableLib/DeleteVariable.c | 130 +++ Library/OcVariableLib/GetVariable.c | 114 +++ Library/OcVariableLib/OcVariableLib.inf | 43 + Library/OcVariableLib/SetVariable.c | 159 ++++ OcSupportPkg.dec | 36 + OcSupportPkg.dsc | 12 + 67 files changed, 8940 insertions(+) create mode 100755 Include/IndustryStandard/CpuId.h create mode 100755 Include/IndustryStandard/GenericIch.h create mode 100755 Include/Library/OcAcpiLib.h create mode 100755 Include/Library/OcCpuLib.h create mode 100755 Include/Library/OcDevicePathLib.h create mode 100755 Include/Library/OcFileLib.h create mode 100755 Include/Library/OcMiscLib.h create mode 100755 Include/Library/OcPrintLib.h create mode 100755 Include/Library/OcProtocolLib.h create mode 100755 Include/Library/OcStringLib.h create mode 100755 Include/Library/OcTimerLib.h create mode 100755 Include/Library/OcVariableLib.h create mode 100755 Include/Macros.h create mode 100755 Include/Protocol/OcLog.h create mode 100755 Library/OcAcpiLib/AcpiFindLegacyRsdPtr.c create mode 100755 Library/OcAcpiLib/AcpiFindRsdPtr.c create mode 100755 Library/OcAcpiLib/AcpiLocateTable.c create mode 100755 Library/OcAcpiLib/OcAcpiLib.inf create mode 100755 Library/OcCpuLib/OcCpuLib.c create mode 100755 Library/OcCpuLib/OcCpuLib.inf create mode 100755 Library/OcCpuLib/ProcessorInfo.h create mode 100755 Library/OcDebugLogLib/OcDebugLogLib.c create mode 100755 Library/OcDebugLogLib/OcDebugLogLib.inf create mode 100755 Library/OcDevicePathLib/OcDevicePathLib.c create mode 100755 Library/OcDevicePathLib/OcDevicePathLib.inf create mode 100755 Library/OcFileLib/FileExists.c create mode 100755 Library/OcFileLib/GetFileInfo.c create mode 100755 Library/OcFileLib/GetNextDirEntry.c create mode 100755 Library/OcFileLib/GetVolumeLabel.c create mode 100755 Library/OcFileLib/OcFileLib.inf create mode 100755 Library/OcFileLib/OcFileLibInternal.h create mode 100755 Library/OcFileLib/OpenDirectory.c create mode 100755 Library/OcFileLib/OpenFileSystem.c create mode 100755 Library/OcFileLib/ReadFile.c create mode 100755 Library/OcFileLib/ReadFvFile.c create mode 100755 Library/OcFileLib/WriteFile.c create mode 100755 Library/OcMiscLib/Base64Decode.c create mode 100755 Library/OcMiscLib/ConvertDataToString.c create mode 100755 Library/OcMiscLib/LegacyRegionLock.c create mode 100755 Library/OcMiscLib/LegacyRegionUnLock.c create mode 100755 Library/OcMiscLib/LogBootOrder.c create mode 100755 Library/OcMiscLib/LogHexDump.c create mode 100755 Library/OcMiscLib/OcMiscLib.inf create mode 100755 Library/OcMiscLib/SetPlatformData.c create mode 100755 Library/OcPrintLib/GuidTable.c create mode 100755 Library/OcPrintLib/GuidTable.h create mode 100755 Library/OcPrintLib/OcPrintLib.c create mode 100755 Library/OcPrintLib/OcPrintLib.inf create mode 100755 Library/OcPrintLib/StringTable.c create mode 100755 Library/OcProtocolLib/OcProtocolLib.inf create mode 100755 Library/OcProtocolLib/RegisterProtocolCallback.c create mode 100755 Library/OcProtocolLib/SafeHandleProtocol.c create mode 100755 Library/OcProtocolLib/SafeInstallProtocolInterface.c create mode 100755 Library/OcProtocolLib/SafeLocateProtocol.c create mode 100755 Library/OcProtocolLib/SignalProtocolEvent.c create mode 100755 Library/OcStringLib/OcAsciiLib.c create mode 100755 Library/OcStringLib/OcStringLib.inf create mode 100755 Library/OcStringLib/OcUnicodeLib.c create mode 100755 Library/OcTimerLib/OcTimerLib.c create mode 100755 Library/OcTimerLib/OcTimerLib.inf create mode 100755 Library/OcVariableLib/CheckVariable.c create mode 100755 Library/OcVariableLib/DeleteVariable.c create mode 100755 Library/OcVariableLib/GetVariable.c create mode 100755 Library/OcVariableLib/OcVariableLib.inf create mode 100755 Library/OcVariableLib/SetVariable.c diff --git a/Include/IndustryStandard/CpuId.h b/Include/IndustryStandard/CpuId.h new file mode 100755 index 00000000..b74d32bb --- /dev/null +++ b/Include/IndustryStandard/CpuId.h @@ -0,0 +1,215 @@ +/** @file + Copyright (C) 2016, The HermitCrabs Lab. All rights reserved. + + All rights reserved. + + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + 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 CPUID_H_ +#define CPUID_H_ + +#include + +#define CPUID_L2_CACHE_FEATURE 0x80000006 + +// Feature Flag Values Reported in the EDX Register + +#define CPUID_FEATURE_FPU BIT0 ///< Floating point unit on-chip +#define CPUID_FEATURE_VME BIT1 ///< Virtual Mode Extension +#define CPUID_FEATURE_DE BIT2 ///< Debugging Extension +#define CPUID_FEATURE_PSE BIT3 ///< Page Size Extension +#define CPUID_FEATURE_TSC BIT4 ///< Time Stamp Counter +#define CPUID_FEATURE_MSR BIT5 ///< Model Specific Registers +#define CPUID_FEATURE_PAE BIT6 ///< Physical Address Extension +#define CPUID_FEATURE_MCE BIT7 ///< Machine Check Exception +#define CPUID_FEATURE_CX8 BIT8 ///< CMPXCHG8B +#define CPUID_FEATURE_APIC BIT9 ///< On-chip APIC +#define CPUID_FEATURE_SEP BIT11 ///< Fast System Call +#define CPUID_FEATURE_MTRR BIT12 ///< Memory Type Range Register +#define CPUID_FEATURE_PGE BIT13 ///< Page Global Enable +#define CPUID_FEATURE_MCA BIT14 ///< Machine Check Architecture +#define CPUID_FEATURE_CMOV BIT15 ///< Conditional Move Instruction +#define CPUID_FEATURE_PAT BIT16 ///< Page Attribute Table +#define CPUID_FEATURE_PSE36 BIT17 ///< 36-bit Page Size Extension +#define CPUID_FEATURE_PSN BIT18 ///< Processor Serial Number +#define CPUID_FEATURE_CLFSH BIT19 ///< CLFLUSH Instruction Supported +#define CPUID_FEATURE_RESV20 BIT20 ///< Reserved +#define CPUID_FEATURE_DS BIT21 ///< Debug Store +#define CPUID_FEATURE_ACPI BIT22 ///< Thermal Monitor and Clock Control +#define CPUID_FEATURE_MMX BIT23 ///< MMX Supported +#define CPUID_FEATURE_FXSR BIT24 ///< Fast Floating Point Save/Restore +#define CPUID_FEATURE_SSE BIT25 ///< Streaming SIMD Extensions +#define CPUID_FEATURE_SSE2 BIT26 ///< Streaming SIMD Extensions 2 +#define CPUID_FEATURE_SS BIT27 ///< Self-Snoop +#define CPUID_FEATURE_HTT BIT28 ///< Hyper-Threading Technology +#define CPUID_FEATURE_TM BIT29 ///< Thermal Monitor (TM1) +#define CPUID_FEATURE_IA64 BIT30 ///< Itanium Family Emulating IA-32 +#define CPUID_FEATURE_PBE BIT31 ///< Pending Break Enable + +// Feature Flag Values Reported in the ECX Register + +#define CPUID_FEATURE_SSE3 BIT32 ///< Streaming SIMD extensions 3 +#define CPUID_FEATURE_PCLMULQDQ BIT33 ///< PCLMULQDQ Instruction +#define CPUID_FEATURE_DTES64 BIT34 ///< 64-Bit Debug Store +#define CPUID_FEATURE_MONITOR BIT35 ///< MONITOR/MWAIT +#define CPUID_FEATURE_DSCPL BIT36 ///< CPL Qualified Debug Store +#define CPUID_FEATURE_VMX BIT37 ///< Virtual Machine Extensions (VMX) +#define CPUID_FEATURE_SMX BIT38 ///< Safer Mode Extensions (SMX) +#define CPUID_FEATURE_EST BIT39 ///< Enhanced Intel SpeedStep (GV3) +#define CPUID_FEATURE_TM2 BIT40 ///< Thermal Monitor 2 +#define CPUID_FEATURE_SSSE3 BIT41 ///< Supplemental SSE3 Instructions +#define CPUID_FEATURE_CID BIT42 ///< L1 Context ID +#define CPUID_FEATURE_SEGLIM64 BIT43 ///< 64-bit segment limit checking +#define CPUID_FEATURE_RESVH12 BIT44 ///< Reserved +#define CPUID_FEATURE_CX16 BIT45 ///< CMPXCHG16B Instruction +#define CPUID_FEATURE_xTPR BIT46 ///< Task Priority Update Control +#define CPUID_FEATURE_PDCM BIT47 ///< Perfmon/Debug Capability MSR +#define CPUID_FEATURE_RESVH16 BIT48 ///< Reserved +#define CPUID_FEATURE_PCID BIT49 ///< ASID-PCID support +#define CPUID_FEATURE_DCA BIT50 ///< Direct Cache Access +#define CPUID_FEATURE_SSE4_1 BIT51 ///< Streaming SIMD Extensions 4.1 +#define CPUID_FEATURE_SSE4_2 BIT52 ///< Streaming SIMD Extensions 4.1 +#define CPUID_FEATURE_xAPIC BIT53 ///< Extended xAPIC Support +#define CPUID_FEATURE_MOVBE BIT54 ///< MOVBE Instruction +#define CPUID_FEATURE_POPCNT BIT55 ///< POPCNT Instruction +#define CPUID_FEATURE_TSCTMR BIT56 ///< TSC deadline timer +#define CPUID_FEATURE_AES BIT57 ///< AES instructions +#define CPUID_FEATURE_XSAVE BIT58 ///< XSAVE/XSTOR States +#define CPUID_FEATURE_OSXSAVE BIT59 ///< OS Has Enabled XSETBV/XGETBV +#define CPUID_FEATURE_AVX1_0 BIT60 ///< AVX 1.0 instructions +#define CPUID_FEATURE_RDRAND BIT61 ///< RDRAND instruction +#define CPUID_FEATURE_F16C BIT62 ///< Float16 convert instructions +#define CPUID_FEATURE_VMM BIT63 ///< VMM (Hypervisor) present + +// The CPUID_EXTFEATURE_XXX values define 64-bit values +// returned in %ecx:%edx to a CPUID request with %eax of 0x80000001: + +#define CPUID_EXTFEATURE_SYSCALL BIT11 ///< SYSCALL/sysret + +#define CPUID_EXTFEATURE_XD BIT20 ///< eXecute Disable +#define CPUID_EXTFEATURE_1GBPAGE BIT21 ///< 1GB pages + +#define CPUID_EXTFEATURE_RDTSCP BIT27 ///< RDTSCP + +#define CPUID_EXTFEATURE_EM64T BIT29 ///< Extended Mem 64 Technology + +#define CPUID_EXTFEATURE_LAHF BIT32 ///< LAFH/SAHF instructions + + +// The CPUID_EXTFEATURE_XXX values define 64-bit values +// returned in %ecx:%edx to a CPUID request with %eax of 0x80000007: + +#define CPUID_EXTFEATURE_TSCI BIT8 ///< TSC Invariant + +// When the EAX register contains a value of 2, the CPUID instruction loads +// the EAX, EBX, ECX, and EDX registers with descriptors that indicate the +// processor's cache and TLB characteristics. + +// CPUID_CACHE_SIZE +/// Number of 8-bit descriptor values +#define CPUID_CACHE_SIZE 16 + +enum { + CpuIdCacheNull = 0x00, ///< NULL + CpuIdCacheItlb4K_32_4 = 0x01, ///< Inst TLB: 4K pages, 32 ents, 4-way + CpuIdCacheItlb4M_2 = 0x02, ///< Inst TLB: 4M pages, 2 ents + CpuIdCacheDtlb4K_64_4 = 0x03, ///< Data TLB: 4K pages, 64 ents, 4-way + CpuIdCacheDtlb4M_8_4 = 0x04, ///< Data TLB: 4M pages, 8 ents, 4-way + CpuIdCacheDtlb4M_32_4 = 0x05, ///< Data TLB: 4M pages, 32 ents, 4-way + CpuIdCacheL1I_8K = 0x06, ///< Icache: 8K + CpuIdCacheL1I_16K = 0x08, ///< Icache: 16K + CpuIdCacheL1I_32K = 0x09, ///< Icache: 32K, 4-way, 64 bytes + CpuIdCacheL1D_8K = 0x0A, ///< Dcache: 8K + CpuIdCacheL1D_16K = 0x0C, ///< Dcache: 16K + CpuIdCacheL1D_16K_4_32 = 0x0D, ///< Dcache: 16K, 4-way, 64 byte, ECC + CpuIdCacheL2_256K_8_64 = 0x21, ///< L2: 256K, 8-way, 64 bytes + CpuIdCacheL3_512K = 0x22, ///< L3: 512K + CpuIdCacheL3_1M = 0x23, ///< L3: 1M + CpuIdCacheL3_2M = 0x25, ///< L3: 2M + CpuIdCacheL3_4M = 0x29, ///< L3: 4M + CpuIdCacheL1D_32K_8 = 0x2C, ///< Dcache: 32K, 8-way, 64 byte + CpuIdCacheL1I_32K_8 = 0x30, ///< Icache: 32K, 8-way + CpuIdCacheL2_128K_S4 = 0x39, ///< L2: 128K, 4-way, sectored, 64B + CpuIdCacheL2_192K_S6 = 0x3A, ///< L2: 192K, 6-way, sectored, 64B + CpuIdCacheL2_128K_S2 = 0x3B, ///< L2: 128K, 2-way, sectored, 64B + CpuIdCacheL2_256K_S4 = 0x3C, ///< L2: 256K, 4-way, sectored, 64B + CpuIdCacheL2_384K_S6 = 0x3D, ///< L2: 384K, 6-way, sectored, 64B + CpuIdCacheL2_512K_S4 = 0x3E, ///< L2: 512K, 4-way, sectored, 64B + CpuIdCacheNoCache = 0x40, ///< No 2nd level or 3rd-level cache + CpuIdCacheL2_128K = 0x41, ///< L2: 128K + CpuIdCacheL2_256K = 0x42, ///< L2: 256K + CpuIdCacheL2_512K = 0x43, ///< L2: 512K + CpuIdCacheL2_1M_4 = 0x44, ///< L2: 1M, 4-way + CpuIdCacheL2_2M_4 = 0x45, ///< L2: 2M, 4-way + CpuIdCacheL3_4M_4_64 = 0x46, ///< L3: 4M, 4-way, 64 bytes + CpuIdCacheL3_8M_8_64 = 0x47, ///< L3: 8M, 8-way, 64 bytes*/ + CpuIdCacheL2_3M_12_64 = 0x48, ///< L3: 3M, 8-way, 64 bytes*/ + CpuIdCacheL2_4M_16_64 = 0x49, ///< L2: 4M, 16-way, 64 bytes + CpuIdCacheL2_6M_12_64 = 0x4A, ///< L2: 6M, 12-way, 64 bytes + CpuIdCacheL2_8M_16_64 = 0x4B, ///< L2: 8M, 16-way, 64 bytes + CpuIdCacheL2_12M_12_64 = 0x4C, ///< L2: 12M, 12-way, 64 bytes + CpuIdCacheL2_16M_16_64 = 0x4D, ///< L2: 16M, 16-way, 64 bytes + CpuIdCacheL2_6M_24_64 = 0x4E, ///< L2: 6M, 24-way, 64 bytes + CpuIdCacheItlb64 = 0x50, ///< Inst TLB: 64 entries + CpuIdCacheItlb128 = 0x51, ///< Inst TLB: 128 entries + CpuIdCacheItlb256 = 0x52, ///< Inst TLB: 256 entries + CpuIdCacheItlb4M2M_7 = 0x55, ///< Inst TLB: 4M/2M, 7 entries + CpuIdCacheDtlb4M_16_4 = 0x56, ///< Data TLB: 4M, 16 entries, 4-way + CpuIdCacheDtlb4K_16_4 = 0x57, ///< Data TLB: 4K, 16 entries, 4-way + CpuIdCacheDtlb4M2M_32_4 = 0x5A, ///< Data TLB: 4M/2M, 32 entries + CpuIdCacheDtlb64 = 0x5B, ///< Data TLB: 64 entries + CpuIdCacheDtlb128 = 0x5C, ///< Data TLB: 128 entries + CpuIdCacheDtlb256 = 0x5D, ///< Data TLB: 256 entries + CpuIdCacheL1D_16K_8_64 = 0x60, ///< Data cache: 16K, 8-way, 64 bytes + CpuIdCacheL1D_8K_4_64 = 0x66, ///< Data cache: 8K, 4-way, 64 bytes + CpuIdCacheL1D_16K_4_64 = 0x67, ///< Data cache: 16K, 4-way, 64 bytes + CpuIdCacheL1D_32K_4_64 = 0x68, ///< Data cache: 32K, 4-way, 64 bytes + CpuIdCacheTRACE_12K_8 = 0x70, ///< Trace cache 12K-uop, 8-way + CpuIdCacheTRACE_16K_8 = 0x71, ///< Trace cache 16K-uop, 8-way + CpuIdCacheTRACE_32K_8 = 0x72, ///< Trace cache 32K-uop, 8-way + CpuIdCacheTRACE_64K_8 = 0x73, ///< Trace cache 64K-uop, 8-way + CpuIdCacheL2_1M_4_64 = 0x78, ///< L2: 1M, 4-way, 64 bytes + CpuIdCacheL2_128K_8_64_2 = 0x79, ///< L2: 128K, 8-way, 64b, 2 lines/sec + CpuIdCacheL2_256K_8_64_2 = 0x7A, ///< L2: 256K, 8-way, 64b, 2 lines/sec + CpuIdCacheL2_512K_8_64_2 = 0x7B, ///< L2: 512K, 8-way, 64b, 2 lines/sec + CpuIdCacheL2_1M_8_64_2 = 0x7C, ///< L2: 1M, 8-way, 64b, 2 lines/sec + CpuIdCacheL2_2M_8_64 = 0x7D, ///< L2: 2M, 8-way, 64 bytes + CpuIdCacheL2_512K_2_64 = 0x7F, ///< L2: 512K, 2-way, 64 bytes + CpuIdCacheL2_256K_8_32 = 0x82, ///< L2: 256K, 8-way, 32 bytes + CpuIdCacheL2_512K_8_32 = 0x83, ///< L2: 512K, 8-way, 32 bytes + CpuIdCacheL2_1M_8_32 = 0x84, ///< L2: 1M, 8-way, 32 bytes + CpuIdCacheL2_2M_8_32 = 0x85, ///< L2: 2M, 8-way, 32 bytes + CpuIdCacheL2_512K_4_64 = 0x86, ///< L2: 512K, 4-way, 64 bytes + CpuIdCacheL2_1M_8_64 = 0x87, ///< L2: 1M, 8-way, 64 bytes + CpuIdCacheItlb4K_128_4 = 0xB0, ///< ITLB: 4KB, 128 entries, 4-way + CpuIdCacheItlb4M_4_4 = 0xB1, ///< ITLB: 4MB, 4 entries, 4-way, or + CpuIdCacheItlb2M_8_4 = 0xB1, ///< ITLB: 2MB, 8 entries, 4-way, or + CpuIdCacheItlb4M_8 = 0xB1, ///< ITLB: 4MB, 8 entries + CpuIdCacheItlb4K_64_4 = 0xB2, ///< ITLB: 4KB, 64 entries, 4-way + CpuIdCacheDtlb4K_128_4 = 0xB3, ///< DTLB: 4KB, 128 entries, 4-way + CpuIdCacheDtlb4K_256_4 = 0xB4, ///< DTLB: 4KB, 256 entries, 4-way + CpuIdCache2TLB_4K_512_4 = 0xCA, ///< 2nd-level TLB: 4KB, 512, 4-way + CpuIdCacheL3_512K_4_64 = 0xD0, ///< L3: 512KB, 4-way, 64 bytes + CpuIdCacheL3_1M_4_64 = 0xD1, ///< L3: 1M, 4-way, 64 bytes + CpuIdCacheL3_2M_4_64 = 0xD2, ///< L3: 2M, 4-way, 64 bytes + CpuIdCacheL3_1M_8_64 = 0xD6, ///< L3: 1M, 8-way, 64 bytes + CpuIdCacheL3_2M_8_64 = 0xD7, ///< L3: 2M, 8-way, 64 bytes + CpuIdCacheL3_4M_8_64 = 0xD8, ///< L3: 4M, 8-way, 64 bytes + CpuIdCacheL3_1M5_12_64 = 0xDC, ///< L3: 1.5M, 12-way, 64 bytes + CpuIdCacheL3_3M_12_64 = 0xDD, ///< L3: 3M, 12-way, 64 bytes + CpuIdCacheL3_6M_12_64 = 0xDE, ///< L3: 6M, 12-way, 64 bytes + CpuIdCacheL3_2M_16_64 = 0xE2, ///< L3: 2M, 16-way, 64 bytes + CpuIdCacheL3_4M_16_64 = 0xE3, ///< L3: 4M, 16-way, 64 bytes + CpuIdCacheL3_8M_16_64 = 0xE4, ///< L3: 8M, 16-way, 64 bytes + CpuIdCachePrefetch64 = 0xF0, ///< 64-Byte Prefetching + CpuIdCachePrefetch128 = 0xF1, ///< 128-Byte Prefetching +}; + +#endif // CPUID_H_ diff --git a/Include/IndustryStandard/GenericIch.h b/Include/IndustryStandard/GenericIch.h new file mode 100755 index 00000000..bda6ae59 --- /dev/null +++ b/Include/IndustryStandard/GenericIch.h @@ -0,0 +1,70 @@ +/** @file + Copyright (C) 2016, The HermitCrabs Lab. All rights reserved. + + All rights reserved. + + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + 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 GENERIC_ICH_H_ +#define GENERIC_ICH_H_ + +// GenericIchDefs Generic ICH Definitions. +// +// Definitions beginning with "R_" are registers. +// Definitions beginning with "B_" are bits within registers. +// Definitions beginning with "V_" are meaningful values of bits within the registers. + +// IchPciAddressing PCI Bus Address for ICH. + +#define PCI_BUS_NUMBER_ICH 0x00 ///< ICH is on PCI Bus 0. +#define PCI_DEVICE_NUMBER_ICH 31 ///< ICH is Device 31. +#define PCI_FUNCTION_NUMBER_ICH_LPC 0 ///< LPC is Function 0. +#define PCI_FUNCTION_NUMBER_ICH_SMBUS 2 ///< SMB is Function 2. + + +// IchAcpiCntr Control for the ICH's ACPI Counter. + +#define R_ICH_ACPI_BASE 0x40 +#define B_ICH_ACPI_BASE_BAR 0x0000FF80 +#define R_ICH_ACPI_CNT 0x44 +#define B_ICH_ACPI_CNT_ACPI_EN 0x80 + +// Pre Intel Sunrisepoint + +#define R_ICH_LPC_ACPI_BASE R_ICH_ACPI_BASE +#define B_ICH_LPC_ACPI_BASE_BAR B_ICH_ACPI_BASE_BAR +#define R_ICH_LPC_ACPI_CNT R_ICH_ACPI_CNT +#define B_ICH_LPC_ACPI_CNT_ACPI_EN B_ICH_ACPI_CNT_ACPI_EN + +// Intel Sunrisepoint + +#define R_ICH_SMBUS_ACPI_BASE R_ICH_ACPI_BASE +#define B_ICH_SMBUS_ACPI_BASE_BAR B_ICH_ACPI_BASE_BAR +#define R_ICH_SMBUS_ACPI_CNT R_ICH_ACPI_CNT +#define B_ICH_SMBUS_ACPI_CNT_ACPI_EN B_ICH_ACPI_CNT_ACPI_EN + + +// IchAcpiTimer The ICH's ACPI Timer. + +#define R_ACPI_PM1_TMR 0x08 +#define V_ACPI_TMR_FREQUENCY 3579545 +#define V_ACPI_PM1_TMR_MAX_VAL 0x01000000 ///< The timer is 24 bit overflow. + +// PCI_ICH_LPC_ADDRESS +/// Macro to generate the PCI address of any given ICH LPC Register. +#define PCI_ICH_LPC_ADDRESS(Register) \ + ((UINTN)(PCI_LIB_ADDRESS (PCI_BUS_NUMBER_ICH, PCI_DEVICE_NUMBER_ICH, PCI_FUNCTION_NUMBER_ICH_LPC, (Register)))) + +// PCI_ICH_SMBUS_ADDRESS +/// Macro to generate the PCI address of any given ICH SMBUS Register. +#define PCI_ICH_SMBUS_ADDRESS(Register) \ + ((UINTN)(PCI_LIB_ADDRESS (PCI_BUS_NUMBER_ICH, PCI_DEVICE_NUMBER_ICH, PCI_FUNCTION_NUMBER_ICH_SMBUS, (Register)))) + +#endif // GENERIC_ICH_H_ diff --git a/Include/Library/OcAcpiLib.h b/Include/Library/OcAcpiLib.h new file mode 100755 index 00000000..ad8a67a4 --- /dev/null +++ b/Include/Library/OcAcpiLib.h @@ -0,0 +1,62 @@ +/** @file + Copyright (C) 2016, The HermitCrabs Lab. All rights reserved. + + All rights reserved. + + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + 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 OC_ACPI_LIB_H_ +#define OC_ACPI_LIB_H_ + +// TODO: remove this nasty temporary workaround + +#include + +// AcpiFindLegacyRsdPtr +/** Find RSD_PTR Table In Legacy Area + + @retval EFI_ACPI_6_0_ROOT_SYSTEM_DESCRIPTION_POINTER +**/ +EFI_ACPI_6_0_ROOT_SYSTEM_DESCRIPTION_POINTER * +AcpiFindLegacyRsdPtr ( + VOID + ); + +// AcpiFindRsdPtr +/** Find RSD_PTR Table From System Configuration Tables + + @retval EFI_ACPI_6_0_ROOT_SYSTEM_DESCRIPTION_POINTER +**/ +EFI_ACPI_6_0_ROOT_SYSTEM_DESCRIPTION_POINTER * +AcpiFindRsdPtr ( + VOID + ); + +// AcpiLocateTable +/** Locate an existing ACPI table. + + @param[in] Signature + @param[in, out] Table + @param[in, out] Handle + @param[in, out] Version + + @retval EFI_SUCCESS + @retval EFI_NOT_FOUND + @retval EFI_INVALID_PARAMETER +**/ +EFI_STATUS +AcpiLocateTable ( + IN UINT32 Signature, + IN OUT EFI_ACPI_DESCRIPTION_HEADER **Table, + IN OUT UINTN *Handle, + IN OUT EFI_ACPI_TABLE_VERSION *Version + ); + +#endif // OC_ACPI_LIB_H_ diff --git a/Include/Library/OcCpuLib.h b/Include/Library/OcCpuLib.h new file mode 100755 index 00000000..7676b95e --- /dev/null +++ b/Include/Library/OcCpuLib.h @@ -0,0 +1,66 @@ +/** @file + Copyright (C) 2016 - 2017, The HermitCrabs Lab. All rights reserved. + + All rights reserved. + + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + 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 OC_CPU_LIB_H_ +#define OC_CPU_LIB_H_ + +// CPU_INFO +typedef struct { + UINT8 Type; + UINT8 Vendor[16]; + CHAR8 BrandString[48]; + + UINT8 Family; + UINT8 Model; + UINT8 ExtModel; + UINT8 ExtFamily; + UINT8 Stepping; + UINT64 Features; + UINT64 ExtFeatures; + UINT32 Signature; + UINT8 Brand; + + UINT32 MaxExtId; + + UINT8 MaxDiv; + UINT8 CurBusRatio; ///< Current Multiplier + UINT8 MinBusRatio; ///< Min Bus Ratio + UINT8 MaxBusRatio; ///< Max Bus Ratio + UINT8 MaxBusRatioDiv; + + UINT8 TurboBusRatio1; + UINT8 TurboBusRatio2; + UINT8 TurboBusRatio3; + UINT8 TurboBusRatio4; + + UINT64 ARTFrequency; + UINT64 TSCFrequency; + UINT64 CPUFrequency; + UINT64 FSBFrequency; + +} CPU_INFO; + +// OcCpuScanProcessor +/** Scan the processor and fill the cpu info structure with results + + @param[in] Cpu A pointer to the cpu info structure to fill with results + + @retval EFI_SUCCESS The scan was completed successfully. +**/ +EFI_STATUS +OcCpuScanProcessor ( + IN CPU_INFO *Platform + ); + +#endif // OC_CPU_LIB_H_ diff --git a/Include/Library/OcDevicePathLib.h b/Include/Library/OcDevicePathLib.h new file mode 100755 index 00000000..803699ec --- /dev/null +++ b/Include/Library/OcDevicePathLib.h @@ -0,0 +1,107 @@ +/** @file + Copyright (C) 2016, The HermitCrabs Lab. All rights reserved. + + All rights reserved. + + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + 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 OC_DEVICE_PATH_LIB_H_ +#define OC_DEVICE_PATH_LIB_H_ + +// AppendFileNameDevicePath +/** + + @param[in] DevicePath The device path which to append the file path. + @param[in] FileName The file name to append to the device path. + + @retval EFI_SUCCESS The defaults were initialized successfully. + @retval EFI_INVALID_PARAMETER The parameters passed were invalid. + @retval EFI_OUT_OF_RESOURCES The system ran out of memory. +**/ +EFI_DEVICE_PATH_PROTOCOL * +AppendFileNameDevicePath ( + IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, + IN CHAR16 *FileName + ); + +// DevicePathToText +/** Converts a device path structure to its string representative. + + @param[in] StorageDevicePath The device path to convert to unicode string. + @param[in] DisplayOnly If DisplayOnly is TRUE, then the shorter text + representation of the display node is used, + where applicable. If DisplayOnly is FALSE, + then the longer text representation of the + display node is used. + @param[in] AllowShortcuts If AllowShortcuts is TRUE, then the shortcut + forms of text representation for a device node + can be used, where applicable. + + @retval EFI_SUCCESS The defaults were initialized successfully. + @retval EFI_INVALID_PARAMETER The parameters passed were invalid. + @retval EFI_OUT_OF_RESOURCES The system ran out of memory. +**/ +CHAR16 * +DevicePathToText ( + IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, + IN BOOLEAN DisplayOnly, + IN BOOLEAN AllowShortcuts + ); + +// FindDevicePathNodeWithType +/** Locate the node inside the device path specified by Type an SubType values. + + @param[in] DevicePath The device path used in the search. + @param[in] Type The Type field of the device path node specified by Node. + @param[in] SubType The SubType field of the device path node specified by Node. + + @return Returned is the first Device Path Node with the given type. +**/ +EFI_DEVICE_PATH_PROTOCOL * +FindDevicePathNodeWithType ( + IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, + IN UINT8 Type, + IN UINT8 SubType OPTIONAL + ); + +// IsDevicePathEqual +/** + + @param[in] DevicePath1 The first device path protocol to compare. + @param[in] DevicePath2 The second device path protocol to compare. + + @retval TRUE The device paths matched + @retval FALSE The device paths were different +**/ +BOOLEAN +EFIAPI +IsDevicePathEqual ( + IN EFI_DEVICE_PATH_PROTOCOL *DevicePath1, + IN EFI_DEVICE_PATH_PROTOCOL *DevicePath2 + ); + +// IsDeviceChild +/** + + @param[in] ParentPath The parent device path protocol to check against. + @param[in] ChildPath The device path protocol of the child device to compare. + + @retval TRUE The child device path contains the parent device path. + @retval FALSE The device paths were different +**/ +BOOLEAN +EFIAPI +IsDeviceChild ( + IN EFI_DEVICE_PATH_PROTOCOL *ParentPath, + IN EFI_DEVICE_PATH_PROTOCOL *ChildPath, + IN UINT8 EndPathType + ); + +#endif // OC_DEVICE_PATH_LIB_H_ diff --git a/Include/Library/OcFileLib.h b/Include/Library/OcFileLib.h new file mode 100755 index 00000000..1e2028de --- /dev/null +++ b/Include/Library/OcFileLib.h @@ -0,0 +1,226 @@ +/** @file + Copyright (C) 2016 - 2017, The HermitCrabs Lab. All rights reserved. + + All rights reserved. + + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + 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 OC_FILE_LIB_H_ +#define OC_FILE_LIB_H_ + +// Include the abstracted protocol for its definitions + +#include + +#include + +#define FILE_ITERATE_DIRECTORIES EFI_FILE_DIRECTORY +#define FILE_ITERATE_FILES (EFI_FILE_VALID_ATTR ^ EFI_FILE_DIRECTORY) + +// FileExists +/** + + @param[in] DevicePath A pointer to the device path to check for the file. + @param[in] FilePath A pointer to the NULL terminated unicode file name. + + @retval TRUE The file path was found on the device. + @retval FALSE The file path was not found on the device. +**/ +BOOLEAN +FileExists ( + IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, + IN CHAR16 *FilePath + ); + +// FolderFileExists +/** + + @param[in] DevicePath A pointer to the device path to check for the file. + @param[in] DirectoryPath A pointer to the NULL terminated ascii directory name. + @param[in] FilePath A pointer to the NULL terminated ascii file name. + + @retval TRUE The file path was found on the device. + @retval FALSE The file path was not found on the device. +**/ +BOOLEAN +FolderFileExists ( + IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, + IN CHAR8 *DirectoryPath OPTIONAL, + IN CHAR8 *FilePath OPTIONAL + ); + +// GetFileInfo +/** + + @param[in] DevicePath A pointer to the device path to device. + @param[in] Directory A pointer to the directory that contains the file. + @param[in] FileName A pointer to the the filename. + @param[out] FileInfo A pointer to the FILE_INFO structure returned or NULL + + @retval EFI_SUCCESS The FILE_INFO structure was successfully returned. +**/ +EFI_STATUS +GetFileInfo ( + IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, + IN CHAR16 *Directory, + IN CHAR16 *FileName, + OUT EFI_FILE_INFO **FileInfo + ); + +// GetNextDirEntry +/** + + @param[in] DevicePath + @param[out] DirEntry + @param[in] SearchMask + + @retval EFI_SUCCESS The volume label was successfully returned. +**/ +EFI_STATUS +GetNextDirEntry ( + IN EFI_FILE *Directory, + OUT EFI_FILE_INFO **DirEntry, + IN UINT64 SearchMask + ); + +// GetVolumeLabel +/** + + @param[in] DevicePath A pointer to the device path to retrieve the volume label from. + @param[out] VolumeLabel A pointer to the NULL terminated unicode volume label. + + @retval EFI_SUCCESS The volume label was successfully returned. +**/ +EFI_STATUS +GetVolumeLabel ( + IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, + IN OUT CHAR16 **VolumeLabel + ); + +// OpenDirectory +/** Read file from device path + + @param[in] DevicePath The whole device path to the file. + @param[out] FileSize The size of the file read or 0 + + @retval A pointer to a buffer containing the file read or NULL + **/ +EFI_STATUS +OpenDirectory ( + IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, + IN CHAR16 *DirectoryPath, + IN UINT64 Mode, + IN UINT64 Attributes, + OUT EFI_FILE **DirectoryHandle OPTIONAL + ); + +// OpenFileSystem +/** Read file from device path + + @param[in] DevicePath The whole device path to the file. + @param[out] FileSystem The size of the file read or 0 + + @retval EFI_SUCCESS The Filesystem was successfully opened and returned. +**/ +EFI_STATUS +OpenFileSystem ( + IN EFI_DEVICE_PATH_PROTOCOL **DevicePath, + IN OUT EFI_SIMPLE_FILE_SYSTEM_PROTOCOL **FileSystem + ); + +// ReadFileFromDevicePath +/** Read file from device path + + @param[in] DevicePath The whole device path to the file. + @param[out] FileSize The size of the file read or 0 + + @retval A pointer to a buffer containing the file read or NULL +**/ +VOID * +ReadFileFromDevicePath ( + IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, + OUT UINTN *FileSize + ); + +// ReadFile +/** Read file from device path + + @param[in] DevicePath The device path for the device. + @param[in] FilePath The full path to the file on the device. + @param[out] FileBuffer A pointer to a buffer containing the file read or NULL + @param[out] FileSize The size of the file read or 0 + + @retval EFI_SUCCESS The platform detection executed successfully. +**/ +EFI_STATUS +ReadFile ( + IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, + IN CHAR16 *FilePath, + OUT VOID **FileBuffer, + OUT UINTN *FileBufferSize + ); + +// ReadFvFile +/** Read firmware file from device path + + @param[in] FvFileGuid The guid of the firmware file to read. + @param[out] FileBuffer The size of the file read or 0 + @param[out] FileSize The size of the file read or 0 + + @retval A pointer to a buffer containing the file read or NULL +**/ +EFI_STATUS +ReadFvFile ( + IN GUID *FvFileGuid, + OUT VOID **FileBuffer, + OUT UINTN *FileSize + ); + +// SaveFile +/** Save filebuffer to device path + + @param[in] DevicePath The device path for the device. + @param[in] DirectoryPath The directory path to place the file on the device. + @param[in] FilePath The filename to use when saving the file on the device. + @param[out] FileBuffer A pointer to a buffer containing the file read or NULL + @param[out] FileSize The size of the file buffer to save + + @retval EFI_SUCCESS The platform detection executed successfully. +**/ +EFI_STATUS +SaveFile ( + IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, + IN CHAR16 *Directory, + IN CHAR16 *FileName, + IN VOID *FileBuffer, + IN UINTN FileSize + ); + +// WriteFilePath +/** Write file to device path + + @param[in] DevicePath The device path to the device to create the file on. + @param[in] FilePath The full path to use when writing the file on the device. + @param[in] FileBuffer A pointer to a buffer containing the file contents. + @param[in] FileSize The size of the file buffer to save + @param[in] Attributes + + @retval EFI_SUCCESS The platform detection executed successfully. +**/ +EFI_STATUS +WriteFilePath ( + IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, + IN CHAR16 *FilePath, + IN VOID *FileBuffer, + IN UINTN FileSize, + IN UINT64 Attributes + ); + +#endif // OC_FILE_LIB_H_ diff --git a/Include/Library/OcMiscLib.h b/Include/Library/OcMiscLib.h new file mode 100755 index 00000000..7e6f6544 --- /dev/null +++ b/Include/Library/OcMiscLib.h @@ -0,0 +1,136 @@ +/** @file + Copyright (C) 2016 - 2018, The HermitCrabs Lab. All rights reserved. + + All rights reserved. + + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + 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 OC_MISC_LIB_H_ +#define OC_MISC_LIB_H_ + +// PLATFORM_DATA_HEADER +typedef struct { + struct { + CHAR16 Reserved[8]; + UINT32 KeySize; + UINT32 DataSize; + } Hdr; +} PLATFORM_DATA_HEADER; + +// Base64Decode +/** + + @param[in] EncodedData A pointer to the data to convert. + @param[in] EncodedDataLength The length of data to convert. + @param[in] DecodedSize A pointer to location to store the decoded size. + + @retval An ascii string representing the data. +**/ +UINT8 * +Base64Decode ( + IN CHAR8 *EncodedData, + IN UINTN EncodedDataLength, + OUT UINTN *DecodedSize + ); + +// ConvertDataToString +/** Attempt to convert the data into an ascii string. + + @param[in] Data A pointer to the data to convert. + @param[in] DataSize The length of data to convert. + + @retval An ascii string representing the data. +**/ +CHAR8 * +ConvertDataToString ( + IN VOID *Data, + IN UINTN DataSize + ); + +// LegacyRegionlock +/** Lock the legacy region specified to enable modification. + + @param[in] LegacyAddress The address of the region to lock. + @param[in] LegacyLength The size of the region to lock. + + @retval EFI_SUCCESS The region was locked successfully. +**/ +EFI_STATUS +LegacyRegionLock ( + IN UINT32 LegacyAddress, + IN UINT32 LegacyLength + ); + +// LegacyRegionUnlock +/** Unlock the legacy region specified to enable modification. + + @param[in] LegacyAddress The address of the region to unlock. + @param[in] LegacyLength The size of the region to unlock. + + @retval EFI_SUCCESS The region was unlocked successfully. +**/ +EFI_STATUS +LegacyRegionUnlock ( + IN UINT32 LegacyAddress, + IN UINT32 LegacyLength + ); + +/** Log the boot options passed + + @param[in] BootOrder A pointer to the boot order list. + @param[in] BootOrderLength Size of the boot order list. + + @retval EFI_SUCCESS The entry point is executed successfully. +**/ +EFI_STATUS +LogBootOrder ( + IN INT16 *BootOrder, + IN UINTN BootOrderSize + ); + +// LogHexDump +/** Convert memory locations into hex strings and output to the boot log + + @param[in] Address The address of the region to dump hex from. + @param[in] Address2 The address to show when dumping hex. + @param[in] Length The length of the string to show. + @param[in] LineSize How many bytes to show per line. + @param[in] DisplayAscii Flag to show ascii charater also. + + @retval EFI_SUCCESS The region was unlocked successfully. +**/ +EFI_STATUS +LogHexDump ( + IN VOID *Address, + IN VOID *Address2, + IN UINTN Length, + IN UINTN LineSize, + IN BOOLEAN DisplayAscii + ); + +// SetPlatformData +/** + + @param[in] DataRecordGuid The guid of the record to use. + @param[in] Key A pointer to the ascii key string. + @param[in] Data A pointer to the data to store. + @param[in] DataSize The length of the data to store. + + @retval EFI_SUCCESS The datahub was updated successfully. +**/ +EFI_STATUS +SetPlatformData ( + IN EFI_GUID *DataRecordGuid, + IN CHAR8 *Key, + IN VOID *Data, + IN UINT32 DataSize + ); + +#endif // OC_MISC_LIB_H_ diff --git a/Include/Library/OcPrintLib.h b/Include/Library/OcPrintLib.h new file mode 100755 index 00000000..e569bfdc --- /dev/null +++ b/Include/Library/OcPrintLib.h @@ -0,0 +1,165 @@ +/** @file + Copyright (C) 2016 - 2018, The HermitCrabs Lab. All rights reserved. + + All rights reserved. + + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + 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 _OC_PRINT_LIB_H +#define _OC_PRINT_LIB_H + +#define LOG(arg) OcLog arg + +/** + * +**/ + +#ifndef __FUNCTION_NAME__ + #ifdef _MSC_VER + #define __FUNCTION_NAME__ __FUNCTION__ + #else + #define __FUNCTION_NAME__ __func__ + #endif +#endif + +/** + * Print Primitives +**/ + +#define LEFT_JUSTIFY 0x01 +#define PREFIX_SIGN 0x02 +#define PREFIX_BLANK 0x04 +#define COMMA_TYPE 0x08 +#define LONG_TYPE 0x10 +#define PREFIX_ZERO 0x20 +#define RADIX_HEX 0x80 +#define UPPER_CASE_HEX 0x100 +#define PAD_TO_WIDTH 0x200 +#define PRECISION 0x800 + +/** + * Format Identifiers +**/ + +#define OUTPUT_ASCII 0x00 +#define OUTPUT_UNICODE 0x40 +#define OUTPUT_CONSOLE 0x80 +#define FORMAT_ASCII 0x000 +#define FORMAT_UNICODE 0x100 +#define ARGUMENT_ASCII 0x000 +#define ARGUMENT_UNICODE 0x400 +#define ARGUMENT_REVERSED 0x1000 + +/** + * The maximum number of values OcVSPrint will process - 128 because of bin decodes +**/ + +#define MAXIMUM_VALUE_CHARACTERS 128 + +/** + * The number of warning status strings in mOcStatusString +**/ + +#define WARNING_STATUS_NUMBER 5 + +/** + * The number of error status strings in mOcStatusString +**/ + +#define ERROR_STATUS_NUMBER 33 + +// OcLog +/// @brief +/// +/// @param[in] ErrorLevel The firmware allocated handle for the EFI image. +/// @param[in] Format A pointer to the string format list which describes the VA_ARGS list +/// @param[in] ...... VA_ARGS list +/// +/// @retval EFI_SUCCESS The platform detection executed successfully. + +VOID +EFIAPI +OcLog ( + IN UINTN ErrorLevel, + IN const CHAR8 *Format, + ... + ) +; + +// OcSPrint +/// @brief +/// +/// @param[out] StartOfBuffer A pointer to the character buffer to print the results of the parsing of Format into. +/// @param[in] BufferSize Maximum number of characters to put into buffer. Zero means no limit. +/// @param[in] Flags Intial flags value. Can only have FORMAT_UNICODE and OUTPUT_UNICODE set. +/// @param[in] FormatString A pointer a Null-terminated format string which describes the VA_ARGS list. +/// @param[in] ...... VA_ARGS list +/// +/// @retval EFI_SUCCESS The platform detection executed successfully. + +UINTN +EFIAPI +OcSPrint ( + OUT VOID *StartOfBuffer, + IN UINTN BufferSize, + IN UINTN Flags, + IN VOID *FormatString, + ... + ) +; + +// OcVSPrint +/// @brief Worker function that produces a Null-terminated string in an output buffer based on a Null-terminated format string and variable argument list. +/// +/// @param[in] Buffer A pointer to the character buffer to print the results of the parsing of Format into. +/// @param[in] BufferSize Maximum number of characters to put into buffer. Zero means no limit. +/// @param[in] Flags Intial flags value. Can only have FORMAT_UNICODE and OUTPUT_UNICODE set. +/// @param[in] FormatString A pointer a Null-terminated format string which describes the VA_ARGS list +/// @param[in] ...... VA_ARGS list +/// +/// @retval Number of characters printed not including the Null-terminator. + +UINTN +EFIAPI +OcVSPrint ( + OUT CHAR8 *Buffer, + IN UINTN BufferSize, + IN UINTN Flags, + IN CONST CHAR8 *Format, + IN VA_LIST Marker + ) +; + + +// OcGuidToString +/// @brief +/// +/// @param[in] Guid A pointer to the guid to convert to string. +/// +/// @retval A pointer to the buffer containg the string representation of the guid. + +CHAR8 * +EFIAPI +OcGuidToString ( + IN EFI_GUID *Guid + ) +; + +// mOcPrintLibHexStr +/// @brief +/// +extern CONST CHAR8 mOcPrintLibHexStr[]; + +// mOcStatusString +/// @brief +/// +extern CONST CHAR8 *CONST mOcStatusString[]; + +#endif /* _OC_PRINT_LIB_H */ diff --git a/Include/Library/OcProtocolLib.h b/Include/Library/OcProtocolLib.h new file mode 100755 index 00000000..387a5d30 --- /dev/null +++ b/Include/Library/OcProtocolLib.h @@ -0,0 +1,112 @@ +/** @file + Copyright (C) 2016, The HermitCrabs Lab. All rights reserved. + + All rights reserved. + + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + 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 OC_PROTOCOL_LIB_H_ +#define OC_PROTOCOL_LIB_H_ + +// RegisterProtocolCallback +/** + + @param[in] Protocol The numeric ID of the protocol for which the event is to be registered. + @param[in] NotifyFunction Pointer to the event’s notification function, if any. + @param[in] NotifyContext Pointer to the notification function’s context; corresponds to parameter Context in the + notification function. + @param[in] Event Event that is to be signaled whenever a protocol interface is registered for Protocol. + The same EFI_EVENT may be used for multiple protocol notify registrations. + @param[in] Registration A pointer to a memory location to receive the registration value. + This value must be saved and used by the notification function of Event to retrieve the + list of handles that have added a protocol interface of type Protocol. + + @retval EFI_SUCCESS The event Callback was created successfully. +**/ +EFI_STATUS +EFIAPI +RegisterProtocolCallback ( + IN EFI_GUID *Protocol, + IN EFI_EVENT_NOTIFY NotifyFunction, + IN VOID *NotifyContext, + OUT EFI_EVENT *Event, + OUT VOID **Registration + ); + +// SafeInstallProtocolInterface +/** + + @param[in] ProtocolGuid The numeric ID of the protocol interface. It is the caller’s responsibility to pass in a + valid GUID. + @param[in] Interface A pointer to the protocol interface. The Interface must adhere to the structure defined by + Protocol. + NULL can be used if a structure is not associated with Protocol. + @param[in] Handle A pointer to the EFI_HANDLE on which the interface is to be installed. If *Handle is NULL on + input, a new handle is created and returned on output. + If *Handle is not NULL on input, the protocol is added to the handle, and the handle is + returned unmodified. + If *Handle is not a valid handle, then EFI_INVALID_PARAMETER is returned. + @param[in] DupeCheck A boolean flag to check if protocol already exists. + + @retval EFI_SUCCESS The entry point is executed successfully. +**/ +EFI_STATUS +SafeInstallProtocolInterface ( + IN GUID *ProtocolGuid, + IN VOID *Interface, + IN EFI_HANDLE Handle, + IN BOOLEAN DupeCheck + ); + +// SafeLocateProtocol +/** + + @param[in] Protocol Provides the protocol to search for. + @param[in] Registration Optional registration key returned from RegisterProtocolNotify(). If Registration is NULL, + then it is ignored. + @param[out] Interface On return, a pointer to the first interface that matches Protocol and Registration. + + @retval EFI_SUCCESS The entry point is executed successfully. +**/ +EFI_STATUS +SafeLocateProtocol ( + IN EFI_GUID *Protocol, + IN VOID *Registration OPTIONAL, + OUT VOID **Interface + ); + +// SafeHandleProtocol +/** + + @param[in] Handle The handle being queried. If Handle is not a valid EFI_HANDLE, then EFI_INVALID_PARAMETER is returned. + @param[in] Protocol The published unique identifier of the protocol. It is the caller’s responsibility to pass in a valid GUID. + @param[out] Interface Supplies the address where a pointer to the corresponding Protocol Interface is returned. + NULL will be returned if a structure is not associated with Protocol. + + @retval EFI_SUCCESS The entry point is executed successfully. +**/ +EFI_STATUS +SafeHandleProtocol ( + IN EFI_HANDLE Handle, + IN EFI_GUID *Protocol, + OUT VOID **Interface + ); + +// SignalProtocolEvent +/** + + @param[in] ProtocolGuid The published unique identifier of the protocol to publish. +**/ +VOID +SignalProtocolEvent ( + IN EFI_GUID *ProtocolGuid + ); + +#endif // OC_PROTOCOL_LIB_H_ diff --git a/Include/Library/OcStringLib.h b/Include/Library/OcStringLib.h new file mode 100755 index 00000000..1d1311da --- /dev/null +++ b/Include/Library/OcStringLib.h @@ -0,0 +1,403 @@ +/** @file + Copyright (C) 2016 - 2018, The HermitCrabs Lab. All rights reserved. + + All rights reserved. + + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + 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 OC_STRING_LIB_H_ +#define OC_STRING_LIB_H_ + +// IsAsciiPrint +/** Check if character is printable + + @param[in] Char The ascii character to check if is printable. + + @retval TRUE, if character is printable. +**/ +BOOLEAN +IsAsciiPrint ( + IN CHAR8 Char + ); + +// IsAsciiDecimalDigitCharacter +/** Check if character is a decimal digit + + @param[in] Char The ascii character to check if is printable. + + @retval TRUE, if character is a decimal digit. +**/ +BOOLEAN +IsAsciiDecimalDigitCharacter ( + IN CHAR8 Char + ); + +// IsAsciiSpace +/** Check if character is a white space character + + @param[in] Char The ascii character to check if is white space. + + @retval TRUE, if character is a white space character +**/ +INTN +IsAsciiSpace ( + IN CHAR8 Char + ); + +// AsciiHexCharToUintn +/** Convert ascii hexadecimal character to unsigned integer. + + @param[in] Char The ascii character to convert to integer. + + @retval Integer value of character representation. +**/ +UINTN +AsciiHexCharToUintn ( + IN CHAR8 Char + ); + +// AsciiStrnIntegerCmp +/** + + @param[in] String1 A pointer to a buffer containing the first ascii string to compare. + @param[in] String2 A pointer to a buffer containing the second ascii string to compare. + @param[in] Length The number of characters to compare. + + @retval Integer value of character representation. +**/ +INTN +AsciiStrnIntegerCmp ( + IN CHAR8 *String1, + IN CHAR8 *String2, + IN UINTN Length + ); + +// AsciiStrToInteger +/** Convert ascii string to unsigned integer. + + @param[in] Char The null terminated ascii string to convert to integer. + + @retval Integer value of the ascii string. +**/ +INTN +AsciiStrToInteger ( + IN CHAR8 *Start + ); + +// AsciiToUpperChar +/** Convert ascii character to upper case + + @param[in] Char The ascii character to convert to upperase. + + @retval Upper case representation of the ascii character. +**/ +CHAR8 +AsciiToUpperChar ( + IN CHAR8 Char + ); + +// OcAsciiStrStr +/** + Returns the first occurrence of a Null-terminated ASCII sub-string + in a Null-terminated ASCII string. + + @param[in] String1 A pointer to a Null-terminated ASCII string. + @param[in] SearchString A pointer to a Null-terminated ASCII string to search for. + + @retval NULL If the SearchString does not appear in String. + +**/ +CHAR8 * +OcAsciiStrStr ( + IN CONST CHAR8 *String, + IN CONST CHAR8 *SearchString + ); + +// OcAsciiStrnCmp +/** + Compares two Null-terminated ASCII strings with maximum lengths, and returns + the difference between the first mismatched ASCII characters. + + @param[in] String1 A pointer to a Null-terminated ASCII string. + @param[in] String2 A pointer to a Null-terminated ASCII string. + @param[in] 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 +OcAsciiStrnCmp ( + IN CONST CHAR8 *FirstString, + IN CONST CHAR8 *SecondString, + IN UINTN Length + ); + +// OcAsciiStrToGuid +/** Convert correctly formatted string into a GUID. + + @param[in] StringGuid A pointer to a buffer containing the ascii string. + @param[in] Guid A pointer to location to store the converted GUID. + + @retval EFI_SUCCESS The conversion completed successfully. +**/ +EFI_STATUS +OcAsciiStrToGuid ( + IN CONST CHAR8 *StringGuid, + IN OUT EFI_GUID *Guid + ); + +// OcAsciiStrToUnicode +/** Convert null terminated ascii string to unicode. + + @param[in] String1 A pointer to the ascii string to convert to unicode. + @param[out] String2 A pointer to the converted unicode string. + @param[in] Length Length or 0 to calculate the length of the ascii string to convert. + + @retval A pointer to the converted unicode string. +**/ +CHAR16 * +OcAsciiStrToUnicode ( + IN CHAR8 *String1, + IN CHAR16 *String2, + IN UINTN Length + ); + +// AsciiTrimWhiteSpace +/** Remove leading and trailing spaces in the string + + @param[in] Start A pointer to the ascii string + + @retval A pointer to the converted ascii string. +**/ +CHAR8 * +AsciiTrimWhiteSpace ( + IN CHAR8 *String + ); + +// AsciiBaseName +/** Return the filename element of a pathname + + @param[in] FullPath A pointer to a ascii path + + @retval A pointer to the converted ascii string. +**/ +CHAR8 * +AsciiBaseName ( + IN CHAR8 *FullPath + ); + +// AsciiDirName +/** Return the folder element of a pathname + + @param[in] FullPath A pointer to a ascii path + + @retval A pointer to the converted ascii string. +**/ +CHAR8 * +AsciiDirName ( + IN CHAR8 *FullPath + ); + +// IsPrint +/** Check if character is printable + + @param[in] Char The unicode character to check if is printable. + + @retval TRUE, if character is printable. +**/ +BOOLEAN +IsPrint ( + IN CHAR16 Char + ); + +// IsDecimalDigitCharacter +/** Check if character is a decimal digit + + @param[in] Char The unicode character to check if is printable. + + @retval TRUE, if character is a decimal digit. +**/ +BOOLEAN +IsDecimalDigitCharacter ( + IN CHAR16 Char + ); + +// IsSpace +/** Check if character is a white space character + + @param[in] Char The unicode character to check if is white space. + + @retval TRUE, if character is a white space character +**/ +INTN +IsSpace ( + IN CHAR16 Char + ); + +// HexCharToUintn +/** Convert unicode hexadecimal character to unsigned integer. + + @param[in] Char The unicode character to convert to integer. + + @retval Integer value of character representation. +**/ +UINTN +HexCharToUintn ( + IN CHAR16 Char + ); + +// StrnIntegerCmp +/** + + @param[in] String1 A pointer to a buffer containing the first unicode string to compare. + @param[in] String2 A pointer to a buffer containing the second unicode string to compare. + @param[in] Length The number of characters to compare. + + @retval Integer value of character representation. +**/ +INTN +StrnIntegerCmp ( + IN CHAR16 *String1, + IN CHAR16 *String2, + IN UINTN Length + ); + +// StrToInteger +/** Convert unicode string to unsigned integer. + + @param[in] Char The null terminated unicode string to convert to integer. + + @retval Integer value of the unicode string. +**/ +INTN +StrToInteger ( + IN CHAR16 *Start + ); + +// ToUpperChar +/** Convert unicode character to upper case + + @param[in] Char The unicode character to convert to upperase. + + @retval Upper case representation of the unicode character. +**/ +CHAR16 +ToUpperChar ( + IN CHAR16 Char + ); + +// OcStrToGuid +/** Convert correctly formatted string into a GUID. + + @param[in] StringGuid A pointer to a buffer containing the unicode string. + @param[in] Guid A pointer to location to store the converted GUID. + + @retval EFI_SUCCESS The conversion completed successfully. +**/ +EFI_STATUS +OcStrToGuid ( + IN CONST CHAR16 *StringGuid, + IN OUT EFI_GUID *Guid + ); + +// OcStrToAscii +/** Convert null terminated unicode string to ascii. + + @param[in] String1 A pointer to the unicode string to convert to ascii. + @param[out] String2 A pointer to the converted ascii string. + + @retval A pointer to the converted ascii string. +**/ +CHAR8 * +OcStrToAscii ( + IN CHAR16 *String1, + IN CHAR8 *String2 + ); + +// StrCmpiAscii +/** Compare unicode string with ascii string ignoring case + + @param[in] String1 A pointer to a unicode string to compare. + @param[in] String2 A pointer to a ascii string to compare. + + @retval A pointer to the converted ascii string. +**/ +UINTN +StrCmpiAscii ( + IN CHAR16 *String1, + IN CHAR8 *String2 + ); + +// StrCmpiBasic +/** Compare unicode strings ignoring case + + @param[in] String1 A pointer to a unicode string to compare. + @param[in] String2 A pointer to a unicode string to compare. + + @retval A pointer to the converted ascii string. +**/ +UINTN +StrCmpiBasic ( + IN CHAR16 *String1, + IN CHAR16 *String2 + ); + +// UnicodeBaseName +/** Return the filename element of a pathname + + @param[in] FullPath A pointer to a unicode path + + @retval A pointer to the converted ascii string. +**/ +CHAR16 * +UnicodeBaseName ( + IN CHAR16 *FullPath + ); + +// UnicodeDirName +/** Return the folder element of a pathname + + @param[in] FullPath A pointer to a unicode path + + @retval A pointer to the converted ascii string. +**/ +CHAR16 * +UnicodeDirName ( + IN CHAR16 *FullPath + ); + +// UnicodeParseString +/** + + @param[in] String A pointer to a unicode string + @param[in] Variable A pointer to a unicode string variable name to parse for + + @retval A pointer to the variable value +**/ +CHAR16 * +UnicodeParseString ( + IN CHAR16 *String, + IN CHAR16 *Variable + ); + +// TrimWhiteSpace +/** Remove leading and trailing spaces in the string + + @param[in] Start A pointer to the unicode string + + @retval A pointer to the converted unicode string. +**/ +CHAR16 * +TrimWhiteSpace ( + IN CHAR16 *String + ); + +#endif // OC_STRING_LIB_H_ diff --git a/Include/Library/OcTimerLib.h b/Include/Library/OcTimerLib.h new file mode 100755 index 00000000..7be5bb8f --- /dev/null +++ b/Include/Library/OcTimerLib.h @@ -0,0 +1,30 @@ +/** @file + Copyright (C) 2016, The HermitCrabs Lab. All rights reserved. + + All rights reserved. + + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + 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 OC_TIMER_LIB_H_ +#define OC_TIMER_LIB_H_ + +// CalculateTSC +/** Calculate the TSC frequency + + @param[in] Recalculate Switch to enable using cached value if already calculated. + + @retval The calculated TSC frequency. +**/ +UINT64 +CalculateTSC ( + IN BOOLEAN Recalculate + ); + +#endif // OC_TIMER_LIB_H_ diff --git a/Include/Library/OcVariableLib.h b/Include/Library/OcVariableLib.h new file mode 100755 index 00000000..3ff7ea17 --- /dev/null +++ b/Include/Library/OcVariableLib.h @@ -0,0 +1,96 @@ +/** @file + Copyright (C) 2016 - 2017, The HermitCrabs Lab. All rights reserved. + + All rights reserved. + + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + 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 OC_VARIABLE_LIB_H_ +#define OC_VARIABLE_LIB_H_ + +// CheckVariableBoolean +/** Check the boolean-value of an EFI Variable. + + @param[in] Name The firmware allocated handle for the EFI image. + @param[in] VendorGuid A unique identifier for the vendor. + + @retval Boolean value indicating TRUE, if variable exists. +**/ +BOOLEAN +CheckVariableBoolean ( + IN CHAR16 *Name, + IN EFI_GUID *VendorGuid + ); + +// DeleteVariables +/** Deletes all EFI Variables matching the pattern. + + @param[in] VendorGuid A unique identifier for the vendor. + @param[in] SearchName A Null-terminated Unicode string that is the name of the vendor’s variable. Each SearchName is + unique for each VendorGuid. + SearchName must contain 1 or more Unicode characters. If SearchName is an empty Unicode + string, then EFI_INVALID_PARAMETER is returned. + + @retval EFI_SUCCESS The variable was deleted successfully. +**/ +EFI_STATUS +DeleteVariables ( + IN EFI_GUID *VendorGuid, + IN CHAR16 *SearchName + ); + +// OcGetVariable +/** Return the variables value in buffer. + + @param[in] Name A Null-terminated Ascii string that is the name of the vendor’s variable. Each Name is + unique for each VendorGuid. + Name must contain 1 or more Ascii characters. If Name is an empty Ascii string, then + EFI_INVALID_PARAMETER is returned. + @param[in] VendorGuid A unique identifier for the vendor. + @param[in,out] BufferPtr Pointer to store the buffer. + @param[in,out] BufferSize Size of the variables data buffer. + + @retval A pointer to the variables data +**/ +EFI_STATUS +OcGetVariable ( + IN CHAR8 *Name, + IN EFI_GUID *VendorGuid, + IN OUT VOID **BufferPtr, + IN OUT UINTN *BufferSize + ); + +// SetVariable +/** Sets an EFI Variable. + + @param[in] Name A Null-terminated Ascii string that is the name of the vendor’s variable. Each Name is + unique for each VendorGuid. + Name must contain 1 or more Ascii characters. If Name is an empty Ascii string, then + EFI_INVALID_PARAMETER is returned. + @param[in] VendorGuid A unique identifier for the vendor. + @param[in] Attributes Attributes bitmask to set for the variable. Refer to the GetVariable() function + description. + @param[in] DataSize The size in bytes of the Data buffer. A size of zero causes the variable to be deleted. + @param[in] Data The contents for the variable. + @param[in] OverideDefault A boolean flag which enables updating a previously set value. + + @retval EFI_SUCCESS The variable was set successfully. +**/ +EFI_STATUS +SetVariable ( + IN CHAR8 *Name, + IN EFI_GUID *VendorGuid, + IN UINT32 Attributes, + IN UINTN DataSize, + IN VOID *Data, + IN BOOLEAN OverideDefault + ); + +#endif // OC_VARIABLE_LIB_H_ diff --git a/Include/Macros.h b/Include/Macros.h new file mode 100755 index 00000000..f496bd39 --- /dev/null +++ b/Include/Macros.h @@ -0,0 +1,99 @@ +/** @file + Copyright (C) 2016, The HermitCrabs Lab. All rights reserved. + + All rights reserved. + + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + 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 OPEN_CORE_MACROS_H_ +#define OPEN_CORE_MACROS_H_ + +#ifndef FUNCTION_NAME + #ifdef _MSC_VER + #define FUNCTION_NAME __FUNCTION__ + #else + #define FUNCTION_NAME __func__ + #endif +#endif + +#define DEBUG_CONSOLE 0x40000000 + +#define EFI_FIELD_OFFSET(TYPE,Field) ((UINTN)(&(((TYPE *) 0)->Field))) + +// FIXME: Find EFI original decls + +#define EFI_MAX_PATH_LENGTH 0x200 +#define EFI_MAX_PATH_SIZE (EFI_MAX_PATH_LENGTH * sizeof (CHAR16)) + +#define EFI_GUID_STRING_LENGTH 36 + +#define KILO (1000ULL) +#define MEGA (KILO * KILO) +#define GIGA (KILO * MEGA) +#define TERA (KILO * GIGA) +#define PETA (KILO * TERA) + +// PTR_OFFSET +/// Adds Offset bytes to SourcePtr and returns new pointer as ReturnType. +#define PTR_OFFSET(SourcePtr, Offset, ReturnType) ((ReturnType)(((UINT8 *)(UINTN)SourcePtr) + Offset)) + +#define CALC_EFI_PCI_ADDRESS(Bus, Device, Function, Register) \ + ((UINT64) ((((UINTN) Bus) << 24) + (((UINTN) Device) << 16) + (((UINTN) Function) << 8) + ((UINTN) Register))) + +#define ROUND_WORD(x) ALIGN_VALUE ((UINTN)(x), sizeof (UINT16)) +#define ROUND_LONG(x) ALIGN_VALUE ((UINTN)(x), sizeof (UINT32)) +#define ROUND_PAGE(x) ALIGN_VALUE ((UINTN)(x), EFI_PAGE_SIZE) + +#define QUAD(hi, lo) (((UINT64)(hi)) << 32 | (lo)) +#define BIT(n) (1ULL << (n)) +#define BITMASK(h, l) ((BIT (h) | (BIT (h) - 1)) & ~(BIT (l) - 1)) +#define BITFIELD(x,h,l) (((x) & BITMASK(h, l)) >> l) + +#ifndef ARRAY_SIZE +#define ARRAY_SIZE(a) (sizeof (a) / sizeof (*(a))) +#endif + +#define IS_DIGIT(a) (((a) >= '0') && ((a) <= '9')) +#define IS_HEX(a) (((a) >= 'a') && ((a) <= 'f')) +#define IS_UPPER(a) (((a) >= 'A') && ((a) <= 'Z')) +#define IS_ALPHA(x) ((((x) >= 'a') && ((x) <='z')) || (((x) >= 'A') && ((x) <= 'Z'))) +#define IS_ASCII(x) (((x) >= 0x20) && ((x) <= 0x7F)) +#define IS_PUNCT(x) (((x) == '.') || ((x) == '-')) + +#define SWAP16(V) ((((UINT16)((V) & 0x00FF)) << 8) \ + | (((UINT16)((V) & 0xFF00)) >> 8)) + +#define SWAP32(V) ((((UINT32)(V) & 0x000000FF) << 24) \ + | (((UINT32)(V) & 0x0000FF00) << 8) \ + | (((UINT32)(V) & 0x00FF0000) >> 8) \ + | (((UINT32)(V) & 0xFF000000) >> 24)) + +#define SWAP64(V) (((((UINT64)(V)) << 56) & 0xFF00000000000000ULL) \ + | ((((UINT64)(V)) << 40) & 0x00FF000000000000ULL) \ + | ((((UINT64)(V)) << 24) & 0x0000FF0000000000ULL) \ + | ((((UINT64)(V)) << 8) & 0x000000FF00000000ULL) \ + | ((((UINT64)(V)) >> 8) & 0x00000000FF000000ULL) \ + | ((((UINT64)(V)) >> 24) & 0x0000000000FF0000ULL) \ + | ((((UINT64)(V)) >> 40) & 0x000000000000FF00ULL) \ + | ((((UINT64)(V)) >> 56) & 0x00000000000000FFULL)) + +#define DEEP_DEBUG +#ifndef DEEP_DEBUG + #define DEBUG_FUNCTION_ENTRY(ErrorLevel) + #define DEBUG_FUNCTION_RETURN(ErrorLevel) +#else + #define DEBUG_FUNCTION_ENTRY(ErrorLevel) \ + DEBUG (((ErrorLevel), "%a: Started\n", FUNCTION_NAME)) + #define DEBUG_FUNCTION_RETURN(ErrorLevel) \ + DEBUG (((ErrorLevel), "%a: Finished\n", FUNCTION_NAME)) +#endif + +#endif // OPEN_CORE_MACROS_H_ diff --git a/Include/Protocol/OcLog.h b/Include/Protocol/OcLog.h new file mode 100755 index 00000000..547f416d --- /dev/null +++ b/Include/Protocol/OcLog.h @@ -0,0 +1,120 @@ +/** @file + Copyright (C) 2016, The HermitCrabs Lab. All rights reserved. + + All rights reserved. + + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + 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 OC_LOG_PROTOCOL_H_ +#define OC_LOG_PROTOCOL_H_ + +// The defines for the log flags. + +#define OC_LOG_DISABLE 0 +#define OC_LOG_ENABLE BIT0 +#define OC_LOG_CONSOLE BIT1 +#define OC_LOG_SERIAL BIT2 +#define OC_LOG_VARIABLE BIT3 +#define OC_LOG_FILE BIT4 +#define OC_LOG_NONVOLATILE BIT5 + +typedef UINTN OC_LOG_OPTIONS; + +// OC_LOG_PROTOCOL_GUID +/// The GUID of the OC_LOG_PROTOCOL. +#define OC_LOG_PROTOCOL_GUID \ + { \ + 0xDBB6008F, 0x89E4, 0x4272, { 0x98, 0x81, 0xCE, 0x3A, 0xFD, 0x97, 0x24, 0xD0 } \ + } + +// OC_LOG_PROTOCOL +/// The forward declaration for the protocol for the OC_LOG_PROTOCOL. +typedef struct OC_LOG_PROTOCOL OC_LOG_PROTOCOL; + +// OcLogAddEntry +/** Add an entry to the log buffer + + @param[in] This This protocol. + @param[in] ErrorLevel Debug level. + @param[in] FormatString String containing the output format. + @param[in] Marker Address of the VA_ARGS marker. + + @retval EFI_SUCCESS The timers were reset successfully. +**/ +typedef +EFI_STATUS +(EFIAPI *OC_LOG_ADD_ENTRY) ( + IN OC_LOG_PROTOCOL *This, + IN UINTN ErrorLevel, + IN CONST CHAR8 *FormatString, + IN VA_LIST Marker + ); + +// OcLogResetTimers +/** Reset the internal timers + + @param[in] This This protocol. + + @retval EFI_SUCCESS The timers were reset successfully. +**/ +typedef +EFI_STATUS +(EFIAPI *OC_LOG_RESET_TIMERS) ( + IN OC_LOG_PROTOCOL *This + ); + +// OcLogGetLog +/** Retrieve pointer to the log buffer + + @param[in] This This protocol. + @param[in] OcLogBuffer Address to store the buffer pointer. + + @retval EFI_SUCCESS The timers were reset successfully. +**/ +typedef +EFI_STATUS +(EFIAPI *OC_LOG_GET_LOG) ( + IN OC_LOG_PROTOCOL *This, + OUT CHAR16 **OcLogBuffer + ); + +// OcLogSaveLog +/** Save the current log + + @param[in] This This protocol. + @param[in] NonVolatile Variable. + @param[in] FilePath Filepath to save the log. OPTIONAL + + @retval EFI_SUCCESS The log was saved successfully. +**/ +typedef +EFI_STATUS +(EFIAPI *OC_LOG_SAVE_LOG) ( + IN OC_LOG_PROTOCOL *This, + IN UINT32 NonVolatile OPTIONAL, + IN EFI_DEVICE_PATH_PROTOCOL *FilePath OPTIONAL + ); + +// _OC_LOG_PROTOCOL +/// The structure exposed by the OC_LOG_PROTOCOL. +struct OC_LOG_PROTOCOL { + UINT32 Revision; ///< The revision of the installed protocol. + OC_LOG_OPTIONS Options; ///< The current options of the installed protocol. + OC_LOG_ADD_ENTRY AddEntry; ///< A pointer to the AddEntry function. + OC_LOG_GET_LOG GetLog; ///< A pointer to the GetLog function. + OC_LOG_SAVE_LOG SaveLog; ///< A pointer to the SaveLog function. + OC_LOG_RESET_TIMERS ResetTimers; ///< A pointer to the ResetTimers function. +}; + +// gOcLogProtocolGuid +/// A global variable storing the GUID of the OC_LOG_PROTOCOL. +extern EFI_GUID gOcLogProtocolGuid; + +#endif // OC_LOG_PROTOCOL_H_ diff --git a/Library/OcAcpiLib/AcpiFindLegacyRsdPtr.c b/Library/OcAcpiLib/AcpiFindLegacyRsdPtr.c new file mode 100755 index 00000000..e163fc74 --- /dev/null +++ b/Library/OcAcpiLib/AcpiFindLegacyRsdPtr.c @@ -0,0 +1,71 @@ +/** @file + Copyright (C) 2016, The HermitCrabs Lab. All rights reserved. + + All rights reserved. + + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +**/ +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include + +#include + +#include + +// AcpiFindLegacyRsdPtr +/** Find RSD_PTR Table In Legacy Area + + @retval EFI_ACPI_6_0_ROOT_SYSTEM_DESCRIPTION_POINTER +**/ +EFI_ACPI_6_0_ROOT_SYSTEM_DESCRIPTION_POINTER * +AcpiFindLegacyRsdPtr ( + VOID + ) +{ + EFI_ACPI_6_0_ROOT_SYSTEM_DESCRIPTION_POINTER *RsdPtr; + + UINTN Address; + UINTN Index; + + // First Search 0x0E0000 - 0x0FFFFF for RSD_PTR + + RsdPtr = NULL; + + for (Address = 0x0E0000; Address < 0x0FFFFF; Address += 16) { + if (*(UINT64 *)Address == EFI_ACPI_6_0_ROOT_SYSTEM_DESCRIPTION_POINTER_SIGNATURE) { + RsdPtr = (EFI_ACPI_6_0_ROOT_SYSTEM_DESCRIPTION_POINTER *)Address; + } + } + + // Then Search EBDA 0x40E - 0x800 + + if (RsdPtr == NULL) { + Address = ((*(UINT16 *)(UINTN)0x040E) << 4); + + for (Index = 0; Index < 0x0400; Index += 16) { + if (*(UINT64 *)(Address + Index) == EFI_ACPI_6_0_ROOT_SYSTEM_DESCRIPTION_POINTER_SIGNATURE) { + RsdPtr = (EFI_ACPI_6_0_ROOT_SYSTEM_DESCRIPTION_POINTER *)Address; + } + } + } + + return RsdPtr; +} diff --git a/Library/OcAcpiLib/AcpiFindRsdPtr.c b/Library/OcAcpiLib/AcpiFindRsdPtr.c new file mode 100755 index 00000000..976e1708 --- /dev/null +++ b/Library/OcAcpiLib/AcpiFindRsdPtr.c @@ -0,0 +1,62 @@ +/** @file + Copyright (C) 2016, The HermitCrabs Lab. All rights reserved. + + All rights reserved. + + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +**/ +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include + +#include + +#include + +// AcpiFindRsdPtr +/** Find RSD_PTR Table From System Configuration Tables + + @retval EFI_ACPI_6_0_ROOT_SYSTEM_DESCRIPTION_POINTER +**/ +EFI_ACPI_6_0_ROOT_SYSTEM_DESCRIPTION_POINTER * +AcpiFindRsdPtr ( + VOID + ) +{ + EFI_ACPI_6_0_ROOT_SYSTEM_DESCRIPTION_POINTER *RsdPtr; + + UINTN Index; + + RsdPtr = NULL; + + // Find ACPI table RSD_PTR from system table + + for (Index = 0; Index < gST->NumberOfTableEntries; ++Index) { + if (CompareGuid (&(gST->ConfigurationTable[Index].VendorGuid), &gEfiAcpi20TableGuid) + || CompareGuid (&(gST->ConfigurationTable[Index].VendorGuid), &gEfiAcpi10TableGuid) + || CompareGuid (&(gST->ConfigurationTable[Index].VendorGuid), &gEfiAcpiTableGuid)) { + RsdPtr = gST->ConfigurationTable[Index].VendorTable; + + break; + } + } + + return RsdPtr; +} diff --git a/Library/OcAcpiLib/AcpiLocateTable.c b/Library/OcAcpiLib/AcpiLocateTable.c new file mode 100755 index 00000000..d63f3955 --- /dev/null +++ b/Library/OcAcpiLib/AcpiLocateTable.c @@ -0,0 +1,88 @@ +/** @file + Copyright (C) 2016, The HermitCrabs Lab. All rights reserved. + + All rights reserved. + + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +**/ +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include + +#include + +#include + +// AcpiLocateTable +/** + + @param[in] Signature + @param[in, out] Table + @param[in, out] Handle + @param[in, out] Version + + @retval EFI_SUCCESS + @retval EFI_NOT_FOUND + @retval EFI_INVALID_PARAMETER +**/ +EFI_STATUS +AcpiLocateTable ( + IN UINT32 Signature, + IN OUT EFI_ACPI_DESCRIPTION_HEADER **Table, + IN OUT UINTN *Handle, + IN OUT EFI_ACPI_TABLE_VERSION *Version + ) +{ + EFI_ACPI_SUPPORT_PROTOCOL *AcpiSupport; + + EFI_STATUS Status; + INTN Index; + + AcpiSupport = NULL; + Status = gBS->LocateProtocol ( + &gEfiAcpiSupportProtocolGuid, + NULL, + (VOID **)&AcpiSupport + ); + + if (!EFI_ERROR (Status)) { + Index = 0; + + // Iterate The Tables To Find Matching Table + + do { + Status = AcpiSupport->GetAcpiTable ( + AcpiSupport, + Index, + (VOID **)Table, + Version, + Handle + ); + + if (Status == EFI_NOT_FOUND) { + break; + } + + ++Index; + } while ((*Table)->Signature != Signature); + } + + return Status; +} diff --git a/Library/OcAcpiLib/OcAcpiLib.inf b/Library/OcAcpiLib/OcAcpiLib.inf new file mode 100755 index 00000000..cccb66ca --- /dev/null +++ b/Library/OcAcpiLib/OcAcpiLib.inf @@ -0,0 +1,42 @@ +## @file +# +# Component description file for Oc Variable Library. +# +# Copyright (C) 2016, The HermitCrabs Lab. All rights reserved.
+# +# All rights reserved. +# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# +# 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 = OcAcpiLib + FILE_GUID = 74A1EF2F-1374-4645-AFF4-3C3AD3697870 + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = OcVariableLib|PEIM DXE_DRIVER DXE_RUNTIME_DRIVER UEFI_DRIVER UEFI_APPLICATION DXE_SMM_DRIVER + +# VALID_ARCHITECTURES = IA32 X64 + +[Packages] + OcSupportPkg/OcSupportPkg.dec + IntelFrameworkPkg/IntelFrameworkPkg.dec + IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + +[LibraryClasses] + BaseLib + +[Sources] + AcpiLocateTable.c + AcpiFindLegacyRsdPtr.c + AcpiFindRsdPtr.c \ No newline at end of file diff --git a/Library/OcCpuLib/OcCpuLib.c b/Library/OcCpuLib/OcCpuLib.c new file mode 100755 index 00000000..74f4c889 --- /dev/null +++ b/Library/OcCpuLib/OcCpuLib.c @@ -0,0 +1,270 @@ +/** @file + Copyright (C) 2016 - 2017, The HermitCrabs Lab. All rights reserved. + + All rights reserved. + + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +**/ + +#include + +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "ProcessorInfo.h" + +// OcCpuScanProcessor +/** Scan the processor and fill the cpu info structure with results + + @param[in] Cpu A pointer to the cpu info structure to fill with results + + @retval EFI_SUCCESS The scan was completed successfully. +**/ +EFI_STATUS +OcCpuScanProcessor ( + IN CPU_INFO *Cpu + ) +{ + EFI_STATUS Status; + + UINT32 CpuidEax; + UINT32 CpuidEbx; + UINT32 CpuidEcx; + UINT32 CpuidEdx; + UINT64 Msr = 0; + + DEBUG_FUNCTION_ENTRY (DEBUG_VERBOSE); + + Status = EFI_INVALID_PARAMETER; + + if (Cpu != NULL) { + + // Get vendor CPUID 0x00000000 + AsmCpuid (CPUID_SIGNATURE, &CpuidEax, (UINT32 *)Cpu->Vendor, (UINT32 *)(Cpu->Vendor + 8), (UINT32 *)(Cpu->Vendor + 4)); + + // Get extended CPUID 0x80000000 + AsmCpuid (CPUID_EXTENDED_FUNCTION, &CpuidEax, &CpuidEbx, &CpuidEcx, &CpuidEdx); + + Cpu->MaxExtId = CpuidEax; + + // Get brand string CPUID 0x80000002 - 0x80000004 + if (Cpu->MaxExtId >= CPUID_BRAND_STRING3) { + + // The brandstring 48 bytes max, guaranteed NULL terminated. + UINT32 *BrandString = (UINT32 *)Cpu->BrandString; + + AsmCpuid ( + CPUID_BRAND_STRING1, + BrandString, + (BrandString + 1), + (BrandString + 2), + (BrandString + 3) + ); + + AsmCpuid ( + CPUID_BRAND_STRING2, + (BrandString + 4), + (BrandString + 5), + (BrandString + 6), + (BrandString + 7) + ); + + AsmCpuid ( + CPUID_BRAND_STRING3, + (BrandString + 8), + (BrandString + 9), + (BrandString + 10), + (BrandString + 11) + ); + } + + // Get processor signature and decode + if (Cpu->MaxExtId >= CPUID_VERSION_INFO) { + + AsmCpuid (CPUID_VERSION_INFO, &CpuidEax, &CpuidEbx, &CpuidEcx, &CpuidEdx); + + Cpu->Signature = CpuidEax; + Cpu->Stepping = (UINT8)BITFIELD (CpuidEax, 3, 0); + Cpu->ExtModel = (UINT8)BITFIELD (CpuidEax, 19, 16); + Cpu->Model = ((UINT8)BITFIELD (CpuidEax, 7, 4) + (Cpu->ExtModel << 4)); + Cpu->Family = (UINT8)BITFIELD (CpuidEax, 11, 8); + Cpu->Type = (UINT8)BITFIELD (CpuidEax, 13, 12); + Cpu->ExtFamily = (UINT8)BITFIELD (CpuidEax, 27, 20); + Cpu->Brand = (UINT8)BITFIELD (CpuidEbx, 7, 0); + Cpu->Features = QUAD (CpuidEcx, CpuidEdx); + + } + + LOG ((EFI_D_INFO, "%a %a\n", "Found", Cpu->BrandString)); + + DEBUG (( + DEBUG_INFO, + "Signature %0X Stepping %0X Model %0X Family %0X Type %0X ExtModel %0X ExtFamily %0X\n", + Cpu->Signature, + Cpu->Stepping, + Cpu->Model, + Cpu->Family, + Cpu->Type, + Cpu->ExtModel, + Cpu->ExtFamily + )); + + if (*(UINT32 *)Cpu->Vendor == CPUID_VENDOR_INTEL) { + + Msr = AsmReadMsr64 (MSR_PKG_CST_CONFIG_CONTROL); + + if ((Cpu->Family == 0x06 && Cpu->Model >= 0x0c) || + (Cpu->Family == 0x0f && Cpu->Model >= 0x03)) + { + + Msr = AsmReadMsr64 (MSR_IA32_PERF_STATUS); + + if (Cpu->Model >= CPU_MODEL_NEHALEM) { + + Cpu->CurBusRatio = (UINT8)BITFIELD(Msr, 15, 8); + + Msr = AsmReadMsr64 (MSR_PLATFORM_INFO); + + Cpu->MinBusRatio = (UINT8)(RShiftU64 (Msr, 40) & 0xFF); + Cpu->MaxBusRatio = (UINT8)(RShiftU64 (Msr, 8) & 0xFF); + + } else { + + Cpu->MaxBusRatio = (UINT8)(Msr >> 8) & 0x1f; + + // Non-integer bus ratio for the max-multi + Cpu->MaxBusRatioDiv = (UINT8)(Msr >> 46) & 0x01; + + // Non-integer bus ratio for the current-multi (undocumented) + //CurrDiv = (UINT8)(Msr >> 14) & 0x01; + + } + + if ((Cpu->Model != CPU_MODEL_NEHALEM_EX) && + (Cpu->Model != CPU_MODEL_WESTMERE_EX)) + { + Msr = AsmReadMsr64 (MSR_TURBO_RATIO_LIMIT); + Cpu->TurboBusRatio1 = (UINT8)(RShiftU64 (Msr, MAX_RATIO_LIMIT_1C_OFFSET) & MAX_RATIO_LIMIT_MASK); + Cpu->TurboBusRatio2 = (UINT8)(RShiftU64 (Msr, MAX_RATIO_LIMIT_2C_OFFSET) & MAX_RATIO_LIMIT_MASK); + Cpu->TurboBusRatio3 = (UINT8)(RShiftU64 (Msr, MAX_RATIO_LIMIT_3C_OFFSET) & MAX_RATIO_LIMIT_MASK); + Cpu->TurboBusRatio4 = (UINT8)(RShiftU64 (Msr, MAX_RATIO_LIMIT_4C_OFFSET) & MAX_RATIO_LIMIT_MASK); + } + + DEBUG (( + DEBUG_INFO, + "Ratio Min %d Max %d Current %d Turbo %d %d %d %d\n", + Cpu->MinBusRatio, + Cpu->MaxBusRatio, + Cpu->CurBusRatio, + Cpu->TurboBusRatio1, + Cpu->TurboBusRatio2, + Cpu->TurboBusRatio3, + Cpu->TurboBusRatio4 + )); + + // SkyLake and later have an Always Running Timer + if (Cpu->Model >= CPU_MODEL_SKYLAKE) { + + AsmCpuid (0x15, &CpuidEax, &CpuidEbx, &CpuidEcx, &CpuidEdx); + + if (CpuidEbx && CpuidEbx) { + + Cpu->CPUFrequency = MultU64x32 (BASE_ART_CLOCK_SOURCE, (UINT32)DivU64x32 (CpuidEbx, CpuidEax)); + + LOG (( + EFI_D_INFO, + "%a %a %11lld %5dMHz %d * %d / %d = %ld\n", + "ART", + "Frequency", + Cpu->CPUFrequency, + DivU64x32 (Cpu->CPUFrequency, 1000000), + BASE_ART_CLOCK_SOURCE, + CpuidEbx, + CpuidEax, + Cpu->CPUFrequency + )); + + Cpu->FSBFrequency = DivU64x32 (Cpu->CPUFrequency, Cpu->MaxBusRatio); + + } + } + + // Calculate the Tsc frequency + Cpu->TSCFrequency = CalculateTSC (FALSE); + + if (Cpu->CPUFrequency == 0) { + + LOG (( + EFI_D_INFO, + "%a %a %11lld %5dMHz\n", + "TSC", + "Frequency", + Cpu->TSCFrequency, + DivU64x32 (Cpu->TSCFrequency, 1000000) + )); + + // Both checked to workaround virtual cpu + if ((Cpu->MinBusRatio > 0) && + (Cpu->MaxBusRatio > Cpu->MinBusRatio)) + { + Cpu->FSBFrequency = DivU64x32 (Cpu->TSCFrequency, Cpu->MaxBusRatio); + Cpu->CPUFrequency = MultU64x32 (Cpu->FSBFrequency, Cpu->MaxBusRatio); + + } else { + + Cpu->CPUFrequency = Cpu->TSCFrequency; + Cpu->FSBFrequency = 100000000; + } + } + + LOG (( + EFI_D_INFO, + "%a %a %11lld %5dMHz\n", + "CPU", + "Frequency", + Cpu->CPUFrequency, + DivU64x32 (Cpu->CPUFrequency, 1000000) + )); + + LOG (( + EFI_D_INFO, + "%a %a %11lld %5dMHz\n", + "FSB", + "Frequency", + Cpu->FSBFrequency, + DivU64x32 (Cpu->FSBFrequency, 1000000) + )); + + } + } + + Status = EFI_SUCCESS; + } + + DEBUG_FUNCTION_RETURN (DEBUG_VERBOSE); + + return Status; +} diff --git a/Library/OcCpuLib/OcCpuLib.inf b/Library/OcCpuLib/OcCpuLib.inf new file mode 100755 index 00000000..81158363 --- /dev/null +++ b/Library/OcCpuLib/OcCpuLib.inf @@ -0,0 +1,40 @@ +## @file +# +# Component description file for OcCpulibrary. +# +# Copyright (C) 2016, The HermitCrabs Lab. All rights reserved.
+# +# All rights reserved. +# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# +# 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 = OcCpuLib + FILE_GUID = 5F3FA330-4F32-4AC9-9407-B932CFECFDB2 + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = OcCpuLib|PEIM DXE_DRIVER DXE_RUNTIME_DRIVER UEFI_DRIVER UEFI_APPLICATION DXE_SMM_DRIVER + +# VALID_ARCHITECTURES = IA32 X64 + +[Packages] + OcSupportPkg/OcSupportPkg.dec + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + UefiCpuPkg/UefiCpuPkg.dec + +[LibraryClasses] + BaseLib + IoLib + +[Sources] + OcCpuLib.c diff --git a/Library/OcCpuLib/ProcessorInfo.h b/Library/OcCpuLib/ProcessorInfo.h new file mode 100755 index 00000000..deda53e4 --- /dev/null +++ b/Library/OcCpuLib/ProcessorInfo.h @@ -0,0 +1,207 @@ +/** @file + Copyright (C) 2016 - 2018, The HermitCrabs Lab. All rights reserved. + + All rights reserved. + + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + 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 OC_PROCESSOR_INFO_H_ +#define OC_PROCESSOR_INFO_H_ + +#define CPUID_VENDOR_INTEL 0x756E6547 +#define CPUID_VENDOR_AMD 0x68747541 + +// SandyBridge/IvyBridge bus clock is fixed at 100MHz + +#define BRIDGE_BCLK 100 + +#define BASE_NHM_CLOCK_SOURCE 133333333ULL + +// Skylake bus clock is fixed at 100MHz + +#define BASE_ART_CLOCK_SOURCE 24000000ULL + +#define MSR_IA32_PLATFORM_ID 0x17 +#define MSR_PIC_MSG_CONTROL 0x2E +#define MSR_CORE_THREAD_COUNT 0x35 +#define MSR_IA32_FEATURE_CONTROL 0x3A +#define MSR_IA32_TSC_ADJUST 0x3B +#define MSR_IA32_BIOS_SIGN_ID 0x8B ///< microcode version +#define MSR_PLATFORM_INFO 0xCE + +#define EFI_PLATFORM_INFORMATION 0x000000CE +#define N_EFI_PLATFORM_INFO_MIN_RATIO 40 +#define B_EFI_PLATFORM_INFO_RATIO_MASK 0xFF +#define N_EFI_PLATFORM_INFO_MAX_RATIO 8 +#define B_EFI_PLATFORM_INFO_TDC_TDP_LIMIT (1 << 29) +#define N_EFI_PLATFORM_INFO_RATIO_LIMIT 28 +#define B_EFI_PLATFORM_INFO_RATIO_LIMIT (1 << 28) +#define B_EFI_PLATFORM_INFO_SMM_SAVE_CONTROL (1 << 16) +#define N_EFI_PLATFORM_INFO_PROG_TCC_ACTIVATION_OFFSET 30 +#define B_EFI_PLATFORM_INFO_PROG_TCC_ACTIVATION_OFFSET (1 << 30) + +//#define PLATFORM_INFO_SET_TDP + +#define MSR_PKG_CST_CONFIG_CONTROL 0xE2 +#define MSR_PMG_IO_CAPTURE_BASE 0xE4 +#define MSR_IA32_EXT_CONFIG 0xEE +#define MSR_FEATURE_CONFIG 0x13C +#define MSR_FLEX_RATIO 0x194 +#define MSR_IA32_PERF_STATUS 0x198 +#define MSR_IA32_PERF_CONTROL 0x199 +#define MSR_IA32_CLOCK_MODULATION 0x19A +#define MSR_IA32_THERM_INTERRUPT 0x19B +#define MSR_IA32_THERM_STATUS 0x19C +#define MSR_THERM2_CTL 0x19D + +#define MSR_IA32_MISC_ENABLES 0x1A0 +#define TURBO_DISABLE_MASK ((UINT64)1 << 38) +#define TURBO_MODE_DISABLE_BIT 38 + +#define MSR_TEMPERATURE_TARGET 0x1A2 +#define MSR_MISC_PWR_MGMT 0x1AA +#define MISC_PWR_MGMT_EIST_HW_DIS (1 << 0) +#define MSR_TURBO_RATIO_LIMIT 0x1AD +#define MAX_RATIO_LIMIT_8C_OFFSET 56 +#define MAX_RATIO_LIMIT_7C_OFFSET 48 +#define MAX_RATIO_LIMIT_6C_OFFSET 40 +#define MAX_RATIO_LIMIT_5C_OFFSET 32 +#define MAX_RATIO_LIMIT_4C_OFFSET 24 +#define MAX_RATIO_LIMIT_3C_OFFSET 16 +#define MAX_RATIO_LIMIT_2C_OFFSET 8 +#define MAX_RATIO_LIMIT_1C_OFFSET 0 +#define MAX_RATIO_LIMIT_MASK 0xff +#define MSR_IA32_ENERGY_PERFORMANCE_BIAS 0x1B0 +#define ENERGY_POLICY_PERFORMANCE 0 +#define ENERGY_POLICY_NORMAL 6 +#define ENERGY_POLICY_POWERSAVE 15 +#define MSR_IA32_PACKAGE_THERM_INTERRUPT 0x1B2 +#define MSR_POWER_CTL 0x1FC +#define MSR_IA32_PLATFORM_DCA_CAP 0x1F8 +#define MSR_LT_LOCK_MEMORY 0x2E7 +#define MSR_IA32_MC0_STATUS 0x401 +#define MSR_IA32_CR_PAT 0x277 + +// Sandy Bridge & JakeTown specific 'Running Average Power Limit' MSR's. +#define MSR_PP0_CURRENT_CONFIG 0x601 +#define PP0_CURRENT_LIMIT (112 << 3) ///< 112 A +#define MSR_PP1_CURRENT_CONFIG 0x602 +#define PP1_CURRENT_LIMIT (35 << 3) ///< 35 A +#define MSR_PKG_POWER_SKU_UNIT 0x606 + +#define MSR_PKGC3_IRTL 0x60A +#define MSR_PKGC6_IRTL 0x60B +#define MSR_PKGC7_IRTL 0x60C +#define IRTL_VALID (1 << 15) +#define IRTL_1_NS (0 << 10) +#define IRTL_32_NS (1 << 10) +#define IRTL_1024_NS (2 << 10) +#define IRTL_32768_NS (3 << 10) +#define IRTL_1048576_NS (4 << 10) +#define IRTL_33554432_NS (5 << 10) +#define IRTL_RESPONSE_MASK (0x3ff) + +// long duration in low dword, short duration in high dword +#define MSR_PKG_POWER_LIMIT 0x610 +#define PKG_POWER_LIMIT_MASK 0x7fff +#define PKG_POWER_LIMIT_EN (1 << 15) +#define PKG_POWER_LIMIT_CLAMP (1 << 16) +#define PKG_POWER_LIMIT_TIME_SHIFT 17 +#define PKG_POWER_LIMIT_TIME_MASK 0x7f + +#define MSR_PKG_ENERGY_STATUS 0x611 +#define MSR_PKG_PERF_STATUS 0x613 +#define MSR_PKG_POWER_SKU 0x614 + +// Sandy Bridge IA (Core) domain MSR's. +#define MSR_PP0_POWER_LIMIT 0x638 +#define MSR_PP0_ENERGY_STATUS 0x639 +#define MSR_PP0_POLICY 0x63A +#define MSR_PP0_PERF_STATUS 0x63B + +// Sandy Bridge Uncore (IGPU) domain MSR's (Not on JakeTown). +#define MSR_PP1_POWER_LIMIT 0x640 +#define MSR_PP1_ENERGY_STATUS 0x641 +#define MSR_PP1_POLICY 0x642 + +// JakeTown only Memory MSR's. +#define MSR_DRAM_POWER_LIMIT 0x618 +#define MSR_DRAM_ENERGY_STATUS 0x619 +#define MSR_DRAM_PERF_STATUS 0x61B +#define MSR_DRAM_POWER_INFO 0x61C + +/// x86 Page Address Translation +enum { + PageAddressTranslationUncached = 0, + PageAddressTranslationWriteCombining = 1, + PageAddressTranslationWriteThrough = 4, + PageAddressTranslationWriteProtected = 5, + PageAddressTranslationWriteBack = 6, + /// Uncached, but can be overriden by MTRR + PageAddressTranslationOverridableUncached = 7, +}; + +#define K8_FIDVID_STATUS 0xC0010042 +#define K10_COFVID_STATUS 0xC0010071 + +#define CPU_MODEL_DOTHAN 0x0D ///< Dothan +#define CPU_MODEL_YONAH 0x0E ///< Sossaman, Yonah +#define CPU_MODEL_MEROM 0x0F ///< Allendale, Conroe, Kentsfield, Woodcrest, Clovertown, Tigerton, Merom +#define CPU_MODEL_PENRYN 0x17 ///< Wolfdale, Yorkfield, Harpertown, Penryn +#define CPU_MODEL_NEHALEM 0x1A ///< Bloomfield. Nehalem-EP, Nehalem-WS, Gainestown +#define CPU_MODEL_ATOM 0x1C ///< Atom +#define CPU_MODEL_FIELDS 0x1E ///< Lynnfield, Clarksfield, Jasper Forest +#define CPU_MODEL_DALES 0x1F ///< Havendale, Auburndale +#define CPU_MODEL_DALES_32NM 0x25 ///< Clarkdale, Arrandale +#define CPU_MODEL_SANDYBRIDGE 0x2A ///< Sandy Bridge +#define CPU_MODEL_WESTMERE 0x2C ///< Gulftown, Westmere-EP, Westmere-WS +#define CPU_MODEL_JAKETOWN 0x2D ///< Sandy Bridge Xeon +#define CPU_MODEL_NEHALEM_EX 0x2E ///< Beckton +#define CPU_MODEL_WESTMERE_EX 0x2F +#define CPU_MODEL_IVYBRIDGE 0x3A ///< Ivy Bridge +#define CPU_MODEL_HASWELL 0x3C +#define CPU_MODEL_BROADWELL 0x3D ///< Broadwell +#define CPU_MODEL_IVYBRIDGE_E5 0x3E +#define CPU_MODEL_HASWELL_MB 0x3F ///< Haswell MB +#define CPU_MODEL_HASWELL_ULT 0x45 ///< Haswell ULT +#define CPU_MODEL_HASWELL_ULX 0x46 ///< Haswell ULX +#define CPU_MODEL_SKYLAKE 0x5E ///< Skylake-S + +#define CPU_MODEL_DENVERTON 0x5F ///< Goldmont Microserver +#define CPU_MODEL_CANNONLAKE 0x66 +#define CPU_MODEL_XEON_MILL 0x85 ///< Knights Mill +#define CPU_MODEL_KABYLAKE_U 0x8E ///< Kabylake Mobile +#define CPU_MODEL_KABYLAKE 0x9E ///< Kabylake Dektop + +#define CPU_SOCKET_UNKNOWN 0x02 +#define CPU_SOCKET_PGA478 0x0F +#define CPU_SOCKET_LGA771 0x14 +#define CPU_SOCKET_LGA775 0x15 +#define CPU_SOCKET_LGA1156 0x1D +#define CPU_SOCKET_LGA1366 0x19 + +// CPU_P_STATE_COORDINATION +/// P-State Coordination +typedef enum { + /// The OS Power Manager is responsible for coordinating the P-state among logical + /// processors with dependencies and must initiate the transition on all of those Logical Processors. + CpuPStateCoordinationSoftwareAll = 0xFC, + + /// The OS Power Manager is responsible for coordinating the P-state among logical + /// processors with dependencies and may initiate the transition on any of those Logical Processors. + CpuPStateCoordinationSoftwareAny = 0xFD, + + /// The processor hardware is responsible for coordinating the P-state among logical + /// processors dependencies. The OS is responsible for keeping the P-state request up to date on all + /// logical processors. + CpuPStateCoordinationHardwareAll = 0xFE +} CPU_P_STATE_COORDINATION; + +#endif // OC_PROCESSOR_INFO_H_ diff --git a/Library/OcDebugLogLib/OcDebugLogLib.c b/Library/OcDebugLogLib/OcDebugLogLib.c new file mode 100755 index 00000000..65334df8 --- /dev/null +++ b/Library/OcDebugLogLib/OcDebugLogLib.c @@ -0,0 +1,245 @@ +/** @file + Copyright (C) 2016 - 2018, The HermitCrabs Lab. All rights reserved. + + All rights reserved. + + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +**/ + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +STATIC OC_LOG_PROTOCOL *mOcLog = NULL; + +// DebugPrint +/** Prints a debug message to the debug output device if the specified error level is enabled. + + If any bit in ErrorLevel is also set in DebugPrintErrorLevelLib function + GetDebugPrintErrorLevel (), then print the message specified by Format and the + associated variable argument list to the debug output device. + + If Format is NULL, then ASSERT(). + + @param ErrorLevel The error level of the debug message. + @param Format The format string for the debug message to print. + @param ... The variable argument list whose contents are accessed + based on the format string specified by Format. +**/ +VOID +EFIAPI +DebugPrint ( + IN UINTN ErrorLevel, + IN CONST CHAR8 *Format, + ... + ) +{ + EFI_STATUS Status; + VA_LIST Marker; + CHAR16 *LogBuffer; + + ASSERT (Format != NULL); + + // Check driver debug mask value and global mask + + if ((ErrorLevel & GetDebugPrintErrorLevel ()) != 0) { + VA_START (Marker, Format); + + if (mOcLog == NULL) { + Status = gBS->LocateProtocol ( + &gOcLogProtocolGuid, + NULL, + (VOID **)&mOcLog + ); + } + + if (mOcLog != NULL) { + LogBuffer = NULL; + Status = mOcLog->GetLog (mOcLog, &LogBuffer); + + if (!EFI_ERROR (Status) && (LogBuffer != NULL)) { + // Save end of current buffer + + LogBuffer += StrLen (LogBuffer); + + mOcLog->AddEntry (mOcLog, ErrorLevel, Format, Marker); + } + } + + VA_END (Marker); + } +} + +// DebugAssert +/** Prints an assert message containing a filename, line number, and description. + This may be followed by a breakpoint or a dead loop. + + Print a message of the form "ASSERT (): \n" + to the debug output device. If DEBUG_PROPERTY_ASSERT_BREAKPOINT_ENABLED bit of + PcdDebugProperyMask is set then CpuBreakpoint() is called. Otherwise, if + DEBUG_PROPERTY_ASSERT_DEADLOOP_ENABLED bit of PcdDebugProperyMask is set then + CpuDeadLoop() is called. If neither of these bits are set, then this function + returns immediately after the message is printed to the debug output device. + DebugAssert() must actively prevent recursion. If DebugAssert() is called while + processing another DebugAssert(), then DebugAssert() must return immediately. + + If FileName is NULL, then a string of "(NULL) Filename" is printed. + If Description is NULL, then a string of "(NULL) Description" is printed. + + @param FileName The pointer to the name of the source file that generated the assert condition. + @param LineNumber The line number in the source file that generated the assert condition + @param Description The pointer to the description of the assert condition. + +**/ +VOID +EFIAPI +DebugAssert ( + IN CONST CHAR8 *FileName, + IN UINTN LineNumber, + IN CONST CHAR8 *Description + ) +{ + // Generate the ASSERT() message in Ascii format + DebugPrint (DEBUG_ERROR, "ASSERT %a(%d): %a\n", FileName, LineNumber, Description); + + // Generate a Breakpoint, DeadLoop, or NOP based on PCD settings + if ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_ASSERT_BREAKPOINT_ENABLED) != 0) { + CpuBreakpoint (); + } else if ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_ASSERT_DEADLOOP_ENABLED) != 0) { + CpuDeadLoop (); + } +} + +// DebugClearMemory +/** Fills a target buffer with PcdDebugClearMemoryValue, and returns the target buffer. + + This function fills Length bytes of Buffer with the value specified by + PcdDebugClearMemoryValue, and returns Buffer. + + If Buffer is NULL, then ASSERT(). + If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). + + @param Buffer The pointer to the target buffer to be filled with PcdDebugClearMemoryValue. + @param Length The number of bytes in Buffer to fill with zeros PcdDebugClearMemoryValue. + + @return Buffer The pointer to the target buffer filled with PcdDebugClearMemoryValue. +**/ +VOID * +EFIAPI +DebugClearMemory ( + OUT VOID *Buffer, + IN UINTN Length + ) +{ + ASSERT (Buffer != NULL); + + // SetMem() checks for the the ASSERT() condition on Length and returns Buffer + + return SetMem (Buffer, Length, PcdGet8 (PcdDebugClearMemoryValue)); +} + +// DebugAssertEnabled +/** Returns TRUE, if ASSERT() macros are enabled. + + This function returns TRUE, if the DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of + PcdDebugProperyMask is set. Otherwise FALSE is returned. + + @retval TRUE The DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of PcdDebugProperyMask is set. + @retval FALSE The DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of PcdDebugProperyMask is clear. +**/ +BOOLEAN +EFIAPI +DebugAssertEnabled ( + VOID + ) +{ + return (BOOLEAN)((PcdGet8 (PcdDebugPropertyMask) & DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED) != 0); +} + +// DebugPrintEnabled +/** Returns TRUE, if DEBUG() macros are enabled. + + This function returns TRUE, if the DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of + PcdDebugProperyMask is set. Otherwise FALSE is returned. + + @retval TRUE The DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of PcdDebugProperyMask is set. + @retval FALSE The DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of PcdDebugProperyMask is clear. +**/ +BOOLEAN +EFIAPI +DebugPrintEnabled ( + VOID + ) +{ + return (BOOLEAN)((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_DEBUG_PRINT_ENABLED) != 0); +} + +// DebugCodeEnabled +/** Returns TRUE, if DEBUG_CODE() macros are enabled. + + This function returns TRUE, if the DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of + PcdDebugProperyMask is set. Otherwise FALSE is returned. + + @retval TRUE The DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of PcdDebugProperyMask is set. + @retval FALSE The DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of PcdDebugProperyMask is clear. + +**/ +BOOLEAN +EFIAPI +DebugCodeEnabled ( + VOID + ) +{ + return (BOOLEAN)((PcdGet8 (PcdDebugPropertyMask) & DEBUG_PROPERTY_DEBUG_CODE_ENABLED) != 0); +} + +// DebugClearMemoryEnabled +/** Returns TRUE, if DEBUG_CLEAR_MEMORY() macro is enabled. + + This function returns TRUE, if the DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED bit of + PcdDebugProperyMask is set. Otherwise FALSE is returned. + + @retval TRUE The DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED bit of PcdDebugProperyMask is set. + @retval FALSE The DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED bit of PcdDebugProperyMask is clear. + +**/ +BOOLEAN +EFIAPI +DebugClearMemoryEnabled ( + VOID + ) +{ + return (BOOLEAN)((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED) != 0); +} + +// DebugPrintLevelEnabled +/** Returns TRUE, if any one of the bit is set both in ErrorLevel and PcdFixedDebugPrintErrorLevel. + + This function compares the bit mask of ErrorLevel and PcdFixedDebugPrintErrorLevel. + + @retval TRUE Current ErrorLevel is supported. + @retval FALSE Current ErrorLevel is not supported. + +**/ +BOOLEAN +EFIAPI +DebugPrintLevelEnabled ( + IN CONST UINTN ErrorLevel + ) +{ + return (BOOLEAN)((ErrorLevel & PcdGet32 (PcdFixedDebugPrintErrorLevel)) != 0); +} diff --git a/Library/OcDebugLogLib/OcDebugLogLib.inf b/Library/OcDebugLogLib/OcDebugLogLib.inf new file mode 100755 index 00000000..eb25ac5b --- /dev/null +++ b/Library/OcDebugLogLib/OcDebugLogLib.inf @@ -0,0 +1,45 @@ +## @file +# +# Component description file for Debug Library using the OcLog protocol. +# +# Copyright (C) 2016, The HermitCrabs Lab. All rights reserved.
+# +# All rights reserved. +# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# +# 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 = OcDebugLogLib + FILE_GUID = 85E15002-397B-441B-AC5C-BF952B0E7331 + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = DebugLib + +# VALID_ARCHITECTURES = IA32 X64 IPF EBC + +[Packages] + OcSupportPkg/OcSupportPkg.dec + MdePkg/MdePkg.dec + +[Protocols] + gOcLogProtocolGuid + +[LibraryClasses] + DebugPrintErrorLevelLib + +[Pcd] + gEfiMdePkgTokenSpaceGuid.PcdDebugClearMemoryValue + gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask + gEfiMdePkgTokenSpaceGuid.PcdFixedDebugPrintErrorLevel + +[Sources] + OcDebugLogLib.c diff --git a/Library/OcDevicePathLib/OcDevicePathLib.c b/Library/OcDevicePathLib/OcDevicePathLib.c new file mode 100755 index 00000000..6fb20f68 --- /dev/null +++ b/Library/OcDevicePathLib/OcDevicePathLib.c @@ -0,0 +1,321 @@ +/** @file + Copyright (C) 2016 - 2018, The HermitCrabs Lab. All rights reserved. + + All rights reserved. + + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +**/ + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +// AppendFileNameDevicePath +/** + + @param[in] DevicePath The device path which to append the file path. + @param[in] FileName The file name to append to the device path. + + @retval EFI_SUCCESS The defaults were initialized successfully. + @retval EFI_INVALID_PARAMETER The parameters passed were invalid. + @retval EFI_OUT_OF_RESOURCES The system ran out of memory. +**/ +EFI_DEVICE_PATH_PROTOCOL * +AppendFileNameDevicePath ( + IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, + IN CHAR16 *FileName + ) +{ + EFI_DEVICE_PATH_PROTOCOL *AppendedDevicePath; + + FILEPATH_DEVICE_PATH *FilePathNode; + EFI_DEVICE_PATH_PROTOCOL *DevicePathEndNode; + UINTN FileNameSize; + UINTN FileDevicePathNodeSize; + + AppendedDevicePath = NULL; + + if (DevicePath != NULL && FileName != NULL) { + FileNameSize = StrSize (FileName); + FileDevicePathNodeSize = (FileNameSize + sizeof (*FilePathNode) + sizeof (*DevicePath)); + FilePathNode = AllocateZeroPool (FileDevicePathNodeSize); + + if (FilePathNode != NULL) { + FilePathNode->Header.Type = MEDIA_DEVICE_PATH; + FilePathNode->Header.SubType = MEDIA_FILEPATH_DP; + + SetDevicePathNodeLength (&FilePathNode->Header, FileNameSize + sizeof (*FilePathNode)); + + CopyMem (FilePathNode->PathName, FileName, FileNameSize); + + DevicePathEndNode = NextDevicePathNode (&FilePathNode->Header); + + SetDevicePathEndNode (DevicePathEndNode); + + AppendedDevicePath = AppendDevicePath (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)FilePathNode); + } + } + + return AppendedDevicePath; +} + +// DevicePathToText +/** + + @param[in] StorageDevicePath The device path to convert to unicode string. + @param[in] DisplayOnly + @param[in] AllowShortcuts + + @retval EFI_SUCCESS The defaults were initialized successfully. + @retval EFI_INVALID_PARAMETER The parameters passed were invalid. + @retval EFI_OUT_OF_RESOURCES The system ran out of memory. +**/ +CHAR16 * +DevicePathToText ( + IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, + IN BOOLEAN DisplayOnly, + IN BOOLEAN AllowShortcuts + ) +{ + CHAR16 *DevicePathString; + EFI_DEVICE_PATH_PROTOCOL *ShortDevicePath = NULL; + EFI_DEVICE_PATH_TO_TEXT_PROTOCOL *DevicePathToText = NULL; + EFI_STATUS Status; + + Status = SafeLocateProtocol ( + &gEfiDevicePathToTextProtocolGuid, + NULL, + (VOID **)&DevicePathToText + ); + + // TODO: Shorten the device path to the last node ? + + if (DisplayOnly == TRUE && AllowShortcuts == TRUE) { + + ShortDevicePath = FindDevicePathNodeWithType ( + DevicePath, + MEDIA_DEVICE_PATH, + MEDIA_HARDDRIVE_DP); + + } + + if (ShortDevicePath == NULL) { + ShortDevicePath = DevicePath; + } + + DevicePathString = NULL; + + if (!EFI_ERROR (Status)) { + DevicePathString = DevicePathToText->ConvertDevicePathToText ( + ShortDevicePath, + DisplayOnly, + AllowShortcuts + ); + } + + return DevicePathString; +} + +// FindDevicePathNodeWithType +/** + + @param[in] DevicePath The device path used in the search. + @param[in] Type The Type field of the device path node specified by Node. + @param[in] SubType The SubType field of the device path node specified by Node. + + @return Returned is the first Device Path Node with the given type. +**/ +EFI_DEVICE_PATH_PROTOCOL * +FindDevicePathNodeWithType ( + IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, + IN UINT8 Type, + IN UINT8 SubType OPTIONAL + ) +{ + EFI_DEVICE_PATH_PROTOCOL *DevicePathNode; + + DevicePathNode = NULL; + + while (!IsDevicePathEnd (DevicePath)) { + if ((DevicePathType (DevicePath) == Type) + && ((SubType == 0) || (DevicePathSubType (DevicePath) == SubType))) { + DevicePathNode = DevicePath; + + break; + } + + DevicePath = NextDevicePathNode (DevicePath); + } + + return DevicePathNode; +} + +// IsDevicePathEqual +/** + + @param[in] DevicePath1 The first device path protocol to compare. + @param[in] DevicePath2 The second device path protocol to compare. + + @retval TRUE The device paths matched + @retval FALSE The device paths were different +**/ +BOOLEAN +EFIAPI +IsDevicePathEqual ( + IN EFI_DEVICE_PATH_PROTOCOL *DevicePath1, + IN EFI_DEVICE_PATH_PROTOCOL *DevicePath2 + ) +{ + BOOLEAN Equal; + UINT8 Type1; + UINT8 SubType1; + UINTN Len1; + CHAR16 *FilePath1; + CHAR16 *FilePath2; + + // TODO: Compare Normal & Short Device Paths + + Equal = FALSE; + + while (TRUE) { + + Type1 = DevicePathType (DevicePath1); + SubType1 = DevicePathSubType (DevicePath1); + Len1 = DevicePathNodeLength (DevicePath1); + + if (Type1 != DevicePathType (DevicePath2) || + SubType1 != DevicePathSubType (DevicePath2) || + Len1 != DevicePathNodeLength (DevicePath2)) + { + + // Compare short HD paths + if (DevicePathType (DevicePath1) == MEDIA_DEVICE_PATH && + DevicePathSubType(DevicePath1) == MEDIA_HARDDRIVE_DP) { + + DevicePath2 = FindDevicePathNodeWithType ( + DevicePath2, + MEDIA_DEVICE_PATH, + MEDIA_HARDDRIVE_DP); + + } else if (DevicePathType (DevicePath2) == MEDIA_DEVICE_PATH && + DevicePathSubType (DevicePath2) == MEDIA_HARDDRIVE_DP) { + + DevicePath1 = FindDevicePathNodeWithType ( + DevicePath1, + MEDIA_DEVICE_PATH, + MEDIA_HARDDRIVE_DP); + } else { + + // Not equal + break; + + } + + // Fall through with short HD paths to check + + } + + // Same type/subtype/len ... + + if (IsDevicePathEnd (DevicePath1) && + IsDevicePathEnd (DevicePath2)) + { + // END node - they are the same + Equal = TRUE; + break; + } + + // Do mem compare of nodes or special compare for selected types/subtypes + if (Type1 == MEDIA_DEVICE_PATH && SubType1 == MEDIA_FILEPATH_DP) { + + // Special compare: case insensitive file path compare + skip leading \ char + FilePath1 = &((FILEPATH_DEVICE_PATH *)DevicePath1)->PathName[0]; + + if (FilePath1[0] == L'\\') { + FilePath1++; + } + + FilePath2 = &((FILEPATH_DEVICE_PATH *)DevicePath2)->PathName[0]; + if (FilePath2[0] == L'\\') { + FilePath2++; + } + + if (StrCmpiBasic (FilePath1, FilePath2) != 0) { + // Not equal + break; + } + + } else { + + if (CompareMem (DevicePath1, DevicePath2, DevicePathNodeLength (DevicePath1)) != 0) { + // Not equal + break; + } + } + + // Advance to next node + DevicePath1 = NextDevicePathNode (DevicePath1); + DevicePath2 = NextDevicePathNode (DevicePath2); + } + + return Equal; +} + +// IsDeviceChild +/** + + @param[in] ParentPath The parent device path protocol to check against. + @param[in] ChildPath The device path protocol of the child device to compare. + + @retval TRUE The child device path contains the parent device path. + @retval FALSE The device paths were different +**/ +BOOLEAN +EFIAPI +IsDeviceChild ( + IN EFI_DEVICE_PATH_PROTOCOL *ParentPath, + IN EFI_DEVICE_PATH_PROTOCOL *ChildPath, + IN UINT8 EndPathType + ) +{ + EFI_DEVICE_PATH_PROTOCOL *DevicePath; + EFI_DEVICE_PATH_PROTOCOL *ChildPathEndNode; + + BOOLEAN Matched; + + DevicePath = DuplicateDevicePath (ChildPath); + + ChildPathEndNode = DevicePath; + + while (!IsDevicePathEndType (ChildPathEndNode) && + !(DevicePathType (ChildPathEndNode) == MEDIA_DEVICE_PATH && + DevicePathSubType (ChildPathEndNode) == EndPathType)) + + { + ChildPathEndNode = NextDevicePathNode (ChildPathEndNode); + } + + SetDevicePathEndNode (ChildPathEndNode); + + Matched = IsDevicePathEqual (ParentPath, DevicePath); + + FreePool (DevicePath); + + return Matched; +} diff --git a/Library/OcDevicePathLib/OcDevicePathLib.inf b/Library/OcDevicePathLib/OcDevicePathLib.inf new file mode 100755 index 00000000..b70828bf --- /dev/null +++ b/Library/OcDevicePathLib/OcDevicePathLib.inf @@ -0,0 +1,43 @@ +## @file +# +# Component description file for OcDevicePathLibrary. +# +# Copyright (C) 2016, The HermitCrabs Lab. All rights reserved.
+# +# All rights reserved. +# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# +# 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 = OcDevicePathLib + FILE_GUID = BDEBB36A-9261-4908-9E42-FE59E0B43B82 + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = OcDevicePathLib|PEIM DXE_DRIVER DXE_RUNTIME_DRIVER UEFI_DRIVER UEFI_APPLICATION DXE_SMM_DRIVER + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 +# + +[Sources] + OcDevicePathLib.c + +[Packages] + OcSupportPkg/OcSupportPkg.dec + MdePkg/MdePkg.dec + +[LibraryClasses] + +[Protocols] + gEfiDevicePathToTextProtocolGuid diff --git a/Library/OcFileLib/FileExists.c b/Library/OcFileLib/FileExists.c new file mode 100755 index 00000000..03faf912 --- /dev/null +++ b/Library/OcFileLib/FileExists.c @@ -0,0 +1,149 @@ +/** @file + Copyright (C) 2016 - 2018, The HermitCrabs Lab. All rights reserved. + + All rights reserved. + + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +**/ + +#include + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "OcFileLibInternal.h" +#include "Macros.h" + +// FileExists +/** + + @param[in] DevicePath A pointer to the device path to check for the file. + @param[in] FilePath A pointer to the NULL terminated unicode file name. + + @retval TRUE The file path was found on the device. + @retval FALSE The file path was not found on the device. +**/ +BOOLEAN +FileExists ( + IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, + IN CHAR16 *FilePath + ) +{ + BOOLEAN Exists; + + EFI_STATUS Status; + CHAR16 *DirectoryPath; + CHAR16 *FileName; + EFI_FILE_INFO *FileInfo; + UINTN FilePathSize; + + Exists = FALSE; + + if (DevicePath != NULL && FilePath != NULL) { + FilePathSize = StrSize (FilePath); + DirectoryPath = AllocateZeroPool (FilePathSize); + FileName = (FilePath + StrLen (FilePath)) - 1; + + if (DirectoryPath != NULL) { + + // Split FilePath into DirectoryPath and FileName + + CHAR16 *TempDirectoryPath = DirectoryPath; + UINTN FilePathLen; + + while ((FileName > FilePath) && (*FileName != L'\\')) { + --FileName; + } + + ++FileName; + + FilePathLen = (FileName - FilePath); + + while ((FilePathLen > 0) && (*FilePath != 0)) { + *(TempDirectoryPath++) = *(FilePath++); + FilePathLen--; + } + *TempDirectoryPath = 0; + + if (*DirectoryPath != 0 && *FileName != 0) { + + FileInfo = NULL; + Status = GetFileInfo ( + DevicePath, + DirectoryPath, + FileName, + &FileInfo + ); + + FreePool ((VOID *)DirectoryPath); + + if (!EFI_ERROR (Status)) { + Exists = TRUE; + } + } + } + } + + return Exists; +} + +// FolderFileExists +/** + + @param[in] DevicePath A pointer to the device path to check for the file. + @param[in] DirectoryPath A pointer to the NULL terminated ascii directory name. + @param[in] FilePath A pointer to the NULL terminated ascii file name. + + @retval TRUE The file path was found on the device. + @retval FALSE The file path was not found on the device. +**/ +BOOLEAN +FolderFileExists ( + IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, + IN CHAR8 *DirectoryPath OPTIONAL, + IN CHAR8 *FilePath OPTIONAL + ) +{ + BOOLEAN Exists; + CHAR16 *FullUnicodePath; + CHAR16 *UnicodeFilePath; + + Exists = FALSE; + + if (DevicePath != NULL && (DirectoryPath != NULL || FilePath != NULL)) { + FullUnicodePath = AllocateZeroPool (EFI_MAX_PATH_SIZE); + if (FullUnicodePath != NULL) { + UnicodeFilePath = FullUnicodePath; + if (DirectoryPath != NULL) { + OcAsciiStrToUnicode (DirectoryPath, UnicodeFilePath, 0); + UnicodeFilePath += StrLen (UnicodeFilePath); + } + if (FilePath != NULL) { + *(UnicodeFilePath++) = L'\\'; + OcAsciiStrToUnicode (FilePath, UnicodeFilePath, 0); + } + Exists = FileExists (DevicePath, FullUnicodePath); + FreePool (FullUnicodePath); + } + } + + return Exists; +} diff --git a/Library/OcFileLib/GetFileInfo.c b/Library/OcFileLib/GetFileInfo.c new file mode 100755 index 00000000..01624ec1 --- /dev/null +++ b/Library/OcFileLib/GetFileInfo.c @@ -0,0 +1,164 @@ +/** @file + Copyright (C) 2016 - 2018, The HermitCrabs Lab. All rights reserved. + + All rights reserved. + + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +**/ + +#include + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "OcFileLibInternal.h" + +// GetFileInfo +/** + + @param[in] DevicePath A pointer to the device path to device. + @param[in] Directory A pointer to the directory that contains the file. + @param[in] FileName A pointer to the the filename. + @param[out] FileInfo A pointer to the FILE_INFO structure returned or NULL + + @retval EFI_SUCCESS The FILE_INFO structure was successfully returned. +**/ +EFI_STATUS +GetFileInfo ( + IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, + IN CHAR16 *Directory, + IN CHAR16 *FileName, + OUT EFI_FILE_INFO **FileInfo + ) +{ + EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *FileSystem; + EFI_FILE *FileSystemRoot; + + EFI_STATUS Status; + EFI_FILE *File; + UINTN FileInfoSize; + CHAR16 *FilePath; + UINTN FilePathSize; + + Status = EFI_INVALID_PARAMETER; + + if ((DevicePath != NULL) && (Directory != NULL) && (FileName != NULL)) { + + Status = EFI_OUT_OF_RESOURCES; + FilePathSize = StrSize (Directory) + StrSize (FileName); + FilePath = AllocateZeroPool (FilePathSize); + + if (FilePath != NULL) { + + CHAR16 *TempFilePath = FilePath; + + while (*Directory != 0) { + *(TempFilePath++) = *(Directory++); + } + + while (*FileName != 0) { + *(TempFilePath++) = *(FileName++); + } + + *TempFilePath = 0; + + // Open the Filesystem on our DeviceHandle. + + FileSystem = NULL; + Status = OpenFileSystem ( + &DevicePath, + &FileSystem + ); + + if (!EFI_ERROR (Status)) { + // We need to open the target volume to be able to load files from it. + // What we get is the filesystem root. This function also has to be called + // if any further calls to FileSystem return EFI_MEDIA_CHANGED to indicate + // that our volume has changed. + + do { + FileSystemRoot = NULL; + Status = FileSystem->OpenVolume ( + FileSystem, + &FileSystemRoot + ); + + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Could not open the file system - %r\n", Status)); + + break; + } + + // Now we can try to open the target file on our filesystem. + + File = NULL; + Status = FileSystemRoot->Open ( + FileSystemRoot, + &File, + FilePath, + EFI_FILE_MODE_READ, + EFI_FILE_READ_ONLY + ); + + if (!EFI_ERROR (Status)) { + // Try to retrieve information of our file. + + FileInfoSize = 0; + Status = File->GetInfo ( + File, + &gEfiFileInfoGuid, + &FileInfoSize, + NULL + ); + + if (Status == EFI_BUFFER_TOO_SMALL) { + // The first call to this function we get the right size of the + // FileInfo buffer, so we allocate it with that size and call the function again. + // + // Some drivers do not count 0 at the end of file name + + *FileInfo = AllocateZeroPool (FileInfoSize + sizeof (CHAR16)); + + if (*FileInfo != NULL) { + Status = File->GetInfo ( + File, + &gEfiFileInfoGuid, + &FileInfoSize, + *FileInfo + ); + } + } + } + + if (!EFI_ERROR (Status)) { + break; + } + + // If we get the EFI_MEDIA_CHANGED error, we need to reopen the volume by calling + // OpenVolume() on our DeviceHandle + } while (Status == EFI_MEDIA_CHANGED); + } + + FreePool ((VOID *)FilePath); + } + } + + return Status; +} diff --git a/Library/OcFileLib/GetNextDirEntry.c b/Library/OcFileLib/GetNextDirEntry.c new file mode 100755 index 00000000..b42d957f --- /dev/null +++ b/Library/OcFileLib/GetNextDirEntry.c @@ -0,0 +1,95 @@ +/** @file + Copyright (C) 2016, The HermitCrabs Lab. All rights reserved. + + All rights reserved. + + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +**/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "OcFileLibInternal.h" + +// GetNextDirEntry +/** + + @param[in] DevicePath + @param[out] DirEntry + @param[in] SearchMask + + @retval EFI_SUCCESS The volume label was successfully returned. +**/ +EFI_STATUS +GetNextDirEntry ( + IN EFI_FILE *Directory, + OUT EFI_FILE_INFO **DirEntry, + IN UINT64 SearchMask + ) +{ + EFI_STATUS Status; + + EFI_FILE_INFO *FileInfo; + UINTN FileInfoSize; + UINTN BufferSize; + + Status = EFI_INVALID_PARAMETER; + + if ((Directory != NULL) && (DirEntry != NULL)) { + // Some fs drivers dont support passing a buffersize of 0 so + // allocate buffer for FILE_INFO structure including a maximum + // filename length of 255 chars. + BufferSize = sizeof (*FileInfo) + (255 * sizeof (CHAR16)); + FileInfo = AllocatePool (BufferSize); + Status = EFI_OUT_OF_RESOURCES; + + if (FileInfo != NULL) { + // Iterate the directory entries for a match + do { + // Handle buggy FS driver implementations by passing a buffer + // thats already allocated. + + FileInfoSize = BufferSize; + Status = Directory->Read (Directory, &FileInfoSize, FileInfo); + + if (!EFI_ERROR (Status) && (FileInfoSize != 0)) { + if (((SearchMask == FILE_ITERATE_DIRECTORIES) + && ((SearchMask & FileInfo->Attribute) == EFI_FILE_DIRECTORY)) + || ((SearchMask != FILE_ITERATE_DIRECTORIES) + && ((SearchMask & FileInfo->Attribute) == FileInfo->Attribute))) { + *DirEntry = FileInfo; + + Status = EFI_SUCCESS; + + break; + } + } else { + // No match found so free the buffer + + Status = EFI_NOT_FOUND; + + FreePool ((VOID *)FileInfo); + + break; + } + } while (TRUE); + } + } + + return Status; +} diff --git a/Library/OcFileLib/GetVolumeLabel.c b/Library/OcFileLib/GetVolumeLabel.c new file mode 100755 index 00000000..a5444fa7 --- /dev/null +++ b/Library/OcFileLib/GetVolumeLabel.c @@ -0,0 +1,103 @@ +/** @file + Copyright (C) 2016, The HermitCrabs Lab. All rights reserved. + + All rights reserved. + + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +**/ + +#include + +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "OcFileLibInternal.h" + +// GetVolumeLabel +/** + + @param[in] DevicePath A pointer to the device path to retrieve the volume label from. + @param[out] VolumeLabel A pointer to the NULL terminated unicode volume label. + + @retval EFI_SUCCESS The volume label was successfully returned. +**/ +EFI_STATUS +GetVolumeLabel ( + IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, + IN OUT CHAR16 **VolumeLabel + ) +{ + EFI_STATUS Status; + + EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *FileSystem; + EFI_FILE_HANDLE File; + EFI_FILE_SYSTEM_VOLUME_LABEL *VolumeInfo; + UINTN FileSize; + + Status = EFI_INVALID_PARAMETER; + + if ((DevicePath != NULL) && (VolumeLabel != NULL)) { + // Open the Filesystem on our DevicePath. + + FileSystem = NULL; + Status = OpenFileSystem ( + &DevicePath, + &FileSystem + ); + + if (!EFI_ERROR (Status)) { + File = NULL; + Status = FileSystem->OpenVolume ( + FileSystem, + &File + ); + + if (!EFI_ERROR (Status)) { + FileSize = 0; + VolumeInfo = NULL; + Status = File->GetInfo ( + File, + &gEfiFileSystemVolumeLabelInfoIdGuid, + &FileSize, + VolumeInfo + ); + + if (Status == EFI_BUFFER_TOO_SMALL) { + VolumeInfo = AllocateZeroPool (FileSize); + Status = File->GetInfo ( + File, + &gEfiFileSystemVolumeLabelInfoIdGuid, + &FileSize, + VolumeInfo + ); + + if (!EFI_ERROR (Status)) { + *VolumeLabel = AllocateCopyPool (StrSize (VolumeInfo->VolumeLabel), VolumeInfo->VolumeLabel); + + FreePool ((VOID *)VolumeInfo); + } + } + } + } + } + + return Status; +} diff --git a/Library/OcFileLib/OcFileLib.inf b/Library/OcFileLib/OcFileLib.inf new file mode 100755 index 00000000..2dd82eb7 --- /dev/null +++ b/Library/OcFileLib/OcFileLib.inf @@ -0,0 +1,54 @@ +## @file +# +# Component description file for OcFileLibrary. +# +# Copyright (C) 2016 - 2017, The HermitCrabs Lab. All rights reserved.
+# +# All rights reserved. +# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# +# 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 = OcFileLib + FILE_GUID = E7FF8BF4-1641-44AF-BFCE-EF3CF0EF21BE + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = OcFileLib|PEIM DXE_DRIVER DXE_RUNTIME_DRIVER UEFI_DRIVER UEFI_APPLICATION DXE_SMM_DRIVER + +# VALID_ARCHITECTURES = IA32 X64 + +[Sources] + FileExists.c + GetFileInfo.c + GetNextDirEntry.c + GetVolumeLabel.c + OpenDirectory.c + OpenFileSystem.c + ReadFile.c + ReadFvFile.c + WriteFile.c + +[Packages] + OcSupportPkg/OcSupportPkg.dec + MdePkg/MdePkg.dec + IntelFrameworkPkg/IntelFrameworkPkg.dec + +[LibraryClasses] + BaseLib + +[Guids] + gEfiFileInfoGuid ## CONSUMES + gEfiFileSystemInfoGuid ## CONSUMES + gEfiFileSystemVolumeLabelInfoIdGuid ## CONSUMES + +[Protocols] + gEfiFirmwareVolume2ProtocolGuid diff --git a/Library/OcFileLib/OcFileLibInternal.h b/Library/OcFileLib/OcFileLibInternal.h new file mode 100755 index 00000000..0cbf8f36 --- /dev/null +++ b/Library/OcFileLib/OcFileLibInternal.h @@ -0,0 +1,18 @@ +/** @file + Copyright (C) 2016, The HermitCrabs Lab. All rights reserved. + + All rights reserved. + + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + 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 OC_FILE_LIB_INTERNAL_H_ +#define OC_FILE_LIB_INTERNAL_H_ + +#endif // OC_FILE_LIB_INTERNAL_H_ diff --git a/Library/OcFileLib/OpenDirectory.c b/Library/OcFileLib/OpenDirectory.c new file mode 100755 index 00000000..7da29729 --- /dev/null +++ b/Library/OcFileLib/OpenDirectory.c @@ -0,0 +1,115 @@ +/** @file + Copyright (C) 2016, The HermitCrabs Lab. All rights reserved. + + All rights reserved. + + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +**/ + +#include + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "OcFileLibInternal.h" + +// OpenDirectory +/** Read file from device path + + Open + EFI_FILE_MODE_READ + Create + (EFI_FILE_MODE_CREATE | EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE) + + @param[in] DevicePath The whole device path to the file. + @param[out] FileSize The size of the file read or 0 + + @retval A pointer to a buffer containing the file read or NULL +**/ +EFI_STATUS +OpenDirectory ( + IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, + IN CHAR16 *DirectoryPath, + IN UINT64 Mode, + IN UINT64 Attributes, + OUT EFI_FILE **DirectoryHandle OPTIONAL + ) +{ + EFI_STATUS Status; + + EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *FileSystem; + EFI_FILE *FileSystemRoot; + EFI_FILE *Directory; + + Status = EFI_INVALID_PARAMETER; + + if ((DevicePath != NULL) && (DirectoryPath != NULL)) { + // Open the Filesystem on our DeviceHandle. + + FileSystem = NULL; + Status = OpenFileSystem ( + &DevicePath, + &FileSystem + ); + + if (!EFI_ERROR (Status)) { + // We neeed to open the target volume to be able to load files from it. + // What we get is the filesystem root. This function also has to be called + // if any further calls to FileSystem return EFI_MEDIA_CHANGED to indicate + // that our volume has changed. + + do { + FileSystemRoot = NULL; + Status = FileSystem->OpenVolume (FileSystem, &FileSystemRoot); + + + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Could not open the file system - %r\n", Status)); + + break; + } + + // Now we can try to open the target file on our filesystem. + + Directory = NULL; + Status = FileSystemRoot->Open ( + FileSystemRoot, + &Directory, + DirectoryPath, + Mode, + (Attributes | EFI_FILE_DIRECTORY) + ); + + if (!EFI_ERROR (Status)) { + break; + } + } while (Status == EFI_MEDIA_CHANGED); + } + + if (DirectoryHandle != NULL) { + *DirectoryHandle = Directory; + } else { + Directory->Close (Directory); + } + + } + + return Status; +} diff --git a/Library/OcFileLib/OpenFileSystem.c b/Library/OcFileLib/OpenFileSystem.c new file mode 100755 index 00000000..bb215fb4 --- /dev/null +++ b/Library/OcFileLib/OpenFileSystem.c @@ -0,0 +1,73 @@ +/** @file + Copyright (C) 2016, The HermitCrabs Lab. All rights reserved. + + All rights reserved. + + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +**/ + +#include + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "OcFileLibInternal.h" + +// OpenFileSystem +/** Read file from device path + + @param[in] DevicePath The whole device path to the file. + @param[out] FileSystem The size of the file read or 0 + + @retval A pointer to a buffer containing the file read or NULL +**/ +EFI_STATUS +OpenFileSystem ( + IN EFI_DEVICE_PATH_PROTOCOL **DevicePath, + IN OUT EFI_SIMPLE_FILE_SYSTEM_PROTOCOL **FileSystem + ) +{ + EFI_STATUS Status; + EFI_HANDLE Handle; + + // Get our DeviceHandle + + Status = gBS->LocateDevicePath (&gEfiSimpleFileSystemProtocolGuid, + DevicePath, + &Handle); + + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Could not locate EfiSimpleFileSystemProtocol for device handle %X - %r\n", DevicePath, Status)); + } else { + // Open the SimpleFileSystem Protocol + + Status = gBS->HandleProtocol ( + Handle, + &gEfiSimpleFileSystemProtocolGuid, + (VOID **)FileSystem + ); + + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Could not open EfiSimpleFileSystemProtocol for device handle - %r\n", Status)); + } + } + + return Status; +} diff --git a/Library/OcFileLib/ReadFile.c b/Library/OcFileLib/ReadFile.c new file mode 100755 index 00000000..34504bdc --- /dev/null +++ b/Library/OcFileLib/ReadFile.c @@ -0,0 +1,242 @@ +/** @file + Copyright (C) 2016, The HermitCrabs Lab. All rights reserved. + + All rights reserved. + + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +**/ + +#include + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "OcFileLibInternal.h" + +// ReadFileFromDevicePath +/** Read file from device path + + @param[in] DevicePath The whole device path to the file. + @param[out] FileSize The size of the file read or 0 + + @retval A pointer to a buffer containing the file read or NULL +**/ +VOID * +ReadFileFromDevicePath ( + IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, + IN OUT UINTN *FileSize + ) +{ + VOID *FileBuffer; + + EFI_STATUS Status; + EFI_HANDLE Handle; + EFI_FILE_HANDLE FileHandle; + EFI_FILE_HANDLE LastHandle; + EFI_FILE_INFO *FileInfo; + EFI_DEVICE_PATH_PROTOCOL *DevicePathNode; + EFI_DEVICE_PATH_PROTOCOL *OrigDevicePathNode; + EFI_DEVICE_PATH_PROTOCOL *TempDevicePathNode; + EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *Volume; + UINTN FileInfoSize; + + FileBuffer = NULL; + + if ((DevicePath != NULL) && (FileSize != NULL)) { + OrigDevicePathNode = DuplicateDevicePath (DevicePath); + + if (OrigDevicePathNode != NULL) { + DevicePathNode = OrigDevicePathNode; + Status = gBS->LocateDevicePath ( + &gEfiSimpleFileSystemProtocolGuid, + &DevicePathNode, + &Handle + ); + + if (!EFI_ERROR (Status)) { + Volume = NULL; + Status = gBS->HandleProtocol ( + Handle, + &gEfiSimpleFileSystemProtocolGuid, + (VOID**)&Volume + ); + + if (!EFI_ERROR (Status)) { + // Open the volume to get the file system handle + Status = Volume->OpenVolume (Volume, &FileHandle); + + if (!EFI_ERROR (Status)) { + // Duplicate the device path to avoid the access to unaligned device path node. + // Because the device path consists of one or more FILE PATH MEDIA DEVICE PATH + // nodes, It assures the fields in device path nodes are 2 byte aligned. + TempDevicePathNode = DuplicateDevicePath (DevicePathNode); + Status = EFI_OUT_OF_RESOURCES; + + if (TempDevicePathNode != NULL) { + // Parse each MEDIA_FILEPATH_DP node. There may be more than one, since the + // directory information and filename can be seperate. The goal is to inch + // our way down each device path node and close the previous node + + DevicePathNode = TempDevicePathNode; + + while (!IsDevicePathEnd (DevicePathNode)) { + if ((DevicePathType (DevicePathNode) != MEDIA_DEVICE_PATH) + || (DevicePathSubType (DevicePathNode) != MEDIA_FILEPATH_DP)) { + Status = EFI_UNSUPPORTED; + + break; + } + + LastHandle = FileHandle; + FileHandle = NULL; + + Status = LastHandle->Open ( + LastHandle, + &FileHandle, + ((FILEPATH_DEVICE_PATH *)DevicePathNode)->PathName, + EFI_FILE_MODE_READ, + 0 + ); + + // Close the previous node + LastHandle->Close (LastHandle); + + if (EFI_ERROR (Status)) { + FileHandle = NULL; + + break; + } + + DevicePathNode = NextDevicePathNode (DevicePathNode); + } + + if (!EFI_ERROR (Status)) { + // We have found the file. Now we need to read it. Before we can read the file we need to + // figure out how big the file is. + + FileInfoSize = 0; + Status = FileHandle->GetInfo ( + FileHandle, + &gEfiFileInfoGuid, + &FileInfoSize, + NULL + ); + + if (Status == EFI_BUFFER_TOO_SMALL) { + // Some drivers do not count 0 at the end of file name + FileInfo = AllocatePool (FileInfoSize + sizeof (CHAR16)); + + if (FileInfo != NULL) { + Status = FileHandle->GetInfo ( + FileHandle, + &gEfiFileInfoGuid, + &FileInfoSize, + FileInfo + ); + + if (!EFI_ERROR (Status)) { + // Allocate space for the file + FileBuffer = AllocatePool ((UINTN)FileInfo->FileSize); + + if (FileBuffer != NULL) { + // Read the file into the buffer we allocated + + *FileSize = (UINTN)FileInfo->FileSize; + Status = FileHandle->Read ( + FileHandle, + FileSize, + FileBuffer + ); + + if (EFI_ERROR (Status)) { + FreePool ((VOID *)FileBuffer); + + FileBuffer = NULL; + *FileSize = 0; + } + } + } + + FreePool ((VOID *)FileInfo); + } + } + } + + FreePool ((VOID *)TempDevicePathNode); + } + + if (FileHandle != NULL) { + FileHandle->Close (FileHandle); + } + } + } + } + + FreePool ((VOID *)OrigDevicePathNode); + } + } + + return FileBuffer; +} + +// ReadFile +/** Read file from device path + + @param[in] DevicePath The device path for the device. + @param[in] FilePath The full path to the file on the device. + @param[out] FileBuffer A pointer to a buffer containing the file read or NULL + @param[out] FileSize The size of the file read or 0 + + @retval EFI_SUCCESS The platform detection executed successfully. +**/ +EFI_STATUS +ReadFile ( + IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, + IN CHAR16 *FilePath, + OUT VOID **FileBuffer, + OUT UINTN *FileBufferSize + ) +{ + EFI_STATUS Status; + + EFI_DEVICE_PATH_PROTOCOL *WholeDevicePath; + + Status = EFI_INVALID_PARAMETER; + + if ((DevicePath != NULL) && (FilePath != NULL) && (FileBuffer != NULL) && (FileBufferSize != NULL)) { + Status = EFI_NOT_FOUND; + + *FileBuffer = NULL; + *FileBufferSize = 0; + + WholeDevicePath = AppendFileNameDevicePath (DevicePath, FilePath); + + if (WholeDevicePath != NULL) { + *FileBuffer = ReadFileFromDevicePath (WholeDevicePath, FileBufferSize); + + if (*FileBuffer != NULL) { + Status = EFI_SUCCESS; + } + + } + } + + return Status; +} + diff --git a/Library/OcFileLib/ReadFvFile.c b/Library/OcFileLib/ReadFvFile.c new file mode 100755 index 00000000..a7d92e87 --- /dev/null +++ b/Library/OcFileLib/ReadFvFile.c @@ -0,0 +1,187 @@ +/** @file + Copyright (C) 2016, The HermitCrabs Lab. All rights reserved. + + All rights reserved. + + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +**/ + +#include +#include + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "OcFileLibInternal.h" + +// ReadFvFile +/** Search for and read a file from a firmware volume + + @param[in] FvFileGuid The guid of the firmware file to read. + @param[out] FileBuffer The address of a buffer with the contents of the file read or NULL + @param[out] FileSize The size of the file read or 0 + + @retval EFI_SUCCESS The file was loaded successfully. + @retval EFI_INVALID_PARAMETER The parameters passed were invalid. + @retval EFI_OUT_OF_RESOURCES The system ran out of memory. +**/ +EFI_STATUS +ReadFvFile ( + IN GUID *FvFileGuid, + OUT VOID **FileBuffer, + OUT UINTN *FileSize + ) +{ + EFI_STATUS Status; + + EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv = NULL; + EFI_COMPRESSION_SECTION *CompressionHeader; + EFI_DECOMPRESS_PROTOCOL *Decompress = NULL; + EFI_FV_FILE_ATTRIBUTES Attributes = 0; + EFI_FV_FILETYPE Type = 0; + EFI_HANDLE *FvHandleBuffer; + UINT32 AuthenticationStatus = 0; + UINTN Index; + UINTN FvHandleCount; + UINT8 *FvFileBuffer = NULL; + UINTN FvFileSize = 0; + UINT8 *DestinationBuffer; + VOID *ScratchBuffer; + UINT32 DestinationSize; + UINT32 ScratchSize; + + Status = EFI_INVALID_PARAMETER; + + if ((FvFileGuid != NULL) && (FileBuffer != NULL) & (FileSize != NULL)) { + Status = gBS->LocateHandleBuffer ( + ByProtocol, + &gEfiFirmwareVolume2ProtocolGuid, + NULL, + &FvHandleCount, + &FvHandleBuffer + ); + + if (!EFI_ERROR (Status)) { + for (Index = 0; Index < FvHandleCount; ++Index) { + Status = gBS->HandleProtocol ( + FvHandleBuffer[Index], + &gEfiFirmwareVolume2ProtocolGuid, + (VOID **)&Fv + ); + + if (!EFI_ERROR (Status)) { + Status = Fv->ReadFile ( + Fv, + FvFileGuid, + (VOID **)&FvFileBuffer, + &FvFileSize, + &Type, + &Attributes, + &AuthenticationStatus + ); + + if (!EFI_ERROR (Status)) { + CompressionHeader = (EFI_COMPRESSION_SECTION *)FvFileBuffer; + + if (CompressionHeader->CommonHeader.Type == EFI_SECTION_COMPRESSION) { + if (CompressionHeader->CompressionType == EFI_NOT_COMPRESSED) { + // The stream is not actually compressed, just encapsulated. So just copy it. + + *FileBuffer = AllocatePool (FvFileSize - sizeof (*CompressionHeader)); + Status = EFI_OUT_OF_RESOURCES; + + if (*FileBuffer != NULL) { + *FileSize = (FvFileSize - sizeof (*CompressionHeader)); + + CopyMem (*FileBuffer, FvFileBuffer + sizeof (*CompressionHeader), *FileSize); + + Status = EFI_SUCCESS; + } + } else { + Status = gBS->LocateProtocol ( + &gEfiDecompressProtocolGuid, + NULL, + (VOID **)&Decompress + ); + + if (EFI_ERROR (Status)) { + Status = EFI_NOT_FOUND; + } else { + // Retrieve buffer size requirements for decompression + + Status = Decompress->GetInfo ( + Decompress, + (CompressionHeader + 1), + ((UINT32)FvFileSize - sizeof (*CompressionHeader)), + &DestinationSize, + &ScratchSize + ); + + if (EFI_ERROR (Status)) { + continue; + } + + DestinationBuffer = AllocatePool (DestinationSize); + ScratchBuffer = AllocatePool (ScratchSize); + Status = EFI_OUT_OF_RESOURCES; + + if ((DestinationBuffer != NULL) && (ScratchBuffer != NULL)) { + Status = Decompress->Decompress ( + Decompress, + (CompressionHeader + 1), + ((UINT32)FvFileSize - sizeof (*CompressionHeader)), + DestinationBuffer, + DestinationSize, + ScratchBuffer, + ScratchSize + ); + + if (!EFI_ERROR (Status)) { + *FileBuffer = (DestinationBuffer + sizeof (*CompressionHeader)); + *FileSize = (DestinationSize - sizeof (*CompressionHeader)); + } + + FreePool (ScratchBuffer); + } + } + } + } else { + *FileBuffer = AllocatePool (FvFileSize - sizeof (EFI_COMMON_SECTION_HEADER)); + Status = EFI_OUT_OF_RESOURCES; + + if (*FileBuffer != NULL) { + *FileSize = (FvFileSize - sizeof (EFI_COMMON_SECTION_HEADER)); + + CopyMem (*FileBuffer, (FvFileBuffer + sizeof (EFI_COMMON_SECTION_HEADER)), *FileSize); + + Status = EFI_SUCCESS; + } + } + break; + } + } + } + } + } + + return Status; +} diff --git a/Library/OcFileLib/WriteFile.c b/Library/OcFileLib/WriteFile.c new file mode 100755 index 00000000..ee38f7eb --- /dev/null +++ b/Library/OcFileLib/WriteFile.c @@ -0,0 +1,186 @@ +/** @file + Copyright (C) 2016 - 2018, The HermitCrabs Lab. All rights reserved. + + All rights reserved. + + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +**/ + +#include + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "OcFileLibInternal.h" + +// SaveFile +/** Save filebuffer to device path + + @param[in] DevicePath The device path for the device. + @param[in] DirectoryPath The directory path to place the file on the device. + @param[in] FilePath The filename to use when saving the file on the device. + @param[out] FileBuffer A pointer to a buffer containing the file read or NULL + @param[out] FileSize The size of the file buffer to save + + @retval EFI_SUCCESS The platform detection executed successfully. +**/ +EFI_STATUS +SaveFile ( + IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, + IN CHAR16 *Directory, + IN CHAR16 *FileName, + IN VOID *FileBuffer, + IN UINTN FileSize + ) +{ + EFI_STATUS Status; + CHAR16 *FilePath; + UINTN FilePathSize; + + DEBUG_FUNCTION_ENTRY (DEBUG_VERBOSE); + + Status = EFI_INVALID_PARAMETER; + + if (DevicePath != NULL && Directory != NULL && FileName != NULL && FileName != NULL && FileSize != 0) { + + Status = EFI_OUT_OF_RESOURCES; + FilePathSize = StrSize (Directory) + StrSize (FileName); + FilePath = AllocateZeroPool (FilePathSize); + + if (FilePath != NULL) { + + StrCpyS (FilePath, FilePathSize, Directory); + StrCatS (FilePath, FilePathSize, FileName); + + Status = WriteFilePath ( + DevicePath, + FilePath, + FileBuffer, + FileSize, + EFI_FILE_ARCHIVE + ); + + FreePool (FilePath); + + } + } + + DEBUG_FUNCTION_RETURN (DEBUG_VERBOSE); + + return Status; +} + +// WriteFilePath +/** Write file to device path + + @param[in] DevicePath The device path to the device to create the file on. + @param[in] FilePath The full path to use when writing the file on the device. + @param[in] FileBuffer A pointer to a buffer containing the file contents. + @param[in] FileSize The size of the file buffer to save + @param[in] Attributes + + @retval EFI_SUCCESS The platform detection executed successfully. +**/ +EFI_STATUS +WriteFilePath ( + IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, + IN CHAR16 *FilePath, + IN VOID *FileBuffer, + IN UINTN FileSize, + IN UINT64 Attributes + ) +{ + EFI_STATUS Status; + EFI_FILE *Folder; + EFI_FILE *File; + + EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *FileSystem; + + Status = EFI_INVALID_PARAMETER; + + // Allow creation of zero length files + + if (DevicePath != NULL && FilePath != NULL && FileBuffer != NULL) { + + // Open the Filesystem on our DevicePath. + + FileSystem = NULL; + Status = OpenFileSystem ( + &DevicePath, + &FileSystem + ); + + if (!EFI_ERROR (Status)) { + +Reopen: + + Folder = NULL; + Status = FileSystem->OpenVolume ( + FileSystem, + &Folder + ); + + if (!EFI_ERROR (Status)) { + + // Now we can try to open the target file on our filesystem. + + File = NULL; + Status = Folder->Open ( + Folder, + &File, + FilePath, + EFI_FILE_MODE_CREATE | EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE, + Attributes + ); + + if (EFI_ERROR (Status)) { + + if (Status == EFI_MEDIA_CHANGED) { + goto Reopen; + } + + } else { + + Status = File->Write ( + File, + &FileSize, + FileBuffer + ); + } + + if (File != NULL) { + File->Close (File); + } + + } + + if (Folder != NULL) { + Folder->Close (Folder); + } + + } + + } + + return Status; + +} diff --git a/Library/OcMiscLib/Base64Decode.c b/Library/OcMiscLib/Base64Decode.c new file mode 100755 index 00000000..21cdd3ed --- /dev/null +++ b/Library/OcMiscLib/Base64Decode.c @@ -0,0 +1,271 @@ +/** @file + Copyright (C) 2016, The HermitCrabs Lab. All rights reserved. + + All rights reserved. + + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +**/ + +#include + +#include +#include +#include +#include +#include + +STATIC CONST INT8 mDecoding[] = { + 62, + -1, + -1, + -1, + 63, + 52, + 53, + 54, + 55, + 56, + 57, + 58, + 59, + 60, + 61, + -1, + -1, + -1, + -2, + -1, + -1, + -1, + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + -1, + -1, + -1, + -1, + -1, + -1, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51 +}; + +// BASE64_DECODE_STEP +typedef enum { + StepA, + StepB, + StepC, + StepD +} BASE64_DECODE_STEP; + +// BASE64_DECODE_STATE +typedef struct { + BASE64_DECODE_STEP Step; + UINT8 PlainChar; +} BASE64_DECODE_STATE; + +INT32 +Base64DecodeValue ( + IN UINT8 Value + ) +{ + INT32 Result; + + Value -= 43; + Result = -1; + + if ((Value >= 0) && (Value <= sizeof (mDecoding))) { + Result =mDecoding[Value]; + } + + return Result; +} + +VOID +Base64InitDecodeState ( + IN BASE64_DECODE_STATE *StateIn + ) +{ + StateIn->Step = StepA; + StateIn->PlainChar = 0; +} + +UINTN +Base64DecodeBlock ( + IN CONST UINT8 *Code, + IN UINTN Size, + IN UINT8 *PlainText, + IN BASE64_DECODE_STATE *State + ) +{ + CONST UINT8 *codechar = Code; + + UINT8 *plainchar = PlainText; + INT32 fragment; + + *plainchar = State->PlainChar; + + switch (State->Step) { + while (TRUE) { + case StepA: + { + do { + if (codechar == Code + Size) { + State->Step = StepA; + State->PlainChar = *plainchar; + + return (plainchar - PlainText); + } + + fragment = Base64DecodeValue (*codechar++); + } while (fragment < 0); + + *plainchar = ((fragment & 0x3F) << 2); + } + + case StepB: + { + do { + if (codechar == Code + Size) { + State->Step = StepB; + State->PlainChar = *plainchar; + + return (plainchar - PlainText); + } + fragment = Base64DecodeValue (*codechar++); + } while (fragment < 0); + + *plainchar++ |= (fragment & 0x030) >> 4; + *plainchar = (fragment & 0x00f) << 4; + } + + case StepC: + { + do { + if (codechar == Code + Size) { + State->Step = StepC; + State->PlainChar = *plainchar; + + return (plainchar - PlainText); + } + + fragment = Base64DecodeValue (*codechar++); + } while (fragment < 0); + + *plainchar++ |= (fragment & 0x03c) >> 2; + *plainchar = (fragment & 0x003) << 6; + } + + case StepD: + { + do { + if (codechar == (Code + Size)) { + State->Step = StepD; + State->PlainChar = *plainchar; + + return (plainchar - PlainText); + } + + fragment = Base64DecodeValue (*codechar++); + } while (fragment < 0); + + *plainchar++ |= (fragment & 0x03f); + } + } + } + + // control should not reach here + return plainchar - PlainText; +} + +/** UEFI interface to base64 decode. + + Decodes EncodedData into a new allocated buffer and returns it. Caller is responsible to FreePool() it. + If DecodedSize != NULL, then size of decoded data is put there. +**/ +UINT8 * +Base64Decode ( + IN UINT8 *EncodedData, + IN UINTN EncodedDataLength, + OUT UINTN *DecodedSize + ) +{ + UINT8 *DecodedData; + + BASE64_DECODE_STATE DecodeState; + + DecodedData = NULL; + + if ((EncodedData != NULL) && (EncodedDataLength != 0)) { + // to simplify, we'll allocate the same size, although smaller size is needed + DecodedData = AllocateZeroPool (EncodedDataLength); + + Base64InitDecodeState (&DecodeState); + + *DecodedSize = Base64DecodeBlock ( + EncodedData, + EncodedDataLength, + DecodedData, + &DecodeState + ); + + if (*DecodedSize == 0) { + DecodedData = NULL; + } + } + + return DecodedData; +} diff --git a/Library/OcMiscLib/ConvertDataToString.c b/Library/OcMiscLib/ConvertDataToString.c new file mode 100755 index 00000000..5d4875a9 --- /dev/null +++ b/Library/OcMiscLib/ConvertDataToString.c @@ -0,0 +1,174 @@ +/** @file + Copyright (C) 2016, The HermitCrabs Lab. All rights reserved. + + All rights reserved. + + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +**/ + +#include + +#include + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +// ConvertDataToString +/** Attempt to convert the data into an ascii string. + + @param[in] Data A pointer to the data to convert. + @param[in] DataSize The length of data to convert. + + @retval An ascii string representing the data. +**/ +CHAR8 * +ConvertDataToString ( + IN VOID *Data, + IN UINTN DataSize + ) +{ + CHAR8 *OutputBuffer; + + CHAR8 *String; + UINT8 *VariableData; + UINT8 *Base; + UINTN VariableSize; + UINTN OutputLength; + UINTN Index; + BOOLEAN IsAscii; + //BOOLEAN IsNullTerminated; + BOOLEAN IsUnicode; + + OutputBuffer = NULL; + + if ((Data != NULL) && (DataSize != 0) && (DataSize <= 256)) { + IsAscii = FALSE; + //IsNullTerminated = FALSE; + IsUnicode = FALSE; + VariableData = Data; + VariableSize = DataSize; + + // Detect Unicode String + if ((IS_ASCII (*(CHAR16 *)VariableData) > 0) && (DataSize > sizeof (CHAR16))) { + IsUnicode = TRUE; + + do { + if (!IsAsciiPrint ((CHAR8)(*(CHAR16 *)VariableData))) { + IsUnicode = FALSE; + } + + VariableData += sizeof (CHAR16); + VariableSize -= sizeof (CHAR16); + } while (VariableSize > sizeof (CHAR16)); + + // Check Last Unicode Character + + if ((*(CHAR16 *)VariableData == 0) && IsUnicode) { + //IsNullTerminated = TRUE; + } else if (!IsAsciiPrint ((CHAR8)*(CHAR16 *)VariableData)) { + IsUnicode = FALSE; + } + + } else if ((IS_ASCII (*(CHAR8 *)VariableData) > 0) && (DataSize > sizeof (CHAR8))) { + IsAscii = TRUE; + + // Detect Ascii String + do { + if (!IsAsciiPrint (*(CHAR8 *)VariableData)) { + IsAscii = FALSE; + } + + ++VariableData; + --VariableSize; + } while (VariableSize > sizeof (CHAR8)); + + // Check Last Ascii Character + + if ((*(CHAR8 *)VariableData == 0) && IsAscii) { + //IsNullTerminated = TRUE; + } else if (!IsAsciiPrint (*(CHAR8 *)VariableData)) { + IsAscii = FALSE; + } + } + + // Support Max 128 Chars + OutputLength = MIN (128, DataSize); + + // Create Buffer Adding Space for Quotes and Null Terminator + OutputBuffer = AllocateZeroPool ((UINTN)MultU64x32 (OutputLength, 4)); + + if (OutputBuffer != NULL) { + Base = Data; + String = OutputBuffer; + + if (IsAscii) { + // Create "AsciiString" Output + + *(String++) = '\"'; + + do { + + if (*Base == '\0' || DataSize == 0) { + break; + } + + *(String++) = *(Base++); + + } while ((--OutputLength > 0) && (--DataSize > 0)); + + *(String++) = '\"'; + *(String++) = '\0'; + + } else if (IsUnicode ) { + // Create "UnicodeString" Output + + *(String++) = '\"'; + + do { + if (*(CHAR16 *)Base == L'\0' || DataSize == 0) { + break; + } + + *(String++) = (CHAR8)*(CHAR16 *)Base; + + Base += sizeof (CHAR16); + DataSize -= sizeof (CHAR16); + + } while ((--OutputLength > 0) && (DataSize > 0)); + + *(String++) = '\"'; + *(String++) = '\0'; + + } else { + // Create Hex String Output + for (Index = 0; Index < MIN (32, OutputLength); Index++) { + OcSPrint (&OutputBuffer[Index * 3], 4, OUTPUT_ASCII, "%02X ", Base[Index]); + } + } + } + } + + return OutputBuffer; +} diff --git a/Library/OcMiscLib/LegacyRegionLock.c b/Library/OcMiscLib/LegacyRegionLock.c new file mode 100755 index 00000000..3674fe1b --- /dev/null +++ b/Library/OcMiscLib/LegacyRegionLock.c @@ -0,0 +1,84 @@ +/** @file + Copyright (C) 2016, The HermitCrabs Lab. All rights reserved. + + All rights reserved. + + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +**/ + +#include + +#include + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +// LegacyRegionlock +/** Lock the legacy region specified to enable modification. + + @param[in] LegacyAddress The address of the region to lock. + @param[in] LegacyLength The size of the region to lock. + + @retval EFI_SUCCESS The region was locked successfully. +**/ +EFI_STATUS +LegacyRegionLock ( + IN UINT32 LegacyAddress, + IN UINT32 LegacyLength + ) +{ + EFI_STATUS Status; + + EFI_LEGACY_REGION_PROTOCOL *LegacyRegionProtocol; + UINT32 Granularity; + + LegacyRegionProtocol = NULL; + Status = gBS->LocateProtocol ( + &gEfiLegacyRegionProtocolGuid, + NULL, + (VOID **) &LegacyRegionProtocol + ); + + if (!EFI_ERROR (Status) && (LegacyRegionProtocol != NULL)) { + // Lock Region Using LegacyRegionProtocol + + Granularity = 0; + Status = LegacyRegionProtocol->Lock ( + LegacyRegionProtocol, + LegacyAddress, + LegacyLength, + &Granularity + ); + DEBUG (( + DEBUG_INFO, + "Lock LegacyRegion 0x%0X-0x%0X - %r\n", + LegacyAddress, + (LegacyAddress + (LegacyLength - 1)), + Status + )); + } + + return Status; +} diff --git a/Library/OcMiscLib/LegacyRegionUnLock.c b/Library/OcMiscLib/LegacyRegionUnLock.c new file mode 100755 index 00000000..bf44f64d --- /dev/null +++ b/Library/OcMiscLib/LegacyRegionUnLock.c @@ -0,0 +1,85 @@ +/** @file + Copyright (C) 2016, The HermitCrabs Lab. All rights reserved. + + All rights reserved. + + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +**/ + +#include + +#include + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +// LegacyRegionUnlock +/** Unlock the legacy region specified to enable modification. + + @param[in] LegacyAddress The address of the region to unlock. + @param[in] LegacyLength The size of the region to unlock. + + @retval EFI_SUCCESS The region was unlocked successfully. +**/ +EFI_STATUS +LegacyRegionUnlock ( + IN UINT32 LegacyAddress, + IN UINT32 LegacyLength + ) +{ + EFI_STATUS Status; + + EFI_LEGACY_REGION_PROTOCOL *LegacyRegionProtocol; + UINT32 Granularity; + + Status = gBS->LocateProtocol ( + &gEfiLegacyRegionProtocolGuid, + NULL, + (VOID **) &LegacyRegionProtocol + ); + + if (!EFI_ERROR (Status) && (LegacyRegionProtocol != NULL)) { + // Unlock Region Using LegacyRegionProtocol + + Granularity = 0; + Status = LegacyRegionProtocol->UnLock ( + LegacyRegionProtocol, + LegacyAddress, + LegacyLength, + &Granularity + ); + + DEBUG (( + DEBUG_INFO, + "Unlock LegacyRegion 0x%0X-0x%0X - %r\n", + LegacyAddress, + (LegacyAddress + (LegacyLength - 1)), + Status + )); + } + + return Status; +} + diff --git a/Library/OcMiscLib/LogBootOrder.c b/Library/OcMiscLib/LogBootOrder.c new file mode 100755 index 00000000..c862c77d --- /dev/null +++ b/Library/OcMiscLib/LogBootOrder.c @@ -0,0 +1,109 @@ +/** @file + Copyright (C) 2016 - 2018, The HermitCrabs Lab. All rights reserved. + + All rights reserved. + + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +**/ + +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include + +/** Log the boot options passed + + @param[in] BootOrder A pointer to the boot order list. + @param[in] BootOrderSize Size of the boot order list. + + @retval EFI_SUCCESS The entry point is executed successfully. +**/ +EFI_STATUS +LogBootOrder ( + IN INT16 *BootOrder, + IN UINTN BootOrderSize + ) +{ + EFI_STATUS Status; + CHAR8 *BootOrderString; + INT16 *BootOrderBuffer; + UINTN BootOrderCount; + UINTN Index; + + BootOrderBuffer = NULL; + + if (BootOrder == NULL && BootOrderSize == 0) { + + Status = OcGetVariable ( + "BootOrder", + &gEfiGlobalVariableGuid, + (VOID **)&BootOrderBuffer, + &BootOrderSize + ); + + if (EFI_ERROR (Status)) { + return Status; + } + + if (BootOrder == NULL || BootOrderSize == 0) { + return EFI_NOT_FOUND; + } + + BootOrder = BootOrderBuffer; + + } else if (BootOrder == NULL || BootOrderSize == 0) { + return EFI_INVALID_PARAMETER; + } + + Status = EFI_OUT_OF_RESOURCES; + + BootOrderCount = (UINTN)DivU64x32 (BootOrderSize, sizeof (INT16)); + + BootOrderString = AllocateZeroPool (BootOrderCount * 4); + + if (BootOrderString != NULL) { + + Status = EFI_SUCCESS; + + // Create hex ascii string representation of BootOrder variable + for (Index = 0; Index < BootOrderCount; Index++) { + + OcSPrint ( + &BootOrderString[Index * 3], + 4, + FORMAT_ASCII | OUTPUT_ASCII, + "%02X ", + BootOrder[Index]); + } + + // Remove any trailing white space + *(BootOrderString + Index * 3 - sizeof (CHAR8)) = '\0'; + + // Log BootOrder variable string + LOG ((EFI_D_INFO, "%a %a\n", "BootOrder", BootOrderString)); + + FreePool (BootOrderString); + + } + + if (BootOrderBuffer != NULL) { + FreePool (BootOrderString); + } + + return Status; +} diff --git a/Library/OcMiscLib/LogHexDump.c b/Library/OcMiscLib/LogHexDump.c new file mode 100755 index 00000000..2767cfc3 --- /dev/null +++ b/Library/OcMiscLib/LogHexDump.c @@ -0,0 +1,102 @@ +/** @file + Copyright (C) 2016, The HermitCrabs Lab. All rights reserved. + + All rights reserved. + + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +**/ + +#include +#include + +#include +#include +#include +#include + +#include +#include + +// +// +// + +EFI_STATUS +LogHexDump ( + IN VOID *Address, + IN VOID *Address2, + IN UINTN Length, + IN UINTN LineSize, + IN BOOLEAN DisplayAscii + ) +{ + CHAR8 *HexString; + CHAR8 *AsciiString; + UINT8 *Base; + UINTN DisplayAddress; + UINTN Index; + UINTN LineLength; + + if (Length == 0 || LineSize == 0) { + return EFI_INVALID_PARAMETER; + } + + HexString = AllocateZeroPool (LineSize * 4 + sizeof(CHAR8)); + AsciiString = AllocateZeroPool (LineSize + sizeof(CHAR8)); + + if (HexString == NULL || AsciiString == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + Base = (UINT8 *)Address; + + DisplayAddress = (UINTN)Address2; + + // Iterate + + do { + + LineLength = MIN (LineSize, Length); + + for (Index = 0; Index < LineLength; Index++) { + OcSPrint (&HexString[Index * 3], 4, OUTPUT_ASCII, "%02X ", (UINT8)(Base[Index])); + OcSPrint (&AsciiString[Index], 2, OUTPUT_ASCII, "%c", IsAsciiPrint (Base[Index]) ? Base[Index] : '.'); + } + + if (DisplayAscii == TRUE) { + + DEBUG ((DEBUG_INFO, "0x%0*X %-*a%-*a\n", + 4, + DisplayAddress, + LineSize * 3, + HexString, + LineSize, + AsciiString)); + } else { + + DEBUG ((DEBUG_INFO, "0x%0*X %-*a\n", + 4, + DisplayAddress, + LineSize * 3, + HexString, + LineSize)); + } + + DisplayAddress += LineLength; + + Base += LineLength; + Length -= LineLength; + + } while (Length > 0); + + //FreePool (AsciiString); + FreePool (HexString); + + return EFI_SUCCESS; +} diff --git a/Library/OcMiscLib/OcMiscLib.inf b/Library/OcMiscLib/OcMiscLib.inf new file mode 100755 index 00000000..3a010907 --- /dev/null +++ b/Library/OcMiscLib/OcMiscLib.inf @@ -0,0 +1,55 @@ +## @file +# +# Component description file for OcMisclibrary. +# +# Copyright (C) 2016 - 2018, The HermitCrabs Lab. All rights reserved.
+# +# All rights reserved. +# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# +# 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 = OcMiscLib + FILE_GUID = E9DF6F29-95AC-429A-8E42-FCE1F5B81148 + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = OcMiscLib|PEIM DXE_DRIVER DXE_RUNTIME_DRIVER UEFI_DRIVER UEFI_APPLICATION DXE_SMM_DRIVER + +# VALID_ARCHITECTURES = IA32 X64 + +[Packages] + OcSupportPkg/OcSupportPkg.dec + IntelFrameworkPkg/IntelFrameworkPkg.dec + EfiPkg/EfiPkg.dec + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + +[Guids] + gEfiProcessorSubClassGuid ## SOMETIMES_CONSUMES + gEfiMiscSubClassGuid ## SOMETIMES_CONSUMES + gApplePlatformProducerNameGuid + +[Protocols] + gEfiDataHubProtocolGuid ## SOMETIMES_CONSUMES + gEfiLegacyRegionProtocolGuid + +[LibraryClasses] + BaseLib + +[Sources] + Base64Decode.c + ConvertDataToString.c + LegacyRegionLock.c + LegacyRegionUnLock.c + LogBootOrder.c + LogHexDump.c + SetPlatformData.c diff --git a/Library/OcMiscLib/SetPlatformData.c b/Library/OcMiscLib/SetPlatformData.c new file mode 100755 index 00000000..9b7cb682 --- /dev/null +++ b/Library/OcMiscLib/SetPlatformData.c @@ -0,0 +1,125 @@ +/** @file + Copyright (C) 2016, The HermitCrabs Lab. All rights reserved. + + All rights reserved. + + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +**/ + +#include + +#include + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +// SetPlatformData +/** + + @param[in] DataRecordGuid The guid of the record to use. + @param[in] Key A pointer to the ascii key string. + @param[in] Data A pointer to the data to store. + @param[in] DataSize The length of the data to store. + + @retval EFI_SUCCESS The datahub was updated successfully. +**/ +EFI_STATUS +SetPlatformData ( + IN EFI_GUID *DataRecordGuid, + IN CHAR8 *Key, + IN VOID *Data, + IN UINT32 DataSize + ) +{ + EFI_STATUS Status; + + EFI_DATA_HUB_PROTOCOL *DataHub; + PLATFORM_DATA_HEADER *Entry; + CHAR8 *DataString; + UINT32 KeySize; + + // Locate DataHub + DataHub = NULL; + Status = gBS->LocateProtocol ( + &gEfiDataHubProtocolGuid, + NULL, + (VOID **)&DataHub + ); + + if (!EFI_ERROR (Status)) { + KeySize = (UINT32)(AsciiStrSize (Key) * (sizeof (CHAR16))); + Entry = AllocateZeroPool (DataSize + sizeof (Entry->Hdr) + KeySize); + Status = EFI_OUT_OF_RESOURCES; + + if (Entry) { + + Entry->Hdr.KeySize = KeySize; + Entry->Hdr.DataSize = DataSize; + DataString = NULL; + + OcAsciiStrToUnicode (Key, (CHAR16 *)(((UINTN)Entry) + sizeof (Entry->Hdr)), 0); + + CopyMem ((VOID *)(((UINTN)Entry) + sizeof (Entry->Hdr) + Entry->Hdr.KeySize), Data, (UINTN)Entry->Hdr.DataSize); + + Status = DataHub->LogData ( + DataHub, + DataRecordGuid, + &gApplePlatformProducerNameGuid, + EFI_DATA_RECORD_CLASS_DATA, + Entry, + (sizeof (Entry->Hdr) + Entry->Hdr.KeySize + Entry->Hdr.DataSize) + ); + + if (DataSize < 32) { + DataString = ConvertDataToString (Data, DataSize); + } + + if (DataString != NULL) { + DEBUG (( + DEBUG_INFO, + "Setting DataHub %g:%a = %a (%d)\n", + &gApplePlatformProducerNameGuid, + Key, + DataString, + DataSize + )); + + FreePool ((VOID *)DataString); + } else { + DEBUG (( + DEBUG_INFO, + "Setting DataHub %g:%a (%d)\n", + &gApplePlatformProducerNameGuid, + Key, + DataSize + )); + } + + FreePool ((VOID *)Entry); + } + } + + return Status; +} diff --git a/Library/OcPrintLib/GuidTable.c b/Library/OcPrintLib/GuidTable.c new file mode 100755 index 00000000..2005170e --- /dev/null +++ b/Library/OcPrintLib/GuidTable.c @@ -0,0 +1,105 @@ +/** @file + Copyright (C) 2016, The HermitCrabs Lab. All rights reserved. + + All rights reserved. + + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +**/ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "GuidTable.h" + +GLOBAL_REMOVE_IF_UNREFERENCED CONST GUID_NAME_MAP GuidStringMap[] = { + // Apple Guids + + { &gEfiDevicePathPropertyDatabaseProtocolGuid, "AppleDevicePathPropertyDatabaseProtocol" }, + { &gAppleFirmwarePasswordProtocolGuid, "AppleFirmwarePasswordProtocol" }, + { &gAppleKeyMapAggregatorProtocolGuid, "AppleKeyMapAggregatorProtocol" }, + { &gAppleKeyMapDatabaseProtocolGuid, "AppleKeyMapDatabaseProtocol" }, + + // Tianocore Guids + + { &gEfiDecompressProtocolGuid, "EfiDecompressProtocol" }, + + { &gLzmaCustomDecompressGuid, "LZMA Compress" }, + + { &gEfiAcpiTableGuid, "ACPI Table" }, + { &gEfiAcpi10TableGuid, "ACPI 1.0 Table" }, + { &gEfiAcpi20TableGuid, "ACPI 2.0 Table" }, + + { &gEfiDxeServicesTableGuid, "DXE Services" }, + { &gEfiSalSystemTableGuid, "SAL System Table" }, + + { &gEfiSmbiosTableGuid, "SMBIOS Table" }, + { &gEfiSmbios3TableGuid, "SMBIOS 3 Table" }, + + { &gEfiMpsTableGuid, "MPS Table" }, + { &gEfiHobListGuid, "HOB List Table" }, + { &gEfiMemoryTypeInformationGuid, "Memory Type Information" }, + + { &gEfiPropertiesTableGuid, "EFI Propterties Table" }, + { &gEfiDebugImageInfoTableGuid, "EFI Debug Image Info Table" }, + { &gEfiSystemResourceTableGuid, "EFI System Resource Table" }, + + { NULL, NULL } +}; + +// OcGuidToString +/** + + @param[in] Guid A pointer to the guid to convert to string. + + @retval A pointer to the buffer containg the string representation of the guid. +**/ +CHAR8 * +EFIAPI +OcGuidToString ( + IN EFI_GUID *Guid + ) +{ + UINTN Index; + + STATIC CHAR8 GuidStringBuffer[36]; + + for (Index = 0; GuidStringMap[Index].Guid != NULL; ++Index) { + if (CompareGuid (GuidStringMap[Index].Guid, Guid)) { + return GuidStringMap[Index].ShortName; + } + } + + // Output numeric version of guid instead. + OcSPrint (&GuidStringBuffer, sizeof (GuidStringBuffer), (FORMAT_ASCII | OUTPUT_ASCII), "%G", Guid); + + return (CHAR8 *)&GuidStringBuffer[0]; +} diff --git a/Library/OcPrintLib/GuidTable.h b/Library/OcPrintLib/GuidTable.h new file mode 100755 index 00000000..17b22c0a --- /dev/null +++ b/Library/OcPrintLib/GuidTable.h @@ -0,0 +1,25 @@ +/** @file + Copyright (C) 2016, The HermitCrabs Lab. All rights reserved. + + All rights reserved. + + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + 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 OC_GUID_TABLE_H_ +#define OC_GUID_TABLE_H_ + +typedef struct { + GUID *Guid; + CHAR8 *ShortName; +} GUID_NAME_MAP; + +extern CONST GUID_NAME_MAP GuidStringMap[]; + +#endif // OC_GUID_TABLE_H_ diff --git a/Library/OcPrintLib/OcPrintLib.c b/Library/OcPrintLib/OcPrintLib.c new file mode 100755 index 00000000..e2ee4c07 --- /dev/null +++ b/Library/OcPrintLib/OcPrintLib.c @@ -0,0 +1,814 @@ +/** @file + Copyright (C) 2016 - 2017, The HermitCrabs Lab. All rights reserved. + + All rights reserved. + + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +**/ + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "GuidTable.h" + +// OcFillBuffer +/** Internal function that places the character into the Buffer. + + Internal function that places ASCII or Unicode character into the Buffer. + + @param[in, out] Buffer Buffer to place the Unicode or ASCII string. + @param[in] EndBuffer The end of the input Buffer. No characters will be placed after that. + @param[in] Length Count of character to be placed into Buffer. + @param[in] Character Character to be placed into Buffer. + @param[in] Increment Character increment in Buffer. + + @return Number of characters printed. +**/ +CHAR8 * +OcFillBuffer ( + IN OUT CHAR8 *Buffer, + IN CHAR8 *EndBuffer, + IN INTN Length, + IN UINTN Character, + IN UINTN Increment + ) +{ + INTN Index; + + for (Index = 0; (Index < Length) && (Buffer < EndBuffer); ++Index) { + Buffer[0] = (CHAR8) Character; + Buffer[1] = (CHAR8) (Character >> 8); + Buffer += Increment; + } + + return Buffer; +} + +// OcValueToString +/** Internal function that convert a decimal number to a string in Buffer. + + Print worker function that convert a decimal number to a string in Buffer. + + @param[in, out] Buffer Location to place the Unicode or ASCII string of Value. + @param[in] Value Value to convert to a Decimal or Hexidecimal string in Buffer. + @param[in] Radix Radix of the value + + @return Number of characters printed. +**/ +UINTN +OcValueToString ( + IN OUT CHAR8 *Buffer, + IN INT64 Value, + IN UINTN Radix, + IN BOOLEAN UpperCase + ) +{ + UINTN Digits; + + UINT32 Remainder; + CHAR8 Digit; + + // Loop to convert one digit at a time in reverse order + + *Buffer = 0; + Digits = 0; + + ++Buffer; + + do { + Value = (INT64)DivU64x32Remainder ((UINT64)Value, (UINT32)Radix, &Remainder); + Digit = mOcPrintLibHexStr[Remainder]; + *Buffer = (CHAR8)(UpperCase ? (((Digit >= 'A') && (Digit <= 'Z')) ? (Digit + ('a' - 'A')) : Digit) : Digit); + + ++Buffer; + ++Digits; + } while (Value != 0); + + return Digits; +} + +// OcVSPrint +/** + + @param[out] Buffer A pointer to the character buffer to print the results of the parsing of Format into. + @param[in] BufferSize Maximum number of characters to put into buffer. Zero means no limit. + @param[in] Flags Intial flags value. Can only have FORMAT_UNICODE and OUTPUT_UNICODE set. + @param[in] Format A pointer a Null-terminated format string which describes the VA_ARGS list. + @param[in] Marker A pointer to the VA_ARGS list + + @retval EFI_SUCCESS The platform detection executed successfully. +**/ +UINTN +EFIAPI +OcVSPrint ( + OUT CHAR8 *Buffer, + IN UINTN BufferSize, + IN UINTN Flags, + IN CONST CHAR8 *Format, + IN VA_LIST Marker + ) +{ + UINTN Result; + + CHAR8 *OriginalBuffer; + CHAR8 *EndBuffer; + CHAR8 ValueBuffer[MAXIMUM_VALUE_CHARACTERS]; + UINTN BytesPerOutputCharacter; + UINTN BytesPerFormatCharacter; + UINTN FormatMask; + UINTN FormatCharacter; + UINTN Width; + UINTN Precision; + INT64 Value; + CONST CHAR8 *ArgumentString; + UINTN Character; + EFI_GUID *TmpGuid; + EFI_TIME *TmpTime; + UINTN Count; + UINTN ArgumentMask; + INTN BytesPerArgumentCharacter; + UINTN ArgumentCharacter; + BOOLEAN Done; + UINTN Index; + CHAR8 Prefix; + BOOLEAN ZeroPad; + BOOLEAN Comma; + UINTN Digits; + UINTN Radix; + EFI_STATUS Status; + + Result = 0; + + if (BufferSize != 0) { + //ASSERT (Buffer != NULL); + + BytesPerOutputCharacter = (((Flags & OUTPUT_UNICODE) != 0) ? 2 : 1); + + // Reserve space for the Null terminator. + + --BufferSize; + OriginalBuffer = Buffer; + + // Set the tag for the end of the input Buffer. + EndBuffer = (Buffer + (BufferSize * BytesPerOutputCharacter)); + + if ((Flags & FORMAT_UNICODE) != 0) { + // Make sure format string cannot contain more than PcdMaximumUnicodeStringLength + // Unicode characters if PcdMaximumUnicodeStringLength is not zero. + + //ASSERT (StrSize ((CHAR16 *) Format) != 0); + BytesPerFormatCharacter = sizeof (CHAR16); + FormatMask = MAX_UINT16; + } else { + // Make sure format string cannot contain more than PcdMaximumAsciiStringLength + // Ascii characters if PcdMaximumAsciiStringLength is not zero. + + //ASSERT (AsciiStrSize (Format) != 0); + BytesPerFormatCharacter = sizeof (CHAR8); + FormatMask = MAX_UINT8; + } + + // Get the first character from the format string + FormatCharacter = ((*Format | (*(Format + 1) << 8)) & FormatMask); + + // Loop until the end of the format string is reached or the output buffer is full + while ((FormatCharacter != 0) && (Buffer < EndBuffer)) { + // Clear all the flag bits except those that may have been passed in + Flags &= (OUTPUT_UNICODE | FORMAT_UNICODE); + + // Set the default width to zero, and the default precision to 1 + + Width = 0; + Precision = 1; + Prefix = 0; + Comma = FALSE; + ZeroPad = FALSE; + Count = 0; + Digits = 0; + + switch (FormatCharacter) { + case '%': + { + // Parse Flags and Width + + Done = FALSE; + + while (!Done) { + Format += BytesPerFormatCharacter; + FormatCharacter = ((*Format | (*(Format + 1) << 8)) & FormatMask); + + switch (FormatCharacter) { + case '.': + { + Flags |= PRECISION; + break; + } + + case '-': + { + Flags |= LEFT_JUSTIFY; + break; + } + + case '+': + { + Flags |= PREFIX_SIGN; + break; + } + + case ' ': + { + Flags |= PREFIX_BLANK; + break; + } + + case ',': + { + Flags |= COMMA_TYPE; + break; + } + + case 'L': + case 'l': + { + Flags |= LONG_TYPE; + break; + } + + case '*': + { + if ((Flags & PRECISION) == 0) { + Flags |= PAD_TO_WIDTH; + Width = VA_ARG (Marker, UINTN); + } else { + Precision = VA_ARG (Marker, UINTN); + } + + break; + } + + case '0': + { + if ((Flags & PRECISION) == 0) { + Flags |= PREFIX_ZERO; + } + } + + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + { + Count = 0; + + while ((FormatCharacter >= '0') && (FormatCharacter <= '9')) { + Count = ((Count * 10) + (FormatCharacter - '0')); + Format += BytesPerFormatCharacter; + FormatCharacter = (*Format | (*(Format + 1) << 8)) & FormatMask; + } + + Format -= BytesPerFormatCharacter; + + if ((Flags & PRECISION) == 0) { + Flags |= PAD_TO_WIDTH; + Width = Count; + } else { + Precision = Count; + } + + break; + } + + case '\0': + { + // Make no output if Format string terminates unexpectedly when + // looking up for flag, width, precision and type. + + Format -= BytesPerFormatCharacter; + Precision = 0; + + // break skipped on purpose. + } + + default: + { + Done = TRUE; + break; + } + } + } + + // Handle each argument type + + switch (FormatCharacter) { + case 'p': + { + // Flag space, +, 0, L & l are invalid for type p. + Flags &= ~(PREFIX_BLANK | PREFIX_SIGN | PREFIX_ZERO | LONG_TYPE); + + if (sizeof (VOID *) > sizeof (UINT32)) { + Flags |= LONG_TYPE; + } + } + + case 'X': + { + Flags |= UPPER_CASE_HEX; + + // break skipped on purpose + } + + case 'x': + { + Flags |= RADIX_HEX; + + // break skipped on purpose + } + + case 'd': + { + if ((Flags & LONG_TYPE) == 0) { + Value = (VA_ARG (Marker, INT32)); + } else { + Value = VA_ARG (Marker, INT64); + } + + if ((Flags & PREFIX_BLANK) != 0) { + Prefix = ' '; + } + + if ((Flags & PREFIX_SIGN) != 0) { + Prefix = '+'; + } + + if ((Flags & COMMA_TYPE) != 0) { + Comma = TRUE; + } + + if ((Flags & RADIX_HEX) == 0) { + Radix = 10; + + if (Comma) { + Flags &= (~PREFIX_ZERO); + Precision = 1; + } + + if (Value < 0) { + Flags |= PREFIX_SIGN; + Prefix = '-'; + Value = -Value; + } + } else { + Radix = 16; + Comma = FALSE; + + if (((Flags & LONG_TYPE) == 0) && (Value < 0)) { + Value = (UINT32)Value; + } + } + + // Convert Value to a reversed string + + Count = OcValueToString (ValueBuffer, Value, Radix, ((Flags & UPPER_CASE_HEX) == 0)); + + if ((Value == 0) && (Precision == 0)) { + Count = 0; + } + + ArgumentString = ((CHAR8 *)ValueBuffer + Count); + Digits = (Count % 3); + + if (Digits != 0) { + Digits = (3 - Digits); + } + + if (Comma && (Count != 0)) { + Count += ((Count - 1) / 3); + } + + if (Prefix != 0) { + ++Count; + ++Precision; + } + + Flags |= ARGUMENT_REVERSED; + ZeroPad = TRUE; + + if (((Flags & (PREFIX_ZERO)) != 0) + && ((Flags & (PAD_TO_WIDTH)) != 0) + && ((Flags & (LEFT_JUSTIFY | PRECISION)) == 0)) { + Precision = Width; + } + + break; + } + + case 'b': + { + if ((Flags & LONG_TYPE) == 0) { + Value = (VA_ARG (Marker, INT32)); + } else { + Value = VA_ARG (Marker, INT64); + } + + // Calculate Precision + + if ((Flags & PRECISION) == 0) { + if ((Value > MAX_UINT32) || ((Flags & LONG_TYPE) != 0)) { + Precision = 64; + } else if (Value > MAX_UINT16) { + Precision = 32; + } else if (Value > MAX_UINT8) { + Precision = 16; + } else { + Precision = 8; + } + } + + Precision = MIN (64, Precision); + + // Convert Value to a reversed binary string + + for (Count = 0; Count < Precision; ++Count) { + ValueBuffer[Count] = ((Value & 1) != 0) ? '1' : '0'; + Value >>= 1; + } + + if ((Value == 0) && (Precision == 0)) { + Count = 0; + } + + ArgumentString = (((CHAR8 *)ValueBuffer + Count) - 1); + Digits = (Count % 3); + + if (Digits != 0) { + Digits = (3 - Digits); + } + + Flags |= ARGUMENT_REVERSED; + + break; + } + + case 's': + case 'S': + { + Flags |= ARGUMENT_UNICODE; + + // break skipped on purpose + } + + case 'a': + { + ArgumentString = (CHAR8 *)VA_ARG (Marker, CHAR8 *); + + if (ArgumentString == NULL) { + Flags &= (~ARGUMENT_UNICODE); + ArgumentString = ""; + } + + break; + } + + case 'c': + { + Character = (VA_ARG (Marker, UINTN) & MAX_UINT16); + ArgumentString = (CHAR8 *)&Character; + Flags |= ARGUMENT_UNICODE; + + break; + } + + case 'G': + case 'g': + { + TmpGuid = VA_ARG (Marker, EFI_GUID *); + + if (TmpGuid == NULL) { + ArgumentString = ""; + } else { + if (TmpGuid != NULL) { + OcSPrint ( + ValueBuffer, + MAXIMUM_VALUE_CHARACTERS, + 0, + "%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X", + TmpGuid->Data1, + TmpGuid->Data2, + TmpGuid->Data3, + TmpGuid->Data4[0], + TmpGuid->Data4[1], + TmpGuid->Data4[2], + TmpGuid->Data4[3], + TmpGuid->Data4[4], + TmpGuid->Data4[5], + TmpGuid->Data4[6], + TmpGuid->Data4[7] + ); + } + + ArgumentString = ValueBuffer; + } + + break; + } + + case 't': + { + TmpTime = VA_ARG (Marker, EFI_TIME *); + + if (TmpTime == NULL) { + ArgumentString = ""; + } else { + OcSPrint ( + ValueBuffer, + MAXIMUM_VALUE_CHARACTERS, + 0, + "%04d-%02d-%02d %02d:%02d:%02d", + TmpTime->Year, + TmpTime->Month, + TmpTime->Day, + TmpTime->Hour, + TmpTime->Minute, + TmpTime->Second + ); + + ArgumentString = ValueBuffer; + } + + break; + } + + case 'r': + { + Status = VA_ARG (Marker, EFI_STATUS); + ArgumentString = ValueBuffer; + + // Only convert the status code to a string for debug builds. + + #if defined (MDEPKG_NDEBUG) + #else + + if (EFI_ERROR (Status)) { + // Clear error bit + + Index = (Status & ~MAX_BIT); + + if ((Index > 0) && (Index <= ERROR_STATUS_NUMBER)) { + ArgumentString = mOcStatusString[Index + WARNING_STATUS_NUMBER]; + } + } else { + Index = Status; + + if (Index <= WARNING_STATUS_NUMBER) { + ArgumentString = mOcStatusString[Index]; + } + } + + #endif + + if (ArgumentString == ValueBuffer) { + OcSPrint ((CHAR8 *)ValueBuffer, MAXIMUM_VALUE_CHARACTERS, 0, "%08X", Status); + } + + break; + } + + case '\n': + { + ArgumentString = (((Flags & OUTPUT_CONSOLE) == 0) ? "\n\r" : "\n"); + + break; + } + + case '%': + default: + { + // if the type is '%' or unknown, then print it to the screen + + ArgumentString = (CHAR8 *)&FormatCharacter; + Flags |= ARGUMENT_UNICODE; + + break; + } + } + + break; + } + case '\n': + ArgumentString = (((Flags & OUTPUT_CONSOLE) == 0) ? "\n\r" : "\n"); + + break; + + default: + ArgumentString = (CHAR8 *)&FormatCharacter; + Flags |= ARGUMENT_UNICODE; + + break; + } + + // Retrieve the ArgumentString attriubutes + + if ((Flags & ARGUMENT_UNICODE) != 0) { + ArgumentMask = MAX_UINT16; + BytesPerArgumentCharacter = sizeof (CHAR16); + } else { + ArgumentMask = MAX_UINT8; + BytesPerArgumentCharacter = sizeof (CHAR8); + } + + if ((Flags & ARGUMENT_REVERSED) != 0) { + BytesPerArgumentCharacter = -BytesPerArgumentCharacter; + } else { + // Compute the number of characters in ArgumentString and store it in Count + // ArgumentString is either null-terminated, or it contains Precision characters + + for (Count = 0; (Count < Precision) || ((Flags & PRECISION) == 0); ++Count) { + ArgumentCharacter = ((ArgumentString[Count * BytesPerArgumentCharacter] + | ((ArgumentString[(Count * BytesPerArgumentCharacter) + 1]) << 8)) & ArgumentMask); + + if (ArgumentCharacter == 0) { + break; + } + } + } + + if (Precision < Count) { + Precision = Count; + } + + // Pad before the string + if ((Flags & (PAD_TO_WIDTH | LEFT_JUSTIFY)) == (PAD_TO_WIDTH)) { + Buffer = OcFillBuffer (Buffer, EndBuffer, (Width - Precision), ' ', BytesPerOutputCharacter); + } + + if (ZeroPad) { + if (Prefix != 0) { + Buffer = OcFillBuffer (Buffer, EndBuffer, sizeof (*Buffer), Prefix, BytesPerOutputCharacter); + } + + Buffer = OcFillBuffer (Buffer, EndBuffer, (Precision - Count), '0', BytesPerOutputCharacter); + } else { + Buffer = OcFillBuffer (Buffer, EndBuffer, (Precision - Count), ' ', BytesPerOutputCharacter); + + if (Prefix != 0) { + Buffer = OcFillBuffer (Buffer, EndBuffer, sizeof (*Buffer), Prefix, BytesPerOutputCharacter); + } + } + + // Output the Prefix character if it is present + + Index = 0; + + if (Prefix != 0) { + ++Index; + } + + // Copy the string into the output buffer performing the required type conversions + + while (Index < Count) { + ArgumentCharacter = ((ArgumentString[0] | (ArgumentString[1] << 8)) & ArgumentMask); + Buffer = OcFillBuffer (Buffer, EndBuffer, sizeof (*Buffer), ArgumentCharacter, BytesPerOutputCharacter); + ArgumentString += BytesPerArgumentCharacter; + ++Index; + + if (Comma) { + ++Digits; + + if (Digits == 3) { + Digits = 0; + ++Index; + + if (Index < Count) { + Buffer = OcFillBuffer (Buffer, EndBuffer, sizeof (*Buffer), ',', BytesPerOutputCharacter); + } + } + } + } + + // Pad after the string + + if (((Flags & PAD_TO_WIDTH) != 0) + && ((Flags & LEFT_JUSTIFY) != 0)) { + Buffer = OcFillBuffer (Buffer, EndBuffer, (Width - Precision), ' ', BytesPerOutputCharacter); + } + + // Get the next character from the format string + Format += BytesPerFormatCharacter; + + // Get the next character from the format string + FormatCharacter = ((Format[0] | (Format[1] << 8)) & FormatMask); + } + + // Null terminate the Unicode or ASCII string + OcFillBuffer (Buffer, EndBuffer + BytesPerOutputCharacter, 1, 0, BytesPerOutputCharacter); + + // Make sure output buffer cannot contain more than PcdMaximumUnicodeStringLength + // Unicode characters if PcdMaximumUnicodeStringLength is not zero. + + //ASSERT ((((Flags & OUTPUT_UNICODE) == 0)) || (StrSize ((CHAR16 *) OriginalBuffer) != 0)); + + // Make sure output buffer cannot contain more than PcdMaximumAsciiStringLength + // ASCII characters if PcdMaximumAsciiStringLength is not zero. + + //ASSERT ((((Flags & OUTPUT_UNICODE) != 0)) || (AsciiStrSize (OriginalBuffer) != 0)); + + Result = (UINTN)((Buffer - OriginalBuffer) / BytesPerOutputCharacter); + } + + return Result; +} + +// OcSPrint +/** + + @param[out] StartOfBuffer A pointer to the character buffer to print the results of the parsing of Format into. + @param[in] BufferSize Maximum number of characters to put into buffer. Zero means no limit. + @param[in] Flags Intial flags value. Can only have FORMAT_UNICODE and OUTPUT_UNICODE set. + @param[in] FormatString A pointer a Null-terminated format string which describes the VA_ARGS list. + @param[in] ... VA_ARGS list + + @retval EFI_SUCCESS The platform detection executed successfully. +**/ +UINTN +EFIAPI +OcSPrint ( + OUT VOID *StartOfBuffer, + IN UINTN BufferSize, + IN UINTN Flags, + IN VOID *FormatString, + ... + ) +{ + VA_LIST Marker; + + VA_START (Marker, FormatString); + + return OcVSPrint (StartOfBuffer, BufferSize, Flags, FormatString, Marker); +} + +// OcLog +/** + + @param[in] ErrorLevel The firmware allocated handle for the EFI image. + @param[in] Format A pointer to the string format list which describes the VA_ARGS list + @param[in] ... VA_ARGS list + + @retval EFI_SUCCESS The platform detection executed successfully. +**/ +VOID +EFIAPI +OcLog ( + IN UINTN ErrorLevel, + IN CONST CHAR8 *Format, + ... + ) +{ + STATIC OC_LOG_PROTOCOL *OcLog = NULL; + + VA_LIST Marker; + EFI_STATUS Status; + + VA_START (Marker, Format); + + // Locate OcLog Protocol Once + + if (OcLog == NULL) { + Status = gBS->LocateProtocol ( + &gOcLogProtocolGuid, + NULL, + (VOID **)&OcLog + ); + + if (EFI_ERROR (Status)) { + goto Return; + } + } + + if (OcLog != NULL) { + OcLog->AddEntry (OcLog, ErrorLevel, Format, Marker); + } + +Return: + VA_END (Marker); +} diff --git a/Library/OcPrintLib/OcPrintLib.inf b/Library/OcPrintLib/OcPrintLib.inf new file mode 100755 index 00000000..d64c240c --- /dev/null +++ b/Library/OcPrintLib/OcPrintLib.inf @@ -0,0 +1,87 @@ +## @file +# +# Component description file for OcPrintLibrary. +# +# Copyright (C) 2016, The HermitCrabs Lab. All rights reserved.
+# +# All rights reserved. +# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# +# 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 = OcPrintLib + FILE_GUID = 5C2EC928-C3A1-4665-8CE9-6D486F3CA2D0 + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = OcPrintLib|PEIM DXE_DRIVER DXE_RUNTIME_DRIVER UEFI_DRIVER UEFI_APPLICATION DXE_SMM_DRIVER + +# VALID_ARCHITECTURES = IA32 X64 + +[Packages] + OcSupportPkg/OcSupportPkg.dec + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + IntelFrameworkPkg/IntelFrameworkPkg.dec + IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec + EfiPkg/EfiPkg.dec + +[Guids] + # gEfiCoreDxeEdk2FvFileGuid + # gAmiCoreDxeAptio4FvFileGuid + + gEfiAcpiTableGuid + gEfiAcpi10TableGuid + gEfiAcpi20TableGuid + + gEfiDxeServicesTableGuid + gEfiMpsTableGuid + gEfiPropertiesTableGuid + gEfiSalSystemTableGuid + gEfiSmbiosTableGuid + gEfiSmbios3TableGuid + + gLzmaCustomDecompressGuid + gEfiHobListGuid + gEfiMemoryTypeInformationGuid + gEfiDebugImageInfoTableGuid + gEfiSystemResourceTableGuid + +[Protocols] + gEfiDecompressProtocolGuid + + # gBdsStorageDeviceFoundProtocolGuid + # gBdsAllDriversConnectedProtocolGuid + + gEfiDevicePathPropertyDatabaseProtocolGuid + gAppleFirmwarePasswordProtocolGuid + gAppleKeyMapAggregatorProtocolGuid + gAppleKeyMapDatabaseProtocolGuid + + # gOcAcpiGeneratorProtocolGuid + # gOcBootManagementProtocolGuid + # gOcConfigurationProtocolGuid + # gOcHotkeyProtocolGuid + # gOcLogProtocolGuid + # gOcPlatformInfoProtocolGuid + # gOcScanFileSystemProtocolGuid + # gOcSmbiosGeneratorProtocolGuid + # gOcUserInterfaceProtocolGuid + # gOcRecognisePeImageProtocolGuid + # gOcRecogniseBootEntryProtocolGuid + +[LibraryClasses] + BaseLib + +[Sources] + GuidTable.c + OcPrintLib.c + StringTable.c diff --git a/Library/OcPrintLib/StringTable.c b/Library/OcPrintLib/StringTable.c new file mode 100755 index 00000000..1a4b477e --- /dev/null +++ b/Library/OcPrintLib/StringTable.c @@ -0,0 +1,61 @@ +/** @file + Copyright (C) 2016 - 2017, The HermitCrabs Lab. All rights reserved. + + All rights reserved. + + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + 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 + +GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR8 mOcPrintLibHexStr[] = { + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' +}; + +GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR8 *CONST mOcStatusString[] = { + "Success", // RETURN_SUCCESS = 0 + "Warning Unknown Glyph", // RETURN_WARN_UNKNOWN_GLYPH = 1 + "Warning Delete Failure", // RETURN_WARN_DELETE_FAILURE = 2 + "Warning Write Failure", // RETURN_WARN_WRITE_FAILURE = 3 + "Warning Buffer Too Small", // RETURN_WARN_BUFFER_TOO_SMALL = 4 + "Warning Stale Data", // RETURN_WARN_STALE_DATA = 5 + "Load Error", // RETURN_LOAD_ERROR = 1 | MAX_BIT + "Invalid Parameter", // RETURN_INVALID_PARAMETER = 2 | MAX_BIT + "Unsupported", // RETURN_UNSUPPORTED = 3 | MAX_BIT + "Bad Buffer Size", // RETURN_BAD_BUFFER_SIZE = 4 | MAX_BIT + "Buffer Too Small", // RETURN_BUFFER_TOO_SMALL, = 5 | MAX_BIT + "Not Ready", // RETURN_NOT_READY = 6 | MAX_BIT + "Device Error", // RETURN_DEVICE_ERROR = 7 | MAX_BIT + "Write Protected", // RETURN_WRITE_PROTECTED = 8 | MAX_BIT + "Out of Resources", // RETURN_OUT_OF_RESOURCES = 9 | MAX_BIT + "Volume Corrupt", // RETURN_VOLUME_CORRUPTED = 10 | MAX_BIT + "Volume Full", // RETURN_VOLUME_FULL = 11 | MAX_BIT + "No Media", // RETURN_NO_MEDIA = 12 | MAX_BIT + "Media changed", // RETURN_MEDIA_CHANGED = 13 | MAX_BIT + "Not Found", // RETURN_NOT_FOUND = 14 | MAX_BIT + "Access Denied", // RETURN_ACCESS_DENIED = 15 | MAX_BIT + "No Response", // RETURN_NO_RESPONSE = 16 | MAX_BIT + "No mapping", // RETURN_NO_MAPPING = 17 | MAX_BIT + "Time out", // RETURN_TIMEOUT = 18 | MAX_BIT + "Not started", // RETURN_NOT_STARTED = 19 | MAX_BIT + "Already started", // RETURN_ALREADY_STARTED = 20 | MAX_BIT + "Aborted", // RETURN_ABORTED = 21 | MAX_BIT + "ICMP Error", // RETURN_ICMP_ERROR = 22 | MAX_BIT + "TFTP Error", // RETURN_TFTP_ERROR = 23 | MAX_BIT + "Protocol Error", // RETURN_PROTOCOL_ERROR = 24 | MAX_BIT + "Incompatible Version", // RETURN_INCOMPATIBLE_VERSION = 25 | MAX_BIT + "Security Violation", // RETURN_SECURITY_VIOLATION = 26 | MAX_BIT + "CRC Error", // RETURN_CRC_ERROR = 27 | MAX_BIT + "End of Media", // RETURN_END_OF_MEDIA = 28 | MAX_BIT + "Reserved (29)", // RESERVED = 29 | MAX_BIT + "Reserved (30)", // RESERVED = 30 | MAX_BIT + "End of File", // RETURN_END_OF_FILE = 31 | MAX_BIT + "Invalid Language", // RETURN_INVALID_LANGUAGE = 32 | MAX_BIT + "Compromised Data" // RETURN_COMPROMISED_DATA = 33 | MAX_BIT +}; diff --git a/Library/OcProtocolLib/OcProtocolLib.inf b/Library/OcProtocolLib/OcProtocolLib.inf new file mode 100755 index 00000000..f0d7dd90 --- /dev/null +++ b/Library/OcProtocolLib/OcProtocolLib.inf @@ -0,0 +1,48 @@ +## @file +# +# Component description file for OcProtocolLibrary. +# +# Copyright (C) 2016, The HermitCrabs Lab. All rights reserved.
+# +# All rights reserved. +# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# +# 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 = OcProtocolLib + FILE_GUID = 495C5E9B-6794-4A55-A970-D3C33D4CA910 + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = OcProtocolLib|PEIM DXE_DRIVER DXE_RUNTIME_DRIVER UEFI_DRIVER UEFI_APPLICATION DXE_SMM_DRIVER + +# VALID_ARCHITECTURES = IA32 X64 + +[Packages] + OcSupportPkg/OcSupportPkg.dec + IntelFrameworkPkg/IntelFrameworkPkg.dec + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + +[Guids] + gOcLogVariableGuid + +[LibraryClasses] + BaseLib + OcPrintLib + MemoryAllocationLib + +[Sources] + RegisterProtocolCallback.c + SafeHandleProtocol.c + SafeInstallProtocolInterface.c + SafeLocateProtocol.c + SignalProtocolEvent.c diff --git a/Library/OcProtocolLib/RegisterProtocolCallback.c b/Library/OcProtocolLib/RegisterProtocolCallback.c new file mode 100755 index 00000000..15f6a522 --- /dev/null +++ b/Library/OcProtocolLib/RegisterProtocolCallback.c @@ -0,0 +1,68 @@ +/** @file + Copyright (C) 2016, The HermitCrabs Lab. All rights reserved. + + All rights reserved. + + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +**/ + +#include + +#include +#include +#include +#include + +#include + +// RegisterProtocolCallback +/** + + @param[in] Protocol The numeric ID of the protocol for which the event is to be registered. + @param[in] NotifyFunction Pointer to the event’s notification function, if any. + @param[in] NotifyContext Pointer to the notification function’s context; corresponds to parameter Context in the + notification function. + @param[in] Event Event that is to be signaled whenever a protocol interface is registered for Protocol. + The same EFI_EVENT may be used for multiple protocol notify registrations. + @param[in] Registration A pointer to a memory location to receive the registration value. + This value must be saved and used by the notification function of Event to retrieve the + list of handles that have added a protocol interface of type Protocol. + + @retval EFI_SUCCESS The event Callback was created successfully. +**/ +EFI_STATUS +EFIAPI +RegisterProtocolCallback ( + IN EFI_GUID *Protocol, + IN EFI_EVENT_NOTIFY NotifyFunction, + IN VOID *NotifyContext, + OUT EFI_EVENT *Event, + OUT VOID **Registration + ) +{ + EFI_STATUS Status; + + Status = gBS->CreateEvent ( + EVT_NOTIFY_SIGNAL, + TPL_CALLBACK, + NotifyFunction, + NotifyContext, + Event + ); + + if (!EFI_ERROR (Status)) { + Status = gBS->RegisterProtocolNotify ( + Protocol, + *Event, + Registration + ); + } + + return Status; +} diff --git a/Library/OcProtocolLib/SafeHandleProtocol.c b/Library/OcProtocolLib/SafeHandleProtocol.c new file mode 100755 index 00000000..f66b5dba --- /dev/null +++ b/Library/OcProtocolLib/SafeHandleProtocol.c @@ -0,0 +1,52 @@ +/** @file + Copyright (C) 2016, The HermitCrabs Lab. All rights reserved. + + All rights reserved. + + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +**/ + +#include + +#include +#include +#include +#include + +#include + +// SafeHandleProtocol +/** + + @param[in] Handle The handle being queried. If Handle is not a valid EFI_HANDLE, then EFI_INVALID_PARAMETER is + returned. + @param[in] Protocol The published unique identifier of the protocol. It is the caller’s responsibility to pass in + a valid GUID. + @param[out] Interface Supplies the address where a pointer to the corresponding Protocol Interface is returned. + NULL will be returned if a structure is not associated with Protocol. + + @retval EFI_SUCCESS The entry point is executed successfully. +**/ +EFI_STATUS +SafeHandleProtocol ( + IN EFI_HANDLE Handle, + IN EFI_GUID *Protocol, + OUT VOID **Interface + ) +{ + EFI_STATUS Status; + + Status = gBS->HandleProtocol (Handle, Protocol, Interface); + + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Problem Locating %a on Handle %X - %r\n", OcGuidToString (Protocol), Handle, Status)); + } + + return Status; +} diff --git a/Library/OcProtocolLib/SafeInstallProtocolInterface.c b/Library/OcProtocolLib/SafeInstallProtocolInterface.c new file mode 100755 index 00000000..95c033a3 --- /dev/null +++ b/Library/OcProtocolLib/SafeInstallProtocolInterface.c @@ -0,0 +1,79 @@ +/** @file + Copyright (C) 2016, The HermitCrabs Lab. All rights reserved. + + All rights reserved. + + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +**/ + +#include + +#include +#include +#include +#include + +#include + +// SafeInstallProtocolInterface +/** + + @param[in] ProtocolGuid The numeric ID of the protocol interface. It is the caller’s responsibility to pass in a + valid GUID. + @param[in] Interface A pointer to the protocol interface. The Interface must adhere to the structure defined by + Protocol. + NULL can be used if a structure is not associated with Protocol. + @param[in] Handle A pointer to the EFI_HANDLE on which the interface is to be installed. If *Handle is NULL on + input, a new handle is created and returned on output. + If *Handle is not NULL on input, the protocol is added to the handle, and the handle is + returned unmodified. + If *Handle is not a valid handle, then EFI_INVALID_PARAMETER is returned. + @param[in] DupeCheck A boolean flag to check if protocol already exists. + + @retval EFI_SUCCESS The entry point is executed successfully. +**/ +EFI_STATUS +SafeInstallProtocolInterface ( + IN GUID *ProtocolGuid, + IN VOID *Interface, + IN EFI_HANDLE Handle, + IN BOOLEAN DupeCheck + ) +{ + EFI_STATUS Status; + + VOID *Protocol; + + Status = EFI_INVALID_PARAMETER; + + if ((ProtocolGuid != NULL) && (Interface != NULL)) { + if (DupeCheck) { + Status = gBS->LocateProtocol (ProtocolGuid, NULL, (VOID **)&Protocol); + + if (Status == EFI_SUCCESS) { + Status = EFI_ALREADY_STARTED; + + DEBUG ((DEBUG_INFO, "Located %a (%X)\n", OcGuidToString (ProtocolGuid), *(UINT64 *)Protocol)); + goto Return; + } + } + + Status = gBS->InstallProtocolInterface ( + &Handle, + ProtocolGuid, + EFI_NATIVE_INTERFACE, + Interface + ); + + DEBUG ((DEBUG_VERBOSE, "Installed %a (%X)\n", OcGuidToString (ProtocolGuid), *(UINT64 *)Interface)); + } + +Return: + return Status; +} diff --git a/Library/OcProtocolLib/SafeLocateProtocol.c b/Library/OcProtocolLib/SafeLocateProtocol.c new file mode 100755 index 00000000..baa6b3a7 --- /dev/null +++ b/Library/OcProtocolLib/SafeLocateProtocol.c @@ -0,0 +1,54 @@ +/** @file + Copyright (C) 2016, The HermitCrabs Lab. All rights reserved. + + All rights reserved. + + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +**/ + +#include + +#include +#include +#include +#include + +#include + +// SafeLocateProtocol +/** + + @param[in] Protocol Provides the protocol to search for. + @param[in] Registration Optional registration key returned from RegisterProtocolNotify(). If Registration is NULL, + then it is ignored. + @param[out] Interface On return, a pointer to the first interface that matches Protocol and Registration. + + @retval EFI_SUCCESS The entry point is executed successfully. +**/ +EFI_STATUS +SafeLocateProtocol ( + IN EFI_GUID *Protocol, + IN VOID *Registration OPTIONAL, + OUT VOID **Interface + ) +{ + EFI_STATUS Status; + + Status = gBS->LocateProtocol (Protocol, NULL, Interface); + + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Problem Locating %a - %r\n", OcGuidToString (Protocol), Status)); + } + + if (*Interface == NULL) { + Status = EFI_NOT_FOUND; + } + + return Status; +} diff --git a/Library/OcProtocolLib/SignalProtocolEvent.c b/Library/OcProtocolLib/SignalProtocolEvent.c new file mode 100755 index 00000000..56b08b87 --- /dev/null +++ b/Library/OcProtocolLib/SignalProtocolEvent.c @@ -0,0 +1,50 @@ +/** @file + Copyright (C) 2016, The HermitCrabs Lab. All rights reserved. + + All rights reserved. + + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +**/ + +#include + +#include +#include +#include +#include + +#include + +// SignalProtocolEvent +/** + + @param[in] ProtocolGuid The published unique identifier of the protocol to publish. +**/ +VOID +SignalProtocolEvent ( + IN EFI_GUID *ProtocolGuid + ) +{ + EFI_HANDLE Handle; + + Handle = NULL; + + gBS->InstallProtocolInterface ( + &Handle, + ProtocolGuid, + EFI_NATIVE_INTERFACE, + NULL + ); + + gBS->UninstallProtocolInterface ( + Handle, + ProtocolGuid, + NULL + ); +} diff --git a/Library/OcStringLib/OcAsciiLib.c b/Library/OcStringLib/OcAsciiLib.c new file mode 100755 index 00000000..73dafb0d --- /dev/null +++ b/Library/OcStringLib/OcAsciiLib.c @@ -0,0 +1,469 @@ +/** @file + Copyright (C) 2016 - 2018, The HermitCrabs Lab. All rights reserved. + + All rights reserved. + + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +**/ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +// IsAsciiPrint +/** Check if character is printable + + @param[in] Char The ascii character to check if is printable. + + @retval TRUE, if character is printable. +**/ +BOOLEAN +IsAsciiPrint ( + IN CHAR8 Char + ) +{ + return ((Char >= ' ') && (Char < '~')); +} + +// IsAsciiDecimalDigitCharacter +/** Check if character is a decimal digit + + @param[in] Char The ascii character to check if is printable. + + @retval TRUE, if character is a decimal digit. +**/ +BOOLEAN +IsAsciiDecimalDigitCharacter ( + IN CHAR8 Char + ) +{ + return ((Char >= '0') && (Char <= '9')); +} + +// IsAsciiSpace +/** Check if character is a white space character + + @param[in] Char The ascii character to check if is white space. + + @retval TRUE, if character is a white space character +**/ +INTN +IsAsciiSpace ( + IN CHAR8 Char + ) +{ + return ((Char == ' ') + || (Char == '\t') + || (Char == '\v') + || (Char == '\f') + || (Char == '\r')); +} + +// AsciiHexCharToUintn +/** Convert ascii hexadecimal character to unsigned integer. + + @param[in] Char The ascii character to convert to integer. + + @retval Integer value of character representation. +**/ +UINTN +AsciiHexCharToUintn ( + IN CHAR8 Char + ) +{ + UINTN Value; + + if (IsAsciiDecimalDigitCharacter (Char)) { + Value = (UINTN)(Char - L'0'); + } else { + Value = (UINTN)(10 + AsciiToUpperChar (Char) - L'A'); + } + + return Value; +} + +// AsciiStrnIntegerCmp +/** + + @param[in] String1 A pointer to a buffer containing the first ascii string to compare. + @param[in] String2 A pointer to a buffer containing the second ascii string to compare. + @param[in] Length The number of characters to compare. + + @retval Integer value of character representation. +**/ +INTN +AsciiStrnIntegerCmp ( + IN CHAR8 *String1, + IN CHAR8 *String2, + IN UINTN Length + ) +{ + INTN Result; + + UINTN Index; + + Result = 0; + + for (Index = 0; Index < Length; ++Index) { + if (String1[Index] != String2[Index]) { + Result = (String1[Index] - String2[Index]); + + break; + } + + if (String1[Index] == '\0') { + break; + } + } + + return Result; +} + +// AsciiStrToInteger +/** Convert ascii string to unsigned integer. + + @param[in] Char The null terminated ascii string to convert to integer. + + @retval Integer value of the ascii string. +**/ +INTN +AsciiStrToInteger ( + IN CHAR8 *Start + ) +{ + UINTN Base; + INTN Sum; + + BOOLEAN Negative; + + Sum = 0; + + if (Start != NULL) { + while (IsAsciiSpace (*Start) && (*Start != '\0')) { + ++Start; + } + + Base = 10; + Negative = FALSE; + + if (*Start == '-') { + Negative = TRUE; + ++Start; + } else if (*Start == '0') { + ++Start; + + if ((*Start == 'x') || (*Start == 'X')) { + Base = 16; + ++Start; + } + } else if (*Start == '#') { + Base = 16; + ++Start; + } + + if (Base == 10) { + while ((*Start >= '0') && (*Start <= '9')) { + Sum *= 10; + Sum += (*Start - '0'); + + ++Start; + } + + if (Negative) { + Sum = -Sum; + } + } else if (Base == 16) { + Sum = (INTN)AsciiStrHexToUint64 (Start); + } + } + + return Sum; +} + +// AsciiToUpperChar +/** Convert ascii character to upper case + + @param[in] Char The ascii character to convert to upperase. + + @retval Upper case representation of the ascii character. +**/ +CHAR8 +AsciiToUpperChar ( + IN CHAR8 Char + ) +{ + if ((Char >= 'a') && (Char <= 'z')) { + Char -= ('a' - 'A'); + } + + return Char; +} + +// OcAsciiStrToGuid +/** Convert correctly formatted string into a GUID. + + @param[in] StringGuid A pointer to a buffer containing the ascii string. + @param[in] Guid A pointer to location to store the converted GUID. + + @retval EFI_SUCCESS The conversion completed successfully. +**/ +EFI_STATUS +OcAsciiStrToGuid ( + IN CONST CHAR8 *StringGuid, + IN OUT EFI_GUID *Guid + ) +{ + EFI_STATUS Status; + + Status = EFI_INVALID_PARAMETER; + + if ((StringGuid != NULL) && (Guid != NULL)) { + ZeroMem (Guid, sizeof (*Guid)); + + if ((StringGuid[8] == '-') + && (StringGuid[13] == '-') + && (StringGuid[18] == '-') + && (StringGuid[23] == '-')) { + Guid->Data1 = (UINT32)AsciiStrHexToUint64 (StringGuid); + Guid->Data2 = (UINT16)AsciiStrHexToUint64 (StringGuid + 9); + Guid->Data3 = (UINT16)AsciiStrHexToUint64 (StringGuid + 14); + + Guid->Data4[0] = (UINT8)(AsciiHexCharToUintn (StringGuid[19]) * 16 + AsciiHexCharToUintn (StringGuid[20])); + Guid->Data4[1] = (UINT8)(AsciiHexCharToUintn (StringGuid[21]) * 16 + AsciiHexCharToUintn (StringGuid[22])); + Guid->Data4[2] = (UINT8)(AsciiHexCharToUintn (StringGuid[24]) * 16 + AsciiHexCharToUintn (StringGuid[25])); + Guid->Data4[3] = (UINT8)(AsciiHexCharToUintn (StringGuid[26]) * 16 + AsciiHexCharToUintn (StringGuid[27])); + Guid->Data4[4] = (UINT8)(AsciiHexCharToUintn (StringGuid[28]) * 16 + AsciiHexCharToUintn (StringGuid[29])); + Guid->Data4[5] = (UINT8)(AsciiHexCharToUintn (StringGuid[30]) * 16 + AsciiHexCharToUintn (StringGuid[31])); + Guid->Data4[6] = (UINT8)(AsciiHexCharToUintn (StringGuid[32]) * 16 + AsciiHexCharToUintn (StringGuid[33])); + Guid->Data4[7] = (UINT8)(AsciiHexCharToUintn (StringGuid[34]) * 16 + AsciiHexCharToUintn (StringGuid[35])); + + Status = EFI_SUCCESS; + } + } + + return Status; +} + +// OcAsciiStrToUnicode +/** Convert null terminated ascii string to unicode. + + @param[in] String1 A pointer to the ascii string to convert to unicode. + @param[out] String2 A pointer to the converted unicode string. + @param[in] Length Length or 0 to calculate the length of the ascii string to convert. + + @retval A pointer to the converted unicode string. +**/ +CHAR16 * +OcAsciiStrToUnicode ( + IN CHAR8 *String1, + IN CHAR16 *String2, + IN UINTN Length + ) +{ + CHAR16 *Start; + + Start = NULL; + + if ((String1 != NULL) && (String2 != NULL)) { + + if (Length == 0) { + Length = AsciiStrLen (String1); + } + + Start = String2; + + while (*String1 != '\0' && Length--) { + *(String2++) = *(String1++); + } + + *String2 = L'\0'; + } + + return Start; +} + +// UnicodeBaseName +/** Return the filename element of a pathname + + @param[in] FullPath A pointer to a ascii path + + @retval A pointer to the converted ascii string. +**/ +CHAR8 * +AsciiBaseName ( + IN CHAR8 *FullPath + ) +{ + CHAR8 *BaseName; + + BaseName = NULL; + + if (FullPath != NULL) { + BaseName = ((FullPath + AsciiStrLen (FullPath)) - 1); + + while ((BaseName > FullPath) && (BaseName[-1] != '\\') && (BaseName[-1] != '/')) { + --BaseName; + } + } + + return BaseName; +} + +// AsciiDirName +/** Return the folder element of a pathname + + @param[in] FullPath A pointer to a ascii path + + @retval A pointer to the converted ascii string. +**/ +CHAR8 * +AsciiDirName ( + IN CHAR8 *FullPath +) +{ + CHAR8 *DirName; + + if (FullPath != NULL) { + DirName = FullPath + AsciiStrLen (FullPath) - 1; + + if ((*(DirName) != '\\') && (*(DirName) != '/')) { + while ((DirName > FullPath) && (DirName[-1] != '\\') && (DirName[-1] != '/')) { + --DirName; + } + + DirName[-1] = '\0'; + } + } + + return FullPath; +} + +// AsciiTrimWhiteSpace +/** Remove any leading or trailing space in the string + + @param[in] Start A pointer to the ascii string + + @retval A pointer to the converted ascii string. +**/ +CHAR8 * +AsciiTrimWhiteSpace ( + IN CHAR8 *String + ) +{ + CHAR8 *End; + + if (String != NULL) { + + // Trim leading white space + while (IsAsciiSpace (*String)) { + String++; + } + + // Trim trailing white space + End = String + AsciiStrLen (String); + + while (End != String && IsAsciiSpace (*--End)); + + // Write new null terminator + *(++End) = '\0'; + } + + return String; +} + +// OcAsciiStrnCmp +/** + Compares two Null-terminated ASCII strings with maximum lengths, and returns + the difference between the first mismatched ASCII characters. + + @param[in] FirstString A pointer to a Null-terminated ASCII string. + @param[in] SecondString A pointer to a Null-terminated ASCII string. + @param[in] 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 +OcAsciiStrnCmp ( + IN CONST CHAR8 *FirstString, + IN CONST CHAR8 *SecondString, + IN UINTN Length + ) +{ + if (Length == 0) { + return 0; + } + + while ((*FirstString != '\0') && + (*SecondString != '\0') && + (*FirstString == *SecondString) && + (Length > 1)) { + FirstString++; + SecondString++; + Length--; + } + return *FirstString - *SecondString; +} + +// OcAsciiStrStr +/** + Returns the first occurrence of a Null-terminated ASCII sub-string + in a Null-terminated ASCII string. + + @param[in] String1 A pointer to a Null-terminated ASCII string. + @param[in] SearchString A pointer to a Null-terminated ASCII string to search for. + + @retval NULL If the SearchString does not appear in String. + +**/ +CHAR8 * +OcAsciiStrStr ( + IN CONST CHAR8 *String, + IN CONST CHAR8 *SearchString + ) +{ + CONST CHAR8 *FirstMatch; + CONST CHAR8 *SearchStringTmp; + + 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; +} diff --git a/Library/OcStringLib/OcStringLib.inf b/Library/OcStringLib/OcStringLib.inf new file mode 100755 index 00000000..671df154 --- /dev/null +++ b/Library/OcStringLib/OcStringLib.inf @@ -0,0 +1,48 @@ +## @file +# +# Component description file for OcStringlibrary. +# +# Copyright (C) 2016, The HermitCrabs Lab. All rights reserved.
+# +# All rights reserved. +# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# +# 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 = OcStringLib + FILE_GUID = 1E0810F7-9E40-43D0-A036-185407D0231D + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = OcStringLib|PEIM DXE_DRIVER DXE_RUNTIME_DRIVER UEFI_DRIVER UEFI_APPLICATION DXE_SMM_DRIVER + + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 +# + +[Sources] + OcAsciiLib.c + OcUnicodeLib.c + +[Packages] + OcSupportPkg/OcSupportPkg.dec + MdePkg/MdePkg.dec + +[Guids] + +[Protocols] + +[LibraryClasses] + BaseLib + diff --git a/Library/OcStringLib/OcUnicodeLib.c b/Library/OcStringLib/OcUnicodeLib.c new file mode 100755 index 00000000..9df839e9 --- /dev/null +++ b/Library/OcStringLib/OcUnicodeLib.c @@ -0,0 +1,523 @@ +/** @file + Copyright (C) 2016, The HermitCrabs Lab. All rights reserved. + + All rights reserved. + + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +**/ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +// IsPrint +/** Check if character is printable + + @param[in] Char The unicode character to check if is printable. + + @retval TRUE, if character is printable. +**/ +BOOLEAN +IsPrint ( + IN CHAR16 Char + ) +{ + return ((Char >= L' ') && (Char < L'~')); +} + +// IsDecimalDigitCharacter +/** Check if character is a decimal digit + + @param[in] Char The unicode character to check if is printable. + + @retval TRUE, if character is a decimal digit. +**/ +BOOLEAN +IsDecimalDigitCharacter ( + IN CHAR16 Char + ) +{ + return ((Char >= L'0') && (Char <= L'9')); +} + +// IsSpace +/** Check if character is a white space character + + @param[in] Char The unicode character to check if is white space. + + @retval TRUE, if character is a white space character +**/ +INTN +IsSpace ( + IN CHAR16 Char + ) +{ + return ((Char == L' ') + || (Char == L'\t') + || (Char == L'\v') + || (Char == L'\f') + || (Char == L'\r')); +} + +// HexCharToUintn +/** Convert unicode hexadecimal character to unsigned integer. + + @param[in] Char The unicode character to convert to integer. + + @retval Integer value of character representation. +**/ +UINTN +HexCharToUintn ( + IN CHAR16 Char + ) +{ + UINTN Result; + + if (IsDecimalDigitCharacter (Char)) { + Result = (Char - L'0'); + } else { + Result = (UINTN)((10 + ToUpperChar (Char)) - L'A'); + } + + return Result; +} + +// StrnIntegerCmp +/** + + @param[in] String1 A pointer to a buffer containing the first unicode string to compare. + @param[in] String2 A pointer to a buffer containing the second unicode string to compare. + @param[in] Length The number of characters to compare. + + @retval Integer value of character representation. +**/ +INTN +StrnIntegerCmp ( + IN CHAR16 *String1, + IN CHAR16 *String2, + IN UINTN Length + ) +{ + INTN Result; + + UINTN Index; + + Result = 0; + + for (Index = 0; Index < Length; ++Index) { + if (String1[Index] != String2[Index]) { + Result = (String1[Index] - String2[Index]); + + break; + } + + if (String1[Index] == L'\0') { + break; + } + } + + return Result; +} + +// StrToInteger +/** Convert unicode string to unsigned integer. + + @param[in] Char The null terminated unicode string to convert to integer. + + @retval Integer value of the unicode string. +**/ +INTN +StrToInteger ( + IN CHAR16 *Start + ) +{ + UINTN Base; + INTN Sum; + + BOOLEAN Negative; + + Sum = 0; + + if (Start != NULL) { + while (IsSpace ((CHAR8)*Start) && (*Start != L'\0')) { + ++Start; + } + + Base = 10; + Negative = FALSE; + + if (*Start == '-') { + Negative = TRUE; + ++Start; + } else if (*Start == L'0') { + ++Start; + + if ((*Start == L'x') || (*Start == L'X')) { + Base = 16; + ++Start; + } + } else if (*Start == L'#') { + Base = 16; + ++Start; + } + + if (Base == 10) { + while ((*Start >= L'0') && (*Start <= L'9')) { + Sum *= 10; + Sum += (*Start - L'0'); + + ++Start; + } + + if (Negative) { + Sum = -Sum; + } + } else if (Base == 16) { + Sum = (INTN)StrHexToUint64 (Start); + } + } + + return Sum; +} + +// ToUpperChar +/** Convert unicode character to upper case + + @param[in] Char The unicode character to convert to upperase. + + @retval Upper case representation of the unicode character. +**/ +CHAR16 +ToUpperChar ( + IN CHAR16 Char + ) +{ + if ((Char <= MAX_UINT8) && ((Char >= 'a') && (Char <= 'z'))) { + Char -= ('a' - 'A'); + } + + return Char; +} + +// OcStrToGuid +/** Convert correctly formatted string into a GUID. + + @param[in] StringGuid A pointer to a buffer containing the unicode string. + @param[in] Guid A pointer to location to store the converted GUID. + + @retval EFI_SUCCESS The conversion completed successfully. +**/ +EFI_STATUS +OcStrToGuid ( + IN CONST CHAR16 *StringGuid, + IN OUT EFI_GUID *Guid + ) +{ + EFI_STATUS Status; + + Status = EFI_INVALID_PARAMETER; + + if ((StringGuid != NULL) && (Guid != NULL)) { + ZeroMem (Guid, sizeof (*Guid)); + + if ((StringGuid[8] == L'-') + && (StringGuid[13] == L'-') + && (StringGuid[18] == L'-') + && (StringGuid[23] == L'-')) { + Guid->Data1 = (UINT32)StrHexToUint64 (StringGuid); + Guid->Data2 = (UINT16)StrHexToUint64 (StringGuid + 9); + Guid->Data3 = (UINT16)StrHexToUint64 (StringGuid + 14); + + Guid->Data4[0] = (UINT8)(HexCharToUintn (StringGuid[19]) * 16 + HexCharToUintn (StringGuid[20])); + Guid->Data4[1] = (UINT8)(HexCharToUintn (StringGuid[21]) * 16 + HexCharToUintn (StringGuid[22])); + Guid->Data4[2] = (UINT8)(HexCharToUintn (StringGuid[24]) * 16 + HexCharToUintn (StringGuid[25])); + Guid->Data4[3] = (UINT8)(HexCharToUintn (StringGuid[26]) * 16 + HexCharToUintn (StringGuid[27])); + Guid->Data4[4] = (UINT8)(HexCharToUintn (StringGuid[28]) * 16 + HexCharToUintn (StringGuid[29])); + Guid->Data4[5] = (UINT8)(HexCharToUintn (StringGuid[30]) * 16 + HexCharToUintn (StringGuid[31])); + Guid->Data4[6] = (UINT8)(HexCharToUintn (StringGuid[32]) * 16 + HexCharToUintn (StringGuid[33])); + Guid->Data4[7] = (UINT8)(HexCharToUintn (StringGuid[34]) * 16 + HexCharToUintn (StringGuid[35])); + + Status = EFI_SUCCESS; + } + } + + return Status; +} + +// OcStrToAscii +/** Convert null terminated unicode string to ascii. + + @param[in] String1 A pointer to the unicode string to convert to ascii. + @param[out] String2 A pointer to the converted ascii string. + + @retval A pointer to the converted ascii string. +**/ +CHAR8 * +OcStrToAscii ( + IN CHAR16 *String1, + IN CHAR8 *String2 + ) +{ + CHAR8 *Start; + + Start = NULL; + + if ((String1 != NULL) && (String2 != NULL)) { + Start = String2; + + while (*String1 != L'\0') { + *String2 = (CHAR8)*String1; + + ++String1; + ++String2; + } + + *String2 = '\0'; + } + + return Start; +} + +// StrCmpiAscii +/** Compare unicode string with ascii string ignoring case + + @param[in] String1 A pointer to a unicode string to compare. + @param[in] String2 A pointer to a ascii string to compare. + + @retval A pointer to the converted ascii string. +**/ +UINTN +StrCmpiAscii ( + IN CHAR16 *String1, + IN CHAR8 *String2 + ) +{ + UINTN Result; + + CHAR16 Chr1; + CHAR16 Chr2; + + if ((String1 == NULL) || (String2 == NULL)) { + Result = 1; + } else if ((*String1 == L'\0') && (*String2 == '\0')) { + Result = 0; + } else if ((*String1 == L'\0') || (*String2 == '\0')) { + Result = 1; + } else { + do { + Chr1 = ToUpperChar (*String1); + Chr2 = ToUpperChar ((CHAR16)*String2); + + ++String1; + ++String2; + } while ((String1[-1] != L'\0') && (Chr1 == Chr2)); + + Result = (Chr1 - Chr2); + } + + return Result; +} + +// StrCmpiBasic +/** Compare unicode strings ignoring case + + @param[in] String1 A pointer to a unicode string to compare. + @param[in] String2 A pointer to a unicode string to compare. + + @retval A pointer to the converted ascii string. +**/ +UINTN +StrCmpiBasic ( + IN CHAR16 *String1, + IN CHAR16 *String2 + ) +{ + UINTN Result; + + CHAR16 Chr1; + CHAR16 Chr2; + + if ((String1 == NULL) || (String2 == NULL)) { + Result = 1; + } else if ((*String1 == L'\0') && (*String2 == L'\0')) { + Result = 0; + } else if ((*String1 == L'\0') || (*String2 == L'\0')) { + Result = 1; + } else { + do { + Chr1 = ToUpperChar (*String1); + Chr2 = ToUpperChar (*String2); + + ++String1; + ++String2; + } while ((String1[-1] != L'\0') && (Chr1 == Chr2)); + + Result = (Chr1 - Chr2); + } + + return Result; +} + +// UnicodeBaseName +/** Return the filename element of a pathname + + @param[in] FullPath A pointer to a unicode path + + @retval A pointer to the converted ascii string. +**/ +CHAR16 * +UnicodeBaseName ( + IN CHAR16 *FullPath + ) +{ + CHAR16 *BaseName; + + BaseName = NULL; + + if ((FullPath != NULL) && (*FullPath != L'\0')) { + BaseName = ((FullPath + StrLen (FullPath)) - 1); + + while ((BaseName > FullPath) && (BaseName[-1] != L'\\') && (BaseName[-1] != L'/')) { + --BaseName; + } + } + + return BaseName; +} + +// UnicodeDirName +/** Return the folder element of a pathname + + @param[in] FullPath A pointer to a unicode path + + @retval A pointer to the converted ascii string. +**/ +CHAR16 * +UnicodeDirName ( + IN CHAR16 *FullPath +) +{ + CHAR16 *DirName; + + if ((FullPath != NULL) && (*FullPath != L'\0')) { + DirName = FullPath + StrLen (FullPath) - 1; + + if ((*(DirName) != L'\\') && (*(DirName) != L'/')) { + while ((DirName > FullPath) && (DirName[-1] != L'\\') && (DirName[-1] != L'/')) { + --DirName; + } + + DirName[-1] = L'\0'; + } + } + + return FullPath; +} + +// UnicodeParseString +/** + + @param[in] String A pointer to a unicode string + @param[in] Variable A pointer to a unicode string variable name to parse for + + @retval A pointer to the variable value +**/ +CHAR16 * +UnicodeParseString ( + IN CHAR16 *String, + IN CHAR16 *Variable + ) +{ + CHAR16 *Start; + CHAR16 *Data; + CHAR16 *Value; + + if (String == NULL || Variable == NULL) { + return NULL; + } + + // Check string contains variable + Start = StrStr (String, Variable); + + if (Start == NULL) { + return NULL; + } + + // locate Variable= in string + while (*Start != L'\0') { + if (*Start == L'=') { + break; + } + Start++; + } + + // Extra sanity check + if (*Start++ != L'=') { + return NULL; + } + + Data = AllocateZeroPool (StrSize (Start)); + + if (Data == NULL) { + return NULL; + } + + Value = Data; + + // copy filtering any " from data + while (*Start != L'\0') { + if (*Start != L'"') { + *(Data++) = *Start; + } + Start++; + } + + return Value; +} + +// TrimWhiteSpace +/** Remove any leading or trailing space in the string + + @param[in] Start A pointer to the unicode string + + @retval A pointer to the converted unicode string. +**/ +CHAR16 * +TrimWhiteSpace ( + IN CHAR16 *String + ) +{ + CHAR16 *End; + + if ((String != NULL) && (*String != L'\0')) { + + // Trim leading white space + while (IsSpace (*String)) { + String++; + } + + // Trim trailing white space + End = String + StrLen (String); + + while (End != String && IsSpace (*--End)); + + // Write new null terminator + *(++End) = L'\0'; + } + + return String; +} diff --git a/Library/OcTimerLib/OcTimerLib.c b/Library/OcTimerLib/OcTimerLib.c new file mode 100755 index 00000000..307d56ac --- /dev/null +++ b/Library/OcTimerLib/OcTimerLib.c @@ -0,0 +1,134 @@ +/** @file + Copyright (C) 2016, The HermitCrabs Lab. All rights reserved. + + All rights reserved. + + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +**/ + +#include + +#include +#include + +#include +#include +#include +#include +#include + +#include + +UINT64 mTimerLibTscFrequency = 0; + +// CalculateTSC +/** Calculate the TSC frequency + + @param[in] Recalculate The firmware allocated handle for the EFI image. + + @retval The calculated TSC frequency. +**/ +UINT64 +CalculateTSC ( + IN BOOLEAN Recalculate + ) +{ + UINT32 TimerAddr; + UINT64 Tsc0; + UINT64 Tsc1; + UINT64 AcpiTick0; + UINT64 AcpiTick1; + UINT64 AcpiTicksDelta; + UINT32 AcpiTicksTarget; + UINT32 TimerResolution; + + // Already Calculated, Return Cached Result + + if (((mTimerLibTscFrequency == 0) || Recalculate) && PciRead16 (PCI_ICH_LPC_ADDRESS (0)) == 0x8086) { + TimerAddr = 0; + TimerResolution = 10; + + // Check if ACPI I/O Space Is Enabled On LPC device + + if ((PciRead8 (PCI_ICH_LPC_ADDRESS (R_ICH_LPC_ACPI_CNT)) & B_ICH_LPC_ACPI_CNT_ACPI_EN) != 0) { + TimerAddr = ((PciRead16 (PCI_ICH_LPC_ADDRESS (R_ICH_LPC_ACPI_BASE)) & B_ICH_LPC_ACPI_BASE_BAR) + R_ACPI_PM1_TMR); + //DEBUG ((DEBUG_INFO, "Acpi Timer Addr 0x%0x (LPC)\n", TimerAddr)); + } else { + // Starting from Intel Sunrisepoint (Skylake PCH) the iTCO watchdog resources + // have been moved to reside under the i801 SMBus host controller whereas + // previously they were under the LPC device. + // + // Check if ACPI I/O space is enabled on SMBUS device + + if ((PciRead8 (PCI_ICH_SMBUS_ADDRESS (R_ICH_SMBUS_ACPI_CNT)) & B_ICH_SMBUS_ACPI_CNT_ACPI_EN) != 0) { + TimerAddr = ((PciRead16 (PCI_ICH_SMBUS_ADDRESS (R_ICH_SMBUS_ACPI_BASE)) & B_ICH_SMBUS_ACPI_BASE_BAR) + R_ACPI_PM1_TMR); + //DEBUG ((DEBUG_INFO, "Acpi Timer Addr 0x%0x (SMB)\n", TimerAddr)); + } + } + + if (TimerAddr != 0) { + mTimerLibTscFrequency = 0; + + // Check That Timer Is Advancing + + AcpiTick0 = IoRead32 (TimerAddr); + + gBS->Stall (500); + + AcpiTick1 = IoRead32 (TimerAddr); + + if (AcpiTick0 != AcpiTick1) { + // ACPI PM timers are usually of 24-bit length, but there are some less common cases of 32-bit length also. + // When the maximal number is reached, it overflows. + // The code below can handle overflow with AcpiTicksTarget of up to 24-bit size, + // on both available sizes of ACPI PM Timers (24-bit and 32-bit). + // + // 357954 clocks of ACPI timer (100ms) + + AcpiTicksTarget = (V_ACPI_TMR_FREQUENCY / TimerResolution); + + AcpiTick0 = IoRead32 (TimerAddr); + Tsc0 = AsmReadTsc (); + + do { + CpuPause (); + + // Check How Many AcpiTicks Have Passed Since We Started + + AcpiTick1 = IoRead32 (TimerAddr); + + if (AcpiTick0 <= AcpiTick1) { + // No Overflow + + AcpiTicksDelta = (AcpiTick1 - AcpiTick0); + } else if ((AcpiTick0 - AcpiTick1) <= 0x00FFFFFF) { + // Overflow, 24 Bit Timer + + AcpiTicksDelta = ((0x00FFFFFF - AcpiTick0) + AcpiTick1); + + } else { + // Overflow, 32 Bit Timer + + AcpiTicksDelta = ((MAX_UINT32 - AcpiTick0) + AcpiTick1); + } + + // Keep Checking Acpi ticks Until Target Is Reached + } while (AcpiTicksDelta < AcpiTicksTarget); + + Tsc1 = AsmReadTsc (); + mTimerLibTscFrequency = MultU64x32 ((Tsc1 - Tsc0), TimerResolution); + + } + } + } + + //DEBUG ((DEBUG_INFO, "TscFrequency %lld\n", mTimerLibTscFrequency)); + + return mTimerLibTscFrequency; +} diff --git a/Library/OcTimerLib/OcTimerLib.inf b/Library/OcTimerLib/OcTimerLib.inf new file mode 100755 index 00000000..82f34dba --- /dev/null +++ b/Library/OcTimerLib/OcTimerLib.inf @@ -0,0 +1,41 @@ +## @file +# +# Component description file for OcTimerLibrary. +# +# Copyright (C) 2016, The HermitCrabs Lab. All rights reserved.
+# +# All rights reserved. +# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# +# 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 = OcTimerLib + FILE_GUID = 8BF2026F-C0BB-4A5D-A7DB-395DAB5A73E7 + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = OcTimerLib|PEIM DXE_DRIVER DXE_RUNTIME_DRIVER UEFI_DRIVER UEFI_APPLICATION DXE_SMM_DRIVER + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 +# + +[Sources] + OcTimerLib.c + +[Packages] + OcSupportPkg/OcSupportPkg.dec + MdePkg/MdePkg.dec + +[LibraryClasses] + PciLib diff --git a/Library/OcVariableLib/CheckVariable.c b/Library/OcVariableLib/CheckVariable.c new file mode 100755 index 00000000..4c204413 --- /dev/null +++ b/Library/OcVariableLib/CheckVariable.c @@ -0,0 +1,56 @@ +/** @file + Copyright (C) 2016, The HermitCrabs Lab. All rights reserved. + + All rights reserved. + + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +**/ +#include + +#include +#include +#include +#include +#include +#include + +// CheckVariableBoolean +/** Check the boolean-value of an EFI Variable. + + @param[in] Name The firmware allocated handle for the EFI image. + @param[in] VendorGuid A unique identifier for the vendor. + + @retval Boolean value indicating TRUE, if variable exists. +**/ +BOOLEAN +CheckVariableBoolean ( + IN CHAR16 *Name, + IN EFI_GUID *VendorGuid + ) +{ + BOOLEAN Value; + + EFI_STATUS Status; + UINTN VariableSize; + + VariableSize = sizeof (Value); + Status = gRT->GetVariable ( + Name, + VendorGuid, + NULL, + &VariableSize, + &Value + ); + + if (EFI_ERROR (Status)) { + Value = FALSE; + } + + return Value; +} diff --git a/Library/OcVariableLib/DeleteVariable.c b/Library/OcVariableLib/DeleteVariable.c new file mode 100755 index 00000000..7565a452 --- /dev/null +++ b/Library/OcVariableLib/DeleteVariable.c @@ -0,0 +1,130 @@ +/** @file + Copyright (C) 2016, The HermitCrabs Lab. All rights reserved. + + All rights reserved. + + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +**/ + +#include + +#include +#include +#include +#include +#include +#include + +// DeleteVariables +/** Deletes all EFI Variables matching the pattern. + + @param[in] VendorGuid A unique identifier for the vendor. + @param[in] SearchName A Null-terminated Unicode string that is the name of the vendor’s variable. Each SearchName is + unique for each VendorGuid. + SearchName must contain 1 or more Unicode characters. If SearchName is an empty Unicode + string, then EFI_INVALID_PARAMETER is returned. + + @retval EFI_SUCCESS The variable was deleted successfully. +**/ +EFI_STATUS +DeleteVariables ( + IN EFI_GUID *VendorGuid, + IN CHAR16 *SearchName + ) +{ + EFI_STATUS Status; + + EFI_GUID VariableGuid; + UINTN VariableNameBufferSize; + UINTN VariableNameSize; + CHAR16 *VariableName; + + Status = EFI_INVALID_PARAMETER; + + if ((VendorGuid != NULL) && (SearchName != NULL)) { + + // Start with a minimal buffer to find the name of the first entry + VariableNameBufferSize = sizeof (*VariableName); + VariableName = AllocateZeroPool (VariableNameBufferSize); + + DEBUG (( + DEBUG_VARIABLE, + "Delete Guid %g : Search String \'%s\'\n", + VendorGuid, + SearchName + )); + + while (VariableName != NULL) { + VariableNameSize = VariableNameBufferSize; + Status = gRT->GetNextVariableName ( + &VariableNameSize, + VariableName, + &VariableGuid + ); + + if (Status == EFI_BUFFER_TOO_SMALL) { + VariableName = ReallocatePool ( + VariableNameBufferSize, + VariableNameSize, + VariableName + ); + + if (VariableName == NULL) { + Status = EFI_OUT_OF_RESOURCES; + break; + } + + VariableNameBufferSize = VariableNameSize; + Status = gRT->GetNextVariableName ( + &VariableNameSize, + VariableName, + &VariableGuid + ); + } + + if (EFI_ERROR (Status)) { + if (Status == EFI_NOT_FOUND) { + Status = EFI_SUCCESS; + } + + break; + } + + // If provided are we looking for this Guid ?, otherwise continue + if (VendorGuid != NULL && (!CompareGuid (&VariableGuid, VendorGuid))) { + continue; + } + + // If provided does the name contain our search string ?, otherwise continue + if (SearchName != NULL && (!StrStr (VariableName, SearchName))) { + continue; + } + + // FIXME: Skip gOpenCoreOverridesGuid:BootLog to avoid multiple hits + + Status = gRT->SetVariable ( + VariableName, + &VariableGuid, + 0, + 0, + NULL + ); + + DEBUG ((DEBUG_VARIABLE, "Delete %g:%s - %r\n", VariableGuid, VariableName, Status)); + + } + + if (VariableName != NULL) { + FreePool ((VOID *)VariableName); + } + + } + + return Status; +} diff --git a/Library/OcVariableLib/GetVariable.c b/Library/OcVariableLib/GetVariable.c new file mode 100755 index 00000000..9a2efa26 --- /dev/null +++ b/Library/OcVariableLib/GetVariable.c @@ -0,0 +1,114 @@ +/** @file + Copyright (C) 2016 - 2017, The HermitCrabs Lab. All rights reserved. + + All rights reserved. + + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +**/ + +#include + +#include +#include +#include +#include +#include +#include +#include + +// OcGetVariable +/** Return the variables value in buffer. + + @param[in] Name A Null-terminated Ascii string that is the name of the vendor’s variable. Each Name is + unique for each VendorGuid. + Name must contain 1 or more Ascii characters. If Name is an empty Ascii string, then + EFI_INVALID_PARAMETER is returned. + @param[in] VendorGuid A unique identifier for the vendor. + @param[in,out] BufferPtr Pointer to store the buffer. + @param[in,out] BufferSize Size of the variables data buffer. + + @retval A pointer to the variables data +**/ +EFI_STATUS +OcGetVariable ( + IN CHAR8 *Name, + IN EFI_GUID *VendorGuid, + IN OUT VOID **BufferPtr, + IN OUT UINTN *BufferSize + ) +{ + EFI_STATUS Status; + VOID *TempBuffer; + CHAR16 *VariableName; + + Status = EFI_INVALID_PARAMETER; + + if (Name == NULL || VendorGuid == NULL || BufferPtr == NULL || BufferSize == NULL) { + return Status; + } + + VariableName = AllocateZeroPool (AsciiStrSize (Name) * sizeof(CHAR16)); + + if (VariableName) { + + OcAsciiStrToUnicode (Name, VariableName, 0); + + Status = gRT->GetVariable ( + VariableName, + VendorGuid, + NULL, + BufferSize, + *BufferPtr + ); + + if (EFI_ERROR (Status)) { + + if ((Status == EFI_BUFFER_TOO_SMALL) && (*BufferPtr == NULL)) { + + Status = EFI_OUT_OF_RESOURCES; + TempBuffer = AllocateZeroPool (*BufferSize); + + if (TempBuffer != NULL) { + + Status = gRT->GetVariable ( + VariableName, + VendorGuid, + NULL, + BufferSize, + TempBuffer + ); + + if (!EFI_ERROR (Status)) { + *BufferPtr = TempBuffer; + } else { + FreePool (TempBuffer); + } + } + } + } + + FreePool (VariableName); + } + + return Status; +} + + +// GetVariableAndSize +/** Return the variables value in buffer. + + @param[in] Name A Null-terminated Unicode string that is the name of the vendor’s variable. Each Name is + unique for each VendorGuid. + Name must contain 1 or more Unicode characters. If Name is an empty Unicode string, then + EFI_INVALID_PARAMETER is returned. + @param[in] VendorGuid A unique identifier for the vendor. + @param[out] VariableSize Size of the variables data buffer. + + @retval A pointer to the variables data +**/ diff --git a/Library/OcVariableLib/OcVariableLib.inf b/Library/OcVariableLib/OcVariableLib.inf new file mode 100755 index 00000000..24c0de9c --- /dev/null +++ b/Library/OcVariableLib/OcVariableLib.inf @@ -0,0 +1,43 @@ +## @file +# +# Component description file for Oc Variable Library. +# +# Copyright (C) 2016, The HermitCrabs Lab. All rights reserved.
+# +# All rights reserved. +# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# +# 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 = OcVariableLib + FILE_GUID = 58C96726-9D10-42F1-A0AE-3024BA770600 + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = OcVariableLib|PEIM DXE_DRIVER DXE_RUNTIME_DRIVER UEFI_DRIVER UEFI_APPLICATION DXE_SMM_DRIVER + +# VALID_ARCHITECTURES = IA32 X64 + +[Packages] + OcSupportPkg/OcSupportPkg.dec + IntelFrameworkPkg/IntelFrameworkPkg.dec + IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + +[LibraryClasses] + BaseLib + +[Sources] + CheckVariable.c + DeleteVariable.c + GetVariable.c + SetVariable.c diff --git a/Library/OcVariableLib/SetVariable.c b/Library/OcVariableLib/SetVariable.c new file mode 100755 index 00000000..48a43eea --- /dev/null +++ b/Library/OcVariableLib/SetVariable.c @@ -0,0 +1,159 @@ +/** @file + Copyright (C) 2016 - 2018, The HermitCrabs Lab. All rights reserved. + + All rights reserved. + + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +**/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +// SetVariable +/** Sets an EFI Variable. + + @param[in] Name A Null-terminated Unicode string that is the name of the vendor’s variable. Each Name is + unique for each VendorGuid. + Name must contain 1 or more Unicode characters. If Name is an empty Unicode string, then + EFI_INVALID_PARAMETER is returned. + @param[in] VendorGuid A unique identifier for the vendor. + @param[in] Attributes Attributes bitmask to set for the variable. Refer to the GetVariable() function + description. + @param[in] DataSize The size in bytes of the Data buffer. A size of zero causes the variable to be deleted. + @param[in] Data The contents for the variable. + @param[in] OverideDefault A boolean flag which enables updating a previously set value. + + @retval EFI_SUCCESS The variable was set successfully. +**/ +EFI_STATUS +SetVariable ( + IN CHAR8 *Name, + IN EFI_GUID *VendorGuid, + IN UINT32 Attributes, + IN UINTN DataSize, + IN VOID *Data, + IN BOOLEAN OverideDefault + ) +{ + EFI_STATUS Status; + + UINTN Size; + CHAR16 *VariableName; + + Status = EFI_OUT_OF_RESOURCES; + VariableName = AllocateZeroPool (AsciiStrSize (Name) * sizeof (CHAR16)); + + if (VariableName != NULL) { + + OcAsciiStrToUnicode (Name, VariableName, 0); + + Size = 0; + Status = gRT->GetVariable ( + VariableName, + VendorGuid, + NULL, + &Size, + NULL + ); + + if (Status == EFI_BUFFER_TOO_SMALL && !OverideDefault) { + Status = EFI_WRITE_PROTECTED; + } else { + CHAR8 *DataString; + CHAR8 *AttributeString; + UINTN AttributeStringSize; + + Status = gRT->SetVariable ( + VariableName, + VendorGuid, + Attributes, + DataSize, + Data + ); + + AttributeStringSize = 32; + AttributeString = AllocateZeroPool (AttributeStringSize); + + if (AttributeString != NULL) { + // Convert Attributes into text string + + if ((Attributes & EFI_VARIABLE_NON_VOLATILE) != 0) { + AsciiStrCatS (AttributeString, AttributeStringSize, "+NV"); + } + + if ((Attributes & EFI_VARIABLE_RUNTIME_ACCESS) != 0) { + AsciiStrCatS (AttributeString, AttributeStringSize, "+RT+BS"); + } else if ((Attributes & EFI_VARIABLE_BOOTSERVICE_ACCESS) != 0) { + AsciiStrCatS (AttributeString, AttributeStringSize, "+BS"); + } + + if ((Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD) != 0) { + AsciiStrCatS (AttributeString, AttributeStringSize, "+HR"); + } + + if ((Attributes & EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS) != 0) { + AsciiStrCatS (AttributeString, AttributeStringSize, "+AW"); + } + + if ((Attributes & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) != 0) { + AsciiStrCatS (AttributeString, AttributeStringSize, "+AT"); + } + + // Remove leading + + if (AttributeString[0] == '+') { + CopyMem (AttributeString, (AttributeString + 1), AsciiStrSize (AttributeString + 1)); + } + + DataString = ConvertDataToString (Data, DataSize); + + if (DataString != NULL) { + DEBUG (( + DEBUG_VARIABLE, + "Setting %a %g:%s = %a (%d)\n", + AttributeString, + VendorGuid, + VariableName, + DataString, + DataSize + )); + + FreePool ((VOID *)DataString); + } else { + DEBUG (( + DEBUG_VARIABLE, + "Setting %a %g:%s (%d)\n", + AttributeString, + VendorGuid, + VariableName, + DataSize + )); + } + + FreePool ((VOID *)AttributeString); + } else { + Status = EFI_OUT_OF_RESOURCES; + } + + } + + } + + return Status; +} diff --git a/OcSupportPkg.dec b/OcSupportPkg.dec index 33838328..fb1dd104 100644 --- a/OcSupportPkg.dec +++ b/OcSupportPkg.dec @@ -22,6 +22,12 @@ [Includes] Include +[Guids] + gOcLogVariableGuid = { 0x4D1FDA02, 0x38C7, 0x4A6A, { 0x9C, 0xC6, 0x4B, 0xCC, 0xA8, 0xB3, 0x01, 0x02 }} + +[Protocols] + gOcLogProtocolGuid = { 0xDBB6008F, 0x89E4, 0x4272, { 0x98, 0x81, 0xCE, 0x3A, 0xFD, 0x97, 0x24, 0xD0 }} + [LibraryClasses] ## @libraryclass OcPngLib|Include/Library/OcPngLib.h @@ -35,4 +41,34 @@ ## @libraryclass OcAppleImageVerificationLib|Include/Library/OcAppleImageVerificationLib.h + ## @libraryclass + OcAcpiLib|Include/Library/OcAcpiLib.h + + ## @libraryclass + OcCpuLib|Include/Library/OcCpuLib.h + + ## @libraryclass + OcDevicePathLib|Include/Library/OcDevicePathLib.h + + ## @libraryclass + OcFileLib|Include/Library/OcFileLib.h + + ## @libraryclass + OcMiscLib|Include/Library/OcMiscLib.h + + ## @libraryclass + OcPrintLib|Include/Library/OcPrintLib.h + + ## @libraryclass + OcProtocolLib|Include/Library/OcProtocolLib.h + + ## @libraryclass + OcStringLib|Include/Library/OcStringLib.h + + ## @libraryclass + OcTimerLib|Include/Library/OcTimerLib.h + + ## @libraryclass + OcVariableLib|Include/Library/OcVariableLib.h + # [Protocols] diff --git a/OcSupportPkg.dsc b/OcSupportPkg.dsc index 9e804f6b..4466565d 100644 --- a/OcSupportPkg.dsc +++ b/OcSupportPkg.dsc @@ -46,12 +46,24 @@ UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf UefiUsbLib|MdePkg/Library/UefiUsbLib/UefiUsbLib.inf IoLib|MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf + PciLib|MdePkg/Library/BasePciLibCf8/BasePciLibCf8.inf [Components] OcSupportPkg/Library/OcAppleImageVerificationLib/OcAppleImageVerificationLib.inf OcSupportPkg/Library/OcCryptoLib/OcCryptoLib.inf OcSupportPkg/Library/OcOverflowLib/OcOverflowLib.inf OcSupportPkg/Library/OcPngLib/OcPngLib.inf + OcSupportPkg/Library/OcAcpiLib/OcAcpiLib.inf + OcSupportPkg/Library/OcCpuLib/OcCpuLib.inf + OcSupportPkg/Library/OcDebugLogLib/OcDebugLogLib.inf + OcSupportPkg/Library/OcDevicePathLib/OcDevicePathLib.inf + OcSupportPkg/Library/OcFileLib/OcFileLib.inf + OcSupportPkg/Library/OcMiscLib/OcMiscLib.inf + OcSupportPkg/Library/OcPrintLib/OcPrintLib.inf + OcSupportPkg/Library/OcProtocolLib/OcProtocolLib.inf + OcSupportPkg/Library/OcStringLib/OcStringLib.inf + OcSupportPkg/Library/OcTimerLib/OcTimerLib.inf + OcSupportPkg/Library/OcVariableLib/OcVariableLib.inf [PcdsFixedAtBuild] !if $(TARGET) == DEBUG