From f1ec65ba24e1c7ca07c971dd737932c756f5780d Mon Sep 17 00:00:00 2001 From: jljusten Date: Wed, 30 May 2012 23:14:38 +0000 Subject: [PATCH] OvmfPkg: Add QemuFwCfgLib library class and implementation QEMU's Firmware Configuration interface gives the firmware access to various types of information. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Jordan Justen Reviewed-by: Laszlo Ersek git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@13383 6f19259b-4bc3-4df7-8a09-765794883524 --- OvmfPkg/Include/Library/QemuFwCfgLib.h | 157 +++++++++++ .../Library/QemuFwCfgLib/Ia32/IoLibExAsm.S | 32 +++ .../Library/QemuFwCfgLib/Ia32/IoLibExAsm.asm | 40 +++ OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c | 246 ++++++++++++++++++ OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.inf | 53 ++++ OvmfPkg/Library/QemuFwCfgLib/X64/IoLibExAsm.S | 30 +++ .../Library/QemuFwCfgLib/X64/IoLibExAsm.asm | 36 +++ OvmfPkg/OvmfPkg.dec | 6 +- OvmfPkg/OvmfPkgIa32.dsc | 2 + OvmfPkg/OvmfPkgIa32X64.dsc | 1 + OvmfPkg/OvmfPkgX64.dsc | 1 + 11 files changed, 603 insertions(+), 1 deletion(-) create mode 100644 OvmfPkg/Include/Library/QemuFwCfgLib.h create mode 100644 OvmfPkg/Library/QemuFwCfgLib/Ia32/IoLibExAsm.S create mode 100644 OvmfPkg/Library/QemuFwCfgLib/Ia32/IoLibExAsm.asm create mode 100644 OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c create mode 100644 OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.inf create mode 100644 OvmfPkg/Library/QemuFwCfgLib/X64/IoLibExAsm.S create mode 100644 OvmfPkg/Library/QemuFwCfgLib/X64/IoLibExAsm.asm diff --git a/OvmfPkg/Include/Library/QemuFwCfgLib.h b/OvmfPkg/Include/Library/QemuFwCfgLib.h new file mode 100644 index 0000000000..5a3db7e809 --- /dev/null +++ b/OvmfPkg/Include/Library/QemuFwCfgLib.h @@ -0,0 +1,157 @@ +/** @file + QEMU/KVM Firmware Configuration access + + Copyright (c) 2011 - 2012, Intel Corporation. All rights reserved.
+ This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef __FW_CFG_LIB__ +#define __FW_CFG_LIB__ + +typedef enum { + QemuFwCfgItemSignature = 0x0000, + QemuFwCfgItemInterfaceVersion = 0x0001, + QemuFwCfgItemSystemUuid = 0x0002, + QemuFwCfgItemRamSize = 0x0003, + QemuFwCfgItemGraphicsEnabled = 0x0004, + QemuFwCfgItemSmpCpuCount = 0x0005, + QemuFwCfgItemMachineId = 0x0006, + QemuFwCfgItemKernelAddress = 0x0007, + QemuFwCfgItemKernelSize = 0x0008, + QemuFwCfgItemKernelCommandLine = 0x0009, + QemuFwCfgItemInitrdAddress = 0x000a, + QemuFwCfgItemInitrdSize = 0x000b, + QemuFwCfgItemBootDevice = 0x000c, + QemuFwCfgItemNumaData = 0x000d, + QemuFwCfgItemBootMenu = 0x000e, + QemuFwCfgItemMaximumCpuCount = 0x000f, + QemuFwCfgItemKernelEntry = 0x0010, + QemuFwCfgItemKernelData = 0x0011, + QemuFwCfgItemInitrdData = 0x0012, + QemuFwCfgItemCommandLineAddress = 0x0013, + QemuFwCfgItemCommandLineSize = 0x0014, + QemuFwCfgItemCommandLineData = 0x0015, + QemuFwCfgItemKernelSetupAddress = 0x0016, + QemuFwCfgItemKernelSetupSize = 0x0017, + QemuFwCfgItemKernelSetupData = 0x0018, + + QemuFwCfgItemX86AcpiTables = 0x8000, + QemuFwCfgItemX86SmbiosTables = 0x8001, + QemuFwCfgItemX86Irq0Override = 0x8002, + QemuFwCfgItemX86E820Table = 0x8003, + QemuFwCfgItemX86HpetData = 0x8004, + +} FIRMWARE_CONFIG_ITEM; + + +/** + Returns a boolean indicating if the firmware configuration interface + is available or not. + + @retval TRUE The interface is available + @retval FALSE The interface is not available + +**/ +BOOLEAN +EFIAPI +QemuFwCfgIsAvailable ( + VOID + ); + + +/** + Selects a firmware configuration item for reading. + + Following this call, any data read from this item will start from + the beginning of the configuration item's data. + + @param[in] QemuFwCfgItem - Firmware Configuration item to read + +**/ +VOID +EFIAPI +QemuFwCfgSelectItem ( + IN FIRMWARE_CONFIG_ITEM QemuFwCfgItem + ); + + +/** + Reads firmware configuration bytes into a buffer + + If called multiple times, then the data read will + continue at the offset of the firmware configuration + item where the previous read ended. + + @param[in] Size - Size in bytes to read + @param[in] Buffer - Buffer to store data into + +**/ +VOID +EFIAPI +QemuFwCfgReadBytes ( + IN UINTN Size, + IN VOID *Buffer OPTIONAL + ); + + +/** + Reads a UINT8 firmware configuration value + + @return Value of Firmware Configuration item read + +**/ +UINT8 +EFIAPI +QemuFwCfgRead8 ( + VOID + ); + + +/** + Reads a UINT16 firmware configuration value + + @return Value of Firmware Configuration item read + +**/ +UINT16 +EFIAPI +QemuFwCfgRead16 ( + VOID + ); + + +/** + Reads a UINT32 firmware configuration value + + @return Value of Firmware Configuration item read + +**/ +UINT32 +EFIAPI +QemuFwCfgRead32 ( + VOID + ); + + +/** + Reads a UINT64 firmware configuration value + + @return Value of Firmware Configuration item read + +**/ +UINT64 +EFIAPI +QemuFwCfgRead64 ( + VOID + ); + + +#endif + diff --git a/OvmfPkg/Library/QemuFwCfgLib/Ia32/IoLibExAsm.S b/OvmfPkg/Library/QemuFwCfgLib/Ia32/IoLibExAsm.S new file mode 100644 index 0000000000..a32b2c60c4 --- /dev/null +++ b/OvmfPkg/Library/QemuFwCfgLib/Ia32/IoLibExAsm.S @@ -0,0 +1,32 @@ +#------------------------------------------------------------------------------ +# +# Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.
+# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php. +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +#------------------------------------------------------------------------------ + +#------------------------------------------------------------------------------ +# VOID +# EFIAPI +# IoReadFifo8 ( +# IN UINTN Port, +# IN UINTN Size, +# IN VOID *Buffer +# ); +#------------------------------------------------------------------------------ +ASM_GLOBAL ASM_PFX(IoReadFifo8) +ASM_PFX(IoReadFifo8): + movw 4(%esp), %dx + movl 8(%esp), %ecx + pushl %edi + movl 16(%esp), %edi +rep insb + popl %edi + ret + diff --git a/OvmfPkg/Library/QemuFwCfgLib/Ia32/IoLibExAsm.asm b/OvmfPkg/Library/QemuFwCfgLib/Ia32/IoLibExAsm.asm new file mode 100644 index 0000000000..e46af81e8d --- /dev/null +++ b/OvmfPkg/Library/QemuFwCfgLib/Ia32/IoLibExAsm.asm @@ -0,0 +1,40 @@ +;------------------------------------------------------------------------------ +; +; Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.
+; This program and the accompanying materials +; are licensed and made available under the terms and conditions of the BSD License +; which accompanies this distribution. The full text of the license may be found at +; http://opensource.org/licenses/bsd-license.php. +; +; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +; +;------------------------------------------------------------------------------ + + .586P + .model flat,C + .code + +;------------------------------------------------------------------------------ +; VOID +; EFIAPI +; IoReadFifo8 ( +; IN UINTN Port, +; IN UINTN Size, +; IN VOID *Buffer +; ); +;------------------------------------------------------------------------------ +IoReadFifo8 PROC + + mov dx, [esp + 4] + mov ecx, [esp + 8] + push edi + mov edx, [esp + 16] +rep insb + pop edi + ret + +IoReadFifo8 ENDP + + END + diff --git a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c new file mode 100644 index 0000000000..b94dc67392 --- /dev/null +++ b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c @@ -0,0 +1,246 @@ +/** @file + + Copyright (c) 2011 - 2012, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include "Uefi.h" +#include +#include +#include +#include +#include +#include +#include + +STATIC BOOLEAN mQemuFwCfgSupported = FALSE; + + +/** + Reads an 8-bit I/O port fifo into a block of memory. + + Reads the 8-bit I/O fifo port specified by Port. + + The port is read Count times, and the read data is + stored in the provided Buffer. + + This function must guarantee that all I/O read and write operations are + serialized. + + If 8-bit I/O port operations are not supported, then ASSERT(). + + @param Port The I/O port to read. + @param Count The number of times to read I/O port. + @param Buffer The buffer to store the read data into. + +**/ +VOID +EFIAPI +IoReadFifo8 ( + IN UINTN Port, + IN UINTN Count, + OUT VOID *Buffer + ); + + +/** + Returns a boolean indicating if the firmware configuration interface + is available or not. + + @retval TRUE The interface is available + @retval FALSE The interface is not available + +**/ +BOOLEAN +EFIAPI +QemuFwCfgIsAvailable ( + VOID + ) +{ + return mQemuFwCfgSupported; +} + + +/** + Selects a firmware configuration item for reading. + + Following this call, any data read from this item will start from + the beginning of the configuration item's data. + + @param[in] QemuFwCfgItem - Firmware Configuration item to read + +**/ +VOID +EFIAPI +QemuFwCfgSelectItem ( + IN FIRMWARE_CONFIG_ITEM QemuFwCfgItem + ) +{ + DEBUG ((EFI_D_INFO, "Select Item: 0x%x\n", (UINT16)(UINTN) QemuFwCfgItem)); + IoWrite16 (0x510, (UINT16)(UINTN) QemuFwCfgItem); +} + + +/** + Reads firmware configuration bytes into a buffer + + @param[in] Size - Size in bytes to read + @param[in] Buffer - Buffer to store data into (OPTIONAL if Size is 0) + +**/ +VOID +EFIAPI +InternalQemuFwCfgReadBytes ( + IN UINTN Size, + IN VOID *Buffer OPTIONAL + ) +{ + IoReadFifo8 (0x511, Size, Buffer); +} + + +/** + Reads firmware configuration bytes into a buffer + + If called multiple times, then the data read will + continue at the offset of the firmware configuration + item where the previous read ended. + + @param[in] Size - Size in bytes to read + @param[in] Buffer - Buffer to store data into + +**/ +VOID +EFIAPI +QemuFwCfgReadBytes ( + IN UINTN Size, + IN VOID *Buffer + ) +{ + if (mQemuFwCfgSupported) { + InternalQemuFwCfgReadBytes (Size, Buffer); + } else { + ZeroMem (Buffer, Size); + } +} + + +/** + Reads a UINT8 firmware configuration value + + @return Value of Firmware Configuration item read + +**/ +UINT8 +EFIAPI +QemuFwCfgRead8 ( + VOID + ) +{ + UINT8 Result; + + QemuFwCfgReadBytes (sizeof (Result), &Result); + + return Result; +} + + +/** + Reads a UINT16 firmware configuration value + + @return Value of Firmware Configuration item read + +**/ +UINT16 +EFIAPI +QemuFwCfgRead16 ( + VOID + ) +{ + UINT16 Result; + + QemuFwCfgReadBytes (sizeof (Result), &Result); + + return Result; +} + + +/** + Reads a UINT32 firmware configuration value + + @return Value of Firmware Configuration item read + +**/ +UINT32 +EFIAPI +QemuFwCfgRead32 ( + VOID + ) +{ + UINT32 Result; + + QemuFwCfgReadBytes (sizeof (Result), &Result); + + return Result; +} + + +/** + Reads a UINT64 firmware configuration value + + @return Value of Firmware Configuration item read + +**/ +UINT64 +EFIAPI +QemuFwCfgRead64 ( + VOID + ) +{ + UINT64 Result; + + QemuFwCfgReadBytes (sizeof (Result), &Result); + + return Result; +} + + +RETURN_STATUS +EFIAPI +QemuFwCfgInitialize ( + VOID + ) +{ + UINT32 Signature; + UINT32 Revision; + + // + // Enable the access routines while probing to see if it is supported. + // + mQemuFwCfgSupported = TRUE; + + QemuFwCfgSelectItem (QemuFwCfgItemSignature); + Signature = QemuFwCfgRead32 (); + DEBUG ((EFI_D_INFO, "FW CFG Signature: 0x%x\n", Signature)); + QemuFwCfgSelectItem (QemuFwCfgItemInterfaceVersion); + Revision = QemuFwCfgRead32 (); + DEBUG ((EFI_D_INFO, "FW CFG Revision: 0x%x\n", Revision)); + if ((Signature != SIGNATURE_32 ('Q', 'E', 'M', 'U')) || + (Revision < 1) + ) { + DEBUG ((EFI_D_INFO, "QemuFwCfg interface not supported.\n")); + mQemuFwCfgSupported = FALSE; + return RETURN_SUCCESS; + } + + DEBUG ((EFI_D_INFO, "QemuFwCfg interface is supported.\n")); + return RETURN_SUCCESS; +} diff --git a/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.inf b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.inf new file mode 100644 index 0000000000..a5446f0b93 --- /dev/null +++ b/OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.inf @@ -0,0 +1,53 @@ +## @file +# +# Copyright (c) 2008 - 2012, Intel Corporation. All rights reserved.
+# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = QemuFwCfgLib + FILE_GUID = fdd53716-31e1-4acc-9007-8bd5d877c96f + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = QemuFwCfgLib + + CONSTRUCTOR = QemuFwCfgInitialize + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 +# + +[Sources] + QemuFwCfgLib.c + +[Sources.IA32] + Ia32/IoLibExAsm.asm + Ia32/IoLibExAsm.S + +[Sources.X64] + X64/IoLibExAsm.asm + X64/IoLibExAsm.S + +[Packages] + MdePkg/MdePkg.dec + OvmfPkg/OvmfPkg.dec + +[LibraryClasses] + BaseLib + BaseMemoryLib + DebugLib + IoLib + MemoryAllocationLib + UefiBootServicesTableLib + diff --git a/OvmfPkg/Library/QemuFwCfgLib/X64/IoLibExAsm.S b/OvmfPkg/Library/QemuFwCfgLib/X64/IoLibExAsm.S new file mode 100644 index 0000000000..b1125ed7da --- /dev/null +++ b/OvmfPkg/Library/QemuFwCfgLib/X64/IoLibExAsm.S @@ -0,0 +1,30 @@ +#------------------------------------------------------------------------------ +# +# Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.
+# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php. +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +#------------------------------------------------------------------------------ + +#------------------------------------------------------------------------------ +# VOID +# EFIAPI +# IoReadFifo8 ( +# IN UINTN Port, // rcx +# IN UINTN Size, // rdx +# IN VOID *Buffer // r8 +# ); +#------------------------------------------------------------------------------ +ASM_GLOBAL ASM_PFX(IoReadFifo8) +ASM_PFX(IoReadFifo8): + xchg %rcx, %rdx + xchg %r8, %rdi # rdi: buffer address; r8: save rdi +rep insb + mov %r8, %rdi # restore rdi + ret + diff --git a/OvmfPkg/Library/QemuFwCfgLib/X64/IoLibExAsm.asm b/OvmfPkg/Library/QemuFwCfgLib/X64/IoLibExAsm.asm new file mode 100644 index 0000000000..c60ad2c5d4 --- /dev/null +++ b/OvmfPkg/Library/QemuFwCfgLib/X64/IoLibExAsm.asm @@ -0,0 +1,36 @@ +;------------------------------------------------------------------------------ +; +; Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.
+; This program and the accompanying materials +; are licensed and made available under the terms and conditions of the BSD License +; which accompanies this distribution. The full text of the license may be found at +; http://opensource.org/licenses/bsd-license.php. +; +; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +; +;------------------------------------------------------------------------------ + + .code + +;------------------------------------------------------------------------------ +; VOID +; EFIAPI +; IoReadFifo8 ( +; IN UINTN Port, // rcx +; IN UINTN Size, // rdx +; IN VOID *Buffer // r8 +; ); +;------------------------------------------------------------------------------ +IoReadFifo8 PROC + + xchg rcx, rdx + xchg rdi, r8 ; rdi: buffer address; r8: save rdi +rep insb + mov rdi, r8 ; restore rdi + ret + +IoReadFifo8 ENDP + + END + diff --git a/OvmfPkg/OvmfPkg.dec b/OvmfPkg/OvmfPkg.dec index dd86bd7bb6..2a01968e1b 100644 --- a/OvmfPkg/OvmfPkg.dec +++ b/OvmfPkg/OvmfPkg.dec @@ -1,7 +1,7 @@ ## @file # EFI/Framework Open Virtual Machine Firmware (OVMF) platform # -# Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.
+# Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.
# # This program and the accompanying materials # are licensed and made available under the terms and conditions of the BSD License @@ -27,6 +27,10 @@ # NvVarsFileLib|Include/Library/NvVarsFileLib.h + ## @libraryclass Access QEMU's firmware configuration interface + # + QemuFwCfgLib|Include/Library/QemuFwCfgLib.h + ## @libraryclass Serialize (and deserialize) variables # SerializeVariablesLib|Include/Library/SerializeVariablesLib.h diff --git a/OvmfPkg/OvmfPkgIa32.dsc b/OvmfPkg/OvmfPkgIa32.dsc index c8522df735..ffd9238a71 100644 --- a/OvmfPkg/OvmfPkgIa32.dsc +++ b/OvmfPkg/OvmfPkgIa32.dsc @@ -94,6 +94,8 @@ DpcLib|MdeModulePkg/Library/DxeDpcLib/DxeDpcLib.inf UefiUsbLib|MdePkg/Library/UefiUsbLib/UefiUsbLib.inf SerializeVariablesLib|OvmfPkg/Library/SerializeVariablesLib/SerializeVariablesLib.inf + QemuFwCfgLib|OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.inf + LockBoxLib|MdeModulePkg/Library/LockBoxNullLib/LockBoxNullLib.inf !ifdef $(SOURCE_DEBUG_ENABLE) PeCoffExtraActionLib|SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/PeCoffExtraActionLibDebug.inf diff --git a/OvmfPkg/OvmfPkgIa32X64.dsc b/OvmfPkg/OvmfPkgIa32X64.dsc index fe09441482..fc2677f024 100644 --- a/OvmfPkg/OvmfPkgIa32X64.dsc +++ b/OvmfPkg/OvmfPkgIa32X64.dsc @@ -94,6 +94,7 @@ DpcLib|MdeModulePkg/Library/DxeDpcLib/DxeDpcLib.inf UefiUsbLib|MdePkg/Library/UefiUsbLib/UefiUsbLib.inf SerializeVariablesLib|OvmfPkg/Library/SerializeVariablesLib/SerializeVariablesLib.inf + QemuFwCfgLib|OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.inf LockBoxLib|MdeModulePkg/Library/LockBoxNullLib/LockBoxNullLib.inf !ifdef $(SOURCE_DEBUG_ENABLE) diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc index a312ddbe59..f2bd5a7a1f 100644 --- a/OvmfPkg/OvmfPkgX64.dsc +++ b/OvmfPkg/OvmfPkgX64.dsc @@ -94,6 +94,7 @@ DpcLib|MdeModulePkg/Library/DxeDpcLib/DxeDpcLib.inf UefiUsbLib|MdePkg/Library/UefiUsbLib/UefiUsbLib.inf SerializeVariablesLib|OvmfPkg/Library/SerializeVariablesLib/SerializeVariablesLib.inf + QemuFwCfgLib|OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgLib.inf LockBoxLib|MdeModulePkg/Library/LockBoxNullLib/LockBoxNullLib.inf !ifdef $(SOURCE_DEBUG_ENABLE) -- 2.39.2