diff options
| author | kx <kx@radix.pro> | 2024-06-04 06:43:08 +0300 |
|---|---|---|
| committer | kx <kx@radix.pro> | 2024-06-04 06:43:08 +0300 |
| commit | 7e2ccccace24636f29ddc210b94606abd4c7e42b (patch) | |
| tree | 545d43ea12671048956cafeb12303e84d601e571 /UnitTestFrameworkPkg/Library | |
| parent | 27b044605cd5f6b33a3d231576003850b3fe305b (diff) | |
| download | edk2-trunk.tar.xz | |
Renormalized end-of-lines from master@27b044605cd5f6b33a3d231576003850b3fe305btrunk
Diffstat (limited to 'UnitTestFrameworkPkg/Library')
68 files changed, 11032 insertions, 11032 deletions
diff --git a/UnitTestFrameworkPkg/Library/CmockaLib/CmockaLib.inf b/UnitTestFrameworkPkg/Library/CmockaLib/CmockaLib.inf index eeee6bc2b3..a9e06fbc4d 100644 --- a/UnitTestFrameworkPkg/Library/CmockaLib/CmockaLib.inf +++ b/UnitTestFrameworkPkg/Library/CmockaLib/CmockaLib.inf @@ -1,35 +1,35 @@ -## @file
-# This module provides Cmocka Library implementation.
-#
-# Copyright (c) 2019 - 2020, Intel Corporation. All rights reserved.<BR>
-# SPDX-License-Identifier: BSD-2-Clause-Patent
-#
-##
-
-[Defines]
- INF_VERSION = 0x00010005
- BASE_NAME = CmockaLib
- MODULE_UNI_FILE = CmockaLib.uni
- FILE_GUID = F1662152-3399-49AC-BE44-CAA97575FACE
- MODULE_TYPE = BASE
- VERSION_STRING = 0.1
- LIBRARY_CLASS = CmockaLib|HOST_APPLICATION
-
-#
-# VALID_ARCHITECTURES = IA32 X64
-#
-
-[Sources]
- cmocka/src/cmocka.c
-
-[Packages]
- UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec
-
-[BuildOptions]
- MSFT:*_*_*_CC_FLAGS == /c -DHAVE_VSNPRINTF -DHAVE_SNPRINTF /Zi
- MSFT:NOOPT_*_*_CC_FLAGS = /Od
-
- GCC:*_*_*_CC_FLAGS == -g -DHAVE_SIGNAL_H
- GCC:NOOPT_*_*_CC_FLAGS = -O0
- GCC:*_*_IA32_CC_FLAGS = -m32
- GCC:*_*_X64_CC_FLAGS = -m64
+## @file +# This module provides Cmocka Library implementation. +# +# Copyright (c) 2019 - 2020, Intel Corporation. All rights reserved.<BR> +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = CmockaLib + MODULE_UNI_FILE = CmockaLib.uni + FILE_GUID = F1662152-3399-49AC-BE44-CAA97575FACE + MODULE_TYPE = BASE + VERSION_STRING = 0.1 + LIBRARY_CLASS = CmockaLib|HOST_APPLICATION + +# +# VALID_ARCHITECTURES = IA32 X64 +# + +[Sources] + cmocka/src/cmocka.c + +[Packages] + UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec + +[BuildOptions] + MSFT:*_*_*_CC_FLAGS == /c -DHAVE_VSNPRINTF -DHAVE_SNPRINTF /Zi + MSFT:NOOPT_*_*_CC_FLAGS = /Od + + GCC:*_*_*_CC_FLAGS == -g -DHAVE_SIGNAL_H + GCC:NOOPT_*_*_CC_FLAGS = -O0 + GCC:*_*_IA32_CC_FLAGS = -m32 + GCC:*_*_X64_CC_FLAGS = -m64 diff --git a/UnitTestFrameworkPkg/Library/CmockaLib/CmockaLib.uni b/UnitTestFrameworkPkg/Library/CmockaLib/CmockaLib.uni index acdb72d075..5c415de89f 100644 --- a/UnitTestFrameworkPkg/Library/CmockaLib/CmockaLib.uni +++ b/UnitTestFrameworkPkg/Library/CmockaLib/CmockaLib.uni @@ -1,14 +1,14 @@ -// /** @file
-// This module provides Cmocka Library implementation.
-//
-// This module provides Cmocka Library implementation.
-//
-// Copyright (c) 2019 - 2020, Intel Corporation. All rights reserved.<BR>
-//
-// SPDX-License-Identifier: BSD-2-Clause-Patent
-//
-// **/
-
-#string STR_MODULE_ABSTRACT #language en-US "Cmocka Library implementation"
-
-#string STR_MODULE_DESCRIPTION #language en-US "This module provides Cmocka Library implementation."
+// /** @file +// This module provides Cmocka Library implementation. +// +// This module provides Cmocka Library implementation. +// +// Copyright (c) 2019 - 2020, Intel Corporation. All rights reserved.<BR> +// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + +#string STR_MODULE_ABSTRACT #language en-US "Cmocka Library implementation" + +#string STR_MODULE_DESCRIPTION #language en-US "This module provides Cmocka Library implementation." diff --git a/UnitTestFrameworkPkg/Library/FunctionMockLib/FunctionMockLib.c b/UnitTestFrameworkPkg/Library/FunctionMockLib/FunctionMockLib.c index b7bb23f186..2190f49cd9 100644 --- a/UnitTestFrameworkPkg/Library/FunctionMockLib/FunctionMockLib.c +++ b/UnitTestFrameworkPkg/Library/FunctionMockLib/FunctionMockLib.c @@ -1,7 +1,7 @@ -/** @file
- Macro-only FunctionMockLib library instance with no services.
-
- Copyright (c) 2023, Intel Corporation. All rights reserved.<BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
+/** @file + Macro-only FunctionMockLib library instance with no services. + + Copyright (c) 2023, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ diff --git a/UnitTestFrameworkPkg/Library/FunctionMockLib/FunctionMockLib.inf b/UnitTestFrameworkPkg/Library/FunctionMockLib/FunctionMockLib.inf index 44c5946be5..a1a2641dc9 100644 --- a/UnitTestFrameworkPkg/Library/FunctionMockLib/FunctionMockLib.inf +++ b/UnitTestFrameworkPkg/Library/FunctionMockLib/FunctionMockLib.inf @@ -1,31 +1,31 @@ -## @file
-# This module provides FunctionMockLib Library implementation.
-#
-# Copyright (c) 2023, Intel Corporation. All rights reserved.<BR>
-# SPDX-License-Identifier: BSD-2-Clause-Patent
-#
-##
-
-[Defines]
- INF_VERSION = 0x00010018
- BASE_NAME = FunctionMockLib
- MODULE_UNI_FILE = FunctionMockLib.uni
- FILE_GUID = DF1CAF2F-D584-4EC1-9ABF-07E8B10AD560
- MODULE_TYPE = HOST_APPLICATION
- VERSION_STRING = 0.1
- LIBRARY_CLASS = FunctionMockLib
-
-#
-# VALID_ARCHITECTURES = IA32 X64
-#
-
-[Sources]
- FunctionMockLib.c
-
-[LibraryClasses]
- GoogleTestLib
- SubhookLib
-
-[Packages]
- MdePkg/MdePkg.dec
- UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec
+## @file +# This module provides FunctionMockLib Library implementation. +# +# Copyright (c) 2023, Intel Corporation. All rights reserved.<BR> +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x00010018 + BASE_NAME = FunctionMockLib + MODULE_UNI_FILE = FunctionMockLib.uni + FILE_GUID = DF1CAF2F-D584-4EC1-9ABF-07E8B10AD560 + MODULE_TYPE = HOST_APPLICATION + VERSION_STRING = 0.1 + LIBRARY_CLASS = FunctionMockLib + +# +# VALID_ARCHITECTURES = IA32 X64 +# + +[Sources] + FunctionMockLib.c + +[LibraryClasses] + GoogleTestLib + SubhookLib + +[Packages] + MdePkg/MdePkg.dec + UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec diff --git a/UnitTestFrameworkPkg/Library/FunctionMockLib/FunctionMockLib.uni b/UnitTestFrameworkPkg/Library/FunctionMockLib/FunctionMockLib.uni index 13e5308ce0..012e563577 100644 --- a/UnitTestFrameworkPkg/Library/FunctionMockLib/FunctionMockLib.uni +++ b/UnitTestFrameworkPkg/Library/FunctionMockLib/FunctionMockLib.uni @@ -1,11 +1,11 @@ -// /** @file
-// This module provides FunctionMockLib Library implementation.
-//
-// Copyright (c) 2023, Intel Corporation. All rights reserved.<BR>
-// SPDX-License-Identifier: BSD-2-Clause-Patent
-//
-// **/
-
-#string STR_MODULE_ABSTRACT #language en-US "FunctionMockLib Library implementation"
-
-#string STR_MODULE_DESCRIPTION #language en-US "This module provides FunctionMockLib Library implementation."
+// /** @file +// This module provides FunctionMockLib Library implementation. +// +// Copyright (c) 2023, Intel Corporation. All rights reserved.<BR> +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + +#string STR_MODULE_ABSTRACT #language en-US "FunctionMockLib Library implementation" + +#string STR_MODULE_DESCRIPTION #language en-US "This module provides FunctionMockLib Library implementation." diff --git a/UnitTestFrameworkPkg/Library/GoogleTestLib/GoogleTestLib.inf b/UnitTestFrameworkPkg/Library/GoogleTestLib/GoogleTestLib.inf index 0c522832e9..c7c510f384 100644 --- a/UnitTestFrameworkPkg/Library/GoogleTestLib/GoogleTestLib.inf +++ b/UnitTestFrameworkPkg/Library/GoogleTestLib/GoogleTestLib.inf @@ -1,33 +1,33 @@ -## @file
-# This module provides GoogleTest Library implementation.
-#
-# Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
-# SPDX-License-Identifier: BSD-2-Clause-Patent
-#
-##
-
-[Defines]
- INF_VERSION = 0x00010018
- BASE_NAME = GoogleTestLib
- MODULE_UNI_FILE = GoogleTestLib.uni
- FILE_GUID = A90E4751-AD30-43CC-980B-01E356B49ADF
- MODULE_TYPE = HOST_APPLICATION
- VERSION_STRING = 0.1
- LIBRARY_CLASS = GoogleTestLib
-
-#
-# VALID_ARCHITECTURES = IA32 X64
-#
-
-[Sources]
- googletest/googletest/src/gtest-all.cc
- googletest/googlemock/src/gmock-all.cc
-
-[Packages]
- MdePkg/MdePkg.dec
- UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec
-
-[BuildOptions]
- MSFT:*_*_*_CC_FLAGS == /c /EHs /Zi /Od /MT
- GCC:*_*_IA32_CC_FLAGS == -g -c -fshort-wchar -fexceptions -O0 -m32 -malign-double -fno-pie
- GCC:*_*_X64_CC_FLAGS == -g -c -fshort-wchar -fexceptions -O0 -m64 -fno-pie "-DEFIAPI=__attribute__((ms_abi))"
+## @file +# This module provides GoogleTest Library implementation. +# +# Copyright (c) 2022, Intel Corporation. All rights reserved.<BR> +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x00010018 + BASE_NAME = GoogleTestLib + MODULE_UNI_FILE = GoogleTestLib.uni + FILE_GUID = A90E4751-AD30-43CC-980B-01E356B49ADF + MODULE_TYPE = HOST_APPLICATION + VERSION_STRING = 0.1 + LIBRARY_CLASS = GoogleTestLib + +# +# VALID_ARCHITECTURES = IA32 X64 +# + +[Sources] + googletest/googletest/src/gtest-all.cc + googletest/googlemock/src/gmock-all.cc + +[Packages] + MdePkg/MdePkg.dec + UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec + +[BuildOptions] + MSFT:*_*_*_CC_FLAGS == /c /EHs /Zi /Od /MT + GCC:*_*_IA32_CC_FLAGS == -g -c -fshort-wchar -fexceptions -O0 -m32 -malign-double -fno-pie + GCC:*_*_X64_CC_FLAGS == -g -c -fshort-wchar -fexceptions -O0 -m64 -fno-pie "-DEFIAPI=__attribute__((ms_abi))" diff --git a/UnitTestFrameworkPkg/Library/GoogleTestLib/GoogleTestLib.uni b/UnitTestFrameworkPkg/Library/GoogleTestLib/GoogleTestLib.uni index 695588ce3f..2a0af3f7f5 100644 --- a/UnitTestFrameworkPkg/Library/GoogleTestLib/GoogleTestLib.uni +++ b/UnitTestFrameworkPkg/Library/GoogleTestLib/GoogleTestLib.uni @@ -1,11 +1,11 @@ -// /** @file
-// This module provides GoogleTest Library implementation.
-//
-// Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
-// SPDX-License-Identifier: BSD-2-Clause-Patent
-//
-// **/
-
-#string STR_MODULE_ABSTRACT #language en-US "GoogleTest Library implementation"
-
-#string STR_MODULE_DESCRIPTION #language en-US "This module provides GoogleTest Library implementation."
+// /** @file +// This module provides GoogleTest Library implementation. +// +// Copyright (c) 2022, Intel Corporation. All rights reserved.<BR> +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + +#string STR_MODULE_ABSTRACT #language en-US "GoogleTest Library implementation" + +#string STR_MODULE_DESCRIPTION #language en-US "This module provides GoogleTest Library implementation." diff --git a/UnitTestFrameworkPkg/Library/Posix/DebugLibPosix/DebugLibPosix.c b/UnitTestFrameworkPkg/Library/Posix/DebugLibPosix/DebugLibPosix.c index 694f4beb8b..1156fab66a 100644 --- a/UnitTestFrameworkPkg/Library/Posix/DebugLibPosix/DebugLibPosix.c +++ b/UnitTestFrameworkPkg/Library/Posix/DebugLibPosix/DebugLibPosix.c @@ -1,279 +1,279 @@ -/** @file
- Instance of Debug Library based on POSIX APIs
-
- Uses Print Library to produce formatted output strings sent to printf().
-
- Copyright (c) 2018 - 2020, Intel Corporation. All rights reserved.<BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
-**/
-
-#include <stdio.h>
-
-#include <Base.h>
-#include <Library/DebugLib.h>
-#include <Library/BaseLib.h>
-#include <Library/PrintLib.h>
-#include <Library/BaseMemoryLib.h>
-
-///
-/// Define the maximum debug and assert message length that this library supports
-///
-#define MAX_DEBUG_MESSAGE_LENGTH 0x100
-
-/**
- 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,
- ...
- )
-{
- VA_LIST Marker;
-
- VA_START (Marker, Format);
- DebugVPrint (ErrorLevel, Format, Marker);
- VA_END (Marker);
-}
-
-/**
- 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 Format string for the debug message to print.
- @param VaListMarker VA_LIST marker for the variable argument list.
-
-**/
-VOID
-EFIAPI
-DebugVPrint (
- IN UINTN ErrorLevel,
- IN CONST CHAR8 *Format,
- IN VA_LIST VaListMarker
- )
-{
- CHAR8 Buffer[MAX_DEBUG_MESSAGE_LENGTH];
-
- AsciiVSPrint (Buffer, sizeof (Buffer), Format, VaListMarker);
- printf ("%s", Buffer);
-}
-
-/**
- Prints a debug message to the debug output device if the specified
- error level is enabled.
- This function use BASE_LIST which would provide a more compatible
- service than VA_LIST.
-
- 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 Format string for the debug message to print.
- @param BaseListMarker BASE_LIST marker for the variable argument list.
-
-**/
-VOID
-EFIAPI
-DebugBPrint (
- IN UINTN ErrorLevel,
- IN CONST CHAR8 *Format,
- IN BASE_LIST BaseListMarker
- )
-{
- CHAR8 Buffer[MAX_DEBUG_MESSAGE_LENGTH];
-
- AsciiBSPrint (Buffer, sizeof (Buffer), Format, BaseListMarker);
- printf ("%s", Buffer);
-}
-
-/**
- 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 <FileName>(<LineNumber>): <Description>\n"
- to the debug output device. If DEBUG_PROPERTY_ASSERT_BREAKPOINT_ENABLED bit of
- PcdDebugPropertyMask is set then CpuBreakpoint() is called. Otherwise, if
- DEBUG_PROPERTY_ASSERT_DEADLOOP_ENABLED bit of PcdDebugPropertyMask 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 <FileName> string of "(NULL) Filename" is printed.
- If Description is NULL, then a <Description> 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
- )
-{
- printf ("ASSERT: %s(%d): %s\n", FileName, (INT32)(UINT32)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 ();
- }
-}
-
-/**
- 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
- )
-{
- //
- // If Buffer is NULL, then ASSERT().
- //
- ASSERT (Buffer != NULL);
-
- //
- // SetMem() checks for the the ASSERT() condition on Length and returns Buffer
- //
- return SetMem (Buffer, Length, PcdGet8 (PcdDebugClearMemoryValue));
-}
-
-/**
- Returns TRUE if ASSERT() macros are enabled.
-
- This function returns TRUE if the DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of
- PcdDebugPropertyMask is set. Otherwise FALSE is returned.
-
- @retval TRUE The DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of PcdDebugPropertyMask is set.
- @retval FALSE The DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of PcdDebugPropertyMask is clear.
-
-**/
-BOOLEAN
-EFIAPI
-DebugAssertEnabled (
- VOID
- )
-{
- return (BOOLEAN)((PcdGet8 (PcdDebugPropertyMask) & DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED) != 0);
-}
-
-/**
- Returns TRUE if DEBUG() macros are enabled.
-
- This function returns TRUE if the DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of
- PcdDebugPropertyMask is set. Otherwise FALSE is returned.
-
- @retval TRUE The DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of PcdDebugPropertyMask is set.
- @retval FALSE The DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of PcdDebugPropertyMask is clear.
-
-**/
-BOOLEAN
-EFIAPI
-DebugPrintEnabled (
- VOID
- )
-{
- return (BOOLEAN)((PcdGet8 (PcdDebugPropertyMask) & DEBUG_PROPERTY_DEBUG_PRINT_ENABLED) != 0);
-}
-
-/**
- Returns TRUE if DEBUG_CODE() macros are enabled.
-
- This function returns TRUE if the DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of
- PcdDebugPropertyMask is set. Otherwise FALSE is returned.
-
- @retval TRUE The DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of PcdDebugPropertyMask is set.
- @retval FALSE The DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of PcdDebugPropertyMask is clear.
-
-**/
-BOOLEAN
-EFIAPI
-DebugCodeEnabled (
- VOID
- )
-{
- return (BOOLEAN)((PcdGet8 (PcdDebugPropertyMask) & DEBUG_PROPERTY_DEBUG_CODE_ENABLED) != 0);
-}
-
-/**
- Returns TRUE if DEBUG_CLEAR_MEMORY() macro is enabled.
-
- This function returns TRUE if the DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED bit of
- PcdDebugPropertyMask is set. Otherwise FALSE is returned.
-
- @retval TRUE The DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED bit of PcdDebugPropertyMask is set.
- @retval FALSE The DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED bit of PcdDebugPropertyMask is clear.
-
-**/
-BOOLEAN
-EFIAPI
-DebugClearMemoryEnabled (
- VOID
- )
-{
- return (BOOLEAN)((PcdGet8 (PcdDebugPropertyMask) & DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED) != 0);
-}
-
-/**
- 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);
-}
+/** @file + Instance of Debug Library based on POSIX APIs + + Uses Print Library to produce formatted output strings sent to printf(). + + Copyright (c) 2018 - 2020, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include <stdio.h> + +#include <Base.h> +#include <Library/DebugLib.h> +#include <Library/BaseLib.h> +#include <Library/PrintLib.h> +#include <Library/BaseMemoryLib.h> + +/// +/// Define the maximum debug and assert message length that this library supports +/// +#define MAX_DEBUG_MESSAGE_LENGTH 0x100 + +/** + 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, + ... + ) +{ + VA_LIST Marker; + + VA_START (Marker, Format); + DebugVPrint (ErrorLevel, Format, Marker); + VA_END (Marker); +} + +/** + 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 Format string for the debug message to print. + @param VaListMarker VA_LIST marker for the variable argument list. + +**/ +VOID +EFIAPI +DebugVPrint ( + IN UINTN ErrorLevel, + IN CONST CHAR8 *Format, + IN VA_LIST VaListMarker + ) +{ + CHAR8 Buffer[MAX_DEBUG_MESSAGE_LENGTH]; + + AsciiVSPrint (Buffer, sizeof (Buffer), Format, VaListMarker); + printf ("%s", Buffer); +} + +/** + Prints a debug message to the debug output device if the specified + error level is enabled. + This function use BASE_LIST which would provide a more compatible + service than VA_LIST. + + 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 Format string for the debug message to print. + @param BaseListMarker BASE_LIST marker for the variable argument list. + +**/ +VOID +EFIAPI +DebugBPrint ( + IN UINTN ErrorLevel, + IN CONST CHAR8 *Format, + IN BASE_LIST BaseListMarker + ) +{ + CHAR8 Buffer[MAX_DEBUG_MESSAGE_LENGTH]; + + AsciiBSPrint (Buffer, sizeof (Buffer), Format, BaseListMarker); + printf ("%s", Buffer); +} + +/** + 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 <FileName>(<LineNumber>): <Description>\n" + to the debug output device. If DEBUG_PROPERTY_ASSERT_BREAKPOINT_ENABLED bit of + PcdDebugPropertyMask is set then CpuBreakpoint() is called. Otherwise, if + DEBUG_PROPERTY_ASSERT_DEADLOOP_ENABLED bit of PcdDebugPropertyMask 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 <FileName> string of "(NULL) Filename" is printed. + If Description is NULL, then a <Description> 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 + ) +{ + printf ("ASSERT: %s(%d): %s\n", FileName, (INT32)(UINT32)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 (); + } +} + +/** + 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 + ) +{ + // + // If Buffer is NULL, then ASSERT(). + // + ASSERT (Buffer != NULL); + + // + // SetMem() checks for the the ASSERT() condition on Length and returns Buffer + // + return SetMem (Buffer, Length, PcdGet8 (PcdDebugClearMemoryValue)); +} + +/** + Returns TRUE if ASSERT() macros are enabled. + + This function returns TRUE if the DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of + PcdDebugPropertyMask is set. Otherwise FALSE is returned. + + @retval TRUE The DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of PcdDebugPropertyMask is set. + @retval FALSE The DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED bit of PcdDebugPropertyMask is clear. + +**/ +BOOLEAN +EFIAPI +DebugAssertEnabled ( + VOID + ) +{ + return (BOOLEAN)((PcdGet8 (PcdDebugPropertyMask) & DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED) != 0); +} + +/** + Returns TRUE if DEBUG() macros are enabled. + + This function returns TRUE if the DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of + PcdDebugPropertyMask is set. Otherwise FALSE is returned. + + @retval TRUE The DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of PcdDebugPropertyMask is set. + @retval FALSE The DEBUG_PROPERTY_DEBUG_PRINT_ENABLED bit of PcdDebugPropertyMask is clear. + +**/ +BOOLEAN +EFIAPI +DebugPrintEnabled ( + VOID + ) +{ + return (BOOLEAN)((PcdGet8 (PcdDebugPropertyMask) & DEBUG_PROPERTY_DEBUG_PRINT_ENABLED) != 0); +} + +/** + Returns TRUE if DEBUG_CODE() macros are enabled. + + This function returns TRUE if the DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of + PcdDebugPropertyMask is set. Otherwise FALSE is returned. + + @retval TRUE The DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of PcdDebugPropertyMask is set. + @retval FALSE The DEBUG_PROPERTY_DEBUG_CODE_ENABLED bit of PcdDebugPropertyMask is clear. + +**/ +BOOLEAN +EFIAPI +DebugCodeEnabled ( + VOID + ) +{ + return (BOOLEAN)((PcdGet8 (PcdDebugPropertyMask) & DEBUG_PROPERTY_DEBUG_CODE_ENABLED) != 0); +} + +/** + Returns TRUE if DEBUG_CLEAR_MEMORY() macro is enabled. + + This function returns TRUE if the DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED bit of + PcdDebugPropertyMask is set. Otherwise FALSE is returned. + + @retval TRUE The DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED bit of PcdDebugPropertyMask is set. + @retval FALSE The DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED bit of PcdDebugPropertyMask is clear. + +**/ +BOOLEAN +EFIAPI +DebugClearMemoryEnabled ( + VOID + ) +{ + return (BOOLEAN)((PcdGet8 (PcdDebugPropertyMask) & DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED) != 0); +} + +/** + 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/UnitTestFrameworkPkg/Library/Posix/DebugLibPosix/DebugLibPosix.inf b/UnitTestFrameworkPkg/Library/Posix/DebugLibPosix/DebugLibPosix.inf index 5babbca3b0..3a52e9cefe 100644 --- a/UnitTestFrameworkPkg/Library/Posix/DebugLibPosix/DebugLibPosix.inf +++ b/UnitTestFrameworkPkg/Library/Posix/DebugLibPosix/DebugLibPosix.inf @@ -1,35 +1,35 @@ -## @file
-# Instance of Debug Library based on POSIX APIs
-#
-# Uses Print Library to produce formatted output strings sent to printf().
-#
-# Copyright (c) 2018 - 2020, Intel Corporation. All rights reserved.<BR>
-# SPDX-License-Identifier: BSD-2-Clause-Patent
-#
-##
-
-[Defines]
- INF_VERSION = 0x00010005
- BASE_NAME = DebugLibPosix
- MODULE_UNI_FILE = DebugLibPosix.uni
- FILE_GUID = 6A77CE89-C1B6-4A6B-9561-07D7127514A7
- MODULE_TYPE = BASE
- VERSION_STRING = 1.0
- LIBRARY_CLASS = DebugLib|HOST_APPLICATION
-
-[Sources]
- DebugLibPosix.c
-
-[Packages]
- MdePkg/MdePkg.dec
-
-[LibraryClasses]
- BaseMemoryLib
- PcdLib
- PrintLib
- BaseLib
-
-[Pcd]
- gEfiMdePkgTokenSpaceGuid.PcdDebugClearMemoryValue ## SOMETIMES_CONSUMES
- gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask ## CONSUMES
- gEfiMdePkgTokenSpaceGuid.PcdFixedDebugPrintErrorLevel ## CONSUMES
+## @file +# Instance of Debug Library based on POSIX APIs +# +# Uses Print Library to produce formatted output strings sent to printf(). +# +# Copyright (c) 2018 - 2020, Intel Corporation. All rights reserved.<BR> +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = DebugLibPosix + MODULE_UNI_FILE = DebugLibPosix.uni + FILE_GUID = 6A77CE89-C1B6-4A6B-9561-07D7127514A7 + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = DebugLib|HOST_APPLICATION + +[Sources] + DebugLibPosix.c + +[Packages] + MdePkg/MdePkg.dec + +[LibraryClasses] + BaseMemoryLib + PcdLib + PrintLib + BaseLib + +[Pcd] + gEfiMdePkgTokenSpaceGuid.PcdDebugClearMemoryValue ## SOMETIMES_CONSUMES + gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask ## CONSUMES + gEfiMdePkgTokenSpaceGuid.PcdFixedDebugPrintErrorLevel ## CONSUMES diff --git a/UnitTestFrameworkPkg/Library/Posix/DebugLibPosix/DebugLibPosix.uni b/UnitTestFrameworkPkg/Library/Posix/DebugLibPosix/DebugLibPosix.uni index d34f1a05be..3fea8f7cc4 100644 --- a/UnitTestFrameworkPkg/Library/Posix/DebugLibPosix/DebugLibPosix.uni +++ b/UnitTestFrameworkPkg/Library/Posix/DebugLibPosix/DebugLibPosix.uni @@ -1,14 +1,14 @@ -// /** @file
-// Instance of Debug Library based on POSIX APIs
-//
-// Uses Print Library to produce formatted output strings sent to printf().
-//
-// Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
-//
-// SPDX-License-Identifier: BSD-2-Clause-Patent
-//
-// **/
-
-#string STR_MODULE_ABSTRACT #language en-US "Instance of Debug Library based on POSIX APIs"
-
-#string STR_MODULE_DESCRIPTION #language en-US "Uses Print Library to produce formatted output strings sent to printf()."
+// /** @file +// Instance of Debug Library based on POSIX APIs +// +// Uses Print Library to produce formatted output strings sent to printf(). +// +// Copyright (c) 2020, Intel Corporation. All rights reserved.<BR> +// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + +#string STR_MODULE_ABSTRACT #language en-US "Instance of Debug Library based on POSIX APIs" + +#string STR_MODULE_DESCRIPTION #language en-US "Uses Print Library to produce formatted output strings sent to printf()." diff --git a/UnitTestFrameworkPkg/Library/Posix/MemoryAllocationLibPosix/MemoryAllocationLibPosix.c b/UnitTestFrameworkPkg/Library/Posix/MemoryAllocationLibPosix/MemoryAllocationLibPosix.c index 54029283fb..9b9653e3a0 100644 --- a/UnitTestFrameworkPkg/Library/Posix/MemoryAllocationLibPosix/MemoryAllocationLibPosix.c +++ b/UnitTestFrameworkPkg/Library/Posix/MemoryAllocationLibPosix/MemoryAllocationLibPosix.c @@ -1,638 +1,638 @@ -/** @file
- Instance of Memory Allocation Library based on POSIX APIs
-
- Uses POSIX APIs malloc() and free() to allocate and free memory.
-
- Copyright (c) 2018 - 2020, Intel Corporation. All rights reserved.<BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
-**/
-
-#include <stdlib.h>
-#include <string.h>
-
-#include <Uefi.h>
-#include <Library/MemoryAllocationLib.h>
-#include <Library/DebugLib.h>
-
-///
-/// Signature for PAGE_HEAD structure
-/// Used to verify that buffer being freed was allocated by this library.
-///
-#define PAGE_HEAD_PRIVATE_SIGNATURE SIGNATURE_32 ('P', 'H', 'D', 'R')
-
-///
-/// Structure placed immediately before an aligned allocation to store the
-/// information required to free the entire buffer allocated to support then
-/// aligned allocation.
-///
-typedef struct {
- UINT32 Signature;
- VOID *AllocatedBufffer;
- UINTN TotalPages;
- VOID *AlignedBuffer;
- UINTN AlignedPages;
-} PAGE_HEAD;
-
-/**
- Allocates one or more 4KB pages of type EfiBootServicesData.
-
- Allocates the number of 4KB pages of type EfiBootServicesData and returns a pointer to the
- allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL
- is returned. If there is not enough memory remaining to satisfy the request, then NULL is
- returned.
-
- @param Pages The number of 4 KB pages to allocate.
-
- @return A pointer to the allocated buffer or NULL if allocation fails.
-
-**/
-VOID *
-EFIAPI
-AllocatePages (
- IN UINTN Pages
- )
-{
- return AllocateAlignedPages (Pages, SIZE_4KB);
-}
-
-/**
- Allocates one or more 4KB pages of type EfiRuntimeServicesData.
-
- Allocates the number of 4KB pages of type EfiRuntimeServicesData and returns a pointer to the
- allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL
- is returned. If there is not enough memory remaining to satisfy the request, then NULL is
- returned.
-
- @param Pages The number of 4 KB pages to allocate.
-
- @return A pointer to the allocated buffer or NULL if allocation fails.
-
-**/
-VOID *
-EFIAPI
-AllocateRuntimePages (
- IN UINTN Pages
- )
-{
- return AllocatePages (Pages);
-}
-
-/**
- Allocates one or more 4KB pages of type EfiReservedMemoryType.
-
- Allocates the number of 4KB pages of type EfiReservedMemoryType and returns a pointer to the
- allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL
- is returned. If there is not enough memory remaining to satisfy the request, then NULL is
- returned.
-
- @param Pages The number of 4 KB pages to allocate.
-
- @return A pointer to the allocated buffer or NULL if allocation fails.
-
-**/
-VOID *
-EFIAPI
-AllocateReservedPages (
- IN UINTN Pages
- )
-{
- return AllocatePages (Pages);
-}
-
-/**
- Frees one or more 4KB pages that were previously allocated with one of the page allocation
- functions in the Memory Allocation Library.
-
- Frees the number of 4KB pages specified by Pages from the buffer specified by Buffer. Buffer
- must have been allocated on a previous call to the page allocation services of the Memory
- Allocation Library. If it is not possible to free allocated pages, then this function will
- perform no actions.
-
- If Buffer was not allocated with a page allocation function in the Memory Allocation Library,
- then ASSERT().
- If Pages is zero, then ASSERT().
-
- @param Buffer The pointer to the buffer of pages to free.
- @param Pages The number of 4 KB pages to free.
-
-**/
-VOID
-EFIAPI
-FreePages (
- IN VOID *Buffer,
- IN UINTN Pages
- )
-{
- FreeAlignedPages (Buffer, Pages);
-}
-
-/**
- Allocates one or more 4KB pages of type EfiBootServicesData at a specified alignment.
-
- Allocates the number of 4KB pages specified by Pages of type EfiBootServicesData with an
- alignment specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is
- returned. If there is not enough memory at the specified alignment remaining to satisfy the
- request, then NULL is returned.
-
- If Alignment is not a power of two and Alignment is not zero, then ASSERT().
- If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT().
-
- @param Pages The number of 4 KB pages to allocate.
- @param Alignment The requested alignment of the allocation. Must be a power of two.
- If Alignment is zero, then byte alignment is used.
-
- @return A pointer to the allocated buffer or NULL if allocation fails.
-
-**/VOID *
-EFIAPI
-AllocateAlignedPages (
- IN UINTN Pages,
- IN UINTN Alignment
- )
-{
- PAGE_HEAD PageHead;
- PAGE_HEAD *PageHeadPtr;
- UINTN AlignmentMask;
-
- ASSERT ((Alignment & (Alignment - 1)) == 0);
-
- if (Alignment < SIZE_4KB) {
- Alignment = SIZE_4KB;
- }
-
- AlignmentMask = Alignment - 1;
-
- //
- // We need reserve Alignment pages for PAGE_HEAD, as meta data.
- //
- PageHead.Signature = PAGE_HEAD_PRIVATE_SIGNATURE;
- PageHead.TotalPages = Pages + EFI_SIZE_TO_PAGES (Alignment) * 2;
- PageHead.AlignedPages = Pages;
- PageHead.AllocatedBufffer = malloc (EFI_PAGES_TO_SIZE (PageHead.TotalPages));
- if (PageHead.AllocatedBufffer == NULL) {
- return NULL;
- }
-
- PageHead.AlignedBuffer = (VOID *)(((UINTN)PageHead.AllocatedBufffer + AlignmentMask) & ~AlignmentMask);
- if ((UINTN)PageHead.AlignedBuffer - (UINTN)PageHead.AllocatedBufffer < sizeof (PAGE_HEAD)) {
- PageHead.AlignedBuffer = (VOID *)((UINTN)PageHead.AlignedBuffer + Alignment);
- }
-
- PageHeadPtr = (VOID *)((UINTN)PageHead.AlignedBuffer - sizeof (PAGE_HEAD));
- memcpy (PageHeadPtr, &PageHead, sizeof (PAGE_HEAD));
-
- return PageHead.AlignedBuffer;
-}
-
-/**
- Allocates one or more 4KB pages of type EfiRuntimeServicesData at a specified alignment.
-
- Allocates the number of 4KB pages specified by Pages of type EfiRuntimeServicesData with an
- alignment specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is
- returned. If there is not enough memory at the specified alignment remaining to satisfy the
- request, then NULL is returned.
-
- If Alignment is not a power of two and Alignment is not zero, then ASSERT().
- If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT().
-
- @param Pages The number of 4 KB pages to allocate.
- @param Alignment The requested alignment of the allocation. Must be a power of two.
- If Alignment is zero, then byte alignment is used.
-
- @return A pointer to the allocated buffer or NULL if allocation fails.
-
-**/
-VOID *
-EFIAPI
-AllocateAlignedRuntimePages (
- IN UINTN Pages,
- IN UINTN Alignment
- )
-{
- return AllocateAlignedPages (Pages, Alignment);
-}
-
-/**
- Allocates one or more 4KB pages of type EfiReservedMemoryType at a specified alignment.
-
- Allocates the number of 4KB pages specified by Pages of type EfiReservedMemoryType with an
- alignment specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is
- returned. If there is not enough memory at the specified alignment remaining to satisfy the
- request, then NULL is returned.
-
- If Alignment is not a power of two and Alignment is not zero, then ASSERT().
- If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT().
-
- @param Pages The number of 4 KB pages to allocate.
- @param Alignment The requested alignment of the allocation. Must be a power of two.
- If Alignment is zero, then byte alignment is used.
-
- @return A pointer to the allocated buffer or NULL if allocation fails.
-
-**/
-VOID *
-EFIAPI
-AllocateAlignedReservedPages (
- IN UINTN Pages,
- IN UINTN Alignment
- )
-{
- return AllocateAlignedPages (Pages, Alignment);
-}
-
-/**
- Frees one or more 4KB pages that were previously allocated with one of the aligned page
- allocation functions in the Memory Allocation Library.
-
- Frees the number of 4KB pages specified by Pages from the buffer specified by Buffer. Buffer
- must have been allocated on a previous call to the aligned page allocation services of the Memory
- Allocation Library. If it is not possible to free allocated pages, then this function will
- perform no actions.
-
- If Buffer was not allocated with an aligned page allocation function in the Memory Allocation
- Library, then ASSERT().
- If Pages is zero, then ASSERT().
-
- @param Buffer The pointer to the buffer of pages to free.
- @param Pages The number of 4 KB pages to free.
-
-**/
-VOID
-EFIAPI
-FreeAlignedPages (
- IN VOID *Buffer,
- IN UINTN Pages
- )
-{
- PAGE_HEAD *PageHeadPtr;
-
- //
- // NOTE: Partial free is not supported. Just keep it.
- //
- PageHeadPtr = (VOID *)((UINTN)Buffer - sizeof (PAGE_HEAD));
- if (PageHeadPtr->Signature != PAGE_HEAD_PRIVATE_SIGNATURE) {
- return;
- }
-
- if (PageHeadPtr->AlignedPages != Pages) {
- return;
- }
-
- PageHeadPtr->Signature = 0;
- free (PageHeadPtr->AllocatedBufffer);
-}
-
-/**
- Allocates a buffer of type EfiBootServicesData.
-
- Allocates the number bytes specified by AllocationSize of type EfiBootServicesData and returns a
- pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is
- returned. If there is not enough memory remaining to satisfy the request, then NULL is returned.
-
- @param AllocationSize The number of bytes to allocate.
-
- @return A pointer to the allocated buffer or NULL if allocation fails.
-
-**/VOID *
-EFIAPI
-AllocatePool (
- IN UINTN AllocationSize
- )
-{
- return malloc (AllocationSize);
-}
-
-/**
- Allocates a buffer of type EfiRuntimeServicesData.
-
- Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData and returns
- a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is
- returned. If there is not enough memory remaining to satisfy the request, then NULL is returned.
-
- @param AllocationSize The number of bytes to allocate.
-
- @return A pointer to the allocated buffer or NULL if allocation fails.
-
-**/
-VOID *
-EFIAPI
-AllocateRuntimePool (
- IN UINTN AllocationSize
- )
-{
- return AllocatePool (AllocationSize);
-}
-
-/**
- Allocates a buffer of type EfiReservedMemoryType.
-
- Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType and returns
- a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is
- returned. If there is not enough memory remaining to satisfy the request, then NULL is returned.
-
- @param AllocationSize The number of bytes to allocate.
-
- @return A pointer to the allocated buffer or NULL if allocation fails.
-
-**/
-VOID *
-EFIAPI
-AllocateReservedPool (
- IN UINTN AllocationSize
- )
-{
- return AllocatePool (AllocationSize);
-}
-
-/**
- Allocates and zeros a buffer of type EfiBootServicesData.
-
- Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, clears the
- buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a
- valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the
- request, then NULL is returned.
-
- @param AllocationSize The number of bytes to allocate and zero.
-
- @return A pointer to the allocated buffer or NULL if allocation fails.
-
-**/
-VOID *
-EFIAPI
-AllocateZeroPool (
- IN UINTN AllocationSize
- )
-{
- VOID *Buffer;
-
- Buffer = malloc (AllocationSize);
- if (Buffer == NULL) {
- return NULL;
- }
-
- memset (Buffer, 0, AllocationSize);
- return Buffer;
-}
-
-/**
- Allocates and zeros a buffer of type EfiRuntimeServicesData.
-
- Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, clears the
- buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a
- valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the
- request, then NULL is returned.
-
- @param AllocationSize The number of bytes to allocate and zero.
-
- @return A pointer to the allocated buffer or NULL if allocation fails.
-
-**/
-VOID *
-EFIAPI
-AllocateRuntimeZeroPool (
- IN UINTN AllocationSize
- )
-{
- return AllocateZeroPool (AllocationSize);
-}
-
-/**
- Allocates and zeros a buffer of type EfiReservedMemoryType.
-
- Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, clears the
- buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a
- valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the
- request, then NULL is returned.
-
- @param AllocationSize The number of bytes to allocate and zero.
-
- @return A pointer to the allocated buffer or NULL if allocation fails.
-
-**/
-VOID *
-EFIAPI
-AllocateReservedZeroPool (
- IN UINTN AllocationSize
- )
-{
- return AllocateZeroPool (AllocationSize);
-}
-
-/**
- Copies a buffer to an allocated buffer of type EfiBootServicesData.
-
- Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, copies
- AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the
- allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there
- is not enough memory remaining to satisfy the request, then NULL is returned.
-
- If Buffer is NULL, then ASSERT().
- If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
-
- @param AllocationSize The number of bytes to allocate and zero.
- @param Buffer The buffer to copy to the allocated buffer.
-
- @return A pointer to the allocated buffer or NULL if allocation fails.
-
-**/
-VOID *
-EFIAPI
-AllocateCopyPool (
- IN UINTN AllocationSize,
- IN CONST VOID *Buffer
- )
-{
- VOID *Memory;
-
- Memory = malloc (AllocationSize);
- if (Memory == NULL) {
- return NULL;
- }
-
- memcpy (Memory, Buffer, AllocationSize);
- return Memory;
-}
-
-/**
- Copies a buffer to an allocated buffer of type EfiRuntimeServicesData.
-
- Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, copies
- AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the
- allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there
- is not enough memory remaining to satisfy the request, then NULL is returned.
-
- If Buffer is NULL, then ASSERT().
- If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
-
- @param AllocationSize The number of bytes to allocate and zero.
- @param Buffer The buffer to copy to the allocated buffer.
-
- @return A pointer to the allocated buffer or NULL if allocation fails.
-
-**/
-VOID *
-EFIAPI
-AllocateRuntimeCopyPool (
- IN UINTN AllocationSize,
- IN CONST VOID *Buffer
- )
-{
- return AllocateCopyPool (AllocationSize, Buffer);
-}
-
-/**
- Copies a buffer to an allocated buffer of type EfiReservedMemoryType.
-
- Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, copies
- AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the
- allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there
- is not enough memory remaining to satisfy the request, then NULL is returned.
-
- If Buffer is NULL, then ASSERT().
- If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
-
- @param AllocationSize The number of bytes to allocate and zero.
- @param Buffer The buffer to copy to the allocated buffer.
-
- @return A pointer to the allocated buffer or NULL if allocation fails.
-
-**/
-VOID *
-EFIAPI
-AllocateReservedCopyPool (
- IN UINTN AllocationSize,
- IN CONST VOID *Buffer
- )
-{
- return AllocateCopyPool (AllocationSize, Buffer);
-}
-
-/**
- Reallocates a buffer of type EfiBootServicesData.
-
- Allocates and zeros the number bytes specified by NewSize from memory of type
- EfiBootServicesData. If OldBuffer is not NULL, then the smaller of OldSize and
- NewSize bytes are copied from OldBuffer to the newly allocated buffer, and
- OldBuffer is freed. A pointer to the newly allocated buffer is returned.
- If NewSize is 0, then a valid buffer of 0 size is returned. If there is not
- enough memory remaining to satisfy the request, then NULL is returned.
-
- If the allocation of the new buffer is successful and the smaller of NewSize and OldSize
- is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().
-
- @param OldSize The size, in bytes, of OldBuffer.
- @param NewSize The size, in bytes, of the buffer to reallocate.
- @param OldBuffer The buffer to copy to the allocated buffer. This is an optional
- parameter that may be NULL.
-
- @return A pointer to the allocated buffer or NULL if allocation fails.
-
-**/
-VOID *
-EFIAPI
-ReallocatePool (
- IN UINTN OldSize,
- IN UINTN NewSize,
- IN VOID *OldBuffer OPTIONAL
- )
-{
- VOID *NewBuffer;
-
- NewBuffer = malloc (NewSize);
- if ((NewBuffer != NULL) && (OldBuffer != NULL)) {
- memcpy (NewBuffer, OldBuffer, MIN (OldSize, NewSize));
- }
-
- if (OldBuffer != NULL) {
- FreePool (OldBuffer);
- }
-
- return NewBuffer;
-}
-
-/**
- Reallocates a buffer of type EfiRuntimeServicesData.
-
- Allocates and zeros the number bytes specified by NewSize from memory of type
- EfiRuntimeServicesData. If OldBuffer is not NULL, then the smaller of OldSize and
- NewSize bytes are copied from OldBuffer to the newly allocated buffer, and
- OldBuffer is freed. A pointer to the newly allocated buffer is returned.
- If NewSize is 0, then a valid buffer of 0 size is returned. If there is not
- enough memory remaining to satisfy the request, then NULL is returned.
-
- If the allocation of the new buffer is successful and the smaller of NewSize and OldSize
- is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().
-
- @param OldSize The size, in bytes, of OldBuffer.
- @param NewSize The size, in bytes, of the buffer to reallocate.
- @param OldBuffer The buffer to copy to the allocated buffer. This is an optional
- parameter that may be NULL.
-
- @return A pointer to the allocated buffer or NULL if allocation fails.
-
-**/
-VOID *
-EFIAPI
-ReallocateRuntimePool (
- IN UINTN OldSize,
- IN UINTN NewSize,
- IN VOID *OldBuffer OPTIONAL
- )
-{
- return ReallocatePool (OldSize, NewSize, OldBuffer);
-}
-
-/**
- Reallocates a buffer of type EfiReservedMemoryType.
-
- Allocates and zeros the number bytes specified by NewSize from memory of type
- EfiReservedMemoryType. If OldBuffer is not NULL, then the smaller of OldSize and
- NewSize bytes are copied from OldBuffer to the newly allocated buffer, and
- OldBuffer is freed. A pointer to the newly allocated buffer is returned.
- If NewSize is 0, then a valid buffer of 0 size is returned. If there is not
- enough memory remaining to satisfy the request, then NULL is returned.
-
- If the allocation of the new buffer is successful and the smaller of NewSize and OldSize
- is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().
-
- @param OldSize The size, in bytes, of OldBuffer.
- @param NewSize The size, in bytes, of the buffer to reallocate.
- @param OldBuffer The buffer to copy to the allocated buffer. This is an optional
- parameter that may be NULL.
-
- @return A pointer to the allocated buffer or NULL if allocation fails.
-
-**/
-VOID *
-EFIAPI
-ReallocateReservedPool (
- IN UINTN OldSize,
- IN UINTN NewSize,
- IN VOID *OldBuffer OPTIONAL
- )
-{
- return ReallocatePool (OldSize, NewSize, OldBuffer);
-}
-
-/**
- Frees a buffer that was previously allocated with one of the pool allocation functions in the
- Memory Allocation Library.
-
- Frees the buffer specified by Buffer. Buffer must have been allocated on a previous call to the
- pool allocation services of the Memory Allocation Library. If it is not possible to free pool
- resources, then this function will perform no actions.
-
- If Buffer was not allocated with a pool allocation function in the Memory Allocation Library,
- then ASSERT().
-
- @param Buffer The pointer to the buffer to free.
-
-**/
-VOID
-EFIAPI
-FreePool (
- IN VOID *Buffer
- )
-{
- free (Buffer);
-}
+/** @file + Instance of Memory Allocation Library based on POSIX APIs + + Uses POSIX APIs malloc() and free() to allocate and free memory. + + Copyright (c) 2018 - 2020, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include <stdlib.h> +#include <string.h> + +#include <Uefi.h> +#include <Library/MemoryAllocationLib.h> +#include <Library/DebugLib.h> + +/// +/// Signature for PAGE_HEAD structure +/// Used to verify that buffer being freed was allocated by this library. +/// +#define PAGE_HEAD_PRIVATE_SIGNATURE SIGNATURE_32 ('P', 'H', 'D', 'R') + +/// +/// Structure placed immediately before an aligned allocation to store the +/// information required to free the entire buffer allocated to support then +/// aligned allocation. +/// +typedef struct { + UINT32 Signature; + VOID *AllocatedBufffer; + UINTN TotalPages; + VOID *AlignedBuffer; + UINTN AlignedPages; +} PAGE_HEAD; + +/** + Allocates one or more 4KB pages of type EfiBootServicesData. + + Allocates the number of 4KB pages of type EfiBootServicesData and returns a pointer to the + allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL + is returned. If there is not enough memory remaining to satisfy the request, then NULL is + returned. + + @param Pages The number of 4 KB pages to allocate. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +AllocatePages ( + IN UINTN Pages + ) +{ + return AllocateAlignedPages (Pages, SIZE_4KB); +} + +/** + Allocates one or more 4KB pages of type EfiRuntimeServicesData. + + Allocates the number of 4KB pages of type EfiRuntimeServicesData and returns a pointer to the + allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL + is returned. If there is not enough memory remaining to satisfy the request, then NULL is + returned. + + @param Pages The number of 4 KB pages to allocate. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +AllocateRuntimePages ( + IN UINTN Pages + ) +{ + return AllocatePages (Pages); +} + +/** + Allocates one or more 4KB pages of type EfiReservedMemoryType. + + Allocates the number of 4KB pages of type EfiReservedMemoryType and returns a pointer to the + allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL + is returned. If there is not enough memory remaining to satisfy the request, then NULL is + returned. + + @param Pages The number of 4 KB pages to allocate. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +AllocateReservedPages ( + IN UINTN Pages + ) +{ + return AllocatePages (Pages); +} + +/** + Frees one or more 4KB pages that were previously allocated with one of the page allocation + functions in the Memory Allocation Library. + + Frees the number of 4KB pages specified by Pages from the buffer specified by Buffer. Buffer + must have been allocated on a previous call to the page allocation services of the Memory + Allocation Library. If it is not possible to free allocated pages, then this function will + perform no actions. + + If Buffer was not allocated with a page allocation function in the Memory Allocation Library, + then ASSERT(). + If Pages is zero, then ASSERT(). + + @param Buffer The pointer to the buffer of pages to free. + @param Pages The number of 4 KB pages to free. + +**/ +VOID +EFIAPI +FreePages ( + IN VOID *Buffer, + IN UINTN Pages + ) +{ + FreeAlignedPages (Buffer, Pages); +} + +/** + Allocates one or more 4KB pages of type EfiBootServicesData at a specified alignment. + + Allocates the number of 4KB pages specified by Pages of type EfiBootServicesData with an + alignment specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is + returned. If there is not enough memory at the specified alignment remaining to satisfy the + request, then NULL is returned. + + If Alignment is not a power of two and Alignment is not zero, then ASSERT(). + If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT(). + + @param Pages The number of 4 KB pages to allocate. + @param Alignment The requested alignment of the allocation. Must be a power of two. + If Alignment is zero, then byte alignment is used. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/VOID * +EFIAPI +AllocateAlignedPages ( + IN UINTN Pages, + IN UINTN Alignment + ) +{ + PAGE_HEAD PageHead; + PAGE_HEAD *PageHeadPtr; + UINTN AlignmentMask; + + ASSERT ((Alignment & (Alignment - 1)) == 0); + + if (Alignment < SIZE_4KB) { + Alignment = SIZE_4KB; + } + + AlignmentMask = Alignment - 1; + + // + // We need reserve Alignment pages for PAGE_HEAD, as meta data. + // + PageHead.Signature = PAGE_HEAD_PRIVATE_SIGNATURE; + PageHead.TotalPages = Pages + EFI_SIZE_TO_PAGES (Alignment) * 2; + PageHead.AlignedPages = Pages; + PageHead.AllocatedBufffer = malloc (EFI_PAGES_TO_SIZE (PageHead.TotalPages)); + if (PageHead.AllocatedBufffer == NULL) { + return NULL; + } + + PageHead.AlignedBuffer = (VOID *)(((UINTN)PageHead.AllocatedBufffer + AlignmentMask) & ~AlignmentMask); + if ((UINTN)PageHead.AlignedBuffer - (UINTN)PageHead.AllocatedBufffer < sizeof (PAGE_HEAD)) { + PageHead.AlignedBuffer = (VOID *)((UINTN)PageHead.AlignedBuffer + Alignment); + } + + PageHeadPtr = (VOID *)((UINTN)PageHead.AlignedBuffer - sizeof (PAGE_HEAD)); + memcpy (PageHeadPtr, &PageHead, sizeof (PAGE_HEAD)); + + return PageHead.AlignedBuffer; +} + +/** + Allocates one or more 4KB pages of type EfiRuntimeServicesData at a specified alignment. + + Allocates the number of 4KB pages specified by Pages of type EfiRuntimeServicesData with an + alignment specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is + returned. If there is not enough memory at the specified alignment remaining to satisfy the + request, then NULL is returned. + + If Alignment is not a power of two and Alignment is not zero, then ASSERT(). + If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT(). + + @param Pages The number of 4 KB pages to allocate. + @param Alignment The requested alignment of the allocation. Must be a power of two. + If Alignment is zero, then byte alignment is used. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +AllocateAlignedRuntimePages ( + IN UINTN Pages, + IN UINTN Alignment + ) +{ + return AllocateAlignedPages (Pages, Alignment); +} + +/** + Allocates one or more 4KB pages of type EfiReservedMemoryType at a specified alignment. + + Allocates the number of 4KB pages specified by Pages of type EfiReservedMemoryType with an + alignment specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is + returned. If there is not enough memory at the specified alignment remaining to satisfy the + request, then NULL is returned. + + If Alignment is not a power of two and Alignment is not zero, then ASSERT(). + If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT(). + + @param Pages The number of 4 KB pages to allocate. + @param Alignment The requested alignment of the allocation. Must be a power of two. + If Alignment is zero, then byte alignment is used. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +AllocateAlignedReservedPages ( + IN UINTN Pages, + IN UINTN Alignment + ) +{ + return AllocateAlignedPages (Pages, Alignment); +} + +/** + Frees one or more 4KB pages that were previously allocated with one of the aligned page + allocation functions in the Memory Allocation Library. + + Frees the number of 4KB pages specified by Pages from the buffer specified by Buffer. Buffer + must have been allocated on a previous call to the aligned page allocation services of the Memory + Allocation Library. If it is not possible to free allocated pages, then this function will + perform no actions. + + If Buffer was not allocated with an aligned page allocation function in the Memory Allocation + Library, then ASSERT(). + If Pages is zero, then ASSERT(). + + @param Buffer The pointer to the buffer of pages to free. + @param Pages The number of 4 KB pages to free. + +**/ +VOID +EFIAPI +FreeAlignedPages ( + IN VOID *Buffer, + IN UINTN Pages + ) +{ + PAGE_HEAD *PageHeadPtr; + + // + // NOTE: Partial free is not supported. Just keep it. + // + PageHeadPtr = (VOID *)((UINTN)Buffer - sizeof (PAGE_HEAD)); + if (PageHeadPtr->Signature != PAGE_HEAD_PRIVATE_SIGNATURE) { + return; + } + + if (PageHeadPtr->AlignedPages != Pages) { + return; + } + + PageHeadPtr->Signature = 0; + free (PageHeadPtr->AllocatedBufffer); +} + +/** + Allocates a buffer of type EfiBootServicesData. + + Allocates the number bytes specified by AllocationSize of type EfiBootServicesData and returns a + pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is + returned. If there is not enough memory remaining to satisfy the request, then NULL is returned. + + @param AllocationSize The number of bytes to allocate. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/VOID * +EFIAPI +AllocatePool ( + IN UINTN AllocationSize + ) +{ + return malloc (AllocationSize); +} + +/** + Allocates a buffer of type EfiRuntimeServicesData. + + Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData and returns + a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is + returned. If there is not enough memory remaining to satisfy the request, then NULL is returned. + + @param AllocationSize The number of bytes to allocate. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +AllocateRuntimePool ( + IN UINTN AllocationSize + ) +{ + return AllocatePool (AllocationSize); +} + +/** + Allocates a buffer of type EfiReservedMemoryType. + + Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType and returns + a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is + returned. If there is not enough memory remaining to satisfy the request, then NULL is returned. + + @param AllocationSize The number of bytes to allocate. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +AllocateReservedPool ( + IN UINTN AllocationSize + ) +{ + return AllocatePool (AllocationSize); +} + +/** + Allocates and zeros a buffer of type EfiBootServicesData. + + Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, clears the + buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a + valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the + request, then NULL is returned. + + @param AllocationSize The number of bytes to allocate and zero. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +AllocateZeroPool ( + IN UINTN AllocationSize + ) +{ + VOID *Buffer; + + Buffer = malloc (AllocationSize); + if (Buffer == NULL) { + return NULL; + } + + memset (Buffer, 0, AllocationSize); + return Buffer; +} + +/** + Allocates and zeros a buffer of type EfiRuntimeServicesData. + + Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, clears the + buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a + valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the + request, then NULL is returned. + + @param AllocationSize The number of bytes to allocate and zero. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +AllocateRuntimeZeroPool ( + IN UINTN AllocationSize + ) +{ + return AllocateZeroPool (AllocationSize); +} + +/** + Allocates and zeros a buffer of type EfiReservedMemoryType. + + Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, clears the + buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a + valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the + request, then NULL is returned. + + @param AllocationSize The number of bytes to allocate and zero. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +AllocateReservedZeroPool ( + IN UINTN AllocationSize + ) +{ + return AllocateZeroPool (AllocationSize); +} + +/** + Copies a buffer to an allocated buffer of type EfiBootServicesData. + + Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, copies + AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the + allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there + is not enough memory remaining to satisfy the request, then NULL is returned. + + If Buffer is NULL, then ASSERT(). + If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). + + @param AllocationSize The number of bytes to allocate and zero. + @param Buffer The buffer to copy to the allocated buffer. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +AllocateCopyPool ( + IN UINTN AllocationSize, + IN CONST VOID *Buffer + ) +{ + VOID *Memory; + + Memory = malloc (AllocationSize); + if (Memory == NULL) { + return NULL; + } + + memcpy (Memory, Buffer, AllocationSize); + return Memory; +} + +/** + Copies a buffer to an allocated buffer of type EfiRuntimeServicesData. + + Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, copies + AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the + allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there + is not enough memory remaining to satisfy the request, then NULL is returned. + + If Buffer is NULL, then ASSERT(). + If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). + + @param AllocationSize The number of bytes to allocate and zero. + @param Buffer The buffer to copy to the allocated buffer. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +AllocateRuntimeCopyPool ( + IN UINTN AllocationSize, + IN CONST VOID *Buffer + ) +{ + return AllocateCopyPool (AllocationSize, Buffer); +} + +/** + Copies a buffer to an allocated buffer of type EfiReservedMemoryType. + + Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, copies + AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the + allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there + is not enough memory remaining to satisfy the request, then NULL is returned. + + If Buffer is NULL, then ASSERT(). + If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). + + @param AllocationSize The number of bytes to allocate and zero. + @param Buffer The buffer to copy to the allocated buffer. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +AllocateReservedCopyPool ( + IN UINTN AllocationSize, + IN CONST VOID *Buffer + ) +{ + return AllocateCopyPool (AllocationSize, Buffer); +} + +/** + Reallocates a buffer of type EfiBootServicesData. + + Allocates and zeros the number bytes specified by NewSize from memory of type + EfiBootServicesData. If OldBuffer is not NULL, then the smaller of OldSize and + NewSize bytes are copied from OldBuffer to the newly allocated buffer, and + OldBuffer is freed. A pointer to the newly allocated buffer is returned. + If NewSize is 0, then a valid buffer of 0 size is returned. If there is not + enough memory remaining to satisfy the request, then NULL is returned. + + If the allocation of the new buffer is successful and the smaller of NewSize and OldSize + is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT(). + + @param OldSize The size, in bytes, of OldBuffer. + @param NewSize The size, in bytes, of the buffer to reallocate. + @param OldBuffer The buffer to copy to the allocated buffer. This is an optional + parameter that may be NULL. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +ReallocatePool ( + IN UINTN OldSize, + IN UINTN NewSize, + IN VOID *OldBuffer OPTIONAL + ) +{ + VOID *NewBuffer; + + NewBuffer = malloc (NewSize); + if ((NewBuffer != NULL) && (OldBuffer != NULL)) { + memcpy (NewBuffer, OldBuffer, MIN (OldSize, NewSize)); + } + + if (OldBuffer != NULL) { + FreePool (OldBuffer); + } + + return NewBuffer; +} + +/** + Reallocates a buffer of type EfiRuntimeServicesData. + + Allocates and zeros the number bytes specified by NewSize from memory of type + EfiRuntimeServicesData. If OldBuffer is not NULL, then the smaller of OldSize and + NewSize bytes are copied from OldBuffer to the newly allocated buffer, and + OldBuffer is freed. A pointer to the newly allocated buffer is returned. + If NewSize is 0, then a valid buffer of 0 size is returned. If there is not + enough memory remaining to satisfy the request, then NULL is returned. + + If the allocation of the new buffer is successful and the smaller of NewSize and OldSize + is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT(). + + @param OldSize The size, in bytes, of OldBuffer. + @param NewSize The size, in bytes, of the buffer to reallocate. + @param OldBuffer The buffer to copy to the allocated buffer. This is an optional + parameter that may be NULL. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +ReallocateRuntimePool ( + IN UINTN OldSize, + IN UINTN NewSize, + IN VOID *OldBuffer OPTIONAL + ) +{ + return ReallocatePool (OldSize, NewSize, OldBuffer); +} + +/** + Reallocates a buffer of type EfiReservedMemoryType. + + Allocates and zeros the number bytes specified by NewSize from memory of type + EfiReservedMemoryType. If OldBuffer is not NULL, then the smaller of OldSize and + NewSize bytes are copied from OldBuffer to the newly allocated buffer, and + OldBuffer is freed. A pointer to the newly allocated buffer is returned. + If NewSize is 0, then a valid buffer of 0 size is returned. If there is not + enough memory remaining to satisfy the request, then NULL is returned. + + If the allocation of the new buffer is successful and the smaller of NewSize and OldSize + is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT(). + + @param OldSize The size, in bytes, of OldBuffer. + @param NewSize The size, in bytes, of the buffer to reallocate. + @param OldBuffer The buffer to copy to the allocated buffer. This is an optional + parameter that may be NULL. + + @return A pointer to the allocated buffer or NULL if allocation fails. + +**/ +VOID * +EFIAPI +ReallocateReservedPool ( + IN UINTN OldSize, + IN UINTN NewSize, + IN VOID *OldBuffer OPTIONAL + ) +{ + return ReallocatePool (OldSize, NewSize, OldBuffer); +} + +/** + Frees a buffer that was previously allocated with one of the pool allocation functions in the + Memory Allocation Library. + + Frees the buffer specified by Buffer. Buffer must have been allocated on a previous call to the + pool allocation services of the Memory Allocation Library. If it is not possible to free pool + resources, then this function will perform no actions. + + If Buffer was not allocated with a pool allocation function in the Memory Allocation Library, + then ASSERT(). + + @param Buffer The pointer to the buffer to free. + +**/ +VOID +EFIAPI +FreePool ( + IN VOID *Buffer + ) +{ + free (Buffer); +} diff --git a/UnitTestFrameworkPkg/Library/Posix/MemoryAllocationLibPosix/MemoryAllocationLibPosix.inf b/UnitTestFrameworkPkg/Library/Posix/MemoryAllocationLibPosix/MemoryAllocationLibPosix.inf index 44ec3fd517..d26e2cae66 100644 --- a/UnitTestFrameworkPkg/Library/Posix/MemoryAllocationLibPosix/MemoryAllocationLibPosix.inf +++ b/UnitTestFrameworkPkg/Library/Posix/MemoryAllocationLibPosix/MemoryAllocationLibPosix.inf @@ -1,27 +1,27 @@ -## @file
-# Instance of Memory Allocation Library based on POSIX APIs
-#
-# Uses POSIX APIs malloc() and free() to allocate and free memory.
-#
-# Copyright (c) 2018 - 2020, Intel Corporation. All rights reserved.<BR>
-# SPDX-License-Identifier: BSD-2-Clause-Patent
-#
-##
-
-[Defines]
- INF_VERSION = 0x00010005
- BASE_NAME = MemoryAllocationLibPosix
- MODULE_UNI_FILE = MemoryAllocationLibPosix.uni
- FILE_GUID = A1672454-A3D3-4AAC-A86B-8D63132BBB91
- MODULE_TYPE = UEFI_DRIVER
- VERSION_STRING = 1.0
- LIBRARY_CLASS = MemoryAllocationLib|HOST_APPLICATION
-
-[Sources]
- MemoryAllocationLibPosix.c
-
-[Packages]
- MdePkg/MdePkg.dec
-
-[LibraryClasses]
- BaseLib
+## @file +# Instance of Memory Allocation Library based on POSIX APIs +# +# Uses POSIX APIs malloc() and free() to allocate and free memory. +# +# Copyright (c) 2018 - 2020, Intel Corporation. All rights reserved.<BR> +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = MemoryAllocationLibPosix + MODULE_UNI_FILE = MemoryAllocationLibPosix.uni + FILE_GUID = A1672454-A3D3-4AAC-A86B-8D63132BBB91 + MODULE_TYPE = UEFI_DRIVER + VERSION_STRING = 1.0 + LIBRARY_CLASS = MemoryAllocationLib|HOST_APPLICATION + +[Sources] + MemoryAllocationLibPosix.c + +[Packages] + MdePkg/MdePkg.dec + +[LibraryClasses] + BaseLib diff --git a/UnitTestFrameworkPkg/Library/Posix/MemoryAllocationLibPosix/MemoryAllocationLibPosix.uni b/UnitTestFrameworkPkg/Library/Posix/MemoryAllocationLibPosix/MemoryAllocationLibPosix.uni index 854b427976..d83c25805e 100644 --- a/UnitTestFrameworkPkg/Library/Posix/MemoryAllocationLibPosix/MemoryAllocationLibPosix.uni +++ b/UnitTestFrameworkPkg/Library/Posix/MemoryAllocationLibPosix/MemoryAllocationLibPosix.uni @@ -1,14 +1,14 @@ -// /** @file
-// Instance of Memory Allocation Library based on POSIX APIs
-//
-// Uses POSIX APIs malloc() and free() to allocate and free memory.
-//
-// Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
-//
-// SPDX-License-Identifier: BSD-2-Clause-Patent
-//
-// **/
-
-#string STR_MODULE_ABSTRACT #language en-US "Instance of Memory Allocation Library based on POSIX APIs"
-
-#string STR_MODULE_DESCRIPTION #language en-US "Uses POSIX APIs malloc() and free() to allocate and free memory."
+// /** @file +// Instance of Memory Allocation Library based on POSIX APIs +// +// Uses POSIX APIs malloc() and free() to allocate and free memory. +// +// Copyright (c) 2020, Intel Corporation. All rights reserved.<BR> +// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + +#string STR_MODULE_ABSTRACT #language en-US "Instance of Memory Allocation Library based on POSIX APIs" + +#string STR_MODULE_DESCRIPTION #language en-US "Uses POSIX APIs malloc() and free() to allocate and free memory." diff --git a/UnitTestFrameworkPkg/Library/SubhookLib/SubhookLib.inf b/UnitTestFrameworkPkg/Library/SubhookLib/SubhookLib.inf index a67be890d8..b6d2f6f93c 100644 --- a/UnitTestFrameworkPkg/Library/SubhookLib/SubhookLib.inf +++ b/UnitTestFrameworkPkg/Library/SubhookLib/SubhookLib.inf @@ -1,31 +1,31 @@ -## @file
-# This module provides Subhook Library implementation.
-#
-# Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
-# SPDX-License-Identifier: BSD-2-Clause-Patent
-#
-##
-
-[Defines]
- INF_VERSION = 0x00010018
- BASE_NAME = SubhookLib
- MODULE_UNI_FILE = SubhookLib.uni
- FILE_GUID = 70E03378-E140-46A8-8E65-7719DA14A240
- MODULE_TYPE = HOST_APPLICATION
- VERSION_STRING = 0.1
- LIBRARY_CLASS = SubhookLib
-
-#
-# VALID_ARCHITECTURES = IA32 X64
-#
-
-[Sources]
- subhook/subhook.c
-
-[Packages]
- UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec
-
-[BuildOptions]
- MSFT:*_*_*_CC_FLAGS == /c /EHsc /Zi /DSUBHOOK_STATIC /Od
- GCC:*_*_IA32_CC_FLAGS == -g -c -O0 -m32
- GCC:*_*_X64_CC_FLAGS == -g -c -O0 -m64
+## @file +# This module provides Subhook Library implementation. +# +# Copyright (c) 2022, Intel Corporation. All rights reserved.<BR> +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x00010018 + BASE_NAME = SubhookLib + MODULE_UNI_FILE = SubhookLib.uni + FILE_GUID = 70E03378-E140-46A8-8E65-7719DA14A240 + MODULE_TYPE = HOST_APPLICATION + VERSION_STRING = 0.1 + LIBRARY_CLASS = SubhookLib + +# +# VALID_ARCHITECTURES = IA32 X64 +# + +[Sources] + subhook/subhook.c + +[Packages] + UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec + +[BuildOptions] + MSFT:*_*_*_CC_FLAGS == /c /EHsc /Zi /DSUBHOOK_STATIC /Od + GCC:*_*_IA32_CC_FLAGS == -g -c -O0 -m32 + GCC:*_*_X64_CC_FLAGS == -g -c -O0 -m64 diff --git a/UnitTestFrameworkPkg/Library/SubhookLib/SubhookLib.uni b/UnitTestFrameworkPkg/Library/SubhookLib/SubhookLib.uni index eb61f03404..f8a222537f 100644 --- a/UnitTestFrameworkPkg/Library/SubhookLib/SubhookLib.uni +++ b/UnitTestFrameworkPkg/Library/SubhookLib/SubhookLib.uni @@ -1,11 +1,11 @@ -// /** @file
-// This module provides Subhook Library implementation.
-//
-// Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
-// SPDX-License-Identifier: BSD-2-Clause-Patent
-//
-// **/
-
-#string STR_MODULE_ABSTRACT #language en-US "Subhook Library implementation"
-
-#string STR_MODULE_DESCRIPTION #language en-US "This module provides Subhook Library implementation."
+// /** @file +// This module provides Subhook Library implementation. +// +// Copyright (c) 2022, Intel Corporation. All rights reserved.<BR> +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + +#string STR_MODULE_ABSTRACT #language en-US "Subhook Library implementation" + +#string STR_MODULE_DESCRIPTION #language en-US "This module provides Subhook Library implementation." diff --git a/UnitTestFrameworkPkg/Library/UnitTestBootLibNull/UnitTestBootLibNull.c b/UnitTestFrameworkPkg/Library/UnitTestBootLibNull/UnitTestBootLibNull.c index a49aaefdb7..e519543782 100644 --- a/UnitTestFrameworkPkg/Library/UnitTestBootLibNull/UnitTestBootLibNull.c +++ b/UnitTestFrameworkPkg/Library/UnitTestBootLibNull/UnitTestBootLibNull.c @@ -1,26 +1,26 @@ -/**
- NULL implementation for UnitTestBootLib to allow simple compilation
-
- Copyright (c) Microsoft Corporation.<BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
-**/
-
-#include <PiDxe.h>
-
-/**
- Set the boot manager to boot from a specific device on the next boot. This
- should be set only for the next boot and shouldn't require any manual clean up
-
- @retval EFI_SUCCESS Boot device for next boot was set.
- @retval EFI_UNSUPPORTED Setting the boot device for the next boot is not
- supportted.
- @retval Other Boot device for next boot can not be set.
-**/
-EFI_STATUS
-EFIAPI
-SetBootNextDevice (
- VOID
- )
-{
- return EFI_UNSUPPORTED;
-}
+/** + NULL implementation for UnitTestBootLib to allow simple compilation + + Copyright (c) Microsoft Corporation.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include <PiDxe.h> + +/** + Set the boot manager to boot from a specific device on the next boot. This + should be set only for the next boot and shouldn't require any manual clean up + + @retval EFI_SUCCESS Boot device for next boot was set. + @retval EFI_UNSUPPORTED Setting the boot device for the next boot is not + supportted. + @retval Other Boot device for next boot can not be set. +**/ +EFI_STATUS +EFIAPI +SetBootNextDevice ( + VOID + ) +{ + return EFI_UNSUPPORTED; +} diff --git a/UnitTestFrameworkPkg/Library/UnitTestBootLibNull/UnitTestBootLibNull.inf b/UnitTestFrameworkPkg/Library/UnitTestBootLibNull/UnitTestBootLibNull.inf index a4a907b65b..75c3bf82db 100644 --- a/UnitTestFrameworkPkg/Library/UnitTestBootLibNull/UnitTestBootLibNull.inf +++ b/UnitTestFrameworkPkg/Library/UnitTestBootLibNull/UnitTestBootLibNull.inf @@ -1,23 +1,23 @@ -## @file
-# NULL library for UnitTestBootUsb
-#
-# Copyright (c) Microsoft Corporation.<BR>
-# SPDX-License-Identifier: BSD-2-Clause-Patent
-#
-##
-
-[Defines]
- INF_VERSION = 0x00010017
- BASE_NAME = UnitTestBootLibNull
- MODULE_UNI_FILE = UnitTestBootLibNull.uni
- FILE_GUID = f143e75d-76e1-4040-b134-8f4f0bd5e3bd
- VERSION_STRING = 1.0
- MODULE_TYPE = DXE_DRIVER
- LIBRARY_CLASS = UnitTestBootLib
-
-[Sources]
- UnitTestBootLibNull.c
-
-[Packages]
- MdePkg/MdePkg.dec
-
+## @file +# NULL library for UnitTestBootUsb +# +# Copyright (c) Microsoft Corporation.<BR> +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x00010017 + BASE_NAME = UnitTestBootLibNull + MODULE_UNI_FILE = UnitTestBootLibNull.uni + FILE_GUID = f143e75d-76e1-4040-b134-8f4f0bd5e3bd + VERSION_STRING = 1.0 + MODULE_TYPE = DXE_DRIVER + LIBRARY_CLASS = UnitTestBootLib + +[Sources] + UnitTestBootLibNull.c + +[Packages] + MdePkg/MdePkg.dec + diff --git a/UnitTestFrameworkPkg/Library/UnitTestBootLibNull/UnitTestBootLibNull.uni b/UnitTestFrameworkPkg/Library/UnitTestBootLibNull/UnitTestBootLibNull.uni index 1ed3b20544..d71529de2a 100644 --- a/UnitTestFrameworkPkg/Library/UnitTestBootLibNull/UnitTestBootLibNull.uni +++ b/UnitTestFrameworkPkg/Library/UnitTestBootLibNull/UnitTestBootLibNull.uni @@ -1,11 +1,11 @@ -// /** @file
-// NULL library for UnitTestBootUsb
-//
-// Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
-// SPDX-License-Identifier: BSD-2-Clause-Patent
-//
-// **/
-
-#string STR_MODULE_ABSTRACT #language en-US "NULL library for UnitTestBootUsb"
-
-#string STR_MODULE_DESCRIPTION #language en-US "NULL library for UnitTestBootUsb."
+// /** @file +// NULL library for UnitTestBootUsb +// +// Copyright (c) 2020, Intel Corporation. All rights reserved.<BR> +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + +#string STR_MODULE_ABSTRACT #language en-US "NULL library for UnitTestBootUsb" + +#string STR_MODULE_DESCRIPTION #language en-US "NULL library for UnitTestBootUsb." diff --git a/UnitTestFrameworkPkg/Library/UnitTestBootLibUsbClass/UnitTestBootLibUsbClass.c b/UnitTestFrameworkPkg/Library/UnitTestBootLibUsbClass/UnitTestBootLibUsbClass.c index b9b2d23eb1..5fed5e7567 100644 --- a/UnitTestFrameworkPkg/Library/UnitTestBootLibUsbClass/UnitTestBootLibUsbClass.c +++ b/UnitTestFrameworkPkg/Library/UnitTestBootLibUsbClass/UnitTestBootLibUsbClass.c @@ -1,130 +1,130 @@ -/**
- Implement UnitTestBootLib using USB Class Boot option. This should be
- industry standard and should work on all platforms
-
- Copyright (c) Microsoft Corporation.<BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
-**/
-
-#include <PiDxe.h>
-#include <Library/DebugLib.h>
-#include <Library/UefiRuntimeServicesTableLib.h>
-#include <Library/UefiBootManagerLib.h>
-#include <Library/DevicePathLib.h>
-#include <Protocol/DevicePath.h>
-#include <Library/MemoryAllocationLib.h>
-
-/**
- Set the boot manager to boot from a specific device on the next boot. This
- should be set only for the next boot and shouldn't require any manual clean up
-
- @retval EFI_SUCCESS Boot device for next boot was set.
- @retval EFI_UNSUPPORTED Setting the boot device for the next boot is not
- supportted.
- @retval Other Boot device for next boot can not be set.
-**/
-EFI_STATUS
-EFIAPI
-SetBootNextDevice (
- VOID
- )
-{
- EFI_STATUS Status;
- EFI_BOOT_MANAGER_LOAD_OPTION NewOption;
- UINT32 Attributes;
- UINT8 *OptionalData;
- UINT32 OptionalDataSize;
- UINT16 BootNextValue;
- USB_CLASS_DEVICE_PATH UsbDp;
- EFI_DEVICE_PATH_PROTOCOL *DpEnd;
- EFI_DEVICE_PATH_PROTOCOL *Dp;
- BOOLEAN NewOptionValid;
-
- OptionalData = NULL;
- OptionalDataSize = 0;
- BootNextValue = 0xABCD; // this should be a safe number...
- DpEnd = NULL;
- Dp = NULL;
- NewOptionValid = FALSE;
-
- UsbDp.Header.Length[0] = (UINT8)(sizeof (USB_CLASS_DEVICE_PATH) & 0xff);
- UsbDp.Header.Length[1] = (UINT8)(sizeof (USB_CLASS_DEVICE_PATH) >> 8);
- UsbDp.Header.Type = MESSAGING_DEVICE_PATH;
- UsbDp.Header.SubType = MSG_USB_CLASS_DP;
- UsbDp.VendorId = 0xFFFF;
- UsbDp.ProductId = 0xFFFF;
- UsbDp.DeviceClass = 0xFF;
- UsbDp.DeviceSubClass = 0xFF;
- UsbDp.DeviceProtocol = 0xFF;
-
- Attributes = LOAD_OPTION_ACTIVE;
-
- DpEnd = AppendDevicePathNode (NULL, NULL);
- if (DpEnd == NULL) {
- DEBUG ((DEBUG_ERROR, "%a: Unable to create device path. DpEnd is NULL.\n", __func__));
- Status = EFI_OUT_OF_RESOURCES;
- goto CLEANUP;
- }
-
- // @MRT --- Is this memory leak because we lose the old Dp memory
- Dp = AppendDevicePathNode (
- DpEnd,
- (EFI_DEVICE_PATH_PROTOCOL *)&UsbDp
- );
- if (Dp == NULL) {
- DEBUG ((DEBUG_ERROR, "%a: Unable to create device path. Dp is NULL.\n", __func__));
- Status = EFI_OUT_OF_RESOURCES;
- goto CLEANUP;
- }
-
- Status = EfiBootManagerInitializeLoadOption (
- &NewOption,
- (UINTN)BootNextValue,
- LoadOptionTypeBoot,
- Attributes,
- L"Generic USB Class Device",
- Dp,
- OptionalData,
- OptionalDataSize
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a: Error creating load option. Status = %r\n", __func__, Status));
- goto CLEANUP;
- }
-
- NewOptionValid = TRUE;
- DEBUG ((DEBUG_VERBOSE, "%a: Generic USB Class Device boot option created.\n", __func__));
- Status = EfiBootManagerLoadOptionToVariable (&NewOption);
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a: Error Saving boot option NV variable. Status = %r\n", __func__, Status));
- goto CLEANUP;
- }
-
- //
- // Set Boot Next
- //
- Status = gRT->SetVariable (
- L"BootNext",
- &gEfiGlobalVariableGuid,
- (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE),
- sizeof (BootNextValue),
- &(BootNextValue)
- );
-
- DEBUG ((DEBUG_VERBOSE, "%a - Set BootNext Status (%r)\n", __func__, Status));
-
-CLEANUP:
- if (Dp != NULL) {
- FreePool (Dp);
- }
-
- if (DpEnd != NULL) {
- FreePool (DpEnd);
- }
-
- if (NewOptionValid) {
- EfiBootManagerFreeLoadOption (&NewOption);
- }
-
- return Status;
-}
+/** + Implement UnitTestBootLib using USB Class Boot option. This should be + industry standard and should work on all platforms + + Copyright (c) Microsoft Corporation.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include <PiDxe.h> +#include <Library/DebugLib.h> +#include <Library/UefiRuntimeServicesTableLib.h> +#include <Library/UefiBootManagerLib.h> +#include <Library/DevicePathLib.h> +#include <Protocol/DevicePath.h> +#include <Library/MemoryAllocationLib.h> + +/** + Set the boot manager to boot from a specific device on the next boot. This + should be set only for the next boot and shouldn't require any manual clean up + + @retval EFI_SUCCESS Boot device for next boot was set. + @retval EFI_UNSUPPORTED Setting the boot device for the next boot is not + supportted. + @retval Other Boot device for next boot can not be set. +**/ +EFI_STATUS +EFIAPI +SetBootNextDevice ( + VOID + ) +{ + EFI_STATUS Status; + EFI_BOOT_MANAGER_LOAD_OPTION NewOption; + UINT32 Attributes; + UINT8 *OptionalData; + UINT32 OptionalDataSize; + UINT16 BootNextValue; + USB_CLASS_DEVICE_PATH UsbDp; + EFI_DEVICE_PATH_PROTOCOL *DpEnd; + EFI_DEVICE_PATH_PROTOCOL *Dp; + BOOLEAN NewOptionValid; + + OptionalData = NULL; + OptionalDataSize = 0; + BootNextValue = 0xABCD; // this should be a safe number... + DpEnd = NULL; + Dp = NULL; + NewOptionValid = FALSE; + + UsbDp.Header.Length[0] = (UINT8)(sizeof (USB_CLASS_DEVICE_PATH) & 0xff); + UsbDp.Header.Length[1] = (UINT8)(sizeof (USB_CLASS_DEVICE_PATH) >> 8); + UsbDp.Header.Type = MESSAGING_DEVICE_PATH; + UsbDp.Header.SubType = MSG_USB_CLASS_DP; + UsbDp.VendorId = 0xFFFF; + UsbDp.ProductId = 0xFFFF; + UsbDp.DeviceClass = 0xFF; + UsbDp.DeviceSubClass = 0xFF; + UsbDp.DeviceProtocol = 0xFF; + + Attributes = LOAD_OPTION_ACTIVE; + + DpEnd = AppendDevicePathNode (NULL, NULL); + if (DpEnd == NULL) { + DEBUG ((DEBUG_ERROR, "%a: Unable to create device path. DpEnd is NULL.\n", __func__)); + Status = EFI_OUT_OF_RESOURCES; + goto CLEANUP; + } + + // @MRT --- Is this memory leak because we lose the old Dp memory + Dp = AppendDevicePathNode ( + DpEnd, + (EFI_DEVICE_PATH_PROTOCOL *)&UsbDp + ); + if (Dp == NULL) { + DEBUG ((DEBUG_ERROR, "%a: Unable to create device path. Dp is NULL.\n", __func__)); + Status = EFI_OUT_OF_RESOURCES; + goto CLEANUP; + } + + Status = EfiBootManagerInitializeLoadOption ( + &NewOption, + (UINTN)BootNextValue, + LoadOptionTypeBoot, + Attributes, + L"Generic USB Class Device", + Dp, + OptionalData, + OptionalDataSize + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a: Error creating load option. Status = %r\n", __func__, Status)); + goto CLEANUP; + } + + NewOptionValid = TRUE; + DEBUG ((DEBUG_VERBOSE, "%a: Generic USB Class Device boot option created.\n", __func__)); + Status = EfiBootManagerLoadOptionToVariable (&NewOption); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a: Error Saving boot option NV variable. Status = %r\n", __func__, Status)); + goto CLEANUP; + } + + // + // Set Boot Next + // + Status = gRT->SetVariable ( + L"BootNext", + &gEfiGlobalVariableGuid, + (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE), + sizeof (BootNextValue), + &(BootNextValue) + ); + + DEBUG ((DEBUG_VERBOSE, "%a - Set BootNext Status (%r)\n", __func__, Status)); + +CLEANUP: + if (Dp != NULL) { + FreePool (Dp); + } + + if (DpEnd != NULL) { + FreePool (DpEnd); + } + + if (NewOptionValid) { + EfiBootManagerFreeLoadOption (&NewOption); + } + + return Status; +} diff --git a/UnitTestFrameworkPkg/Library/UnitTestBootLibUsbClass/UnitTestBootLibUsbClass.inf b/UnitTestFrameworkPkg/Library/UnitTestBootLibUsbClass/UnitTestBootLibUsbClass.inf index 80c4e4f111..fe00f7ed12 100644 --- a/UnitTestFrameworkPkg/Library/UnitTestBootLibUsbClass/UnitTestBootLibUsbClass.inf +++ b/UnitTestFrameworkPkg/Library/UnitTestBootLibUsbClass/UnitTestBootLibUsbClass.inf @@ -1,34 +1,34 @@ -## @file
-# Library to support booting to USB on the next boot
-# This instance uses the industry standard usb class boot option.
-#
-# Copyright (c) Microsoft Corporation.<BR>
-# SPDX-License-Identifier: BSD-2-Clause-Patent
-##
-
-[Defines]
- INF_VERSION = 0x00010017
- BASE_NAME = UnitTestBootLibUsbClass
- MODULE_UNI_FILE = UnitTestBootLibUsbClass.uni
- FILE_GUID = DFADE2A2-DB69-47DE-A37A-40FB6D52E844
- VERSION_STRING = 1.0
- MODULE_TYPE = UEFI_APPLICATION
- LIBRARY_CLASS = UnitTestBootLib
-
-[Sources]
- UnitTestBootLibUsbClass.c
-
-[Packages]
- MdePkg/MdePkg.dec
- MdeModulePkg/MdeModulePkg.dec
- UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec
-
-[LibraryClasses]
- DebugLib
- UefiRuntimeServicesTableLib
- MemoryAllocationLib
- DevicePathLib
- UefiBootManagerLib
-
-[Guids]
- gEfiGlobalVariableGuid ## CONSUMES ## Used to probe boot options and set BootNext.
+## @file +# Library to support booting to USB on the next boot +# This instance uses the industry standard usb class boot option. +# +# Copyright (c) Microsoft Corporation.<BR> +# SPDX-License-Identifier: BSD-2-Clause-Patent +## + +[Defines] + INF_VERSION = 0x00010017 + BASE_NAME = UnitTestBootLibUsbClass + MODULE_UNI_FILE = UnitTestBootLibUsbClass.uni + FILE_GUID = DFADE2A2-DB69-47DE-A37A-40FB6D52E844 + VERSION_STRING = 1.0 + MODULE_TYPE = UEFI_APPLICATION + LIBRARY_CLASS = UnitTestBootLib + +[Sources] + UnitTestBootLibUsbClass.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec + +[LibraryClasses] + DebugLib + UefiRuntimeServicesTableLib + MemoryAllocationLib + DevicePathLib + UefiBootManagerLib + +[Guids] + gEfiGlobalVariableGuid ## CONSUMES ## Used to probe boot options and set BootNext. diff --git a/UnitTestFrameworkPkg/Library/UnitTestBootLibUsbClass/UnitTestBootLibUsbClass.uni b/UnitTestFrameworkPkg/Library/UnitTestBootLibUsbClass/UnitTestBootLibUsbClass.uni index 8468b3537c..056e37e067 100644 --- a/UnitTestFrameworkPkg/Library/UnitTestBootLibUsbClass/UnitTestBootLibUsbClass.uni +++ b/UnitTestFrameworkPkg/Library/UnitTestBootLibUsbClass/UnitTestBootLibUsbClass.uni @@ -1,12 +1,12 @@ -// /** @file
-// Library to support booting to USB on the next boot
-// This instance uses the industry standard usb class boot option.
-//
-// Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
-// SPDX-License-Identifier: BSD-2-Clause-Patent
-//
-// **/
-
-#string STR_MODULE_ABSTRACT #language en-US "Library to support booting to USB on the next boot"
-
-#string STR_MODULE_DESCRIPTION #language en-US "This instance uses the industry standard usb class boot option.."
+// /** @file +// Library to support booting to USB on the next boot +// This instance uses the industry standard usb class boot option. +// +// Copyright (c) 2020, Intel Corporation. All rights reserved.<BR> +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + +#string STR_MODULE_ABSTRACT #language en-US "Library to support booting to USB on the next boot" + +#string STR_MODULE_DESCRIPTION #language en-US "This instance uses the industry standard usb class boot option.." diff --git a/UnitTestFrameworkPkg/Library/UnitTestDebugAssertLib/UnitTestDebugAssertLib.c b/UnitTestFrameworkPkg/Library/UnitTestDebugAssertLib/UnitTestDebugAssertLib.c index 0462ffd64d..01b29a4833 100644 --- a/UnitTestFrameworkPkg/Library/UnitTestDebugAssertLib/UnitTestDebugAssertLib.c +++ b/UnitTestFrameworkPkg/Library/UnitTestDebugAssertLib/UnitTestDebugAssertLib.c @@ -1,49 +1,49 @@ -/** @file
- Unit Test Debug Assert Library
-
- Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#include <Uefi.h>
-#include <Library/BaseLib.h>
-#include <Library/UnitTestLib.h>
-
-///
-/// Point to jump buffer used with SetJump()/LongJump() to test if a function
-/// under test generates an expected ASSERT() condition.
-///
-BASE_LIBRARY_JUMP_BUFFER *gUnitTestExpectAssertFailureJumpBuffer = NULL;
-
-/**
- Unit test library replacement for DebugAssert() in DebugLib.
-
- If FileName is NULL, then a <FileName> string of "(NULL) Filename" is printed.
- If Description is NULL, then a <Description> 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
-UnitTestDebugAssert (
- IN CONST CHAR8 *FileName,
- IN UINTN LineNumber,
- IN CONST CHAR8 *Description
- )
-{
- CHAR8 Message[256];
-
- if (gUnitTestExpectAssertFailureJumpBuffer != NULL) {
- UT_LOG_INFO ("Detected expected ASSERT: %a(%d): %a\n", FileName, LineNumber, Description);
- LongJump (gUnitTestExpectAssertFailureJumpBuffer, 1);
- } else {
- AsciiStrCpyS (Message, sizeof (Message), "Detected unexpected ASSERT(");
- AsciiStrCatS (Message, sizeof (Message), Description);
- AsciiStrCatS (Message, sizeof (Message), ")");
- UnitTestAssertTrue (FALSE, "", LineNumber, FileName, Message);
- }
-}
+/** @file + Unit Test Debug Assert Library + + Copyright (c) 2020, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include <Uefi.h> +#include <Library/BaseLib.h> +#include <Library/UnitTestLib.h> + +/// +/// Point to jump buffer used with SetJump()/LongJump() to test if a function +/// under test generates an expected ASSERT() condition. +/// +BASE_LIBRARY_JUMP_BUFFER *gUnitTestExpectAssertFailureJumpBuffer = NULL; + +/** + Unit test library replacement for DebugAssert() in DebugLib. + + If FileName is NULL, then a <FileName> string of "(NULL) Filename" is printed. + If Description is NULL, then a <Description> 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 +UnitTestDebugAssert ( + IN CONST CHAR8 *FileName, + IN UINTN LineNumber, + IN CONST CHAR8 *Description + ) +{ + CHAR8 Message[256]; + + if (gUnitTestExpectAssertFailureJumpBuffer != NULL) { + UT_LOG_INFO ("Detected expected ASSERT: %a(%d): %a\n", FileName, LineNumber, Description); + LongJump (gUnitTestExpectAssertFailureJumpBuffer, 1); + } else { + AsciiStrCpyS (Message, sizeof (Message), "Detected unexpected ASSERT("); + AsciiStrCatS (Message, sizeof (Message), Description); + AsciiStrCatS (Message, sizeof (Message), ")"); + UnitTestAssertTrue (FALSE, "", LineNumber, FileName, Message); + } +} diff --git a/UnitTestFrameworkPkg/Library/UnitTestDebugAssertLib/UnitTestDebugAssertLib.inf b/UnitTestFrameworkPkg/Library/UnitTestDebugAssertLib/UnitTestDebugAssertLib.inf index cbcf644d0a..4e9a3d9510 100644 --- a/UnitTestFrameworkPkg/Library/UnitTestDebugAssertLib/UnitTestDebugAssertLib.inf +++ b/UnitTestFrameworkPkg/Library/UnitTestDebugAssertLib/UnitTestDebugAssertLib.inf @@ -1,31 +1,31 @@ -## @file
-# Unit Test Debug Assert Library
-#
-# Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
-# SPDX-License-Identifier: BSD-2-Clause-Patent
-#
-##
-
-[Defines]
- INF_VERSION = 0x00010005
- BASE_NAME = UnitTestDebugAssertLib
- MODULE_UNI_FILE = UnitTestDebugAssertLib.uni
- FILE_GUID = 9D53AD0D-5416-451F-A5BF-E5420051A99B
- MODULE_TYPE = BASE
- VERSION_STRING = 1.0
- LIBRARY_CLASS = NULL
-
-#
-# VALID_ARCHITECTURES = IA32 X64 ARM AARCH64
-#
-
-[Sources]
- UnitTestDebugAssertLib.c
-
-[Packages]
- MdePkg/MdePkg.dec
- UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec
-
-[LibraryClasses]
- BaseLib
- UnitTestLib
+## @file +# Unit Test Debug Assert Library +# +# Copyright (c) 2020, Intel Corporation. All rights reserved.<BR> +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = UnitTestDebugAssertLib + MODULE_UNI_FILE = UnitTestDebugAssertLib.uni + FILE_GUID = 9D53AD0D-5416-451F-A5BF-E5420051A99B + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = NULL + +# +# VALID_ARCHITECTURES = IA32 X64 ARM AARCH64 +# + +[Sources] + UnitTestDebugAssertLib.c + +[Packages] + MdePkg/MdePkg.dec + UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec + +[LibraryClasses] + BaseLib + UnitTestLib diff --git a/UnitTestFrameworkPkg/Library/UnitTestDebugAssertLib/UnitTestDebugAssertLib.uni b/UnitTestFrameworkPkg/Library/UnitTestDebugAssertLib/UnitTestDebugAssertLib.uni index 9b794aa205..654f9c663e 100644 --- a/UnitTestFrameworkPkg/Library/UnitTestDebugAssertLib/UnitTestDebugAssertLib.uni +++ b/UnitTestFrameworkPkg/Library/UnitTestDebugAssertLib/UnitTestDebugAssertLib.uni @@ -1,11 +1,11 @@ -// /** @file
-// Unit Test Debug Assert Library
-//
-// Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
-// SPDX-License-Identifier: BSD-2-Clause-Patent
-//
-// **/
-
-#string STR_MODULE_ABSTRACT #language en-US "Unit Test Debug Assert Library"
-
-#string STR_MODULE_DESCRIPTION #language en-US "Unit Test Debug Assert Library"
+// /** @file +// Unit Test Debug Assert Library +// +// Copyright (c) 2020, Intel Corporation. All rights reserved.<BR> +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + +#string STR_MODULE_ABSTRACT #language en-US "Unit Test Debug Assert Library" + +#string STR_MODULE_DESCRIPTION #language en-US "Unit Test Debug Assert Library" diff --git a/UnitTestFrameworkPkg/Library/UnitTestDebugAssertLib/UnitTestDebugAssertLibHost.cpp b/UnitTestFrameworkPkg/Library/UnitTestDebugAssertLib/UnitTestDebugAssertLibHost.cpp index a4405cc205..d3069c9ade 100644 --- a/UnitTestFrameworkPkg/Library/UnitTestDebugAssertLib/UnitTestDebugAssertLibHost.cpp +++ b/UnitTestFrameworkPkg/Library/UnitTestDebugAssertLib/UnitTestDebugAssertLibHost.cpp @@ -1,63 +1,63 @@ -/** @file
- Unit Test Debug Assert Library for host-based environments
-
- Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#include <stdexcept>
-
-#ifdef NULL
- #undef NULL
-#endif
-
-extern "C" {
- #include <Uefi.h>
- #include <UnitTestFrameworkTypes.h>
- #include <Library/BaseLib.h>
- #include <Library/UnitTestLib.h>
-
- ///
- /// Point to jump buffer used with SetJump()/LongJump() to test if a function
- /// under test generates an expected ASSERT() condition.
- ///
- BASE_LIBRARY_JUMP_BUFFER *gUnitTestExpectAssertFailureJumpBuffer = NULL;
-
- /**
- Unit test library replacement for DebugAssert() in DebugLib.
-
- If FileName is NULL, then a <FileName> string of "(NULL) Filename" is printed.
- If Description is NULL, then a <Description> 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
- UnitTestDebugAssert (
- IN CONST CHAR8 *FileName,
- IN UINTN LineNumber,
- IN CONST CHAR8 *Description
- )
- {
- CHAR8 Message[256];
-
- if (gUnitTestExpectAssertFailureJumpBuffer != NULL) {
- UT_LOG_INFO ("Detected expected ASSERT: %a(%d): %a\n", FileName, LineNumber, Description);
- LongJump (gUnitTestExpectAssertFailureJumpBuffer, 1);
- } else {
- if (GetActiveFrameworkHandle () != NULL) {
- AsciiStrCpyS (Message, sizeof (Message), "Detected unexpected ASSERT(");
- AsciiStrCatS (Message, sizeof (Message), Description);
- AsciiStrCatS (Message, sizeof (Message), ")");
- UnitTestAssertTrue (FALSE, "", LineNumber, FileName, Message);
- } else {
- snprintf (Message, sizeof (Message), "Detected unexpected ASSERT: %s(%d): %s\n", FileName, (INT32)(UINT32)LineNumber, Description);
- throw std::runtime_error (Message);
- }
- }
- }
-}
+/** @file + Unit Test Debug Assert Library for host-based environments + + Copyright (c) 2020, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include <stdexcept> + +#ifdef NULL + #undef NULL +#endif + +extern "C" { + #include <Uefi.h> + #include <UnitTestFrameworkTypes.h> + #include <Library/BaseLib.h> + #include <Library/UnitTestLib.h> + + /// + /// Point to jump buffer used with SetJump()/LongJump() to test if a function + /// under test generates an expected ASSERT() condition. + /// + BASE_LIBRARY_JUMP_BUFFER *gUnitTestExpectAssertFailureJumpBuffer = NULL; + + /** + Unit test library replacement for DebugAssert() in DebugLib. + + If FileName is NULL, then a <FileName> string of "(NULL) Filename" is printed. + If Description is NULL, then a <Description> 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 + UnitTestDebugAssert ( + IN CONST CHAR8 *FileName, + IN UINTN LineNumber, + IN CONST CHAR8 *Description + ) + { + CHAR8 Message[256]; + + if (gUnitTestExpectAssertFailureJumpBuffer != NULL) { + UT_LOG_INFO ("Detected expected ASSERT: %a(%d): %a\n", FileName, LineNumber, Description); + LongJump (gUnitTestExpectAssertFailureJumpBuffer, 1); + } else { + if (GetActiveFrameworkHandle () != NULL) { + AsciiStrCpyS (Message, sizeof (Message), "Detected unexpected ASSERT("); + AsciiStrCatS (Message, sizeof (Message), Description); + AsciiStrCatS (Message, sizeof (Message), ")"); + UnitTestAssertTrue (FALSE, "", LineNumber, FileName, Message); + } else { + snprintf (Message, sizeof (Message), "Detected unexpected ASSERT: %s(%d): %s\n", FileName, (INT32)(UINT32)LineNumber, Description); + throw std::runtime_error (Message); + } + } + } +} diff --git a/UnitTestFrameworkPkg/Library/UnitTestDebugAssertLib/UnitTestDebugAssertLibHost.inf b/UnitTestFrameworkPkg/Library/UnitTestDebugAssertLib/UnitTestDebugAssertLibHost.inf index 9a7673f179..8c05a68f12 100644 --- a/UnitTestFrameworkPkg/Library/UnitTestDebugAssertLib/UnitTestDebugAssertLibHost.inf +++ b/UnitTestFrameworkPkg/Library/UnitTestDebugAssertLib/UnitTestDebugAssertLibHost.inf @@ -1,36 +1,36 @@ -## @file
-# Unit Test Debug Assert Library for host-based environments
-#
-# Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
-# SPDX-License-Identifier: BSD-2-Clause-Patent
-#
-##
-
-[Defines]
- INF_VERSION = 0x00010005
- BASE_NAME = UnitTestDebugAssertLibHost
- MODULE_UNI_FILE = UnitTestDebugAssertLibHost.uni
- FILE_GUID = F097D67C-0340-49C8-AB30-ABC1B7D1C8D2
- MODULE_TYPE = HOST_APPLICATION
- VERSION_STRING = 1.0
- LIBRARY_CLASS = NULL
-
-#
-# VALID_ARCHITECTURES = IA32 X64 ARM AARCH64
-#
-
-[Sources]
- UnitTestDebugAssertLibHost.cpp
-
-[Packages]
- MdePkg/MdePkg.dec
- UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec
-
-[LibraryClasses]
- BaseLib
- UnitTestLib
-
-[BuildOptions]
- MSFT:*_*_*_CC_FLAGS == /c /EHs /Zi /Od /MT
- GCC:*_*_IA32_CC_FLAGS == -g -c -fshort-wchar -fexceptions -O0 -m32 -malign-double -fno-pie
- GCC:*_*_X64_CC_FLAGS == -g -c -fshort-wchar -fexceptions -O0 -m64 -fno-pie "-DEFIAPI=__attribute__((ms_abi))"
+## @file +# Unit Test Debug Assert Library for host-based environments +# +# Copyright (c) 2020, Intel Corporation. All rights reserved.<BR> +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = UnitTestDebugAssertLibHost + MODULE_UNI_FILE = UnitTestDebugAssertLibHost.uni + FILE_GUID = F097D67C-0340-49C8-AB30-ABC1B7D1C8D2 + MODULE_TYPE = HOST_APPLICATION + VERSION_STRING = 1.0 + LIBRARY_CLASS = NULL + +# +# VALID_ARCHITECTURES = IA32 X64 ARM AARCH64 +# + +[Sources] + UnitTestDebugAssertLibHost.cpp + +[Packages] + MdePkg/MdePkg.dec + UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec + +[LibraryClasses] + BaseLib + UnitTestLib + +[BuildOptions] + MSFT:*_*_*_CC_FLAGS == /c /EHs /Zi /Od /MT + GCC:*_*_IA32_CC_FLAGS == -g -c -fshort-wchar -fexceptions -O0 -m32 -malign-double -fno-pie + GCC:*_*_X64_CC_FLAGS == -g -c -fshort-wchar -fexceptions -O0 -m64 -fno-pie "-DEFIAPI=__attribute__((ms_abi))" diff --git a/UnitTestFrameworkPkg/Library/UnitTestDebugAssertLib/UnitTestDebugAssertLibHost.uni b/UnitTestFrameworkPkg/Library/UnitTestDebugAssertLib/UnitTestDebugAssertLibHost.uni index 63d1753a85..fa0c125b33 100644 --- a/UnitTestFrameworkPkg/Library/UnitTestDebugAssertLib/UnitTestDebugAssertLibHost.uni +++ b/UnitTestFrameworkPkg/Library/UnitTestDebugAssertLib/UnitTestDebugAssertLibHost.uni @@ -1,11 +1,11 @@ -// /** @file
-// Unit Test Debug Assert Library for host-based environments
-//
-// Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
-// SPDX-License-Identifier: BSD-2-Clause-Patent
-//
-// **/
-
-#string STR_MODULE_ABSTRACT #language en-US "Unit Test Debug Assert Library for host-based environments"
-
-#string STR_MODULE_DESCRIPTION #language en-US "Unit Test Debug Assert Library for host-based environments"
+// /** @file +// Unit Test Debug Assert Library for host-based environments +// +// Copyright (c) 2020, Intel Corporation. All rights reserved.<BR> +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + +#string STR_MODULE_ABSTRACT #language en-US "Unit Test Debug Assert Library for host-based environments" + +#string STR_MODULE_DESCRIPTION #language en-US "Unit Test Debug Assert Library for host-based environments" diff --git a/UnitTestFrameworkPkg/Library/UnitTestLib/Assert.c b/UnitTestFrameworkPkg/Library/UnitTestLib/Assert.c index 53cb71f610..4f36899cd1 100644 --- a/UnitTestFrameworkPkg/Library/UnitTestLib/Assert.c +++ b/UnitTestFrameworkPkg/Library/UnitTestLib/Assert.c @@ -1,587 +1,587 @@ -/**
- Implement UnitTestLib assert services
-
- Copyright (c) Microsoft Corporation.<BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
-**/
-
-#include <Uefi.h>
-#include <UnitTestFrameworkTypes.h>
-#include <Library/UnitTestLib.h>
-#include <Library/BaseLib.h>
-#include <Library/BaseMemoryLib.h>
-#include <Library/DebugLib.h>
-#include <Library/PrintLib.h>
-
-extern BASE_LIBRARY_JUMP_BUFFER gUnitTestJumpBuffer;
-
-STATIC
-EFI_STATUS
-AddUnitTestFailure (
- IN OUT UNIT_TEST *UnitTest,
- IN CONST CHAR8 *FailureMessage,
- IN FAILURE_TYPE FailureType
- )
-{
- //
- // Make sure that you're cooking with gas.
- //
- if ((UnitTest == NULL) || (FailureMessage == NULL)) {
- return EFI_INVALID_PARAMETER;
- }
-
- UnitTest->FailureType = FailureType;
- AsciiStrCpyS (
- &UnitTest->FailureMessage[0],
- UNIT_TEST_TESTFAILUREMSG_LENGTH,
- FailureMessage
- );
-
- return EFI_SUCCESS;
-}
-
-STATIC
-VOID
-EFIAPI
-UnitTestLogFailure (
- IN FAILURE_TYPE FailureType,
- IN CONST CHAR8 *Format,
- ...
- )
-{
- UNIT_TEST_FRAMEWORK_HANDLE FrameworkHandle;
- CHAR8 LogString[UNIT_TEST_TESTFAILUREMSG_LENGTH];
- VA_LIST Marker;
-
- //
- // Get active Framework handle
- //
- FrameworkHandle = GetActiveFrameworkHandle ();
- if (FrameworkHandle == NULL) {
- DEBUG ((DEBUG_ERROR, "%a - FrameworkHandle not initialized\n", __func__));
- return;
- }
-
- //
- // Convert the message to an ASCII String
- //
- VA_START (Marker, Format);
- AsciiVSPrint (LogString, sizeof (LogString), Format, Marker);
- VA_END (Marker);
-
- //
- // Finally, add the string to the log.
- //
- AddUnitTestFailure (
- ((UNIT_TEST_FRAMEWORK *)FrameworkHandle)->CurrentTest,
- LogString,
- FailureType
- );
-
- LongJump (&gUnitTestJumpBuffer, 1);
-}
-
-/**
- If Expression is TRUE, then TRUE is returned.
- If Expression is FALSE, then an assert is triggered and the location of the
- assert provided by FunctionName, LineNumber, FileName, and Description are
- recorded and FALSE is returned.
-
- @param[in] Expression The BOOLEAN result of the expression evaluation.
- @param[in] FunctionName Null-terminated ASCII string of the function
- executing the assert macro.
- @param[in] LineNumber The source file line number of the assert macro.
- @param[in] FileName Null-terminated ASCII string of the filename
- executing the assert macro.
- @param[in] Description Null-terminated ASCII string of the expression being
- evaluated.
-
- @retval TRUE Expression is TRUE.
- @retval FALSE Expression is FALSE.
-**/
-BOOLEAN
-EFIAPI
-UnitTestAssertTrue (
- IN BOOLEAN Expression,
- IN CONST CHAR8 *FunctionName,
- IN UINTN LineNumber,
- IN CONST CHAR8 *FileName,
- IN CONST CHAR8 *Description
- )
-{
- if (!Expression) {
- UT_LOG_ERROR (
- "[ASSERT FAIL] %a:%d: Expression (%a) is not TRUE!\n",
- FileName,
- LineNumber,
- Description
- );
- UnitTestLogFailure (
- FAILURETYPE_ASSERTTRUE,
- "%a:%d: Expression (%a) is not TRUE!\n",
- FileName,
- LineNumber,
- Description
- );
- }
-
- return Expression;
-}
-
-/**
- If Expression is FALSE, then TRUE is returned.
- If Expression is TRUE, then an assert is triggered and the location of the
- assert provided by FunctionName, LineNumber, FileName, and Description are
- recorded and FALSE is returned.
-
- @param[in] Expression The BOOLEAN result of the expression evaluation.
- @param[in] FunctionName Null-terminated ASCII string of the function
- executing the assert macro.
- @param[in] LineNumber The source file line number of the assert macro.
- @param[in] FileName Null-terminated ASCII string of the filename
- executing the assert macro.
- @param[in] Description Null-terminated ASCII string of the expression being
- evaluated.
-
- @retval TRUE Expression is FALSE.
- @retval FALSE Expression is TRUE.
-**/
-BOOLEAN
-EFIAPI
-UnitTestAssertFalse (
- IN BOOLEAN Expression,
- IN CONST CHAR8 *FunctionName,
- IN UINTN LineNumber,
- IN CONST CHAR8 *FileName,
- IN CONST CHAR8 *Description
- )
-{
- if (Expression) {
- UT_LOG_ERROR (
- "[ASSERT FAIL] %a:%d: Expression (%a) is not FALSE!\n",
- FileName,
- LineNumber,
- Description
- );
- UnitTestLogFailure (
- FAILURETYPE_ASSERTFALSE,
- "%a:%d: Expression(%a) is not FALSE!\n",
- FileName,
- LineNumber,
- Description
- );
- }
-
- return !Expression;
-}
-
-/**
- If Status is not an EFI_ERROR(), then TRUE is returned.
- If Status is an EFI_ERROR(), then an assert is triggered and the location of
- the assert provided by FunctionName, LineNumber, FileName, and Description are
- recorded and FALSE is returned.
-
- @param[in] Status The EFI_STATUS value to evaluate.
- @param[in] FunctionName Null-terminated ASCII string of the function
- executing the assert macro.
- @param[in] LineNumber The source file line number of the assert macro.
- @param[in] FileName Null-terminated ASCII string of the filename
- executing the assert macro.
- @param[in] Description Null-terminated ASCII string of the status
- expression being evaluated.
-
- @retval TRUE Status is not an EFI_ERROR().
- @retval FALSE Status is an EFI_ERROR().
-**/
-BOOLEAN
-EFIAPI
-UnitTestAssertNotEfiError (
- IN EFI_STATUS Status,
- IN CONST CHAR8 *FunctionName,
- IN UINTN LineNumber,
- IN CONST CHAR8 *FileName,
- IN CONST CHAR8 *Description
- )
-{
- if (EFI_ERROR (Status)) {
- UT_LOG_ERROR (
- "[ASSERT FAIL] %a:%d: Status '%a' is EFI_ERROR (%r)!\n",
- FileName,
- LineNumber,
- Description,
- Status
- );
- UnitTestLogFailure (
- FAILURETYPE_ASSERTNOTEFIERROR,
- "%a:%d: Status '%a' is EFI_ERROR (%r)!\n",
- FileName,
- LineNumber,
- Description,
- Status
- );
- }
-
- return !EFI_ERROR (Status);
-}
-
-/**
- If ValueA is equal ValueB, then TRUE is returned.
- If ValueA is not equal to ValueB, then an assert is triggered and the location
- of the assert provided by FunctionName, LineNumber, FileName, DescriptionA,
- and DescriptionB are recorded and FALSE is returned.
-
- @param[in] ValueA 64-bit value.
- @param[in] ValueB 64-bit value.
- @param[in] FunctionName Null-terminated ASCII string of the function
- executing the assert macro.
- @param[in] LineNumber The source file line number of the assert macro.
- @param[in] FileName Null-terminated ASCII string of the filename
- executing the assert macro.
- @param[in] DescriptionA Null-terminated ASCII string that is a description
- of ValueA.
- @param[in] DescriptionB Null-terminated ASCII string that is a description
- of ValueB.
-
- @retval TRUE ValueA is equal to ValueB.
- @retval FALSE ValueA is not equal to ValueB.
-**/
-BOOLEAN
-EFIAPI
-UnitTestAssertEqual (
- IN UINT64 ValueA,
- IN UINT64 ValueB,
- IN CONST CHAR8 *FunctionName,
- IN UINTN LineNumber,
- IN CONST CHAR8 *FileName,
- IN CONST CHAR8 *DescriptionA,
- IN CONST CHAR8 *DescriptionB
- )
-{
- if (ValueA != ValueB) {
- UT_LOG_ERROR (
- "[ASSERT FAIL] %a:%d: Value %a != %a (%d != %d)!\n",
- FileName,
- LineNumber,
- DescriptionA,
- DescriptionB,
- ValueA,
- ValueB
- );
- UnitTestLogFailure (
- FAILURETYPE_ASSERTEQUAL,
- "%a:%d: Value %a != %a (%d != %d)!\n",
- FileName,
- LineNumber,
- DescriptionA,
- DescriptionB,
- ValueA,
- ValueB
- );
- }
-
- return (ValueA == ValueB);
-}
-
-/**
- If the contents of BufferA are identical to the contents of BufferB, then TRUE
- is returned. If the contents of BufferA are not identical to the contents of
- BufferB, then an assert is triggered and the location of the assert provided
- by FunctionName, LineNumber, FileName, DescriptionA, and DescriptionB are
- recorded and FALSE is returned.
-
- @param[in] BufferA Pointer to a buffer for comparison.
- @param[in] BufferB Pointer to a buffer for comparison.
- @param[in] Length Number of bytes to compare in BufferA and BufferB.
- @param[in] FunctionName Null-terminated ASCII string of the function
- executing the assert macro.
- @param[in] LineNumber The source file line number of the assert macro.
- @param[in] FileName Null-terminated ASCII string of the filename
- executing the assert macro.
- @param[in] DescriptionA Null-terminated ASCII string that is a description
- of BufferA.
- @param[in] DescriptionB Null-terminated ASCII string that is a description
- of BufferB.
-
- @retval TRUE The contents of BufferA are identical to the contents of
- BufferB.
- @retval FALSE The contents of BufferA are not identical to the contents of
- BufferB.
-**/
-BOOLEAN
-EFIAPI
-UnitTestAssertMemEqual (
- IN VOID *BufferA,
- IN VOID *BufferB,
- IN UINTN Length,
- IN CONST CHAR8 *FunctionName,
- IN UINTN LineNumber,
- IN CONST CHAR8 *FileName,
- IN CONST CHAR8 *DescriptionA,
- IN CONST CHAR8 *DescriptionB
- )
-{
- if (CompareMem (BufferA, BufferB, Length) != 0) {
- UT_LOG_ERROR (
- "[ASSERT FAIL] %a:%d: Value %a != %a for length %d bytes!\n",
- FileName,
- LineNumber,
- DescriptionA,
- DescriptionB,
- Length
- );
- UnitTestLogFailure (
- FAILURETYPE_ASSERTEQUAL,
- "%a:%d: Memory at %a != %a for length %d bytes!\n",
- FileName,
- LineNumber,
- DescriptionA,
- DescriptionB,
- Length
- );
- return FALSE;
- }
-
- return TRUE;
-}
-
-/**
- If ValueA is not equal ValueB, then TRUE is returned.
- If ValueA is equal to ValueB, then an assert is triggered and the location
- of the assert provided by FunctionName, LineNumber, FileName, DescriptionA
- and DescriptionB are recorded and FALSE is returned.
-
- @param[in] ValueA 64-bit value.
- @param[in] ValueB 64-bit value.
- @param[in] FunctionName Null-terminated ASCII string of the function
- executing the assert macro.
- @param[in] LineNumber The source file line number of the assert macro.
- @param[in] FileName Null-terminated ASCII string of the filename
- executing the assert macro.
- @param[in] DescriptionA Null-terminated ASCII string that is a description
- of ValueA.
- @param[in] DescriptionB Null-terminated ASCII string that is a description
- of ValueB.
-
- @retval TRUE ValueA is not equal to ValueB.
- @retval FALSE ValueA is equal to ValueB.
-**/
-BOOLEAN
-EFIAPI
-UnitTestAssertNotEqual (
- IN UINT64 ValueA,
- IN UINT64 ValueB,
- IN CONST CHAR8 *FunctionName,
- IN UINTN LineNumber,
- IN CONST CHAR8 *FileName,
- IN CONST CHAR8 *DescriptionA,
- IN CONST CHAR8 *DescriptionB
- )
-{
- if (ValueA == ValueB) {
- UT_LOG_ERROR (
- "[ASSERT FAIL] %a:%d: Value %a == %a (%d == %d)!\n",
- FileName,
- LineNumber,
- DescriptionA,
- DescriptionB,
- ValueA,
- ValueB
- );
- UnitTestLogFailure (
- FAILURETYPE_ASSERTNOTEQUAL,
- "%a:%d: Value %a == %a (%d == %d)!\n",
- FileName,
- LineNumber,
- DescriptionA,
- DescriptionB,
- ValueA,
- ValueB
- );
- }
-
- return (ValueA != ValueB);
-}
-
-/**
- If Status is equal to Expected, then TRUE is returned.
- If Status is not equal to Expected, then an assert is triggered and the
- location of the assert provided by FunctionName, LineNumber, FileName, and
- Description are recorded and FALSE is returned.
-
- @param[in] Status EFI_STATUS value returned from an API under test.
- @param[in] Expected The expected EFI_STATUS return value from an API
- under test.
- @param[in] FunctionName Null-terminated ASCII string of the function
- executing the assert macro.
- @param[in] LineNumber The source file line number of the assert macro.
- @param[in] FileName Null-terminated ASCII string of the filename
- executing the assert macro.
- @param[in] Description Null-terminated ASCII string that is a description
- of Status.
-
- @retval TRUE Status is equal to Expected.
- @retval FALSE Status is not equal to Expected.
-**/
-BOOLEAN
-EFIAPI
-UnitTestAssertStatusEqual (
- IN EFI_STATUS Status,
- IN EFI_STATUS Expected,
- IN CONST CHAR8 *FunctionName,
- IN UINTN LineNumber,
- IN CONST CHAR8 *FileName,
- IN CONST CHAR8 *Description
- )
-{
- if (Status != Expected) {
- UT_LOG_ERROR (
- "[ASSERT FAIL] %a:%d: Status '%a' is %r, should be %r!\n",
- FileName,
- LineNumber,
- Description,
- Status,
- Expected
- );
- UnitTestLogFailure (
- FAILURETYPE_ASSERTSTATUSEQUAL,
- "%a:%d: Status '%a' is %r, should be %r!\n",
- FileName,
- LineNumber,
- Description,
- Status,
- Expected
- );
- }
-
- return (Status == Expected);
-}
-
-/**
- If Pointer is not equal to NULL, then TRUE is returned.
- If Pointer is equal to NULL, then an assert is triggered and the location of
- the assert provided by FunctionName, LineNumber, FileName, and PointerName
- are recorded and FALSE is returned.
-
- @param[in] Pointer Pointer value to be checked against NULL.
- @param[in] Expected The expected EFI_STATUS return value from a function
- under test.
- @param[in] FunctionName Null-terminated ASCII string of the function
- executing the assert macro.
- @param[in] LineNumber The source file line number of the assert macro.
- @param[in] FileName Null-terminated ASCII string of the filename
- executing the assert macro.
- @param[in] PointerName Null-terminated ASCII string that is a description
- of Pointer.
-
- @retval TRUE Pointer is not equal to NULL.
- @retval FALSE Pointer is equal to NULL.
-**/
-BOOLEAN
-EFIAPI
-UnitTestAssertNotNull (
- IN VOID *Pointer,
- IN CONST CHAR8 *FunctionName,
- IN UINTN LineNumber,
- IN CONST CHAR8 *FileName,
- IN CONST CHAR8 *PointerName
- )
-{
- if (Pointer == NULL) {
- UT_LOG_ERROR (
- "[ASSERT FAIL] %a:%d: Pointer (%a) is NULL!\n",
- FileName,
- LineNumber,
- PointerName
- );
- UnitTestLogFailure (
- FAILURETYPE_ASSERTNOTNULL,
- "%a:%d: Pointer (%a) is NULL!\n",
- FileName,
- LineNumber,
- PointerName
- );
- }
-
- return (Pointer != NULL);
-}
-
-/**
- If UnitTestStatus is UNIT_TEST_PASSED, then log an info message and return
- TRUE because an ASSERT() was expected when FunctionCall was executed and an
- ASSERT() was triggered. If UnitTestStatus is UNIT_TEST_SKIPPED, then log a
- warning message and return TRUE because ASSERT() macros are disabled. If
- UnitTestStatus is UNIT_TEST_ERROR_TEST_FAILED, then log an error message and
- return FALSE because an ASSERT() was expected when FunctionCall was executed,
- but no ASSERT() conditions were triggered. The log messages contain
- FunctionName, LineNumber, and FileName strings to provide the location of the
- UT_EXPECT_ASSERT_FAILURE() macro.
-
- @param[in] UnitTestStatus The status from UT_EXPECT_ASSERT_FAILURE() that
- is either pass, skipped, or failed.
- @param[in] FunctionName Null-terminated ASCII string of the function
- executing the UT_EXPECT_ASSERT_FAILURE() macro.
- @param[in] LineNumber The source file line number of the the function
- executing the UT_EXPECT_ASSERT_FAILURE() macro.
- @param[in] FileName Null-terminated ASCII string of the filename
- executing the UT_EXPECT_ASSERT_FAILURE() macro.
- @param[in] FunctionCall Null-terminated ASCII string of the function call
- executed by the UT_EXPECT_ASSERT_FAILURE() macro.
- @param[out] ResultStatus Used to return the UnitTestStatus value to the
- caller of UT_EXPECT_ASSERT_FAILURE(). This is
- optional parameter that may be NULL.
-
- @retval TRUE UnitTestStatus is UNIT_TEST_PASSED.
- @retval TRUE UnitTestStatus is UNIT_TEST_SKIPPED.
- @retval FALSE UnitTestStatus is UNIT_TEST_ERROR_TEST_FAILED.
-**/
-BOOLEAN
-EFIAPI
-UnitTestExpectAssertFailure (
- IN UNIT_TEST_STATUS UnitTestStatus,
- IN CONST CHAR8 *FunctionName,
- IN UINTN LineNumber,
- IN CONST CHAR8 *FileName,
- IN CONST CHAR8 *FunctionCall,
- OUT UNIT_TEST_STATUS *ResultStatus OPTIONAL
- )
-{
- if (ResultStatus != NULL) {
- *ResultStatus = UnitTestStatus;
- }
-
- if (UnitTestStatus == UNIT_TEST_PASSED) {
- UT_LOG_INFO (
- "[ASSERT PASS] %a:%d: UT_EXPECT_ASSERT_FAILURE(%a) detected expected assert\n",
- FileName,
- LineNumber,
- FunctionCall
- );
- }
-
- if (UnitTestStatus == UNIT_TEST_SKIPPED) {
- UT_LOG_WARNING (
- "[ASSERT WARN] %a:%d: UT_EXPECT_ASSERT_FAILURE(%a) disabled\n",
- FileName,
- LineNumber,
- FunctionCall
- );
- }
-
- if (UnitTestStatus == UNIT_TEST_ERROR_TEST_FAILED) {
- UT_LOG_ERROR (
- "[ASSERT FAIL] %a:%d: Function call (%a) did not ASSERT()!\n",
- FileName,
- LineNumber,
- FunctionCall
- );
- UnitTestLogFailure (
- FAILURETYPE_EXPECTASSERT,
- "%a:%d: Function call (%a) did not ASSERT()!\n",
- FileName,
- LineNumber,
- FunctionCall
- );
- }
-
- return (UnitTestStatus != UNIT_TEST_ERROR_TEST_FAILED);
-}
+/** + Implement UnitTestLib assert services + + Copyright (c) Microsoft Corporation.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include <Uefi.h> +#include <UnitTestFrameworkTypes.h> +#include <Library/UnitTestLib.h> +#include <Library/BaseLib.h> +#include <Library/BaseMemoryLib.h> +#include <Library/DebugLib.h> +#include <Library/PrintLib.h> + +extern BASE_LIBRARY_JUMP_BUFFER gUnitTestJumpBuffer; + +STATIC +EFI_STATUS +AddUnitTestFailure ( + IN OUT UNIT_TEST *UnitTest, + IN CONST CHAR8 *FailureMessage, + IN FAILURE_TYPE FailureType + ) +{ + // + // Make sure that you're cooking with gas. + // + if ((UnitTest == NULL) || (FailureMessage == NULL)) { + return EFI_INVALID_PARAMETER; + } + + UnitTest->FailureType = FailureType; + AsciiStrCpyS ( + &UnitTest->FailureMessage[0], + UNIT_TEST_TESTFAILUREMSG_LENGTH, + FailureMessage + ); + + return EFI_SUCCESS; +} + +STATIC +VOID +EFIAPI +UnitTestLogFailure ( + IN FAILURE_TYPE FailureType, + IN CONST CHAR8 *Format, + ... + ) +{ + UNIT_TEST_FRAMEWORK_HANDLE FrameworkHandle; + CHAR8 LogString[UNIT_TEST_TESTFAILUREMSG_LENGTH]; + VA_LIST Marker; + + // + // Get active Framework handle + // + FrameworkHandle = GetActiveFrameworkHandle (); + if (FrameworkHandle == NULL) { + DEBUG ((DEBUG_ERROR, "%a - FrameworkHandle not initialized\n", __func__)); + return; + } + + // + // Convert the message to an ASCII String + // + VA_START (Marker, Format); + AsciiVSPrint (LogString, sizeof (LogString), Format, Marker); + VA_END (Marker); + + // + // Finally, add the string to the log. + // + AddUnitTestFailure ( + ((UNIT_TEST_FRAMEWORK *)FrameworkHandle)->CurrentTest, + LogString, + FailureType + ); + + LongJump (&gUnitTestJumpBuffer, 1); +} + +/** + If Expression is TRUE, then TRUE is returned. + If Expression is FALSE, then an assert is triggered and the location of the + assert provided by FunctionName, LineNumber, FileName, and Description are + recorded and FALSE is returned. + + @param[in] Expression The BOOLEAN result of the expression evaluation. + @param[in] FunctionName Null-terminated ASCII string of the function + executing the assert macro. + @param[in] LineNumber The source file line number of the assert macro. + @param[in] FileName Null-terminated ASCII string of the filename + executing the assert macro. + @param[in] Description Null-terminated ASCII string of the expression being + evaluated. + + @retval TRUE Expression is TRUE. + @retval FALSE Expression is FALSE. +**/ +BOOLEAN +EFIAPI +UnitTestAssertTrue ( + IN BOOLEAN Expression, + IN CONST CHAR8 *FunctionName, + IN UINTN LineNumber, + IN CONST CHAR8 *FileName, + IN CONST CHAR8 *Description + ) +{ + if (!Expression) { + UT_LOG_ERROR ( + "[ASSERT FAIL] %a:%d: Expression (%a) is not TRUE!\n", + FileName, + LineNumber, + Description + ); + UnitTestLogFailure ( + FAILURETYPE_ASSERTTRUE, + "%a:%d: Expression (%a) is not TRUE!\n", + FileName, + LineNumber, + Description + ); + } + + return Expression; +} + +/** + If Expression is FALSE, then TRUE is returned. + If Expression is TRUE, then an assert is triggered and the location of the + assert provided by FunctionName, LineNumber, FileName, and Description are + recorded and FALSE is returned. + + @param[in] Expression The BOOLEAN result of the expression evaluation. + @param[in] FunctionName Null-terminated ASCII string of the function + executing the assert macro. + @param[in] LineNumber The source file line number of the assert macro. + @param[in] FileName Null-terminated ASCII string of the filename + executing the assert macro. + @param[in] Description Null-terminated ASCII string of the expression being + evaluated. + + @retval TRUE Expression is FALSE. + @retval FALSE Expression is TRUE. +**/ +BOOLEAN +EFIAPI +UnitTestAssertFalse ( + IN BOOLEAN Expression, + IN CONST CHAR8 *FunctionName, + IN UINTN LineNumber, + IN CONST CHAR8 *FileName, + IN CONST CHAR8 *Description + ) +{ + if (Expression) { + UT_LOG_ERROR ( + "[ASSERT FAIL] %a:%d: Expression (%a) is not FALSE!\n", + FileName, + LineNumber, + Description + ); + UnitTestLogFailure ( + FAILURETYPE_ASSERTFALSE, + "%a:%d: Expression(%a) is not FALSE!\n", + FileName, + LineNumber, + Description + ); + } + + return !Expression; +} + +/** + If Status is not an EFI_ERROR(), then TRUE is returned. + If Status is an EFI_ERROR(), then an assert is triggered and the location of + the assert provided by FunctionName, LineNumber, FileName, and Description are + recorded and FALSE is returned. + + @param[in] Status The EFI_STATUS value to evaluate. + @param[in] FunctionName Null-terminated ASCII string of the function + executing the assert macro. + @param[in] LineNumber The source file line number of the assert macro. + @param[in] FileName Null-terminated ASCII string of the filename + executing the assert macro. + @param[in] Description Null-terminated ASCII string of the status + expression being evaluated. + + @retval TRUE Status is not an EFI_ERROR(). + @retval FALSE Status is an EFI_ERROR(). +**/ +BOOLEAN +EFIAPI +UnitTestAssertNotEfiError ( + IN EFI_STATUS Status, + IN CONST CHAR8 *FunctionName, + IN UINTN LineNumber, + IN CONST CHAR8 *FileName, + IN CONST CHAR8 *Description + ) +{ + if (EFI_ERROR (Status)) { + UT_LOG_ERROR ( + "[ASSERT FAIL] %a:%d: Status '%a' is EFI_ERROR (%r)!\n", + FileName, + LineNumber, + Description, + Status + ); + UnitTestLogFailure ( + FAILURETYPE_ASSERTNOTEFIERROR, + "%a:%d: Status '%a' is EFI_ERROR (%r)!\n", + FileName, + LineNumber, + Description, + Status + ); + } + + return !EFI_ERROR (Status); +} + +/** + If ValueA is equal ValueB, then TRUE is returned. + If ValueA is not equal to ValueB, then an assert is triggered and the location + of the assert provided by FunctionName, LineNumber, FileName, DescriptionA, + and DescriptionB are recorded and FALSE is returned. + + @param[in] ValueA 64-bit value. + @param[in] ValueB 64-bit value. + @param[in] FunctionName Null-terminated ASCII string of the function + executing the assert macro. + @param[in] LineNumber The source file line number of the assert macro. + @param[in] FileName Null-terminated ASCII string of the filename + executing the assert macro. + @param[in] DescriptionA Null-terminated ASCII string that is a description + of ValueA. + @param[in] DescriptionB Null-terminated ASCII string that is a description + of ValueB. + + @retval TRUE ValueA is equal to ValueB. + @retval FALSE ValueA is not equal to ValueB. +**/ +BOOLEAN +EFIAPI +UnitTestAssertEqual ( + IN UINT64 ValueA, + IN UINT64 ValueB, + IN CONST CHAR8 *FunctionName, + IN UINTN LineNumber, + IN CONST CHAR8 *FileName, + IN CONST CHAR8 *DescriptionA, + IN CONST CHAR8 *DescriptionB + ) +{ + if (ValueA != ValueB) { + UT_LOG_ERROR ( + "[ASSERT FAIL] %a:%d: Value %a != %a (%d != %d)!\n", + FileName, + LineNumber, + DescriptionA, + DescriptionB, + ValueA, + ValueB + ); + UnitTestLogFailure ( + FAILURETYPE_ASSERTEQUAL, + "%a:%d: Value %a != %a (%d != %d)!\n", + FileName, + LineNumber, + DescriptionA, + DescriptionB, + ValueA, + ValueB + ); + } + + return (ValueA == ValueB); +} + +/** + If the contents of BufferA are identical to the contents of BufferB, then TRUE + is returned. If the contents of BufferA are not identical to the contents of + BufferB, then an assert is triggered and the location of the assert provided + by FunctionName, LineNumber, FileName, DescriptionA, and DescriptionB are + recorded and FALSE is returned. + + @param[in] BufferA Pointer to a buffer for comparison. + @param[in] BufferB Pointer to a buffer for comparison. + @param[in] Length Number of bytes to compare in BufferA and BufferB. + @param[in] FunctionName Null-terminated ASCII string of the function + executing the assert macro. + @param[in] LineNumber The source file line number of the assert macro. + @param[in] FileName Null-terminated ASCII string of the filename + executing the assert macro. + @param[in] DescriptionA Null-terminated ASCII string that is a description + of BufferA. + @param[in] DescriptionB Null-terminated ASCII string that is a description + of BufferB. + + @retval TRUE The contents of BufferA are identical to the contents of + BufferB. + @retval FALSE The contents of BufferA are not identical to the contents of + BufferB. +**/ +BOOLEAN +EFIAPI +UnitTestAssertMemEqual ( + IN VOID *BufferA, + IN VOID *BufferB, + IN UINTN Length, + IN CONST CHAR8 *FunctionName, + IN UINTN LineNumber, + IN CONST CHAR8 *FileName, + IN CONST CHAR8 *DescriptionA, + IN CONST CHAR8 *DescriptionB + ) +{ + if (CompareMem (BufferA, BufferB, Length) != 0) { + UT_LOG_ERROR ( + "[ASSERT FAIL] %a:%d: Value %a != %a for length %d bytes!\n", + FileName, + LineNumber, + DescriptionA, + DescriptionB, + Length + ); + UnitTestLogFailure ( + FAILURETYPE_ASSERTEQUAL, + "%a:%d: Memory at %a != %a for length %d bytes!\n", + FileName, + LineNumber, + DescriptionA, + DescriptionB, + Length + ); + return FALSE; + } + + return TRUE; +} + +/** + If ValueA is not equal ValueB, then TRUE is returned. + If ValueA is equal to ValueB, then an assert is triggered and the location + of the assert provided by FunctionName, LineNumber, FileName, DescriptionA + and DescriptionB are recorded and FALSE is returned. + + @param[in] ValueA 64-bit value. + @param[in] ValueB 64-bit value. + @param[in] FunctionName Null-terminated ASCII string of the function + executing the assert macro. + @param[in] LineNumber The source file line number of the assert macro. + @param[in] FileName Null-terminated ASCII string of the filename + executing the assert macro. + @param[in] DescriptionA Null-terminated ASCII string that is a description + of ValueA. + @param[in] DescriptionB Null-terminated ASCII string that is a description + of ValueB. + + @retval TRUE ValueA is not equal to ValueB. + @retval FALSE ValueA is equal to ValueB. +**/ +BOOLEAN +EFIAPI +UnitTestAssertNotEqual ( + IN UINT64 ValueA, + IN UINT64 ValueB, + IN CONST CHAR8 *FunctionName, + IN UINTN LineNumber, + IN CONST CHAR8 *FileName, + IN CONST CHAR8 *DescriptionA, + IN CONST CHAR8 *DescriptionB + ) +{ + if (ValueA == ValueB) { + UT_LOG_ERROR ( + "[ASSERT FAIL] %a:%d: Value %a == %a (%d == %d)!\n", + FileName, + LineNumber, + DescriptionA, + DescriptionB, + ValueA, + ValueB + ); + UnitTestLogFailure ( + FAILURETYPE_ASSERTNOTEQUAL, + "%a:%d: Value %a == %a (%d == %d)!\n", + FileName, + LineNumber, + DescriptionA, + DescriptionB, + ValueA, + ValueB + ); + } + + return (ValueA != ValueB); +} + +/** + If Status is equal to Expected, then TRUE is returned. + If Status is not equal to Expected, then an assert is triggered and the + location of the assert provided by FunctionName, LineNumber, FileName, and + Description are recorded and FALSE is returned. + + @param[in] Status EFI_STATUS value returned from an API under test. + @param[in] Expected The expected EFI_STATUS return value from an API + under test. + @param[in] FunctionName Null-terminated ASCII string of the function + executing the assert macro. + @param[in] LineNumber The source file line number of the assert macro. + @param[in] FileName Null-terminated ASCII string of the filename + executing the assert macro. + @param[in] Description Null-terminated ASCII string that is a description + of Status. + + @retval TRUE Status is equal to Expected. + @retval FALSE Status is not equal to Expected. +**/ +BOOLEAN +EFIAPI +UnitTestAssertStatusEqual ( + IN EFI_STATUS Status, + IN EFI_STATUS Expected, + IN CONST CHAR8 *FunctionName, + IN UINTN LineNumber, + IN CONST CHAR8 *FileName, + IN CONST CHAR8 *Description + ) +{ + if (Status != Expected) { + UT_LOG_ERROR ( + "[ASSERT FAIL] %a:%d: Status '%a' is %r, should be %r!\n", + FileName, + LineNumber, + Description, + Status, + Expected + ); + UnitTestLogFailure ( + FAILURETYPE_ASSERTSTATUSEQUAL, + "%a:%d: Status '%a' is %r, should be %r!\n", + FileName, + LineNumber, + Description, + Status, + Expected + ); + } + + return (Status == Expected); +} + +/** + If Pointer is not equal to NULL, then TRUE is returned. + If Pointer is equal to NULL, then an assert is triggered and the location of + the assert provided by FunctionName, LineNumber, FileName, and PointerName + are recorded and FALSE is returned. + + @param[in] Pointer Pointer value to be checked against NULL. + @param[in] Expected The expected EFI_STATUS return value from a function + under test. + @param[in] FunctionName Null-terminated ASCII string of the function + executing the assert macro. + @param[in] LineNumber The source file line number of the assert macro. + @param[in] FileName Null-terminated ASCII string of the filename + executing the assert macro. + @param[in] PointerName Null-terminated ASCII string that is a description + of Pointer. + + @retval TRUE Pointer is not equal to NULL. + @retval FALSE Pointer is equal to NULL. +**/ +BOOLEAN +EFIAPI +UnitTestAssertNotNull ( + IN VOID *Pointer, + IN CONST CHAR8 *FunctionName, + IN UINTN LineNumber, + IN CONST CHAR8 *FileName, + IN CONST CHAR8 *PointerName + ) +{ + if (Pointer == NULL) { + UT_LOG_ERROR ( + "[ASSERT FAIL] %a:%d: Pointer (%a) is NULL!\n", + FileName, + LineNumber, + PointerName + ); + UnitTestLogFailure ( + FAILURETYPE_ASSERTNOTNULL, + "%a:%d: Pointer (%a) is NULL!\n", + FileName, + LineNumber, + PointerName + ); + } + + return (Pointer != NULL); +} + +/** + If UnitTestStatus is UNIT_TEST_PASSED, then log an info message and return + TRUE because an ASSERT() was expected when FunctionCall was executed and an + ASSERT() was triggered. If UnitTestStatus is UNIT_TEST_SKIPPED, then log a + warning message and return TRUE because ASSERT() macros are disabled. If + UnitTestStatus is UNIT_TEST_ERROR_TEST_FAILED, then log an error message and + return FALSE because an ASSERT() was expected when FunctionCall was executed, + but no ASSERT() conditions were triggered. The log messages contain + FunctionName, LineNumber, and FileName strings to provide the location of the + UT_EXPECT_ASSERT_FAILURE() macro. + + @param[in] UnitTestStatus The status from UT_EXPECT_ASSERT_FAILURE() that + is either pass, skipped, or failed. + @param[in] FunctionName Null-terminated ASCII string of the function + executing the UT_EXPECT_ASSERT_FAILURE() macro. + @param[in] LineNumber The source file line number of the the function + executing the UT_EXPECT_ASSERT_FAILURE() macro. + @param[in] FileName Null-terminated ASCII string of the filename + executing the UT_EXPECT_ASSERT_FAILURE() macro. + @param[in] FunctionCall Null-terminated ASCII string of the function call + executed by the UT_EXPECT_ASSERT_FAILURE() macro. + @param[out] ResultStatus Used to return the UnitTestStatus value to the + caller of UT_EXPECT_ASSERT_FAILURE(). This is + optional parameter that may be NULL. + + @retval TRUE UnitTestStatus is UNIT_TEST_PASSED. + @retval TRUE UnitTestStatus is UNIT_TEST_SKIPPED. + @retval FALSE UnitTestStatus is UNIT_TEST_ERROR_TEST_FAILED. +**/ +BOOLEAN +EFIAPI +UnitTestExpectAssertFailure ( + IN UNIT_TEST_STATUS UnitTestStatus, + IN CONST CHAR8 *FunctionName, + IN UINTN LineNumber, + IN CONST CHAR8 *FileName, + IN CONST CHAR8 *FunctionCall, + OUT UNIT_TEST_STATUS *ResultStatus OPTIONAL + ) +{ + if (ResultStatus != NULL) { + *ResultStatus = UnitTestStatus; + } + + if (UnitTestStatus == UNIT_TEST_PASSED) { + UT_LOG_INFO ( + "[ASSERT PASS] %a:%d: UT_EXPECT_ASSERT_FAILURE(%a) detected expected assert\n", + FileName, + LineNumber, + FunctionCall + ); + } + + if (UnitTestStatus == UNIT_TEST_SKIPPED) { + UT_LOG_WARNING ( + "[ASSERT WARN] %a:%d: UT_EXPECT_ASSERT_FAILURE(%a) disabled\n", + FileName, + LineNumber, + FunctionCall + ); + } + + if (UnitTestStatus == UNIT_TEST_ERROR_TEST_FAILED) { + UT_LOG_ERROR ( + "[ASSERT FAIL] %a:%d: Function call (%a) did not ASSERT()!\n", + FileName, + LineNumber, + FunctionCall + ); + UnitTestLogFailure ( + FAILURETYPE_EXPECTASSERT, + "%a:%d: Function call (%a) did not ASSERT()!\n", + FileName, + LineNumber, + FunctionCall + ); + } + + return (UnitTestStatus != UNIT_TEST_ERROR_TEST_FAILED); +} diff --git a/UnitTestFrameworkPkg/Library/UnitTestLib/AssertCmocka.c b/UnitTestFrameworkPkg/Library/UnitTestLib/AssertCmocka.c index 0d8e36c938..6ba115f468 100644 --- a/UnitTestFrameworkPkg/Library/UnitTestLib/AssertCmocka.c +++ b/UnitTestFrameworkPkg/Library/UnitTestLib/AssertCmocka.c @@ -1,407 +1,407 @@ -/** @file
- Implement UnitTestLib assert services using cmocka services
-
- Copyright (c) 2019 - 2020, Intel Corporation. All rights reserved.<BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
-**/
-
-#include <stdio.h>
-#include <string.h>
-#include <stdarg.h>
-#include <stddef.h>
-#include <setjmp.h>
-#include <cmocka.h>
-
-#include <Uefi.h>
-#include <Library/BaseMemoryLib.h>
-#include <Library/UnitTestLib.h>
-
-#define MAX_STRING_SIZE 1025
-
-/**
- If Expression is TRUE, then TRUE is returned.
- If Expression is FALSE, then an assert is triggered and the location of the
- assert provided by FunctionName, LineNumber, FileName, and Description are
- recorded and FALSE is returned.
-
- @param[in] Expression The BOOLEAN result of the expression evaluation.
- @param[in] FunctionName Null-terminated ASCII string of the function
- executing the assert macro.
- @param[in] LineNumber The source file line number of the assert macro.
- @param[in] FileName Null-terminated ASCII string of the filename
- executing the assert macro.
- @param[in] Description Null-terminated ASCII string of the expression being
- evaluated.
-
- @retval TRUE Expression is TRUE.
- @retval FALSE Expression is FALSE.
-**/
-BOOLEAN
-EFIAPI
-UnitTestAssertTrue (
- IN BOOLEAN Expression,
- IN CONST CHAR8 *FunctionName,
- IN UINTN LineNumber,
- IN CONST CHAR8 *FileName,
- IN CONST CHAR8 *Description
- )
-{
- CHAR8 TempStr[MAX_STRING_SIZE];
-
- snprintf (TempStr, sizeof (TempStr), "UT_ASSERT_TRUE(%s:%x)", Description, Expression);
- _assert_true (Expression, TempStr, FileName, (INT32)LineNumber);
-
- return Expression;
-}
-
-/**
- If Expression is FALSE, then TRUE is returned.
- If Expression is TRUE, then an assert is triggered and the location of the
- assert provided by FunctionName, LineNumber, FileName, and Description are
- recorded and FALSE is returned.
-
- @param[in] Expression The BOOLEAN result of the expression evaluation.
- @param[in] FunctionName Null-terminated ASCII string of the function
- executing the assert macro.
- @param[in] LineNumber The source file line number of the assert macro.
- @param[in] FileName Null-terminated ASCII string of the filename
- executing the assert macro.
- @param[in] Description Null-terminated ASCII string of the expression being
- evaluated.
-
- @retval TRUE Expression is FALSE.
- @retval FALSE Expression is TRUE.
-**/
-BOOLEAN
-EFIAPI
-UnitTestAssertFalse (
- IN BOOLEAN Expression,
- IN CONST CHAR8 *FunctionName,
- IN UINTN LineNumber,
- IN CONST CHAR8 *FileName,
- IN CONST CHAR8 *Description
- )
-{
- CHAR8 TempStr[MAX_STRING_SIZE];
-
- snprintf (TempStr, sizeof (TempStr), "UT_ASSERT_FALSE(%s:%x)", Description, Expression);
- _assert_true (!Expression, TempStr, FileName, (INT32)LineNumber);
-
- return !Expression;
-}
-
-/**
- If Status is not an EFI_ERROR(), then TRUE is returned.
- If Status is an EFI_ERROR(), then an assert is triggered and the location of
- the assert provided by FunctionName, LineNumber, FileName, and Description are
- recorded and FALSE is returned.
-
- @param[in] Status The EFI_STATUS value to evaluate.
- @param[in] FunctionName Null-terminated ASCII string of the function
- executing the assert macro.
- @param[in] LineNumber The source file line number of the assert macro.
- @param[in] FileName Null-terminated ASCII string of the filename
- executing the assert macro.
- @param[in] Description Null-terminated ASCII string of the status
- expression being evaluated.
-
- @retval TRUE Status is not an EFI_ERROR().
- @retval FALSE Status is an EFI_ERROR().
-**/
-BOOLEAN
-EFIAPI
-UnitTestAssertNotEfiError (
- IN EFI_STATUS Status,
- IN CONST CHAR8 *FunctionName,
- IN UINTN LineNumber,
- IN CONST CHAR8 *FileName,
- IN CONST CHAR8 *Description
- )
-{
- CHAR8 TempStr[MAX_STRING_SIZE];
-
- snprintf (TempStr, sizeof (TempStr), "UT_ASSERT_NOT_EFI_ERROR(%s:%p)", Description, (void *)Status);
- _assert_true (!EFI_ERROR (Status), TempStr, FileName, (INT32)LineNumber);
-
- return !EFI_ERROR (Status);
-}
-
-/**
- If ValueA is equal ValueB, then TRUE is returned.
- If ValueA is not equal to ValueB, then an assert is triggered and the location
- of the assert provided by FunctionName, LineNumber, FileName, DescriptionA,
- and DescriptionB are recorded and FALSE is returned.
-
- @param[in] ValueA 64-bit value.
- @param[in] ValueB 64-bit value.
- @param[in] FunctionName Null-terminated ASCII string of the function
- executing the assert macro.
- @param[in] LineNumber The source file line number of the assert macro.
- @param[in] FileName Null-terminated ASCII string of the filename
- executing the assert macro.
- @param[in] DescriptionA Null-terminated ASCII string that is a description
- of ValueA.
- @param[in] DescriptionB Null-terminated ASCII string that is a description
- of ValueB.
-
- @retval TRUE ValueA is equal to ValueB.
- @retval FALSE ValueA is not equal to ValueB.
-**/
-BOOLEAN
-EFIAPI
-UnitTestAssertEqual (
- IN UINT64 ValueA,
- IN UINT64 ValueB,
- IN CONST CHAR8 *FunctionName,
- IN UINTN LineNumber,
- IN CONST CHAR8 *FileName,
- IN CONST CHAR8 *DescriptionA,
- IN CONST CHAR8 *DescriptionB
- )
-{
- CHAR8 TempStr[MAX_STRING_SIZE];
-
- snprintf (TempStr, sizeof (TempStr), "UT_ASSERT_EQUAL(%s:%llx, %s:%llx)", DescriptionA, ValueA, DescriptionB, ValueB);
- _assert_true ((ValueA == ValueB), TempStr, FileName, (INT32)LineNumber);
-
- return (ValueA == ValueB);
-}
-
-/**
- If the contents of BufferA are identical to the contents of BufferB, then TRUE
- is returned. If the contents of BufferA are not identical to the contents of
- BufferB, then an assert is triggered and the location of the assert provided
- by FunctionName, LineNumber, FileName, DescriptionA, and DescriptionB are
- recorded and FALSE is returned.
-
- @param[in] BufferA Pointer to a buffer for comparison.
- @param[in] BufferB Pointer to a buffer for comparison.
- @param[in] Length Number of bytes to compare in BufferA and BufferB.
- @param[in] FunctionName Null-terminated ASCII string of the function
- executing the assert macro.
- @param[in] LineNumber The source file line number of the assert macro.
- @param[in] FileName Null-terminated ASCII string of the filename
- executing the assert macro.
- @param[in] DescriptionA Null-terminated ASCII string that is a description
- of BufferA.
- @param[in] DescriptionB Null-terminated ASCII string that is a description
- of BufferB.
-
- @retval TRUE The contents of BufferA are identical to the contents of
- BufferB.
- @retval FALSE The contents of BufferA are not identical to the contents of
- BufferB.
-**/
-BOOLEAN
-EFIAPI
-UnitTestAssertMemEqual (
- IN VOID *BufferA,
- IN VOID *BufferB,
- IN UINTN Length,
- IN CONST CHAR8 *FunctionName,
- IN UINTN LineNumber,
- IN CONST CHAR8 *FileName,
- IN CONST CHAR8 *DescriptionA,
- IN CONST CHAR8 *DescriptionB
- )
-{
- CHAR8 TempStr[MAX_STRING_SIZE];
- BOOLEAN Result;
-
- Result = (CompareMem (BufferA, BufferB, Length) == 0);
-
- snprintf (TempStr, sizeof (TempStr), "UT_ASSERT_MEM_EQUAL(%s:%p, %s:%p)", DescriptionA, BufferA, DescriptionB, BufferB);
- _assert_true (Result, TempStr, FileName, (INT32)LineNumber);
-
- return Result;
-}
-
-/**
- If ValueA is not equal ValueB, then TRUE is returned.
- If ValueA is equal to ValueB, then an assert is triggered and the location
- of the assert provided by FunctionName, LineNumber, FileName, DescriptionA
- and DescriptionB are recorded and FALSE is returned.
-
- @param[in] ValueA 64-bit value.
- @param[in] ValueB 64-bit value.
- @param[in] FunctionName Null-terminated ASCII string of the function
- executing the assert macro.
- @param[in] LineNumber The source file line number of the assert macro.
- @param[in] FileName Null-terminated ASCII string of the filename
- executing the assert macro.
- @param[in] DescriptionA Null-terminated ASCII string that is a description
- of ValueA.
- @param[in] DescriptionB Null-terminated ASCII string that is a description
- of ValueB.
-
- @retval TRUE ValueA is not equal to ValueB.
- @retval FALSE ValueA is equal to ValueB.
-**/
-BOOLEAN
-EFIAPI
-UnitTestAssertNotEqual (
- IN UINT64 ValueA,
- IN UINT64 ValueB,
- IN CONST CHAR8 *FunctionName,
- IN UINTN LineNumber,
- IN CONST CHAR8 *FileName,
- IN CONST CHAR8 *DescriptionA,
- IN CONST CHAR8 *DescriptionB
- )
-{
- CHAR8 TempStr[MAX_STRING_SIZE];
-
- snprintf (TempStr, sizeof (TempStr), "UT_ASSERT_NOT_EQUAL(%s:%llx, %s:%llx)", DescriptionA, ValueA, DescriptionB, ValueB);
- _assert_true ((ValueA != ValueB), TempStr, FileName, (INT32)LineNumber);
-
- return (ValueA != ValueB);
-}
-
-/**
- If Status is equal to Expected, then TRUE is returned.
- If Status is not equal to Expected, then an assert is triggered and the
- location of the assert provided by FunctionName, LineNumber, FileName, and
- Description are recorded and FALSE is returned.
-
- @param[in] Status EFI_STATUS value returned from an API under test.
- @param[in] Expected The expected EFI_STATUS return value from an API
- under test.
- @param[in] FunctionName Null-terminated ASCII string of the function
- executing the assert macro.
- @param[in] LineNumber The source file line number of the assert macro.
- @param[in] FileName Null-terminated ASCII string of the filename
- executing the assert macro.
- @param[in] Description Null-terminated ASCII string that is a description
- of Status.
-
- @retval TRUE Status is equal to Expected.
- @retval FALSE Status is not equal to Expected.
-**/
-BOOLEAN
-EFIAPI
-UnitTestAssertStatusEqual (
- IN EFI_STATUS Status,
- IN EFI_STATUS Expected,
- IN CONST CHAR8 *FunctionName,
- IN UINTN LineNumber,
- IN CONST CHAR8 *FileName,
- IN CONST CHAR8 *Description
- )
-{
- CHAR8 TempStr[MAX_STRING_SIZE];
-
- snprintf (TempStr, sizeof (TempStr), "UT_ASSERT_STATUS_EQUAL(%s:%p expected:%p)", Description, (VOID *)Status, (VOID *)Expected);
- _assert_true ((Status == Expected), TempStr, FileName, (INT32)LineNumber);
-
- return (Status == Expected);
-}
-
-/**
- If Pointer is not equal to NULL, then TRUE is returned.
- If Pointer is equal to NULL, then an assert is triggered and the location of
- the assert provided by FunctionName, LineNumber, FileName, and PointerName
- are recorded and FALSE is returned.
-
- @param[in] Pointer Pointer value to be checked against NULL.
- @param[in] Expected The expected EFI_STATUS return value from a function
- under test.
- @param[in] FunctionName Null-terminated ASCII string of the function
- executing the assert macro.
- @param[in] LineNumber The source file line number of the assert macro.
- @param[in] FileName Null-terminated ASCII string of the filename
- executing the assert macro.
- @param[in] PointerName Null-terminated ASCII string that is a description
- of Pointer.
-
- @retval TRUE Pointer is not equal to NULL.
- @retval FALSE Pointer is equal to NULL.
-**/
-BOOLEAN
-EFIAPI
-UnitTestAssertNotNull (
- IN VOID *Pointer,
- IN CONST CHAR8 *FunctionName,
- IN UINTN LineNumber,
- IN CONST CHAR8 *FileName,
- IN CONST CHAR8 *PointerName
- )
-{
- CHAR8 TempStr[MAX_STRING_SIZE];
-
- snprintf (TempStr, sizeof (TempStr), "UT_ASSERT_NOT_NULL(%s:%p)", PointerName, Pointer);
- _assert_true ((Pointer != NULL), TempStr, FileName, (INT32)LineNumber);
-
- return (Pointer != NULL);
-}
-
-/**
- If UnitTestStatus is UNIT_TEST_PASSED, then log an info message and return
- TRUE because an ASSERT() was expected when FunctionCall was executed and an
- ASSERT() was triggered. If UnitTestStatus is UNIT_TEST_SKIPPED, then log a
- warning message and return TRUE because ASSERT() macros are disabled. If
- UnitTestStatus is UNIT_TEST_ERROR_TEST_FAILED, then log an error message and
- return FALSE because an ASSERT() was expected when FunctionCall was executed,
- but no ASSERT() conditions were triggered. The log messages contain
- FunctionName, LineNumber, and FileName strings to provide the location of the
- UT_EXPECT_ASSERT_FAILURE() macro.
-
- @param[in] UnitTestStatus The status from UT_EXPECT_ASSERT_FAILURE() that
- is either pass, skipped, or failed.
- @param[in] FunctionName Null-terminated ASCII string of the function
- executing the UT_EXPECT_ASSERT_FAILURE() macro.
- @param[in] LineNumber The source file line number of the the function
- executing the UT_EXPECT_ASSERT_FAILURE() macro.
- @param[in] FileName Null-terminated ASCII string of the filename
- executing the UT_EXPECT_ASSERT_FAILURE() macro.
- @param[in] FunctionCall Null-terminated ASCII string of the function call
- executed by the UT_EXPECT_ASSERT_FAILURE() macro.
- @param[out] ResultStatus Used to return the UnitTestStatus value to the
- caller of UT_EXPECT_ASSERT_FAILURE(). This is
- optional parameter that may be NULL.
-
- @retval TRUE UnitTestStatus is UNIT_TEST_PASSED.
- @retval TRUE UnitTestStatus is UNIT_TEST_SKIPPED.
- @retval FALSE UnitTestStatus is UNIT_TEST_ERROR_TEST_FAILED.
-**/
-BOOLEAN
-EFIAPI
-UnitTestExpectAssertFailure (
- IN UNIT_TEST_STATUS UnitTestStatus,
- IN CONST CHAR8 *FunctionName,
- IN UINTN LineNumber,
- IN CONST CHAR8 *FileName,
- IN CONST CHAR8 *FunctionCall,
- OUT UNIT_TEST_STATUS *ResultStatus OPTIONAL
- )
-{
- CHAR8 TempStr[MAX_STRING_SIZE];
-
- if (ResultStatus != NULL) {
- *ResultStatus = UnitTestStatus;
- }
-
- if (UnitTestStatus == UNIT_TEST_PASSED) {
- UT_LOG_INFO (
- "[ASSERT PASS] %a:%d: UT_EXPECT_ASSERT_FAILURE(%a) detected expected assert\n",
- FileName,
- LineNumber,
- FunctionCall
- );
- }
-
- if (UnitTestStatus == UNIT_TEST_SKIPPED) {
- UT_LOG_WARNING (
- "[ASSERT WARN] %a:%d: UT_EXPECT_ASSERT_FAILURE(%a) disabled\n",
- FileName,
- LineNumber,
- FunctionCall
- );
- }
-
- if (UnitTestStatus == UNIT_TEST_ERROR_TEST_FAILED) {
- snprintf (TempStr, sizeof (TempStr), "UT_EXPECT_ASSERT_FAILURE(%s) did not trigger ASSERT()", FunctionCall);
- _assert_true (FALSE, TempStr, FileName, (INT32)LineNumber);
- }
-
- return (UnitTestStatus != UNIT_TEST_ERROR_TEST_FAILED);
-}
+/** @file + Implement UnitTestLib assert services using cmocka services + + Copyright (c) 2019 - 2020, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include <stdio.h> +#include <string.h> +#include <stdarg.h> +#include <stddef.h> +#include <setjmp.h> +#include <cmocka.h> + +#include <Uefi.h> +#include <Library/BaseMemoryLib.h> +#include <Library/UnitTestLib.h> + +#define MAX_STRING_SIZE 1025 + +/** + If Expression is TRUE, then TRUE is returned. + If Expression is FALSE, then an assert is triggered and the location of the + assert provided by FunctionName, LineNumber, FileName, and Description are + recorded and FALSE is returned. + + @param[in] Expression The BOOLEAN result of the expression evaluation. + @param[in] FunctionName Null-terminated ASCII string of the function + executing the assert macro. + @param[in] LineNumber The source file line number of the assert macro. + @param[in] FileName Null-terminated ASCII string of the filename + executing the assert macro. + @param[in] Description Null-terminated ASCII string of the expression being + evaluated. + + @retval TRUE Expression is TRUE. + @retval FALSE Expression is FALSE. +**/ +BOOLEAN +EFIAPI +UnitTestAssertTrue ( + IN BOOLEAN Expression, + IN CONST CHAR8 *FunctionName, + IN UINTN LineNumber, + IN CONST CHAR8 *FileName, + IN CONST CHAR8 *Description + ) +{ + CHAR8 TempStr[MAX_STRING_SIZE]; + + snprintf (TempStr, sizeof (TempStr), "UT_ASSERT_TRUE(%s:%x)", Description, Expression); + _assert_true (Expression, TempStr, FileName, (INT32)LineNumber); + + return Expression; +} + +/** + If Expression is FALSE, then TRUE is returned. + If Expression is TRUE, then an assert is triggered and the location of the + assert provided by FunctionName, LineNumber, FileName, and Description are + recorded and FALSE is returned. + + @param[in] Expression The BOOLEAN result of the expression evaluation. + @param[in] FunctionName Null-terminated ASCII string of the function + executing the assert macro. + @param[in] LineNumber The source file line number of the assert macro. + @param[in] FileName Null-terminated ASCII string of the filename + executing the assert macro. + @param[in] Description Null-terminated ASCII string of the expression being + evaluated. + + @retval TRUE Expression is FALSE. + @retval FALSE Expression is TRUE. +**/ +BOOLEAN +EFIAPI +UnitTestAssertFalse ( + IN BOOLEAN Expression, + IN CONST CHAR8 *FunctionName, + IN UINTN LineNumber, + IN CONST CHAR8 *FileName, + IN CONST CHAR8 *Description + ) +{ + CHAR8 TempStr[MAX_STRING_SIZE]; + + snprintf (TempStr, sizeof (TempStr), "UT_ASSERT_FALSE(%s:%x)", Description, Expression); + _assert_true (!Expression, TempStr, FileName, (INT32)LineNumber); + + return !Expression; +} + +/** + If Status is not an EFI_ERROR(), then TRUE is returned. + If Status is an EFI_ERROR(), then an assert is triggered and the location of + the assert provided by FunctionName, LineNumber, FileName, and Description are + recorded and FALSE is returned. + + @param[in] Status The EFI_STATUS value to evaluate. + @param[in] FunctionName Null-terminated ASCII string of the function + executing the assert macro. + @param[in] LineNumber The source file line number of the assert macro. + @param[in] FileName Null-terminated ASCII string of the filename + executing the assert macro. + @param[in] Description Null-terminated ASCII string of the status + expression being evaluated. + + @retval TRUE Status is not an EFI_ERROR(). + @retval FALSE Status is an EFI_ERROR(). +**/ +BOOLEAN +EFIAPI +UnitTestAssertNotEfiError ( + IN EFI_STATUS Status, + IN CONST CHAR8 *FunctionName, + IN UINTN LineNumber, + IN CONST CHAR8 *FileName, + IN CONST CHAR8 *Description + ) +{ + CHAR8 TempStr[MAX_STRING_SIZE]; + + snprintf (TempStr, sizeof (TempStr), "UT_ASSERT_NOT_EFI_ERROR(%s:%p)", Description, (void *)Status); + _assert_true (!EFI_ERROR (Status), TempStr, FileName, (INT32)LineNumber); + + return !EFI_ERROR (Status); +} + +/** + If ValueA is equal ValueB, then TRUE is returned. + If ValueA is not equal to ValueB, then an assert is triggered and the location + of the assert provided by FunctionName, LineNumber, FileName, DescriptionA, + and DescriptionB are recorded and FALSE is returned. + + @param[in] ValueA 64-bit value. + @param[in] ValueB 64-bit value. + @param[in] FunctionName Null-terminated ASCII string of the function + executing the assert macro. + @param[in] LineNumber The source file line number of the assert macro. + @param[in] FileName Null-terminated ASCII string of the filename + executing the assert macro. + @param[in] DescriptionA Null-terminated ASCII string that is a description + of ValueA. + @param[in] DescriptionB Null-terminated ASCII string that is a description + of ValueB. + + @retval TRUE ValueA is equal to ValueB. + @retval FALSE ValueA is not equal to ValueB. +**/ +BOOLEAN +EFIAPI +UnitTestAssertEqual ( + IN UINT64 ValueA, + IN UINT64 ValueB, + IN CONST CHAR8 *FunctionName, + IN UINTN LineNumber, + IN CONST CHAR8 *FileName, + IN CONST CHAR8 *DescriptionA, + IN CONST CHAR8 *DescriptionB + ) +{ + CHAR8 TempStr[MAX_STRING_SIZE]; + + snprintf (TempStr, sizeof (TempStr), "UT_ASSERT_EQUAL(%s:%llx, %s:%llx)", DescriptionA, ValueA, DescriptionB, ValueB); + _assert_true ((ValueA == ValueB), TempStr, FileName, (INT32)LineNumber); + + return (ValueA == ValueB); +} + +/** + If the contents of BufferA are identical to the contents of BufferB, then TRUE + is returned. If the contents of BufferA are not identical to the contents of + BufferB, then an assert is triggered and the location of the assert provided + by FunctionName, LineNumber, FileName, DescriptionA, and DescriptionB are + recorded and FALSE is returned. + + @param[in] BufferA Pointer to a buffer for comparison. + @param[in] BufferB Pointer to a buffer for comparison. + @param[in] Length Number of bytes to compare in BufferA and BufferB. + @param[in] FunctionName Null-terminated ASCII string of the function + executing the assert macro. + @param[in] LineNumber The source file line number of the assert macro. + @param[in] FileName Null-terminated ASCII string of the filename + executing the assert macro. + @param[in] DescriptionA Null-terminated ASCII string that is a description + of BufferA. + @param[in] DescriptionB Null-terminated ASCII string that is a description + of BufferB. + + @retval TRUE The contents of BufferA are identical to the contents of + BufferB. + @retval FALSE The contents of BufferA are not identical to the contents of + BufferB. +**/ +BOOLEAN +EFIAPI +UnitTestAssertMemEqual ( + IN VOID *BufferA, + IN VOID *BufferB, + IN UINTN Length, + IN CONST CHAR8 *FunctionName, + IN UINTN LineNumber, + IN CONST CHAR8 *FileName, + IN CONST CHAR8 *DescriptionA, + IN CONST CHAR8 *DescriptionB + ) +{ + CHAR8 TempStr[MAX_STRING_SIZE]; + BOOLEAN Result; + + Result = (CompareMem (BufferA, BufferB, Length) == 0); + + snprintf (TempStr, sizeof (TempStr), "UT_ASSERT_MEM_EQUAL(%s:%p, %s:%p)", DescriptionA, BufferA, DescriptionB, BufferB); + _assert_true (Result, TempStr, FileName, (INT32)LineNumber); + + return Result; +} + +/** + If ValueA is not equal ValueB, then TRUE is returned. + If ValueA is equal to ValueB, then an assert is triggered and the location + of the assert provided by FunctionName, LineNumber, FileName, DescriptionA + and DescriptionB are recorded and FALSE is returned. + + @param[in] ValueA 64-bit value. + @param[in] ValueB 64-bit value. + @param[in] FunctionName Null-terminated ASCII string of the function + executing the assert macro. + @param[in] LineNumber The source file line number of the assert macro. + @param[in] FileName Null-terminated ASCII string of the filename + executing the assert macro. + @param[in] DescriptionA Null-terminated ASCII string that is a description + of ValueA. + @param[in] DescriptionB Null-terminated ASCII string that is a description + of ValueB. + + @retval TRUE ValueA is not equal to ValueB. + @retval FALSE ValueA is equal to ValueB. +**/ +BOOLEAN +EFIAPI +UnitTestAssertNotEqual ( + IN UINT64 ValueA, + IN UINT64 ValueB, + IN CONST CHAR8 *FunctionName, + IN UINTN LineNumber, + IN CONST CHAR8 *FileName, + IN CONST CHAR8 *DescriptionA, + IN CONST CHAR8 *DescriptionB + ) +{ + CHAR8 TempStr[MAX_STRING_SIZE]; + + snprintf (TempStr, sizeof (TempStr), "UT_ASSERT_NOT_EQUAL(%s:%llx, %s:%llx)", DescriptionA, ValueA, DescriptionB, ValueB); + _assert_true ((ValueA != ValueB), TempStr, FileName, (INT32)LineNumber); + + return (ValueA != ValueB); +} + +/** + If Status is equal to Expected, then TRUE is returned. + If Status is not equal to Expected, then an assert is triggered and the + location of the assert provided by FunctionName, LineNumber, FileName, and + Description are recorded and FALSE is returned. + + @param[in] Status EFI_STATUS value returned from an API under test. + @param[in] Expected The expected EFI_STATUS return value from an API + under test. + @param[in] FunctionName Null-terminated ASCII string of the function + executing the assert macro. + @param[in] LineNumber The source file line number of the assert macro. + @param[in] FileName Null-terminated ASCII string of the filename + executing the assert macro. + @param[in] Description Null-terminated ASCII string that is a description + of Status. + + @retval TRUE Status is equal to Expected. + @retval FALSE Status is not equal to Expected. +**/ +BOOLEAN +EFIAPI +UnitTestAssertStatusEqual ( + IN EFI_STATUS Status, + IN EFI_STATUS Expected, + IN CONST CHAR8 *FunctionName, + IN UINTN LineNumber, + IN CONST CHAR8 *FileName, + IN CONST CHAR8 *Description + ) +{ + CHAR8 TempStr[MAX_STRING_SIZE]; + + snprintf (TempStr, sizeof (TempStr), "UT_ASSERT_STATUS_EQUAL(%s:%p expected:%p)", Description, (VOID *)Status, (VOID *)Expected); + _assert_true ((Status == Expected), TempStr, FileName, (INT32)LineNumber); + + return (Status == Expected); +} + +/** + If Pointer is not equal to NULL, then TRUE is returned. + If Pointer is equal to NULL, then an assert is triggered and the location of + the assert provided by FunctionName, LineNumber, FileName, and PointerName + are recorded and FALSE is returned. + + @param[in] Pointer Pointer value to be checked against NULL. + @param[in] Expected The expected EFI_STATUS return value from a function + under test. + @param[in] FunctionName Null-terminated ASCII string of the function + executing the assert macro. + @param[in] LineNumber The source file line number of the assert macro. + @param[in] FileName Null-terminated ASCII string of the filename + executing the assert macro. + @param[in] PointerName Null-terminated ASCII string that is a description + of Pointer. + + @retval TRUE Pointer is not equal to NULL. + @retval FALSE Pointer is equal to NULL. +**/ +BOOLEAN +EFIAPI +UnitTestAssertNotNull ( + IN VOID *Pointer, + IN CONST CHAR8 *FunctionName, + IN UINTN LineNumber, + IN CONST CHAR8 *FileName, + IN CONST CHAR8 *PointerName + ) +{ + CHAR8 TempStr[MAX_STRING_SIZE]; + + snprintf (TempStr, sizeof (TempStr), "UT_ASSERT_NOT_NULL(%s:%p)", PointerName, Pointer); + _assert_true ((Pointer != NULL), TempStr, FileName, (INT32)LineNumber); + + return (Pointer != NULL); +} + +/** + If UnitTestStatus is UNIT_TEST_PASSED, then log an info message and return + TRUE because an ASSERT() was expected when FunctionCall was executed and an + ASSERT() was triggered. If UnitTestStatus is UNIT_TEST_SKIPPED, then log a + warning message and return TRUE because ASSERT() macros are disabled. If + UnitTestStatus is UNIT_TEST_ERROR_TEST_FAILED, then log an error message and + return FALSE because an ASSERT() was expected when FunctionCall was executed, + but no ASSERT() conditions were triggered. The log messages contain + FunctionName, LineNumber, and FileName strings to provide the location of the + UT_EXPECT_ASSERT_FAILURE() macro. + + @param[in] UnitTestStatus The status from UT_EXPECT_ASSERT_FAILURE() that + is either pass, skipped, or failed. + @param[in] FunctionName Null-terminated ASCII string of the function + executing the UT_EXPECT_ASSERT_FAILURE() macro. + @param[in] LineNumber The source file line number of the the function + executing the UT_EXPECT_ASSERT_FAILURE() macro. + @param[in] FileName Null-terminated ASCII string of the filename + executing the UT_EXPECT_ASSERT_FAILURE() macro. + @param[in] FunctionCall Null-terminated ASCII string of the function call + executed by the UT_EXPECT_ASSERT_FAILURE() macro. + @param[out] ResultStatus Used to return the UnitTestStatus value to the + caller of UT_EXPECT_ASSERT_FAILURE(). This is + optional parameter that may be NULL. + + @retval TRUE UnitTestStatus is UNIT_TEST_PASSED. + @retval TRUE UnitTestStatus is UNIT_TEST_SKIPPED. + @retval FALSE UnitTestStatus is UNIT_TEST_ERROR_TEST_FAILED. +**/ +BOOLEAN +EFIAPI +UnitTestExpectAssertFailure ( + IN UNIT_TEST_STATUS UnitTestStatus, + IN CONST CHAR8 *FunctionName, + IN UINTN LineNumber, + IN CONST CHAR8 *FileName, + IN CONST CHAR8 *FunctionCall, + OUT UNIT_TEST_STATUS *ResultStatus OPTIONAL + ) +{ + CHAR8 TempStr[MAX_STRING_SIZE]; + + if (ResultStatus != NULL) { + *ResultStatus = UnitTestStatus; + } + + if (UnitTestStatus == UNIT_TEST_PASSED) { + UT_LOG_INFO ( + "[ASSERT PASS] %a:%d: UT_EXPECT_ASSERT_FAILURE(%a) detected expected assert\n", + FileName, + LineNumber, + FunctionCall + ); + } + + if (UnitTestStatus == UNIT_TEST_SKIPPED) { + UT_LOG_WARNING ( + "[ASSERT WARN] %a:%d: UT_EXPECT_ASSERT_FAILURE(%a) disabled\n", + FileName, + LineNumber, + FunctionCall + ); + } + + if (UnitTestStatus == UNIT_TEST_ERROR_TEST_FAILED) { + snprintf (TempStr, sizeof (TempStr), "UT_EXPECT_ASSERT_FAILURE(%s) did not trigger ASSERT()", FunctionCall); + _assert_true (FALSE, TempStr, FileName, (INT32)LineNumber); + } + + return (UnitTestStatus != UNIT_TEST_ERROR_TEST_FAILED); +} diff --git a/UnitTestFrameworkPkg/Library/UnitTestLib/Log.c b/UnitTestFrameworkPkg/Library/UnitTestLib/Log.c index f61b9d57b1..0f0dc1f868 100644 --- a/UnitTestFrameworkPkg/Library/UnitTestLib/Log.c +++ b/UnitTestFrameworkPkg/Library/UnitTestLib/Log.c @@ -1,205 +1,205 @@ -/**
- Implemnet UnitTestLib log services
-
- Copyright (c) Microsoft Corporation.<BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
-**/
-
-#include <PiDxe.h>
-#include <UnitTestFrameworkTypes.h>
-#include <Library/UnitTestLib.h>
-#include <Library/BaseLib.h>
-#include <Library/BaseMemoryLib.h>
-#include <Library/MemoryAllocationLib.h>
-#include <Library/DebugLib.h>
-#include <Library/PrintLib.h>
-#include <Library/PcdLib.h>
-
-#define UNIT_TEST_MAX_SINGLE_LOG_STRING_LENGTH (512)
-#define UNIT_TEST_MAX_LOG_BUFFER SIZE_16KB
-
-struct _UNIT_TEST_LOG_PREFIX_STRING {
- UNIT_TEST_STATUS LogLevel;
- CHAR8 *String;
-};
-
-struct _UNIT_TEST_LOG_PREFIX_STRING mLogPrefixStrings[] = {
- { UNIT_TEST_LOG_LEVEL_ERROR, "[ERROR] " },
- { UNIT_TEST_LOG_LEVEL_WARN, "[WARNING] " },
- { UNIT_TEST_LOG_LEVEL_INFO, "[INFO] " },
- { UNIT_TEST_LOG_LEVEL_VERBOSE, "[VERBOSE] " }
-};
-
-//
-// Unit-Test Log helper functions
-//
-
-STATIC
-CONST CHAR8 *
-GetStringForStatusLogPrefix (
- IN UINTN LogLevel
- )
-{
- UINTN Index;
- CHAR8 *Result;
-
- Result = NULL;
- for (Index = 0; Index < ARRAY_SIZE (mLogPrefixStrings); Index++) {
- if (mLogPrefixStrings[Index].LogLevel == LogLevel) {
- Result = mLogPrefixStrings[Index].String;
- break;
- }
- }
-
- return Result;
-}
-
-STATIC
-EFI_STATUS
-AddStringToUnitTestLog (
- IN OUT UNIT_TEST *UnitTest,
- IN CONST CHAR8 *String
- )
-{
- EFI_STATUS Status;
-
- //
- // Make sure that you're cooking with gas.
- //
- if ((UnitTest == NULL) || (String == NULL)) {
- return EFI_INVALID_PARAMETER;
- }
-
- // If this is the first log for the test allocate log space
- if (UnitTest->Log == NULL) {
- UnitTestLogInit (UnitTest, NULL, 0);
- }
-
- if (UnitTest->Log == NULL) {
- DEBUG ((DEBUG_ERROR, "Failed to allocate space for unit test log\n"));
- ASSERT (UnitTest->Log != NULL);
- return EFI_OUT_OF_RESOURCES;
- }
-
- Status = AsciiStrnCatS (
- UnitTest->Log,
- UNIT_TEST_MAX_LOG_BUFFER / sizeof (CHAR8),
- String,
- UNIT_TEST_MAX_SINGLE_LOG_STRING_LENGTH
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "Failed to add unit test log string. Status = %r\n", Status));
- return Status;
- }
-
- return EFI_SUCCESS;
-}
-
-/**
- This function is responsible for initializing the log buffer for a single test. It can
- be used internally, but may also be consumed by the test framework to add pre-existing
- data to a log before it's used.
-
- @param[in,out] TestHandle A handle to the test being initialized.
- @param[in] Buffer [Optional] A pointer to pre-existing log data that should
- be used to initialize the log. Should include a NULL terminator.
- @param[in] BufferSize [Optional] The size of the pre-existing log data.
-
-**/
-VOID
-EFIAPI
-UnitTestLogInit (
- IN OUT UNIT_TEST *Test,
- IN UINT8 *Buffer OPTIONAL,
- IN UINTN BufferSize OPTIONAL
- )
-{
- //
- // Make sure that you're cooking with gas.
- //
- if (Test == NULL) {
- DEBUG ((DEBUG_ERROR, "%a called with invalid Test parameter\n", __func__));
- return;
- }
-
- //
- // If this is the first log for the test allocate log space
- //
- if (Test->Log == NULL) {
- Test->Log = AllocateZeroPool (UNIT_TEST_MAX_LOG_BUFFER);
- }
-
- //
- // check again to make sure allocate worked
- //
- if (Test->Log == NULL) {
- DEBUG ((DEBUG_ERROR, "Failed to allocate memory for the log\n"));
- return;
- }
-
- if ((Buffer != NULL) && (BufferSize > 0) && (BufferSize <= UNIT_TEST_MAX_LOG_BUFFER)) {
- CopyMem (Test->Log, Buffer, BufferSize);
- }
-}
-
-/**
- Test logging function that records a messages in the test framework log.
- Record is associated with the currently executing test case.
-
- @param[in] ErrorLevel The error level of the unit test log message.
- @param[in] Format Formatting string following the format defined in the
- MdePkg/Include/Library/PrintLib.h.
- @param[in] ... Print args.
-**/
-VOID
-EFIAPI
-UnitTestLog (
- IN UINTN ErrorLevel,
- IN CONST CHAR8 *Format,
- ...
- )
-{
- UNIT_TEST_FRAMEWORK_HANDLE FrameworkHandle;
- CHAR8 NewFormatString[UNIT_TEST_MAX_SINGLE_LOG_STRING_LENGTH];
- CHAR8 LogString[UNIT_TEST_MAX_SINGLE_LOG_STRING_LENGTH];
- CONST CHAR8 *LogTypePrefix;
- VA_LIST Marker;
-
- FrameworkHandle = GetActiveFrameworkHandle ();
- if (FrameworkHandle == NULL) {
- DEBUG ((DEBUG_ERROR, "%a - FrameworkHandle not initialized\n", __func__));
- return;
- }
-
- LogTypePrefix = NULL;
-
- //
- // Make sure that this unit test log level is enabled.
- //
- if ((ErrorLevel & (UINTN)PcdGet32 (PcdUnitTestLogLevel)) == 0) {
- return;
- }
-
- //
- // If we need to define a new format string...
- // well... get to it.
- //
- LogTypePrefix = GetStringForStatusLogPrefix (ErrorLevel);
- if (LogTypePrefix != NULL) {
- AsciiSPrint (NewFormatString, sizeof (NewFormatString), "%a%a", LogTypePrefix, Format);
- } else {
- AsciiStrCpyS (NewFormatString, sizeof (NewFormatString), Format);
- }
-
- //
- // Convert the message to an ASCII String
- //
- VA_START (Marker, Format);
- AsciiVSPrint (LogString, sizeof (LogString), NewFormatString, Marker);
- VA_END (Marker);
-
- //
- // Finally, add the string to the log.
- //
- AddStringToUnitTestLog (((UNIT_TEST_FRAMEWORK *)FrameworkHandle)->CurrentTest, LogString);
-}
+/** + Implemnet UnitTestLib log services + + Copyright (c) Microsoft Corporation.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include <PiDxe.h> +#include <UnitTestFrameworkTypes.h> +#include <Library/UnitTestLib.h> +#include <Library/BaseLib.h> +#include <Library/BaseMemoryLib.h> +#include <Library/MemoryAllocationLib.h> +#include <Library/DebugLib.h> +#include <Library/PrintLib.h> +#include <Library/PcdLib.h> + +#define UNIT_TEST_MAX_SINGLE_LOG_STRING_LENGTH (512) +#define UNIT_TEST_MAX_LOG_BUFFER SIZE_16KB + +struct _UNIT_TEST_LOG_PREFIX_STRING { + UNIT_TEST_STATUS LogLevel; + CHAR8 *String; +}; + +struct _UNIT_TEST_LOG_PREFIX_STRING mLogPrefixStrings[] = { + { UNIT_TEST_LOG_LEVEL_ERROR, "[ERROR] " }, + { UNIT_TEST_LOG_LEVEL_WARN, "[WARNING] " }, + { UNIT_TEST_LOG_LEVEL_INFO, "[INFO] " }, + { UNIT_TEST_LOG_LEVEL_VERBOSE, "[VERBOSE] " } +}; + +// +// Unit-Test Log helper functions +// + +STATIC +CONST CHAR8 * +GetStringForStatusLogPrefix ( + IN UINTN LogLevel + ) +{ + UINTN Index; + CHAR8 *Result; + + Result = NULL; + for (Index = 0; Index < ARRAY_SIZE (mLogPrefixStrings); Index++) { + if (mLogPrefixStrings[Index].LogLevel == LogLevel) { + Result = mLogPrefixStrings[Index].String; + break; + } + } + + return Result; +} + +STATIC +EFI_STATUS +AddStringToUnitTestLog ( + IN OUT UNIT_TEST *UnitTest, + IN CONST CHAR8 *String + ) +{ + EFI_STATUS Status; + + // + // Make sure that you're cooking with gas. + // + if ((UnitTest == NULL) || (String == NULL)) { + return EFI_INVALID_PARAMETER; + } + + // If this is the first log for the test allocate log space + if (UnitTest->Log == NULL) { + UnitTestLogInit (UnitTest, NULL, 0); + } + + if (UnitTest->Log == NULL) { + DEBUG ((DEBUG_ERROR, "Failed to allocate space for unit test log\n")); + ASSERT (UnitTest->Log != NULL); + return EFI_OUT_OF_RESOURCES; + } + + Status = AsciiStrnCatS ( + UnitTest->Log, + UNIT_TEST_MAX_LOG_BUFFER / sizeof (CHAR8), + String, + UNIT_TEST_MAX_SINGLE_LOG_STRING_LENGTH + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Failed to add unit test log string. Status = %r\n", Status)); + return Status; + } + + return EFI_SUCCESS; +} + +/** + This function is responsible for initializing the log buffer for a single test. It can + be used internally, but may also be consumed by the test framework to add pre-existing + data to a log before it's used. + + @param[in,out] TestHandle A handle to the test being initialized. + @param[in] Buffer [Optional] A pointer to pre-existing log data that should + be used to initialize the log. Should include a NULL terminator. + @param[in] BufferSize [Optional] The size of the pre-existing log data. + +**/ +VOID +EFIAPI +UnitTestLogInit ( + IN OUT UNIT_TEST *Test, + IN UINT8 *Buffer OPTIONAL, + IN UINTN BufferSize OPTIONAL + ) +{ + // + // Make sure that you're cooking with gas. + // + if (Test == NULL) { + DEBUG ((DEBUG_ERROR, "%a called with invalid Test parameter\n", __func__)); + return; + } + + // + // If this is the first log for the test allocate log space + // + if (Test->Log == NULL) { + Test->Log = AllocateZeroPool (UNIT_TEST_MAX_LOG_BUFFER); + } + + // + // check again to make sure allocate worked + // + if (Test->Log == NULL) { + DEBUG ((DEBUG_ERROR, "Failed to allocate memory for the log\n")); + return; + } + + if ((Buffer != NULL) && (BufferSize > 0) && (BufferSize <= UNIT_TEST_MAX_LOG_BUFFER)) { + CopyMem (Test->Log, Buffer, BufferSize); + } +} + +/** + Test logging function that records a messages in the test framework log. + Record is associated with the currently executing test case. + + @param[in] ErrorLevel The error level of the unit test log message. + @param[in] Format Formatting string following the format defined in the + MdePkg/Include/Library/PrintLib.h. + @param[in] ... Print args. +**/ +VOID +EFIAPI +UnitTestLog ( + IN UINTN ErrorLevel, + IN CONST CHAR8 *Format, + ... + ) +{ + UNIT_TEST_FRAMEWORK_HANDLE FrameworkHandle; + CHAR8 NewFormatString[UNIT_TEST_MAX_SINGLE_LOG_STRING_LENGTH]; + CHAR8 LogString[UNIT_TEST_MAX_SINGLE_LOG_STRING_LENGTH]; + CONST CHAR8 *LogTypePrefix; + VA_LIST Marker; + + FrameworkHandle = GetActiveFrameworkHandle (); + if (FrameworkHandle == NULL) { + DEBUG ((DEBUG_ERROR, "%a - FrameworkHandle not initialized\n", __func__)); + return; + } + + LogTypePrefix = NULL; + + // + // Make sure that this unit test log level is enabled. + // + if ((ErrorLevel & (UINTN)PcdGet32 (PcdUnitTestLogLevel)) == 0) { + return; + } + + // + // If we need to define a new format string... + // well... get to it. + // + LogTypePrefix = GetStringForStatusLogPrefix (ErrorLevel); + if (LogTypePrefix != NULL) { + AsciiSPrint (NewFormatString, sizeof (NewFormatString), "%a%a", LogTypePrefix, Format); + } else { + AsciiStrCpyS (NewFormatString, sizeof (NewFormatString), Format); + } + + // + // Convert the message to an ASCII String + // + VA_START (Marker, Format); + AsciiVSPrint (LogString, sizeof (LogString), NewFormatString, Marker); + VA_END (Marker); + + // + // Finally, add the string to the log. + // + AddStringToUnitTestLog (((UNIT_TEST_FRAMEWORK *)FrameworkHandle)->CurrentTest, LogString); +} diff --git a/UnitTestFrameworkPkg/Library/UnitTestLib/RunTests.c b/UnitTestFrameworkPkg/Library/UnitTestLib/RunTests.c index dc1b6147d2..16abc7db00 100644 --- a/UnitTestFrameworkPkg/Library/UnitTestLib/RunTests.c +++ b/UnitTestFrameworkPkg/Library/UnitTestLib/RunTests.c @@ -1,187 +1,187 @@ -/**
- UnitTestLib APIs to run unit tests
-
- Copyright (c) Microsoft Corporation.
- SPDX-License-Identifier: BSD-2-Clause-Patent
-**/
-
-#include <Uefi.h>
-#include <Library/UnitTestLib.h>
-#include <Library/BaseLib.h>
-#include <Library/BaseMemoryLib.h>
-#include <Library/DebugLib.h>
-#include <Library/UnitTestResultReportLib.h>
-
-STATIC UNIT_TEST_FRAMEWORK_HANDLE mFrameworkHandle = NULL;
-
-BASE_LIBRARY_JUMP_BUFFER gUnitTestJumpBuffer;
-
-UNIT_TEST_FRAMEWORK_HANDLE
-GetActiveFrameworkHandle (
- VOID
- )
-{
- return mFrameworkHandle;
-}
-
-STATIC
-EFI_STATUS
-RunTestSuite (
- IN UNIT_TEST_SUITE *Suite
- )
-{
- UNIT_TEST_LIST_ENTRY *TestEntry;
- UNIT_TEST *Test;
- UNIT_TEST_FRAMEWORK *ParentFramework;
-
- if (Suite == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- TestEntry = NULL;
- ParentFramework = (UNIT_TEST_FRAMEWORK *)Suite->ParentFramework;
-
- DEBUG ((DEBUG_VERBOSE, "---------------------------------------------------------\n"));
- DEBUG ((DEBUG_VERBOSE, "RUNNING TEST SUITE: %a\n", Suite->Title));
- DEBUG ((DEBUG_VERBOSE, "---------------------------------------------------------\n"));
-
- if (Suite->Setup != NULL) {
- Suite->Setup ();
- }
-
- //
- // Iterate all tests within the suite
- //
- for (TestEntry = (UNIT_TEST_LIST_ENTRY *)GetFirstNode (&(Suite->TestCaseList));
- (LIST_ENTRY *)TestEntry != &(Suite->TestCaseList);
- TestEntry = (UNIT_TEST_LIST_ENTRY *)GetNextNode (&(Suite->TestCaseList), (LIST_ENTRY *)TestEntry))
- {
- Test = &TestEntry->UT;
- ParentFramework->CurrentTest = Test;
-
- DEBUG ((DEBUG_VERBOSE, "*********************************************************\n"));
- DEBUG ((DEBUG_VERBOSE, " RUNNING TEST: %a:\n", Test->Description));
- DEBUG ((DEBUG_VERBOSE, "**********************************************************\n"));
-
- //
- // First, check to see whether the test has already been run.
- // NOTE: This would generally only be the case if a saved state was detected and loaded.
- //
- if ((Test->Result != UNIT_TEST_PENDING) && (Test->Result != UNIT_TEST_RUNNING)) {
- DEBUG ((DEBUG_VERBOSE, "Test was run on a previous pass. Skipping.\n"));
- ParentFramework->CurrentTest = NULL;
- continue;
- }
-
- //
- // Next, if we're still running, make sure that our test prerequisites are in place.
- if ((Test->Result == UNIT_TEST_PENDING) && (Test->Prerequisite != NULL)) {
- DEBUG ((DEBUG_VERBOSE, "PREREQ\n"));
- if (SetJump (&gUnitTestJumpBuffer) == 0) {
- if (Test->Prerequisite (Test->Context) != UNIT_TEST_PASSED) {
- DEBUG ((DEBUG_ERROR, "Prerequisite Not Met\n"));
- Test->Result = UNIT_TEST_ERROR_PREREQUISITE_NOT_MET;
- ParentFramework->CurrentTest = NULL;
- continue;
- }
- } else {
- DEBUG ((DEBUG_ERROR, "Prerequisite Not Met\n"));
- Test->Result = UNIT_TEST_ERROR_PREREQUISITE_NOT_MET;
- ParentFramework->CurrentTest = NULL;
- continue;
- }
- }
-
- //
- // Now we should be ready to call the actual test.
- // We set the status to UNIT_TEST_RUNNING in case the test needs to reboot
- // or quit. The UNIT_TEST_RUNNING state will allow the test to resume
- // but will prevent the Prerequisite from being dispatched a second time.
- if (SetJump (&gUnitTestJumpBuffer) == 0) {
- Test->Result = UNIT_TEST_RUNNING;
- Test->Result = Test->RunTest (Test->Context);
- } else {
- Test->Result = UNIT_TEST_ERROR_TEST_FAILED;
- }
-
- //
- // Finally, clean everything up, if need be.
- if (Test->CleanUp != NULL) {
- DEBUG ((DEBUG_VERBOSE, "CLEANUP\n"));
- if (SetJump (&gUnitTestJumpBuffer) == 0) {
- Test->CleanUp (Test->Context);
- }
- }
-
- //
- // End the test.
- //
- ParentFramework->CurrentTest = NULL;
- }
-
- if (Suite->Teardown != NULL) {
- Suite->Teardown ();
- }
-
- return EFI_SUCCESS;
-}
-
-/**
- Execute all unit test cases in all unit test suites added to a Framework.
-
- Once a unit test framework is initialized and all unit test suites and unit
- test cases are registered, this function will cause the unit test framework to
- dispatch all unit test cases in sequence and record the results for reporting.
-
- @param[in] FrameworkHandle A handle to the current running framework that
- dispatched the test. Necessary for recording
- certain test events with the framework.
-
- @retval EFI_SUCCESS All test cases were dispatched.
- @retval EFI_INVALID_PARAMETER FrameworkHandle is NULL.
-**/
-EFI_STATUS
-EFIAPI
-RunAllTestSuites (
- IN UNIT_TEST_FRAMEWORK_HANDLE FrameworkHandle
- )
-{
- UNIT_TEST_FRAMEWORK *Framework;
- UNIT_TEST_SUITE_LIST_ENTRY *Suite;
- EFI_STATUS Status;
-
- Framework = (UNIT_TEST_FRAMEWORK *)FrameworkHandle;
- Suite = NULL;
-
- if (Framework == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- DEBUG ((DEBUG_VERBOSE, "---------------------------------------------------------\n"));
- DEBUG ((DEBUG_VERBOSE, "------------ RUNNING ALL TEST SUITES --------------\n"));
- DEBUG ((DEBUG_VERBOSE, "---------------------------------------------------------\n"));
- mFrameworkHandle = FrameworkHandle;
-
- //
- // Iterate all suites
- //
- for (Suite = (UNIT_TEST_SUITE_LIST_ENTRY *)GetFirstNode (&Framework->TestSuiteList);
- (LIST_ENTRY *)Suite != &Framework->TestSuiteList;
- Suite = (UNIT_TEST_SUITE_LIST_ENTRY *)GetNextNode (&Framework->TestSuiteList, (LIST_ENTRY *)Suite))
- {
- Status = RunTestSuite (&(Suite->UTS));
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "Test Suite Failed with Error. %r\n", Status));
- }
- }
-
- //
- // Save current state so if test is started again it doesn't have to run. It will just report
- //
- SaveFrameworkState (NULL, 0);
- OutputUnitTestFrameworkReport (FrameworkHandle);
-
- mFrameworkHandle = NULL;
-
- return EFI_SUCCESS;
-}
+/** + UnitTestLib APIs to run unit tests + + Copyright (c) Microsoft Corporation. + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include <Uefi.h> +#include <Library/UnitTestLib.h> +#include <Library/BaseLib.h> +#include <Library/BaseMemoryLib.h> +#include <Library/DebugLib.h> +#include <Library/UnitTestResultReportLib.h> + +STATIC UNIT_TEST_FRAMEWORK_HANDLE mFrameworkHandle = NULL; + +BASE_LIBRARY_JUMP_BUFFER gUnitTestJumpBuffer; + +UNIT_TEST_FRAMEWORK_HANDLE +GetActiveFrameworkHandle ( + VOID + ) +{ + return mFrameworkHandle; +} + +STATIC +EFI_STATUS +RunTestSuite ( + IN UNIT_TEST_SUITE *Suite + ) +{ + UNIT_TEST_LIST_ENTRY *TestEntry; + UNIT_TEST *Test; + UNIT_TEST_FRAMEWORK *ParentFramework; + + if (Suite == NULL) { + return EFI_INVALID_PARAMETER; + } + + TestEntry = NULL; + ParentFramework = (UNIT_TEST_FRAMEWORK *)Suite->ParentFramework; + + DEBUG ((DEBUG_VERBOSE, "---------------------------------------------------------\n")); + DEBUG ((DEBUG_VERBOSE, "RUNNING TEST SUITE: %a\n", Suite->Title)); + DEBUG ((DEBUG_VERBOSE, "---------------------------------------------------------\n")); + + if (Suite->Setup != NULL) { + Suite->Setup (); + } + + // + // Iterate all tests within the suite + // + for (TestEntry = (UNIT_TEST_LIST_ENTRY *)GetFirstNode (&(Suite->TestCaseList)); + (LIST_ENTRY *)TestEntry != &(Suite->TestCaseList); + TestEntry = (UNIT_TEST_LIST_ENTRY *)GetNextNode (&(Suite->TestCaseList), (LIST_ENTRY *)TestEntry)) + { + Test = &TestEntry->UT; + ParentFramework->CurrentTest = Test; + + DEBUG ((DEBUG_VERBOSE, "*********************************************************\n")); + DEBUG ((DEBUG_VERBOSE, " RUNNING TEST: %a:\n", Test->Description)); + DEBUG ((DEBUG_VERBOSE, "**********************************************************\n")); + + // + // First, check to see whether the test has already been run. + // NOTE: This would generally only be the case if a saved state was detected and loaded. + // + if ((Test->Result != UNIT_TEST_PENDING) && (Test->Result != UNIT_TEST_RUNNING)) { + DEBUG ((DEBUG_VERBOSE, "Test was run on a previous pass. Skipping.\n")); + ParentFramework->CurrentTest = NULL; + continue; + } + + // + // Next, if we're still running, make sure that our test prerequisites are in place. + if ((Test->Result == UNIT_TEST_PENDING) && (Test->Prerequisite != NULL)) { + DEBUG ((DEBUG_VERBOSE, "PREREQ\n")); + if (SetJump (&gUnitTestJumpBuffer) == 0) { + if (Test->Prerequisite (Test->Context) != UNIT_TEST_PASSED) { + DEBUG ((DEBUG_ERROR, "Prerequisite Not Met\n")); + Test->Result = UNIT_TEST_ERROR_PREREQUISITE_NOT_MET; + ParentFramework->CurrentTest = NULL; + continue; + } + } else { + DEBUG ((DEBUG_ERROR, "Prerequisite Not Met\n")); + Test->Result = UNIT_TEST_ERROR_PREREQUISITE_NOT_MET; + ParentFramework->CurrentTest = NULL; + continue; + } + } + + // + // Now we should be ready to call the actual test. + // We set the status to UNIT_TEST_RUNNING in case the test needs to reboot + // or quit. The UNIT_TEST_RUNNING state will allow the test to resume + // but will prevent the Prerequisite from being dispatched a second time. + if (SetJump (&gUnitTestJumpBuffer) == 0) { + Test->Result = UNIT_TEST_RUNNING; + Test->Result = Test->RunTest (Test->Context); + } else { + Test->Result = UNIT_TEST_ERROR_TEST_FAILED; + } + + // + // Finally, clean everything up, if need be. + if (Test->CleanUp != NULL) { + DEBUG ((DEBUG_VERBOSE, "CLEANUP\n")); + if (SetJump (&gUnitTestJumpBuffer) == 0) { + Test->CleanUp (Test->Context); + } + } + + // + // End the test. + // + ParentFramework->CurrentTest = NULL; + } + + if (Suite->Teardown != NULL) { + Suite->Teardown (); + } + + return EFI_SUCCESS; +} + +/** + Execute all unit test cases in all unit test suites added to a Framework. + + Once a unit test framework is initialized and all unit test suites and unit + test cases are registered, this function will cause the unit test framework to + dispatch all unit test cases in sequence and record the results for reporting. + + @param[in] FrameworkHandle A handle to the current running framework that + dispatched the test. Necessary for recording + certain test events with the framework. + + @retval EFI_SUCCESS All test cases were dispatched. + @retval EFI_INVALID_PARAMETER FrameworkHandle is NULL. +**/ +EFI_STATUS +EFIAPI +RunAllTestSuites ( + IN UNIT_TEST_FRAMEWORK_HANDLE FrameworkHandle + ) +{ + UNIT_TEST_FRAMEWORK *Framework; + UNIT_TEST_SUITE_LIST_ENTRY *Suite; + EFI_STATUS Status; + + Framework = (UNIT_TEST_FRAMEWORK *)FrameworkHandle; + Suite = NULL; + + if (Framework == NULL) { + return EFI_INVALID_PARAMETER; + } + + DEBUG ((DEBUG_VERBOSE, "---------------------------------------------------------\n")); + DEBUG ((DEBUG_VERBOSE, "------------ RUNNING ALL TEST SUITES --------------\n")); + DEBUG ((DEBUG_VERBOSE, "---------------------------------------------------------\n")); + mFrameworkHandle = FrameworkHandle; + + // + // Iterate all suites + // + for (Suite = (UNIT_TEST_SUITE_LIST_ENTRY *)GetFirstNode (&Framework->TestSuiteList); + (LIST_ENTRY *)Suite != &Framework->TestSuiteList; + Suite = (UNIT_TEST_SUITE_LIST_ENTRY *)GetNextNode (&Framework->TestSuiteList, (LIST_ENTRY *)Suite)) + { + Status = RunTestSuite (&(Suite->UTS)); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Test Suite Failed with Error. %r\n", Status)); + } + } + + // + // Save current state so if test is started again it doesn't have to run. It will just report + // + SaveFrameworkState (NULL, 0); + OutputUnitTestFrameworkReport (FrameworkHandle); + + mFrameworkHandle = NULL; + + return EFI_SUCCESS; +} diff --git a/UnitTestFrameworkPkg/Library/UnitTestLib/RunTestsCmocka.c b/UnitTestFrameworkPkg/Library/UnitTestLib/RunTestsCmocka.c index f24b65174c..7a9a887f67 100644 --- a/UnitTestFrameworkPkg/Library/UnitTestLib/RunTestsCmocka.c +++ b/UnitTestFrameworkPkg/Library/UnitTestLib/RunTestsCmocka.c @@ -1,281 +1,281 @@ -/** @file
- UnitTestLib APIs to run unit tests using cmocka
-
- Copyright (c) 2019 - 2020, Intel Corporation. All rights reserved.<BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
-**/
-
-#include <stdio.h>
-#include <string.h>
-#include <stdarg.h>
-#include <stddef.h>
-#include <setjmp.h>
-#include <cmocka.h>
-
-#include <Uefi.h>
-#include <UnitTestFrameworkTypes.h>
-#include <Library/UnitTestLib.h>
-#include <Library/BaseLib.h>
-#include <Library/BaseMemoryLib.h>
-#include <Library/MemoryAllocationLib.h>
-#include <Library/DebugLib.h>
-
-STATIC UNIT_TEST_FRAMEWORK_HANDLE mFrameworkHandle = NULL;
-
-UNIT_TEST_FRAMEWORK_HANDLE
-GetActiveFrameworkHandle (
- VOID
- )
-{
- return mFrameworkHandle;
-}
-
-//
-// The currently active test suite
-//
-UNIT_TEST_SUITE *mActiveUnitTestSuite = NULL;
-
-void
-CmockaUnitTestFunctionRunner (
- void **state
- )
-{
- UNIT_TEST *UnitTest;
- UNIT_TEST_SUITE *Suite;
- UNIT_TEST_FRAMEWORK *Framework;
-
- UnitTest = (UNIT_TEST *)(*state);
- Suite = (UNIT_TEST_SUITE *)(UnitTest->ParentSuite);
- Framework = (UNIT_TEST_FRAMEWORK *)(Suite->ParentFramework);
-
- if (UnitTest->RunTest == NULL) {
- UnitTest->Result = UNIT_TEST_SKIPPED;
- } else {
- UnitTest->Result = UNIT_TEST_RUNNING;
- Framework->CurrentTest = UnitTest;
- UnitTest->Result = UnitTest->RunTest (UnitTest->Context);
- Framework->CurrentTest = NULL;
- }
-}
-
-int
-CmockaUnitTestSetupFunctionRunner (
- void **state
- )
-{
- UNIT_TEST *UnitTest;
- UNIT_TEST_SUITE *Suite;
- UNIT_TEST_FRAMEWORK *Framework;
- UNIT_TEST_STATUS Result;
-
- UnitTest = (UNIT_TEST *)(*state);
- Suite = (UNIT_TEST_SUITE *)(UnitTest->ParentSuite);
- Framework = (UNIT_TEST_FRAMEWORK *)(Suite->ParentFramework);
-
- if (UnitTest->Prerequisite == NULL) {
- return 0;
- }
-
- Framework->CurrentTest = UnitTest;
- Result = UnitTest->Prerequisite (UnitTest->Context);
- Framework->CurrentTest = NULL;
-
- //
- // Return 0 for success. Non-zero for error.
- //
- return (int)Result;
-}
-
-int
-CmockaUnitTestTeardownFunctionRunner (
- void **state
- )
-{
- UNIT_TEST *UnitTest;
- UNIT_TEST_SUITE *Suite;
- UNIT_TEST_FRAMEWORK *Framework;
-
- UnitTest = (UNIT_TEST *)(*state);
- Suite = (UNIT_TEST_SUITE *)(UnitTest->ParentSuite);
- Framework = (UNIT_TEST_FRAMEWORK *)(Suite->ParentFramework);
-
- if (UnitTest->CleanUp != NULL) {
- Framework->CurrentTest = UnitTest;
- UnitTest->CleanUp (UnitTest->Context);
- Framework->CurrentTest = NULL;
- }
-
- //
- // Print out the log messages - This is a partial solution as it
- // does not get the log into the XML. Need cmocka changes to support
- // stdout and stderr in their xml format
- //
- if (UnitTest->Log != NULL) {
- print_message ("UnitTest: %s - %s\n", UnitTest->Name, UnitTest->Description);
- print_message ("Log Output Start\n");
- print_message ("%s", UnitTest->Log);
- print_message ("Log Output End\n");
- }
-
- //
- // Return 0 for success. Non-zero for error.
- //
- return 0;
-}
-
-int
-CmockaUnitTestSuiteSetupFunctionRunner (
- void **state
- )
-{
- if (mActiveUnitTestSuite == NULL) {
- return -1;
- }
-
- if (mActiveUnitTestSuite->Setup == NULL) {
- return 0;
- }
-
- mActiveUnitTestSuite->Setup ();
- //
- // Always succeed
- //
- return 0;
-}
-
-int
-CmockaUnitTestSuiteTeardownFunctionRunner (
- void **state
- )
-{
- if (mActiveUnitTestSuite == NULL) {
- return -1;
- }
-
- if (mActiveUnitTestSuite->Teardown == NULL) {
- return 0;
- }
-
- mActiveUnitTestSuite->Teardown ();
- //
- // Always succeed
- //
- return 0;
-}
-
-STATIC
-EFI_STATUS
-RunTestSuite (
- IN UNIT_TEST_SUITE *Suite
- )
-{
- UNIT_TEST_LIST_ENTRY *TestEntry;
- UNIT_TEST *UnitTest;
- struct CMUnitTest *Tests;
- UINTN Index;
-
- TestEntry = NULL;
-
- if (Suite == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- DEBUG ((DEBUG_VERBOSE, "---------------------------------------------------------\n"));
- DEBUG ((DEBUG_VERBOSE, "RUNNING TEST SUITE: %a\n", Suite->Title));
- DEBUG ((DEBUG_VERBOSE, "---------------------------------------------------------\n"));
-
- //
- // Allocate buffer of CMUnitTest entries
- //
- Tests = AllocateZeroPool (Suite->NumTests * sizeof (struct CMUnitTest));
- ASSERT (Tests != NULL);
-
- //
- // Populate buffer of CMUnitTest entries
- //
- Index = 0;
- for (TestEntry = (UNIT_TEST_LIST_ENTRY *)GetFirstNode (&(Suite->TestCaseList));
- (LIST_ENTRY *)TestEntry != &(Suite->TestCaseList);
- TestEntry = (UNIT_TEST_LIST_ENTRY *)GetNextNode (&(Suite->TestCaseList), (LIST_ENTRY *)TestEntry))
- {
- UnitTest = &TestEntry->UT;
- Tests[Index].name = UnitTest->Description;
- Tests[Index].test_func = CmockaUnitTestFunctionRunner;
- Tests[Index].setup_func = CmockaUnitTestSetupFunctionRunner;
- Tests[Index].teardown_func = CmockaUnitTestTeardownFunctionRunner;
- Tests[Index].initial_state = UnitTest;
- Index++;
- }
-
- ASSERT (Index == Suite->NumTests);
-
- //
- // Run all unit tests in a test suite
- //
- mActiveUnitTestSuite = Suite;
- _cmocka_run_group_tests (
- Suite->Title,
- Tests,
- Suite->NumTests,
- CmockaUnitTestSuiteSetupFunctionRunner,
- CmockaUnitTestSuiteTeardownFunctionRunner
- );
- mActiveUnitTestSuite = NULL;
- FreePool (Tests);
-
- return EFI_SUCCESS;
-}
-
-/**
- Execute all unit test cases in all unit test suites added to a Framework.
-
- Once a unit test framework is initialized and all unit test suites and unit
- test cases are registered, this function will cause the unit test framework to
- dispatch all unit test cases in sequence and record the results for reporting.
-
- @param[in] FrameworkHandle A handle to the current running framework that
- dispatched the test. Necessary for recording
- certain test events with the framework.
-
- @retval EFI_SUCCESS All test cases were dispatched.
- @retval EFI_INVALID_PARAMETER FrameworkHandle is NULL.
-**/
-EFI_STATUS
-EFIAPI
-RunAllTestSuites (
- IN UNIT_TEST_FRAMEWORK_HANDLE FrameworkHandle
- )
-{
- UNIT_TEST_FRAMEWORK *Framework;
- UNIT_TEST_SUITE_LIST_ENTRY *Suite;
- EFI_STATUS Status;
-
- Framework = (UNIT_TEST_FRAMEWORK *)FrameworkHandle;
- Suite = NULL;
-
- if (Framework == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- DEBUG ((DEBUG_VERBOSE, "---------------------------------------------------------\n"));
- DEBUG ((DEBUG_VERBOSE, "------------ RUNNING ALL TEST SUITES --------------\n"));
- DEBUG ((DEBUG_VERBOSE, "---------------------------------------------------------\n"));
- mFrameworkHandle = FrameworkHandle;
-
- //
- // Iterate all suites
- //
- for (Suite = (UNIT_TEST_SUITE_LIST_ENTRY *)GetFirstNode (&Framework->TestSuiteList);
- (LIST_ENTRY *)Suite != &Framework->TestSuiteList;
- Suite = (UNIT_TEST_SUITE_LIST_ENTRY *)GetNextNode (&Framework->TestSuiteList, (LIST_ENTRY *)Suite))
- {
- Status = RunTestSuite (&(Suite->UTS));
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "Test Suite Failed with Error. %r\n", Status));
- }
- }
-
- mFrameworkHandle = NULL;
-
- return EFI_SUCCESS;
-}
+/** @file + UnitTestLib APIs to run unit tests using cmocka + + Copyright (c) 2019 - 2020, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include <stdio.h> +#include <string.h> +#include <stdarg.h> +#include <stddef.h> +#include <setjmp.h> +#include <cmocka.h> + +#include <Uefi.h> +#include <UnitTestFrameworkTypes.h> +#include <Library/UnitTestLib.h> +#include <Library/BaseLib.h> +#include <Library/BaseMemoryLib.h> +#include <Library/MemoryAllocationLib.h> +#include <Library/DebugLib.h> + +STATIC UNIT_TEST_FRAMEWORK_HANDLE mFrameworkHandle = NULL; + +UNIT_TEST_FRAMEWORK_HANDLE +GetActiveFrameworkHandle ( + VOID + ) +{ + return mFrameworkHandle; +} + +// +// The currently active test suite +// +UNIT_TEST_SUITE *mActiveUnitTestSuite = NULL; + +void +CmockaUnitTestFunctionRunner ( + void **state + ) +{ + UNIT_TEST *UnitTest; + UNIT_TEST_SUITE *Suite; + UNIT_TEST_FRAMEWORK *Framework; + + UnitTest = (UNIT_TEST *)(*state); + Suite = (UNIT_TEST_SUITE *)(UnitTest->ParentSuite); + Framework = (UNIT_TEST_FRAMEWORK *)(Suite->ParentFramework); + + if (UnitTest->RunTest == NULL) { + UnitTest->Result = UNIT_TEST_SKIPPED; + } else { + UnitTest->Result = UNIT_TEST_RUNNING; + Framework->CurrentTest = UnitTest; + UnitTest->Result = UnitTest->RunTest (UnitTest->Context); + Framework->CurrentTest = NULL; + } +} + +int +CmockaUnitTestSetupFunctionRunner ( + void **state + ) +{ + UNIT_TEST *UnitTest; + UNIT_TEST_SUITE *Suite; + UNIT_TEST_FRAMEWORK *Framework; + UNIT_TEST_STATUS Result; + + UnitTest = (UNIT_TEST *)(*state); + Suite = (UNIT_TEST_SUITE *)(UnitTest->ParentSuite); + Framework = (UNIT_TEST_FRAMEWORK *)(Suite->ParentFramework); + + if (UnitTest->Prerequisite == NULL) { + return 0; + } + + Framework->CurrentTest = UnitTest; + Result = UnitTest->Prerequisite (UnitTest->Context); + Framework->CurrentTest = NULL; + + // + // Return 0 for success. Non-zero for error. + // + return (int)Result; +} + +int +CmockaUnitTestTeardownFunctionRunner ( + void **state + ) +{ + UNIT_TEST *UnitTest; + UNIT_TEST_SUITE *Suite; + UNIT_TEST_FRAMEWORK *Framework; + + UnitTest = (UNIT_TEST *)(*state); + Suite = (UNIT_TEST_SUITE *)(UnitTest->ParentSuite); + Framework = (UNIT_TEST_FRAMEWORK *)(Suite->ParentFramework); + + if (UnitTest->CleanUp != NULL) { + Framework->CurrentTest = UnitTest; + UnitTest->CleanUp (UnitTest->Context); + Framework->CurrentTest = NULL; + } + + // + // Print out the log messages - This is a partial solution as it + // does not get the log into the XML. Need cmocka changes to support + // stdout and stderr in their xml format + // + if (UnitTest->Log != NULL) { + print_message ("UnitTest: %s - %s\n", UnitTest->Name, UnitTest->Description); + print_message ("Log Output Start\n"); + print_message ("%s", UnitTest->Log); + print_message ("Log Output End\n"); + } + + // + // Return 0 for success. Non-zero for error. + // + return 0; +} + +int +CmockaUnitTestSuiteSetupFunctionRunner ( + void **state + ) +{ + if (mActiveUnitTestSuite == NULL) { + return -1; + } + + if (mActiveUnitTestSuite->Setup == NULL) { + return 0; + } + + mActiveUnitTestSuite->Setup (); + // + // Always succeed + // + return 0; +} + +int +CmockaUnitTestSuiteTeardownFunctionRunner ( + void **state + ) +{ + if (mActiveUnitTestSuite == NULL) { + return -1; + } + + if (mActiveUnitTestSuite->Teardown == NULL) { + return 0; + } + + mActiveUnitTestSuite->Teardown (); + // + // Always succeed + // + return 0; +} + +STATIC +EFI_STATUS +RunTestSuite ( + IN UNIT_TEST_SUITE *Suite + ) +{ + UNIT_TEST_LIST_ENTRY *TestEntry; + UNIT_TEST *UnitTest; + struct CMUnitTest *Tests; + UINTN Index; + + TestEntry = NULL; + + if (Suite == NULL) { + return EFI_INVALID_PARAMETER; + } + + DEBUG ((DEBUG_VERBOSE, "---------------------------------------------------------\n")); + DEBUG ((DEBUG_VERBOSE, "RUNNING TEST SUITE: %a\n", Suite->Title)); + DEBUG ((DEBUG_VERBOSE, "---------------------------------------------------------\n")); + + // + // Allocate buffer of CMUnitTest entries + // + Tests = AllocateZeroPool (Suite->NumTests * sizeof (struct CMUnitTest)); + ASSERT (Tests != NULL); + + // + // Populate buffer of CMUnitTest entries + // + Index = 0; + for (TestEntry = (UNIT_TEST_LIST_ENTRY *)GetFirstNode (&(Suite->TestCaseList)); + (LIST_ENTRY *)TestEntry != &(Suite->TestCaseList); + TestEntry = (UNIT_TEST_LIST_ENTRY *)GetNextNode (&(Suite->TestCaseList), (LIST_ENTRY *)TestEntry)) + { + UnitTest = &TestEntry->UT; + Tests[Index].name = UnitTest->Description; + Tests[Index].test_func = CmockaUnitTestFunctionRunner; + Tests[Index].setup_func = CmockaUnitTestSetupFunctionRunner; + Tests[Index].teardown_func = CmockaUnitTestTeardownFunctionRunner; + Tests[Index].initial_state = UnitTest; + Index++; + } + + ASSERT (Index == Suite->NumTests); + + // + // Run all unit tests in a test suite + // + mActiveUnitTestSuite = Suite; + _cmocka_run_group_tests ( + Suite->Title, + Tests, + Suite->NumTests, + CmockaUnitTestSuiteSetupFunctionRunner, + CmockaUnitTestSuiteTeardownFunctionRunner + ); + mActiveUnitTestSuite = NULL; + FreePool (Tests); + + return EFI_SUCCESS; +} + +/** + Execute all unit test cases in all unit test suites added to a Framework. + + Once a unit test framework is initialized and all unit test suites and unit + test cases are registered, this function will cause the unit test framework to + dispatch all unit test cases in sequence and record the results for reporting. + + @param[in] FrameworkHandle A handle to the current running framework that + dispatched the test. Necessary for recording + certain test events with the framework. + + @retval EFI_SUCCESS All test cases were dispatched. + @retval EFI_INVALID_PARAMETER FrameworkHandle is NULL. +**/ +EFI_STATUS +EFIAPI +RunAllTestSuites ( + IN UNIT_TEST_FRAMEWORK_HANDLE FrameworkHandle + ) +{ + UNIT_TEST_FRAMEWORK *Framework; + UNIT_TEST_SUITE_LIST_ENTRY *Suite; + EFI_STATUS Status; + + Framework = (UNIT_TEST_FRAMEWORK *)FrameworkHandle; + Suite = NULL; + + if (Framework == NULL) { + return EFI_INVALID_PARAMETER; + } + + DEBUG ((DEBUG_VERBOSE, "---------------------------------------------------------\n")); + DEBUG ((DEBUG_VERBOSE, "------------ RUNNING ALL TEST SUITES --------------\n")); + DEBUG ((DEBUG_VERBOSE, "---------------------------------------------------------\n")); + mFrameworkHandle = FrameworkHandle; + + // + // Iterate all suites + // + for (Suite = (UNIT_TEST_SUITE_LIST_ENTRY *)GetFirstNode (&Framework->TestSuiteList); + (LIST_ENTRY *)Suite != &Framework->TestSuiteList; + Suite = (UNIT_TEST_SUITE_LIST_ENTRY *)GetNextNode (&Framework->TestSuiteList, (LIST_ENTRY *)Suite)) + { + Status = RunTestSuite (&(Suite->UTS)); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Test Suite Failed with Error. %r\n", Status)); + } + } + + mFrameworkHandle = NULL; + + return EFI_SUCCESS; +} diff --git a/UnitTestFrameworkPkg/Library/UnitTestLib/UnitTestLib.c b/UnitTestFrameworkPkg/Library/UnitTestLib/UnitTestLib.c index 3e3a850af1..160969f5ef 100644 --- a/UnitTestFrameworkPkg/Library/UnitTestLib/UnitTestLib.c +++ b/UnitTestFrameworkPkg/Library/UnitTestLib/UnitTestLib.c @@ -1,873 +1,873 @@ -/**
- Implement UnitTestLib
-
- Copyright (c) Microsoft Corporation.
- Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
-**/
-
-#include <Uefi.h>
-#include <Library/UnitTestLib.h>
-#include <Library/BaseLib.h>
-#include <Library/BaseMemoryLib.h>
-#include <Library/MemoryAllocationLib.h>
-#include <Library/DebugLib.h>
-#include <Library/UnitTestPersistenceLib.h>
-#include <Library/UnitTestResultReportLib.h>
-
-///
-/// Forward declaration of prototype
-///
-STATIC
-VOID
-UpdateTestFromSave (
- IN OUT UNIT_TEST *Test,
- IN UNIT_TEST_SAVE_HEADER *SavedState
- );
-
-/**
- This function will determine whether the short name violates any rules that would
- prevent it from being used as a reporting name or as a serialization name.
-
- Example: If the name cannot be serialized to a filesystem file name.
-
- @param[in] ShortTitleString A pointer to the short title string to be evaluated.
-
- @retval TRUE The string is acceptable.
- @retval FALSE The string should not be used.
-
-**/
-STATIC
-BOOLEAN
-IsFrameworkShortNameValid (
- IN CHAR8 *ShortTitleString
- )
-{
- // TODO: Finish this function.
- return TRUE;
-}
-
-STATIC
-CHAR8 *
-AllocateAndCopyString (
- IN CHAR8 *StringToCopy
- )
-{
- CHAR8 *NewString;
- UINTN NewStringLength;
-
- NewString = NULL;
- NewStringLength = AsciiStrnLenS (StringToCopy, UNIT_TEST_MAX_STRING_LENGTH) + 1;
- NewString = AllocatePool (NewStringLength * sizeof (CHAR8));
- if (NewString != NULL) {
- AsciiStrCpyS (NewString, NewStringLength, StringToCopy);
- }
-
- return NewString;
-}
-
-STATIC
-VOID
-SetFrameworkFingerprint (
- OUT UINT8 *Fingerprint,
- IN UNIT_TEST_FRAMEWORK *Framework
- )
-{
- UINT32 NewFingerprint;
-
- // For this one we'll just use the title and version as the unique fingerprint.
- NewFingerprint = CalculateCrc32 (Framework->Title, (AsciiStrLen (Framework->Title) * sizeof (CHAR8)));
- NewFingerprint = (NewFingerprint >> 8) ^ CalculateCrc32 (Framework->VersionString, (AsciiStrLen (Framework->VersionString) * sizeof (CHAR8)));
-
- CopyMem (Fingerprint, &NewFingerprint, UNIT_TEST_FINGERPRINT_SIZE);
- return;
-}
-
-STATIC
-VOID
-SetSuiteFingerprint (
- OUT UINT8 *Fingerprint,
- IN UNIT_TEST_FRAMEWORK *Framework,
- IN UNIT_TEST_SUITE *Suite
- )
-{
- UINT32 NewFingerprint;
-
- // For this one, we'll use the fingerprint from the framework, and the title of the suite.
- NewFingerprint = CalculateCrc32 (&Framework->Fingerprint[0], UNIT_TEST_FINGERPRINT_SIZE);
- NewFingerprint = (NewFingerprint >> 8) ^ CalculateCrc32 (Suite->Title, (AsciiStrLen (Suite->Title) * sizeof (CHAR8)));
- NewFingerprint = (NewFingerprint >> 8) ^ CalculateCrc32 (Suite->Name, (AsciiStrLen (Suite->Name) * sizeof (CHAR8)));
-
- CopyMem (Fingerprint, &NewFingerprint, UNIT_TEST_FINGERPRINT_SIZE);
- return;
-}
-
-STATIC
-VOID
-SetTestFingerprint (
- OUT UINT8 *Fingerprint,
- IN UNIT_TEST_SUITE *Suite,
- IN UNIT_TEST *Test
- )
-{
- UINT32 NewFingerprint;
-
- // For this one, we'll use the fingerprint from the suite, and the description and classname of the test.
- NewFingerprint = CalculateCrc32 (&Suite->Fingerprint[0], UNIT_TEST_FINGERPRINT_SIZE);
- NewFingerprint = (NewFingerprint >> 8) ^ CalculateCrc32 (Test->Description, (AsciiStrLen (Test->Description) * sizeof (CHAR8)));
- NewFingerprint = (NewFingerprint >> 8) ^ CalculateCrc32 (Test->Name, (AsciiStrLen (Test->Name) * sizeof (CHAR8)));
-
- CopyMem (Fingerprint, &NewFingerprint, UNIT_TEST_FINGERPRINT_SIZE);
- return;
-}
-
-STATIC
-BOOLEAN
-CompareFingerprints (
- IN UINT8 *FingerprintA,
- IN UINT8 *FingerprintB
- )
-{
- return (CompareMem (FingerprintA, FingerprintB, UNIT_TEST_FINGERPRINT_SIZE) == 0);
-}
-
-/**
- Cleanup a test framework.
-
- After tests are run, this will teardown the entire framework and free all
- allocated data within.
-
- @param[in] FrameworkHandle A handle to the current running framework that
- dispatched the test. Necessary for recording
- certain test events with the framework.
-
- @retval EFI_SUCCESS All resources associated with framework were
- freed.
- @retval EFI_INVALID_PARAMETER FrameworkHandle is NULL.
-**/
-EFI_STATUS
-EFIAPI
-FreeUnitTestFramework (
- IN UNIT_TEST_FRAMEWORK_HANDLE FrameworkHandle
- )
-{
- // TODO: Finish this function.
- return EFI_SUCCESS;
-}
-
-STATIC
-EFI_STATUS
-FreeUnitTestSuiteEntry (
- IN UNIT_TEST_SUITE_LIST_ENTRY *SuiteEntry
- )
-{
- // TODO: Finish this function.
- return EFI_SUCCESS;
-}
-
-STATIC
-EFI_STATUS
-FreeUnitTestTestEntry (
- IN UNIT_TEST_LIST_ENTRY *TestEntry
- )
-{
- // TODO: Finish this function.
- return EFI_SUCCESS;
-}
-
-/**
- Method to Initialize the Unit Test framework. This function registers the
- test name and also initializes the internal state of the test framework to
- receive any new suites and tests.
-
- @param[out] FrameworkHandle Unit test framework to be created.
- @param[in] Title Null-terminated ASCII string that is the user
- friendly name of the framework. String is
- copied.
- @param[in] ShortTitle Null-terminated ASCII short string that is the
- short name of the framework with no spaces.
- String is copied.
- @param[in] VersionString Null-terminated ASCII version string for the
- framework. String is copied.
-
- @retval EFI_SUCCESS The unit test framework was initialized.
- @retval EFI_INVALID_PARAMETER FrameworkHandle is NULL.
- @retval EFI_INVALID_PARAMETER Title is NULL.
- @retval EFI_INVALID_PARAMETER ShortTitle is NULL.
- @retval EFI_INVALID_PARAMETER VersionString is NULL.
- @retval EFI_INVALID_PARAMETER ShortTitle is invalid.
- @retval EFI_OUT_OF_RESOURCES There are not enough resources available to
- initialize the unit test framework.
-**/
-EFI_STATUS
-EFIAPI
-InitUnitTestFramework (
- OUT UNIT_TEST_FRAMEWORK_HANDLE *FrameworkHandle,
- IN CHAR8 *Title,
- IN CHAR8 *ShortTitle,
- IN CHAR8 *VersionString
- )
-{
- EFI_STATUS Status;
- UNIT_TEST_FRAMEWORK_HANDLE NewFrameworkHandle;
- UNIT_TEST_FRAMEWORK *NewFramework;
- UINTN SaveStateSize;
-
- Status = EFI_SUCCESS;
- NewFramework = NULL;
-
- //
- // First, check all pointers and make sure nothing's broked.
- //
- if ((FrameworkHandle == NULL) || (Title == NULL) ||
- (ShortTitle == NULL) || (VersionString == NULL))
- {
- return EFI_INVALID_PARAMETER;
- }
-
- //
- // Next, determine whether all of the strings are good to use.
- //
- if (!IsFrameworkShortNameValid (ShortTitle)) {
- return EFI_INVALID_PARAMETER;
- }
-
- //
- // Next, set aside some space to start messing with the framework.
- //
- NewFramework = AllocateZeroPool (sizeof (UNIT_TEST_FRAMEWORK));
- if (NewFramework == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- //
- // Next, set up all the test data.
- //
- NewFrameworkHandle = (UNIT_TEST_FRAMEWORK_HANDLE)NewFramework;
- NewFramework->Title = AllocateAndCopyString (Title);
- NewFramework->ShortTitle = AllocateAndCopyString (ShortTitle);
- NewFramework->VersionString = AllocateAndCopyString (VersionString);
- NewFramework->Log = NULL;
- NewFramework->CurrentTest = NULL;
- NewFramework->SavedState = NULL;
- if ((NewFramework->Title == NULL) ||
- (NewFramework->ShortTitle == NULL) ||
- (NewFramework->VersionString == NULL))
- {
- Status = EFI_OUT_OF_RESOURCES;
- goto Exit;
- }
-
- InitializeListHead (&(NewFramework->TestSuiteList));
-
- //
- // Create the framework fingerprint.
- //
- SetFrameworkFingerprint (&NewFramework->Fingerprint[0], NewFramework);
-
- //
- // If there is a persisted context, load it now.
- //
- if (DoesCacheExist (NewFrameworkHandle)) {
- Status = LoadUnitTestCache (NewFrameworkHandle, (VOID **)(&NewFramework->SavedState), &SaveStateSize);
- if (EFI_ERROR (Status)) {
- //
- // Don't actually report it as an error, but emit a warning.
- //
- DEBUG ((DEBUG_ERROR, "%a - Cache was detected, but failed to load.\n", __func__));
- Status = EFI_SUCCESS;
- }
- }
-
-Exit:
- //
- // If we're good, then let's copy the framework.
- //
- if (!EFI_ERROR (Status)) {
- *FrameworkHandle = NewFrameworkHandle;
- } else {
- //
- // Otherwise, we need to undo this horrible thing that we've done.
- //
- FreeUnitTestFramework (NewFrameworkHandle);
- }
-
- return Status;
-}
-
-/**
- Registers a Unit Test Suite in the Unit Test Framework.
- At least one test suite must be registered, because all test cases must be
- within a unit test suite.
-
- @param[out] SuiteHandle Unit test suite to create
- @param[in] FrameworkHandle Unit test framework to add unit test suite to
- @param[in] Title Null-terminated ASCII string that is the user
- friendly name of the test suite. String is
- copied.
- @param[in] Name Null-terminated ASCII string that is the short
- name of the test suite with no spaces. String
- is copied.
- @param[in] Setup Setup function, runs before suite. This is an
- optional parameter that may be NULL.
- @param[in] Teardown Teardown function, runs after suite. This is an
- optional parameter that may be NULL.
-
- @retval EFI_SUCCESS The unit test suite was created.
- @retval EFI_INVALID_PARAMETER SuiteHandle is NULL.
- @retval EFI_INVALID_PARAMETER FrameworkHandle is NULL.
- @retval EFI_INVALID_PARAMETER Title is NULL.
- @retval EFI_INVALID_PARAMETER Name is NULL.
- @retval EFI_OUT_OF_RESOURCES There are not enough resources available to
- initialize the unit test suite.
-**/
-EFI_STATUS
-EFIAPI
-CreateUnitTestSuite (
- OUT UNIT_TEST_SUITE_HANDLE *SuiteHandle,
- IN UNIT_TEST_FRAMEWORK_HANDLE FrameworkHandle,
- IN CHAR8 *Title,
- IN CHAR8 *Name,
- IN UNIT_TEST_SUITE_SETUP Setup OPTIONAL,
- IN UNIT_TEST_SUITE_TEARDOWN Teardown OPTIONAL
- )
-{
- EFI_STATUS Status;
- UNIT_TEST_SUITE_LIST_ENTRY *NewSuiteEntry;
- UNIT_TEST_FRAMEWORK *Framework;
-
- Status = EFI_SUCCESS;
- Framework = (UNIT_TEST_FRAMEWORK *)FrameworkHandle;
-
- //
- // First, let's check to make sure that our parameters look good.
- //
- if ((SuiteHandle == NULL) || (Framework == NULL) || (Title == NULL) || (Name == NULL)) {
- return EFI_INVALID_PARAMETER;
- }
-
- //
- // Create the new entry.
- //
- NewSuiteEntry = AllocateZeroPool (sizeof (UNIT_TEST_SUITE_LIST_ENTRY));
- if (NewSuiteEntry == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- //
- // Copy the fields we think we need.
- //
- NewSuiteEntry->UTS.NumTests = 0;
- NewSuiteEntry->UTS.Title = AllocateAndCopyString (Title);
- NewSuiteEntry->UTS.Name = AllocateAndCopyString (Name);
- NewSuiteEntry->UTS.Setup = Setup;
- NewSuiteEntry->UTS.Teardown = Teardown;
- NewSuiteEntry->UTS.ParentFramework = FrameworkHandle;
- InitializeListHead (&(NewSuiteEntry->Entry)); // List entry for sibling suites.
- InitializeListHead (&(NewSuiteEntry->UTS.TestCaseList)); // List entry for child tests.
- if (NewSuiteEntry->UTS.Title == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- goto Exit;
- }
-
- if (NewSuiteEntry->UTS.Name == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- goto Exit;
- }
-
- //
- // Create the suite fingerprint.
- //
- SetSuiteFingerprint (&NewSuiteEntry->UTS.Fingerprint[0], Framework, &NewSuiteEntry->UTS);
-
-Exit:
- //
- // If everything is going well, add the new suite to the tail list for the framework.
- //
- if (!EFI_ERROR (Status)) {
- InsertTailList (&(Framework->TestSuiteList), (LIST_ENTRY *)NewSuiteEntry);
- *SuiteHandle = (UNIT_TEST_SUITE_HANDLE)(&NewSuiteEntry->UTS);
- } else {
- //
- // Otherwise, make with the destruction.
- //
- FreeUnitTestSuiteEntry (NewSuiteEntry);
- }
-
- return Status;
-}
-
-/**
- Adds test case to Suite
-
- @param[in] SuiteHandle Unit test suite to add test to.
- @param[in] Description Null-terminated ASCII string that is the user
- friendly description of a test. String is copied.
- @param[in] Name Null-terminated ASCII string that is the short name
- of the test with no spaces. String is copied.
- @param[in] Function Unit test function.
- @param[in] Prerequisite Prerequisite function, runs before test. This is
- an optional parameter that may be NULL.
- @param[in] CleanUp Clean up function, runs after test. This is an
- optional parameter that may be NULL.
- @param[in] Context Pointer to context. This is an optional parameter
- that may be NULL.
-
- @retval EFI_SUCCESS The unit test case was added to Suite.
- @retval EFI_INVALID_PARAMETER SuiteHandle is NULL.
- @retval EFI_INVALID_PARAMETER Description is NULL.
- @retval EFI_INVALID_PARAMETER Name is NULL.
- @retval EFI_INVALID_PARAMETER Function is NULL.
- @retval EFI_OUT_OF_RESOURCES There are not enough resources available to
- add the unit test case to Suite.
-**/
-EFI_STATUS
-EFIAPI
-AddTestCase (
- IN UNIT_TEST_SUITE_HANDLE SuiteHandle,
- IN CHAR8 *Description,
- IN CHAR8 *Name,
- IN UNIT_TEST_FUNCTION Function,
- IN UNIT_TEST_PREREQUISITE Prerequisite OPTIONAL,
- IN UNIT_TEST_CLEANUP CleanUp OPTIONAL,
- IN UNIT_TEST_CONTEXT Context OPTIONAL
- )
-{
- EFI_STATUS Status;
- UNIT_TEST_LIST_ENTRY *NewTestEntry;
- UNIT_TEST_FRAMEWORK *ParentFramework;
- UNIT_TEST_SUITE *Suite;
-
- Status = EFI_SUCCESS;
- Suite = (UNIT_TEST_SUITE *)SuiteHandle;
-
- //
- // First, let's check to make sure that our parameters look good.
- //
- if ((Suite == NULL) || (Description == NULL) || (Name == NULL) || (Function == NULL)) {
- return EFI_INVALID_PARAMETER;
- }
-
- ParentFramework = (UNIT_TEST_FRAMEWORK *)Suite->ParentFramework;
- //
- // Create the new entry.
- NewTestEntry = AllocateZeroPool (sizeof (UNIT_TEST_LIST_ENTRY));
- if (NewTestEntry == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- //
- // Copy the fields we think we need.
- NewTestEntry->UT.Description = AllocateAndCopyString (Description);
- NewTestEntry->UT.Name = AllocateAndCopyString (Name);
- NewTestEntry->UT.FailureType = FAILURETYPE_NOFAILURE;
- NewTestEntry->UT.FailureMessage[0] = '\0';
- NewTestEntry->UT.Log = NULL;
- NewTestEntry->UT.Prerequisite = Prerequisite;
- NewTestEntry->UT.CleanUp = CleanUp;
- NewTestEntry->UT.RunTest = Function;
- NewTestEntry->UT.Context = Context;
- NewTestEntry->UT.Result = UNIT_TEST_PENDING;
- NewTestEntry->UT.ParentSuite = SuiteHandle;
- InitializeListHead (&(NewTestEntry->Entry)); // List entry for sibling tests.
- if (NewTestEntry->UT.Description == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- goto Exit;
- }
-
- if (NewTestEntry->UT.Name == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- goto Exit;
- }
-
- //
- // Create the test fingerprint.
- //
- SetTestFingerprint (&NewTestEntry->UT.Fingerprint[0], Suite, &NewTestEntry->UT);
-
- // TODO: Make sure that duplicate fingerprints cannot be created.
-
- //
- // If there is saved test data, update this record.
- //
- if (ParentFramework->SavedState != NULL) {
- UpdateTestFromSave (&NewTestEntry->UT, ParentFramework->SavedState);
- }
-
-Exit:
- //
- // If everything is going well, add the new suite to the tail list for the framework.
- //
- if (!EFI_ERROR (Status)) {
- InsertTailList (&(Suite->TestCaseList), (LIST_ENTRY *)NewTestEntry);
- Suite->NumTests++;
- } else {
- //
- // Otherwise, make with the destruction.
- //
- FreeUnitTestTestEntry (NewTestEntry);
- }
-
- return Status;
-}
-
-STATIC
-VOID
-UpdateTestFromSave (
- IN OUT UNIT_TEST *Test,
- IN UNIT_TEST_SAVE_HEADER *SavedState
- )
-{
- UNIT_TEST_SAVE_TEST *CurrentTest;
- UNIT_TEST_SAVE_TEST *MatchingTest;
- UINT8 *FloatingPointer;
- UNIT_TEST_SAVE_CONTEXT *SavedContext;
- UINTN Index;
-
- //
- // First, evaluate the inputs.
- //
- if ((Test == NULL) || (SavedState == NULL)) {
- return;
- }
-
- if (SavedState->TestCount == 0) {
- return;
- }
-
- //
- // Next, determine whether a matching test can be found.
- // Start at the beginning.
- //
- MatchingTest = NULL;
- FloatingPointer = (UINT8 *)SavedState + sizeof (*SavedState);
- for (Index = 0; Index < SavedState->TestCount; Index++) {
- CurrentTest = (UNIT_TEST_SAVE_TEST *)FloatingPointer;
- if (CompareFingerprints (&Test->Fingerprint[0], &CurrentTest->Fingerprint[0])) {
- MatchingTest = CurrentTest;
- //
- // If there's a saved context, it's important that we iterate through the entire list.
- //
- if (!SavedState->HasSavedContext) {
- break;
- }
- }
-
- //
- // If we didn't find it, we have to increment to the next test.
- //
- FloatingPointer = (UINT8 *)CurrentTest + CurrentTest->Size;
- }
-
- //
- // If a matching test was found, copy the status.
- //
- if (MatchingTest) {
- //
- // Override the test status with the saved status.
- //
- Test->Result = MatchingTest->Result;
-
- Test->FailureType = MatchingTest->FailureType;
- AsciiStrnCpyS (
- &Test->FailureMessage[0],
- UNIT_TEST_TESTFAILUREMSG_LENGTH,
- &MatchingTest->FailureMessage[0],
- UNIT_TEST_TESTFAILUREMSG_LENGTH
- );
-
- //
- // If there is a log string associated, grab that.
- // We can tell that there's a log string because the "size" will be larger than
- // the structure size.
- // IMPORTANT NOTE: There are security implications here.
- // This data is user-supplied and we're about to play kinda
- // fast and loose with data buffers.
- //
- if (MatchingTest->Size > sizeof (UNIT_TEST_SAVE_TEST)) {
- UnitTestLogInit (Test, (UINT8 *)MatchingTest->Log, MatchingTest->Size - sizeof (UNIT_TEST_SAVE_TEST));
- }
- }
-
- //
- // If the saved context exists and matches this test, grab it, too.
- //
- if (SavedState->HasSavedContext) {
- //
- // If there was a saved context, the "matching test" loop will have placed the FloatingPointer
- // at the beginning of the context structure.
- //
- SavedContext = (UNIT_TEST_SAVE_CONTEXT *)FloatingPointer;
- if (((SavedContext->Size - sizeof (UNIT_TEST_SAVE_CONTEXT)) > 0) &&
- CompareFingerprints (&Test->Fingerprint[0], &SavedContext->Fingerprint[0]))
- {
- //
- // Override the test context with the saved context.
- //
- Test->Context = (VOID *)SavedContext->Data;
- }
- }
-}
-
-STATIC
-UNIT_TEST_SAVE_HEADER *
-SerializeState (
- IN UNIT_TEST_FRAMEWORK_HANDLE FrameworkHandle,
- IN UNIT_TEST_CONTEXT ContextToSave OPTIONAL,
- IN UINTN ContextToSaveSize
- )
-{
- UNIT_TEST_FRAMEWORK *Framework;
- UNIT_TEST_SAVE_HEADER *Header;
- LIST_ENTRY *SuiteListHead;
- LIST_ENTRY *Suite;
- LIST_ENTRY *TestListHead;
- LIST_ENTRY *Test;
- UINT32 TestCount;
- UINT32 TotalSize;
- UINTN LogSize;
- UNIT_TEST_SAVE_TEST *TestSaveData;
- UNIT_TEST_SAVE_CONTEXT *TestSaveContext;
- UNIT_TEST *UnitTest;
- UINT8 *FloatingPointer;
-
- Framework = (UNIT_TEST_FRAMEWORK *)FrameworkHandle;
- Header = NULL;
-
- //
- // First, let's not make assumptions about the parameters.
- //
- if ((Framework == NULL) ||
- ((ContextToSave != NULL) && (ContextToSaveSize == 0)) ||
- (ContextToSaveSize > MAX_UINT32))
- {
- return NULL;
- }
-
- //
- // Next, we've gotta figure out the resources that will be required to serialize the
- // the framework state so that we can persist it.
- // To start with, we're gonna need a header.
- //
- TotalSize = sizeof (UNIT_TEST_SAVE_HEADER);
- //
- // Now we need to figure out how many tests there are.
- //
- TestCount = 0;
- //
- // Iterate all suites.
- //
- SuiteListHead = &Framework->TestSuiteList;
- for (Suite = GetFirstNode (SuiteListHead); Suite != SuiteListHead; Suite = GetNextNode (SuiteListHead, Suite)) {
- //
- // Iterate all tests within the suite.
- //
- TestListHead = &((UNIT_TEST_SUITE_LIST_ENTRY *)Suite)->UTS.TestCaseList;
- for (Test = GetFirstNode (TestListHead); Test != TestListHead; Test = GetNextNode (TestListHead, Test)) {
- UnitTest = &((UNIT_TEST_LIST_ENTRY *)Test)->UT;
- //
- // Account for the size of a test structure.
- //
- TotalSize += sizeof (UNIT_TEST_SAVE_TEST);
- //
- // If there's a log, make sure to account for the log size.
- //
- if (UnitTest->Log != NULL) {
- //
- // The +1 is for the NULL character. Can't forget the NULL character.
- //
- LogSize = (AsciiStrLen (UnitTest->Log) + 1) * sizeof (CHAR8);
- ASSERT (LogSize < MAX_UINT32);
- TotalSize += (UINT32)LogSize;
- }
-
- //
- // Increment the test count.
- //
- TestCount++;
- }
- }
-
- //
- // If there are no tests, we're done here.
- //
- if (TestCount == 0) {
- return NULL;
- }
-
- //
- // Add room for the context, if there is one.
- //
- if (ContextToSave != NULL) {
- TotalSize += sizeof (UNIT_TEST_SAVE_CONTEXT) + (UINT32)ContextToSaveSize;
- }
-
- //
- // Now that we know the size, we need to allocate space for the serialized output.
- //
- Header = AllocateZeroPool (TotalSize);
- if (Header == NULL) {
- return NULL;
- }
-
- //
- // Alright, let's start setting up some data.
- //
- Header->Version = UNIT_TEST_PERSISTENCE_LIB_VERSION;
- Header->SaveStateSize = TotalSize;
- CopyMem (&Header->Fingerprint[0], &Framework->Fingerprint[0], UNIT_TEST_FINGERPRINT_SIZE);
- CopyMem (&Header->StartTime, &Framework->StartTime, sizeof (EFI_TIME));
- Header->TestCount = TestCount;
- Header->HasSavedContext = FALSE;
-
- //
- // Start adding all of the test cases.
- // Set the floating pointer to the start of the current test save buffer.
- //
- FloatingPointer = (UINT8 *)Header + sizeof (UNIT_TEST_SAVE_HEADER);
- //
- // Iterate all suites.
- //
- SuiteListHead = &Framework->TestSuiteList;
- for (Suite = GetFirstNode (SuiteListHead); Suite != SuiteListHead; Suite = GetNextNode (SuiteListHead, Suite)) {
- //
- // Iterate all tests within the suite.
- //
- TestListHead = &((UNIT_TEST_SUITE_LIST_ENTRY *)Suite)->UTS.TestCaseList;
- for (Test = GetFirstNode (TestListHead); Test != TestListHead; Test = GetNextNode (TestListHead, Test)) {
- TestSaveData = (UNIT_TEST_SAVE_TEST *)FloatingPointer;
- UnitTest = &((UNIT_TEST_LIST_ENTRY *)Test)->UT;
-
- //
- // Save the fingerprint.
- //
- CopyMem (&TestSaveData->Fingerprint[0], &UnitTest->Fingerprint[0], UNIT_TEST_FINGERPRINT_SIZE);
-
- //
- // Save the result.
- //
- TestSaveData->Result = UnitTest->Result;
- TestSaveData->FailureType = UnitTest->FailureType;
- AsciiStrnCpyS (&TestSaveData->FailureMessage[0], UNIT_TEST_TESTFAILUREMSG_LENGTH, &UnitTest->FailureMessage[0], UNIT_TEST_TESTFAILUREMSG_LENGTH);
-
- //
- // If there is a log, save the log.
- //
- FloatingPointer += sizeof (UNIT_TEST_SAVE_TEST);
- if (UnitTest->Log != NULL) {
- //
- // The +1 is for the NULL character. Can't forget the NULL character.
- //
- LogSize = (AsciiStrLen (UnitTest->Log) + 1) * sizeof (CHAR8);
- CopyMem (FloatingPointer, UnitTest->Log, LogSize);
- FloatingPointer += LogSize;
- }
-
- //
- // Update the size once the structure is complete.
- // NOTE: Should this be a straight cast without validation?
- //
- TestSaveData->Size = (UINT32)(FloatingPointer - (UINT8 *)TestSaveData);
- }
- }
-
- //
- // If there is a context to save, let's do that now.
- //
- if ((ContextToSave != NULL) && (Framework->CurrentTest != NULL)) {
- TestSaveContext = (UNIT_TEST_SAVE_CONTEXT *)FloatingPointer;
- TestSaveContext->Size = (UINT32)ContextToSaveSize + sizeof (UNIT_TEST_SAVE_CONTEXT);
- CopyMem (&TestSaveContext->Fingerprint[0], &Framework->CurrentTest->Fingerprint[0], UNIT_TEST_FINGERPRINT_SIZE);
- CopyMem (((UINT8 *)TestSaveContext + sizeof (UNIT_TEST_SAVE_CONTEXT)), ContextToSave, ContextToSaveSize);
- Header->HasSavedContext = TRUE;
- }
-
- return Header;
-}
-
-/**
- Leverages a framework-specific mechanism (see UnitTestPersistenceLib if you're
- a framework author) to save the state of the executing framework along with
- any allocated data so that the test may be resumed upon reentry. A test case
- should pass any needed context (which, to prevent an infinite loop, should be
- at least the current execution count) which will be saved by the framework and
- passed to the test case upon resume.
-
- This should be called while the current test framework is valid and active. It is
- generally called from within a test case prior to quitting or rebooting.
-
- @param[in] ContextToSave A buffer of test case-specific data to be saved
- along with framework state. Will be passed as
- "Context" to the test case upon resume. This
- is an optional parameter that may be NULL.
- @param[in] ContextToSaveSize Size of the ContextToSave buffer.
-
- @retval EFI_SUCCESS The framework state and context were saved.
- @retval EFI_NOT_FOUND An active framework handle was not found.
- @retval EFI_INVALID_PARAMETER ContextToSave is not NULL and
- ContextToSaveSize is 0.
- @retval EFI_INVALID_PARAMETER ContextToSave is >= 4GB.
- @retval EFI_OUT_OF_RESOURCES There are not enough resources available to
- save the framework and context state.
- @retval EFI_DEVICE_ERROR The framework and context state could not be
- saved to a persistent storage device due to a
- device error.
-**/
-EFI_STATUS
-EFIAPI
-SaveFrameworkState (
- IN UNIT_TEST_CONTEXT ContextToSave OPTIONAL,
- IN UINTN ContextToSaveSize
- )
-{
- EFI_STATUS Status;
- UNIT_TEST_FRAMEWORK_HANDLE FrameworkHandle;
- UNIT_TEST_SAVE_HEADER *Header;
-
- Header = NULL;
- FrameworkHandle = GetActiveFrameworkHandle ();
- if (FrameworkHandle == NULL) {
- DEBUG ((DEBUG_ERROR, "%a - Could not save state! FrameworkHandle not initialized\n", __func__));
- return EFI_DEVICE_ERROR;
- }
-
- //
- // Return a unique error code if the framework is not set.
- //
- if (FrameworkHandle == NULL) {
- return EFI_NOT_FOUND;
- }
-
- //
- // First, let's not make assumptions about the parameters.
- //
- if (((ContextToSave != NULL) && (ContextToSaveSize == 0)) ||
- (ContextToSaveSize > MAX_UINT32))
- {
- return EFI_INVALID_PARAMETER;
- }
-
- //
- // Now, let's package up all the data for saving.
- //
- Header = SerializeState (FrameworkHandle, ContextToSave, ContextToSaveSize);
- if (Header == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- //
- // All that should be left to do is save it using the associated persistence lib.
- //
- Status = SaveUnitTestCache (FrameworkHandle, Header, Header->SaveStateSize);
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a - Could not save state! %r\n", __func__, Status));
- Status = EFI_DEVICE_ERROR;
- }
-
- //
- // Free data that was used.
- //
- FreePool (Header);
-
- return Status;
-}
+/** + Implement UnitTestLib + + Copyright (c) Microsoft Corporation. + Copyright (c) 2022, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include <Uefi.h> +#include <Library/UnitTestLib.h> +#include <Library/BaseLib.h> +#include <Library/BaseMemoryLib.h> +#include <Library/MemoryAllocationLib.h> +#include <Library/DebugLib.h> +#include <Library/UnitTestPersistenceLib.h> +#include <Library/UnitTestResultReportLib.h> + +/// +/// Forward declaration of prototype +/// +STATIC +VOID +UpdateTestFromSave ( + IN OUT UNIT_TEST *Test, + IN UNIT_TEST_SAVE_HEADER *SavedState + ); + +/** + This function will determine whether the short name violates any rules that would + prevent it from being used as a reporting name or as a serialization name. + + Example: If the name cannot be serialized to a filesystem file name. + + @param[in] ShortTitleString A pointer to the short title string to be evaluated. + + @retval TRUE The string is acceptable. + @retval FALSE The string should not be used. + +**/ +STATIC +BOOLEAN +IsFrameworkShortNameValid ( + IN CHAR8 *ShortTitleString + ) +{ + // TODO: Finish this function. + return TRUE; +} + +STATIC +CHAR8 * +AllocateAndCopyString ( + IN CHAR8 *StringToCopy + ) +{ + CHAR8 *NewString; + UINTN NewStringLength; + + NewString = NULL; + NewStringLength = AsciiStrnLenS (StringToCopy, UNIT_TEST_MAX_STRING_LENGTH) + 1; + NewString = AllocatePool (NewStringLength * sizeof (CHAR8)); + if (NewString != NULL) { + AsciiStrCpyS (NewString, NewStringLength, StringToCopy); + } + + return NewString; +} + +STATIC +VOID +SetFrameworkFingerprint ( + OUT UINT8 *Fingerprint, + IN UNIT_TEST_FRAMEWORK *Framework + ) +{ + UINT32 NewFingerprint; + + // For this one we'll just use the title and version as the unique fingerprint. + NewFingerprint = CalculateCrc32 (Framework->Title, (AsciiStrLen (Framework->Title) * sizeof (CHAR8))); + NewFingerprint = (NewFingerprint >> 8) ^ CalculateCrc32 (Framework->VersionString, (AsciiStrLen (Framework->VersionString) * sizeof (CHAR8))); + + CopyMem (Fingerprint, &NewFingerprint, UNIT_TEST_FINGERPRINT_SIZE); + return; +} + +STATIC +VOID +SetSuiteFingerprint ( + OUT UINT8 *Fingerprint, + IN UNIT_TEST_FRAMEWORK *Framework, + IN UNIT_TEST_SUITE *Suite + ) +{ + UINT32 NewFingerprint; + + // For this one, we'll use the fingerprint from the framework, and the title of the suite. + NewFingerprint = CalculateCrc32 (&Framework->Fingerprint[0], UNIT_TEST_FINGERPRINT_SIZE); + NewFingerprint = (NewFingerprint >> 8) ^ CalculateCrc32 (Suite->Title, (AsciiStrLen (Suite->Title) * sizeof (CHAR8))); + NewFingerprint = (NewFingerprint >> 8) ^ CalculateCrc32 (Suite->Name, (AsciiStrLen (Suite->Name) * sizeof (CHAR8))); + + CopyMem (Fingerprint, &NewFingerprint, UNIT_TEST_FINGERPRINT_SIZE); + return; +} + +STATIC +VOID +SetTestFingerprint ( + OUT UINT8 *Fingerprint, + IN UNIT_TEST_SUITE *Suite, + IN UNIT_TEST *Test + ) +{ + UINT32 NewFingerprint; + + // For this one, we'll use the fingerprint from the suite, and the description and classname of the test. + NewFingerprint = CalculateCrc32 (&Suite->Fingerprint[0], UNIT_TEST_FINGERPRINT_SIZE); + NewFingerprint = (NewFingerprint >> 8) ^ CalculateCrc32 (Test->Description, (AsciiStrLen (Test->Description) * sizeof (CHAR8))); + NewFingerprint = (NewFingerprint >> 8) ^ CalculateCrc32 (Test->Name, (AsciiStrLen (Test->Name) * sizeof (CHAR8))); + + CopyMem (Fingerprint, &NewFingerprint, UNIT_TEST_FINGERPRINT_SIZE); + return; +} + +STATIC +BOOLEAN +CompareFingerprints ( + IN UINT8 *FingerprintA, + IN UINT8 *FingerprintB + ) +{ + return (CompareMem (FingerprintA, FingerprintB, UNIT_TEST_FINGERPRINT_SIZE) == 0); +} + +/** + Cleanup a test framework. + + After tests are run, this will teardown the entire framework and free all + allocated data within. + + @param[in] FrameworkHandle A handle to the current running framework that + dispatched the test. Necessary for recording + certain test events with the framework. + + @retval EFI_SUCCESS All resources associated with framework were + freed. + @retval EFI_INVALID_PARAMETER FrameworkHandle is NULL. +**/ +EFI_STATUS +EFIAPI +FreeUnitTestFramework ( + IN UNIT_TEST_FRAMEWORK_HANDLE FrameworkHandle + ) +{ + // TODO: Finish this function. + return EFI_SUCCESS; +} + +STATIC +EFI_STATUS +FreeUnitTestSuiteEntry ( + IN UNIT_TEST_SUITE_LIST_ENTRY *SuiteEntry + ) +{ + // TODO: Finish this function. + return EFI_SUCCESS; +} + +STATIC +EFI_STATUS +FreeUnitTestTestEntry ( + IN UNIT_TEST_LIST_ENTRY *TestEntry + ) +{ + // TODO: Finish this function. + return EFI_SUCCESS; +} + +/** + Method to Initialize the Unit Test framework. This function registers the + test name and also initializes the internal state of the test framework to + receive any new suites and tests. + + @param[out] FrameworkHandle Unit test framework to be created. + @param[in] Title Null-terminated ASCII string that is the user + friendly name of the framework. String is + copied. + @param[in] ShortTitle Null-terminated ASCII short string that is the + short name of the framework with no spaces. + String is copied. + @param[in] VersionString Null-terminated ASCII version string for the + framework. String is copied. + + @retval EFI_SUCCESS The unit test framework was initialized. + @retval EFI_INVALID_PARAMETER FrameworkHandle is NULL. + @retval EFI_INVALID_PARAMETER Title is NULL. + @retval EFI_INVALID_PARAMETER ShortTitle is NULL. + @retval EFI_INVALID_PARAMETER VersionString is NULL. + @retval EFI_INVALID_PARAMETER ShortTitle is invalid. + @retval EFI_OUT_OF_RESOURCES There are not enough resources available to + initialize the unit test framework. +**/ +EFI_STATUS +EFIAPI +InitUnitTestFramework ( + OUT UNIT_TEST_FRAMEWORK_HANDLE *FrameworkHandle, + IN CHAR8 *Title, + IN CHAR8 *ShortTitle, + IN CHAR8 *VersionString + ) +{ + EFI_STATUS Status; + UNIT_TEST_FRAMEWORK_HANDLE NewFrameworkHandle; + UNIT_TEST_FRAMEWORK *NewFramework; + UINTN SaveStateSize; + + Status = EFI_SUCCESS; + NewFramework = NULL; + + // + // First, check all pointers and make sure nothing's broked. + // + if ((FrameworkHandle == NULL) || (Title == NULL) || + (ShortTitle == NULL) || (VersionString == NULL)) + { + return EFI_INVALID_PARAMETER; + } + + // + // Next, determine whether all of the strings are good to use. + // + if (!IsFrameworkShortNameValid (ShortTitle)) { + return EFI_INVALID_PARAMETER; + } + + // + // Next, set aside some space to start messing with the framework. + // + NewFramework = AllocateZeroPool (sizeof (UNIT_TEST_FRAMEWORK)); + if (NewFramework == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + // + // Next, set up all the test data. + // + NewFrameworkHandle = (UNIT_TEST_FRAMEWORK_HANDLE)NewFramework; + NewFramework->Title = AllocateAndCopyString (Title); + NewFramework->ShortTitle = AllocateAndCopyString (ShortTitle); + NewFramework->VersionString = AllocateAndCopyString (VersionString); + NewFramework->Log = NULL; + NewFramework->CurrentTest = NULL; + NewFramework->SavedState = NULL; + if ((NewFramework->Title == NULL) || + (NewFramework->ShortTitle == NULL) || + (NewFramework->VersionString == NULL)) + { + Status = EFI_OUT_OF_RESOURCES; + goto Exit; + } + + InitializeListHead (&(NewFramework->TestSuiteList)); + + // + // Create the framework fingerprint. + // + SetFrameworkFingerprint (&NewFramework->Fingerprint[0], NewFramework); + + // + // If there is a persisted context, load it now. + // + if (DoesCacheExist (NewFrameworkHandle)) { + Status = LoadUnitTestCache (NewFrameworkHandle, (VOID **)(&NewFramework->SavedState), &SaveStateSize); + if (EFI_ERROR (Status)) { + // + // Don't actually report it as an error, but emit a warning. + // + DEBUG ((DEBUG_ERROR, "%a - Cache was detected, but failed to load.\n", __func__)); + Status = EFI_SUCCESS; + } + } + +Exit: + // + // If we're good, then let's copy the framework. + // + if (!EFI_ERROR (Status)) { + *FrameworkHandle = NewFrameworkHandle; + } else { + // + // Otherwise, we need to undo this horrible thing that we've done. + // + FreeUnitTestFramework (NewFrameworkHandle); + } + + return Status; +} + +/** + Registers a Unit Test Suite in the Unit Test Framework. + At least one test suite must be registered, because all test cases must be + within a unit test suite. + + @param[out] SuiteHandle Unit test suite to create + @param[in] FrameworkHandle Unit test framework to add unit test suite to + @param[in] Title Null-terminated ASCII string that is the user + friendly name of the test suite. String is + copied. + @param[in] Name Null-terminated ASCII string that is the short + name of the test suite with no spaces. String + is copied. + @param[in] Setup Setup function, runs before suite. This is an + optional parameter that may be NULL. + @param[in] Teardown Teardown function, runs after suite. This is an + optional parameter that may be NULL. + + @retval EFI_SUCCESS The unit test suite was created. + @retval EFI_INVALID_PARAMETER SuiteHandle is NULL. + @retval EFI_INVALID_PARAMETER FrameworkHandle is NULL. + @retval EFI_INVALID_PARAMETER Title is NULL. + @retval EFI_INVALID_PARAMETER Name is NULL. + @retval EFI_OUT_OF_RESOURCES There are not enough resources available to + initialize the unit test suite. +**/ +EFI_STATUS +EFIAPI +CreateUnitTestSuite ( + OUT UNIT_TEST_SUITE_HANDLE *SuiteHandle, + IN UNIT_TEST_FRAMEWORK_HANDLE FrameworkHandle, + IN CHAR8 *Title, + IN CHAR8 *Name, + IN UNIT_TEST_SUITE_SETUP Setup OPTIONAL, + IN UNIT_TEST_SUITE_TEARDOWN Teardown OPTIONAL + ) +{ + EFI_STATUS Status; + UNIT_TEST_SUITE_LIST_ENTRY *NewSuiteEntry; + UNIT_TEST_FRAMEWORK *Framework; + + Status = EFI_SUCCESS; + Framework = (UNIT_TEST_FRAMEWORK *)FrameworkHandle; + + // + // First, let's check to make sure that our parameters look good. + // + if ((SuiteHandle == NULL) || (Framework == NULL) || (Title == NULL) || (Name == NULL)) { + return EFI_INVALID_PARAMETER; + } + + // + // Create the new entry. + // + NewSuiteEntry = AllocateZeroPool (sizeof (UNIT_TEST_SUITE_LIST_ENTRY)); + if (NewSuiteEntry == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + // + // Copy the fields we think we need. + // + NewSuiteEntry->UTS.NumTests = 0; + NewSuiteEntry->UTS.Title = AllocateAndCopyString (Title); + NewSuiteEntry->UTS.Name = AllocateAndCopyString (Name); + NewSuiteEntry->UTS.Setup = Setup; + NewSuiteEntry->UTS.Teardown = Teardown; + NewSuiteEntry->UTS.ParentFramework = FrameworkHandle; + InitializeListHead (&(NewSuiteEntry->Entry)); // List entry for sibling suites. + InitializeListHead (&(NewSuiteEntry->UTS.TestCaseList)); // List entry for child tests. + if (NewSuiteEntry->UTS.Title == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto Exit; + } + + if (NewSuiteEntry->UTS.Name == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto Exit; + } + + // + // Create the suite fingerprint. + // + SetSuiteFingerprint (&NewSuiteEntry->UTS.Fingerprint[0], Framework, &NewSuiteEntry->UTS); + +Exit: + // + // If everything is going well, add the new suite to the tail list for the framework. + // + if (!EFI_ERROR (Status)) { + InsertTailList (&(Framework->TestSuiteList), (LIST_ENTRY *)NewSuiteEntry); + *SuiteHandle = (UNIT_TEST_SUITE_HANDLE)(&NewSuiteEntry->UTS); + } else { + // + // Otherwise, make with the destruction. + // + FreeUnitTestSuiteEntry (NewSuiteEntry); + } + + return Status; +} + +/** + Adds test case to Suite + + @param[in] SuiteHandle Unit test suite to add test to. + @param[in] Description Null-terminated ASCII string that is the user + friendly description of a test. String is copied. + @param[in] Name Null-terminated ASCII string that is the short name + of the test with no spaces. String is copied. + @param[in] Function Unit test function. + @param[in] Prerequisite Prerequisite function, runs before test. This is + an optional parameter that may be NULL. + @param[in] CleanUp Clean up function, runs after test. This is an + optional parameter that may be NULL. + @param[in] Context Pointer to context. This is an optional parameter + that may be NULL. + + @retval EFI_SUCCESS The unit test case was added to Suite. + @retval EFI_INVALID_PARAMETER SuiteHandle is NULL. + @retval EFI_INVALID_PARAMETER Description is NULL. + @retval EFI_INVALID_PARAMETER Name is NULL. + @retval EFI_INVALID_PARAMETER Function is NULL. + @retval EFI_OUT_OF_RESOURCES There are not enough resources available to + add the unit test case to Suite. +**/ +EFI_STATUS +EFIAPI +AddTestCase ( + IN UNIT_TEST_SUITE_HANDLE SuiteHandle, + IN CHAR8 *Description, + IN CHAR8 *Name, + IN UNIT_TEST_FUNCTION Function, + IN UNIT_TEST_PREREQUISITE Prerequisite OPTIONAL, + IN UNIT_TEST_CLEANUP CleanUp OPTIONAL, + IN UNIT_TEST_CONTEXT Context OPTIONAL + ) +{ + EFI_STATUS Status; + UNIT_TEST_LIST_ENTRY *NewTestEntry; + UNIT_TEST_FRAMEWORK *ParentFramework; + UNIT_TEST_SUITE *Suite; + + Status = EFI_SUCCESS; + Suite = (UNIT_TEST_SUITE *)SuiteHandle; + + // + // First, let's check to make sure that our parameters look good. + // + if ((Suite == NULL) || (Description == NULL) || (Name == NULL) || (Function == NULL)) { + return EFI_INVALID_PARAMETER; + } + + ParentFramework = (UNIT_TEST_FRAMEWORK *)Suite->ParentFramework; + // + // Create the new entry. + NewTestEntry = AllocateZeroPool (sizeof (UNIT_TEST_LIST_ENTRY)); + if (NewTestEntry == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + // + // Copy the fields we think we need. + NewTestEntry->UT.Description = AllocateAndCopyString (Description); + NewTestEntry->UT.Name = AllocateAndCopyString (Name); + NewTestEntry->UT.FailureType = FAILURETYPE_NOFAILURE; + NewTestEntry->UT.FailureMessage[0] = '\0'; + NewTestEntry->UT.Log = NULL; + NewTestEntry->UT.Prerequisite = Prerequisite; + NewTestEntry->UT.CleanUp = CleanUp; + NewTestEntry->UT.RunTest = Function; + NewTestEntry->UT.Context = Context; + NewTestEntry->UT.Result = UNIT_TEST_PENDING; + NewTestEntry->UT.ParentSuite = SuiteHandle; + InitializeListHead (&(NewTestEntry->Entry)); // List entry for sibling tests. + if (NewTestEntry->UT.Description == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto Exit; + } + + if (NewTestEntry->UT.Name == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto Exit; + } + + // + // Create the test fingerprint. + // + SetTestFingerprint (&NewTestEntry->UT.Fingerprint[0], Suite, &NewTestEntry->UT); + + // TODO: Make sure that duplicate fingerprints cannot be created. + + // + // If there is saved test data, update this record. + // + if (ParentFramework->SavedState != NULL) { + UpdateTestFromSave (&NewTestEntry->UT, ParentFramework->SavedState); + } + +Exit: + // + // If everything is going well, add the new suite to the tail list for the framework. + // + if (!EFI_ERROR (Status)) { + InsertTailList (&(Suite->TestCaseList), (LIST_ENTRY *)NewTestEntry); + Suite->NumTests++; + } else { + // + // Otherwise, make with the destruction. + // + FreeUnitTestTestEntry (NewTestEntry); + } + + return Status; +} + +STATIC +VOID +UpdateTestFromSave ( + IN OUT UNIT_TEST *Test, + IN UNIT_TEST_SAVE_HEADER *SavedState + ) +{ + UNIT_TEST_SAVE_TEST *CurrentTest; + UNIT_TEST_SAVE_TEST *MatchingTest; + UINT8 *FloatingPointer; + UNIT_TEST_SAVE_CONTEXT *SavedContext; + UINTN Index; + + // + // First, evaluate the inputs. + // + if ((Test == NULL) || (SavedState == NULL)) { + return; + } + + if (SavedState->TestCount == 0) { + return; + } + + // + // Next, determine whether a matching test can be found. + // Start at the beginning. + // + MatchingTest = NULL; + FloatingPointer = (UINT8 *)SavedState + sizeof (*SavedState); + for (Index = 0; Index < SavedState->TestCount; Index++) { + CurrentTest = (UNIT_TEST_SAVE_TEST *)FloatingPointer; + if (CompareFingerprints (&Test->Fingerprint[0], &CurrentTest->Fingerprint[0])) { + MatchingTest = CurrentTest; + // + // If there's a saved context, it's important that we iterate through the entire list. + // + if (!SavedState->HasSavedContext) { + break; + } + } + + // + // If we didn't find it, we have to increment to the next test. + // + FloatingPointer = (UINT8 *)CurrentTest + CurrentTest->Size; + } + + // + // If a matching test was found, copy the status. + // + if (MatchingTest) { + // + // Override the test status with the saved status. + // + Test->Result = MatchingTest->Result; + + Test->FailureType = MatchingTest->FailureType; + AsciiStrnCpyS ( + &Test->FailureMessage[0], + UNIT_TEST_TESTFAILUREMSG_LENGTH, + &MatchingTest->FailureMessage[0], + UNIT_TEST_TESTFAILUREMSG_LENGTH + ); + + // + // If there is a log string associated, grab that. + // We can tell that there's a log string because the "size" will be larger than + // the structure size. + // IMPORTANT NOTE: There are security implications here. + // This data is user-supplied and we're about to play kinda + // fast and loose with data buffers. + // + if (MatchingTest->Size > sizeof (UNIT_TEST_SAVE_TEST)) { + UnitTestLogInit (Test, (UINT8 *)MatchingTest->Log, MatchingTest->Size - sizeof (UNIT_TEST_SAVE_TEST)); + } + } + + // + // If the saved context exists and matches this test, grab it, too. + // + if (SavedState->HasSavedContext) { + // + // If there was a saved context, the "matching test" loop will have placed the FloatingPointer + // at the beginning of the context structure. + // + SavedContext = (UNIT_TEST_SAVE_CONTEXT *)FloatingPointer; + if (((SavedContext->Size - sizeof (UNIT_TEST_SAVE_CONTEXT)) > 0) && + CompareFingerprints (&Test->Fingerprint[0], &SavedContext->Fingerprint[0])) + { + // + // Override the test context with the saved context. + // + Test->Context = (VOID *)SavedContext->Data; + } + } +} + +STATIC +UNIT_TEST_SAVE_HEADER * +SerializeState ( + IN UNIT_TEST_FRAMEWORK_HANDLE FrameworkHandle, + IN UNIT_TEST_CONTEXT ContextToSave OPTIONAL, + IN UINTN ContextToSaveSize + ) +{ + UNIT_TEST_FRAMEWORK *Framework; + UNIT_TEST_SAVE_HEADER *Header; + LIST_ENTRY *SuiteListHead; + LIST_ENTRY *Suite; + LIST_ENTRY *TestListHead; + LIST_ENTRY *Test; + UINT32 TestCount; + UINT32 TotalSize; + UINTN LogSize; + UNIT_TEST_SAVE_TEST *TestSaveData; + UNIT_TEST_SAVE_CONTEXT *TestSaveContext; + UNIT_TEST *UnitTest; + UINT8 *FloatingPointer; + + Framework = (UNIT_TEST_FRAMEWORK *)FrameworkHandle; + Header = NULL; + + // + // First, let's not make assumptions about the parameters. + // + if ((Framework == NULL) || + ((ContextToSave != NULL) && (ContextToSaveSize == 0)) || + (ContextToSaveSize > MAX_UINT32)) + { + return NULL; + } + + // + // Next, we've gotta figure out the resources that will be required to serialize the + // the framework state so that we can persist it. + // To start with, we're gonna need a header. + // + TotalSize = sizeof (UNIT_TEST_SAVE_HEADER); + // + // Now we need to figure out how many tests there are. + // + TestCount = 0; + // + // Iterate all suites. + // + SuiteListHead = &Framework->TestSuiteList; + for (Suite = GetFirstNode (SuiteListHead); Suite != SuiteListHead; Suite = GetNextNode (SuiteListHead, Suite)) { + // + // Iterate all tests within the suite. + // + TestListHead = &((UNIT_TEST_SUITE_LIST_ENTRY *)Suite)->UTS.TestCaseList; + for (Test = GetFirstNode (TestListHead); Test != TestListHead; Test = GetNextNode (TestListHead, Test)) { + UnitTest = &((UNIT_TEST_LIST_ENTRY *)Test)->UT; + // + // Account for the size of a test structure. + // + TotalSize += sizeof (UNIT_TEST_SAVE_TEST); + // + // If there's a log, make sure to account for the log size. + // + if (UnitTest->Log != NULL) { + // + // The +1 is for the NULL character. Can't forget the NULL character. + // + LogSize = (AsciiStrLen (UnitTest->Log) + 1) * sizeof (CHAR8); + ASSERT (LogSize < MAX_UINT32); + TotalSize += (UINT32)LogSize; + } + + // + // Increment the test count. + // + TestCount++; + } + } + + // + // If there are no tests, we're done here. + // + if (TestCount == 0) { + return NULL; + } + + // + // Add room for the context, if there is one. + // + if (ContextToSave != NULL) { + TotalSize += sizeof (UNIT_TEST_SAVE_CONTEXT) + (UINT32)ContextToSaveSize; + } + + // + // Now that we know the size, we need to allocate space for the serialized output. + // + Header = AllocateZeroPool (TotalSize); + if (Header == NULL) { + return NULL; + } + + // + // Alright, let's start setting up some data. + // + Header->Version = UNIT_TEST_PERSISTENCE_LIB_VERSION; + Header->SaveStateSize = TotalSize; + CopyMem (&Header->Fingerprint[0], &Framework->Fingerprint[0], UNIT_TEST_FINGERPRINT_SIZE); + CopyMem (&Header->StartTime, &Framework->StartTime, sizeof (EFI_TIME)); + Header->TestCount = TestCount; + Header->HasSavedContext = FALSE; + + // + // Start adding all of the test cases. + // Set the floating pointer to the start of the current test save buffer. + // + FloatingPointer = (UINT8 *)Header + sizeof (UNIT_TEST_SAVE_HEADER); + // + // Iterate all suites. + // + SuiteListHead = &Framework->TestSuiteList; + for (Suite = GetFirstNode (SuiteListHead); Suite != SuiteListHead; Suite = GetNextNode (SuiteListHead, Suite)) { + // + // Iterate all tests within the suite. + // + TestListHead = &((UNIT_TEST_SUITE_LIST_ENTRY *)Suite)->UTS.TestCaseList; + for (Test = GetFirstNode (TestListHead); Test != TestListHead; Test = GetNextNode (TestListHead, Test)) { + TestSaveData = (UNIT_TEST_SAVE_TEST *)FloatingPointer; + UnitTest = &((UNIT_TEST_LIST_ENTRY *)Test)->UT; + + // + // Save the fingerprint. + // + CopyMem (&TestSaveData->Fingerprint[0], &UnitTest->Fingerprint[0], UNIT_TEST_FINGERPRINT_SIZE); + + // + // Save the result. + // + TestSaveData->Result = UnitTest->Result; + TestSaveData->FailureType = UnitTest->FailureType; + AsciiStrnCpyS (&TestSaveData->FailureMessage[0], UNIT_TEST_TESTFAILUREMSG_LENGTH, &UnitTest->FailureMessage[0], UNIT_TEST_TESTFAILUREMSG_LENGTH); + + // + // If there is a log, save the log. + // + FloatingPointer += sizeof (UNIT_TEST_SAVE_TEST); + if (UnitTest->Log != NULL) { + // + // The +1 is for the NULL character. Can't forget the NULL character. + // + LogSize = (AsciiStrLen (UnitTest->Log) + 1) * sizeof (CHAR8); + CopyMem (FloatingPointer, UnitTest->Log, LogSize); + FloatingPointer += LogSize; + } + + // + // Update the size once the structure is complete. + // NOTE: Should this be a straight cast without validation? + // + TestSaveData->Size = (UINT32)(FloatingPointer - (UINT8 *)TestSaveData); + } + } + + // + // If there is a context to save, let's do that now. + // + if ((ContextToSave != NULL) && (Framework->CurrentTest != NULL)) { + TestSaveContext = (UNIT_TEST_SAVE_CONTEXT *)FloatingPointer; + TestSaveContext->Size = (UINT32)ContextToSaveSize + sizeof (UNIT_TEST_SAVE_CONTEXT); + CopyMem (&TestSaveContext->Fingerprint[0], &Framework->CurrentTest->Fingerprint[0], UNIT_TEST_FINGERPRINT_SIZE); + CopyMem (((UINT8 *)TestSaveContext + sizeof (UNIT_TEST_SAVE_CONTEXT)), ContextToSave, ContextToSaveSize); + Header->HasSavedContext = TRUE; + } + + return Header; +} + +/** + Leverages a framework-specific mechanism (see UnitTestPersistenceLib if you're + a framework author) to save the state of the executing framework along with + any allocated data so that the test may be resumed upon reentry. A test case + should pass any needed context (which, to prevent an infinite loop, should be + at least the current execution count) which will be saved by the framework and + passed to the test case upon resume. + + This should be called while the current test framework is valid and active. It is + generally called from within a test case prior to quitting or rebooting. + + @param[in] ContextToSave A buffer of test case-specific data to be saved + along with framework state. Will be passed as + "Context" to the test case upon resume. This + is an optional parameter that may be NULL. + @param[in] ContextToSaveSize Size of the ContextToSave buffer. + + @retval EFI_SUCCESS The framework state and context were saved. + @retval EFI_NOT_FOUND An active framework handle was not found. + @retval EFI_INVALID_PARAMETER ContextToSave is not NULL and + ContextToSaveSize is 0. + @retval EFI_INVALID_PARAMETER ContextToSave is >= 4GB. + @retval EFI_OUT_OF_RESOURCES There are not enough resources available to + save the framework and context state. + @retval EFI_DEVICE_ERROR The framework and context state could not be + saved to a persistent storage device due to a + device error. +**/ +EFI_STATUS +EFIAPI +SaveFrameworkState ( + IN UNIT_TEST_CONTEXT ContextToSave OPTIONAL, + IN UINTN ContextToSaveSize + ) +{ + EFI_STATUS Status; + UNIT_TEST_FRAMEWORK_HANDLE FrameworkHandle; + UNIT_TEST_SAVE_HEADER *Header; + + Header = NULL; + FrameworkHandle = GetActiveFrameworkHandle (); + if (FrameworkHandle == NULL) { + DEBUG ((DEBUG_ERROR, "%a - Could not save state! FrameworkHandle not initialized\n", __func__)); + return EFI_DEVICE_ERROR; + } + + // + // Return a unique error code if the framework is not set. + // + if (FrameworkHandle == NULL) { + return EFI_NOT_FOUND; + } + + // + // First, let's not make assumptions about the parameters. + // + if (((ContextToSave != NULL) && (ContextToSaveSize == 0)) || + (ContextToSaveSize > MAX_UINT32)) + { + return EFI_INVALID_PARAMETER; + } + + // + // Now, let's package up all the data for saving. + // + Header = SerializeState (FrameworkHandle, ContextToSave, ContextToSaveSize); + if (Header == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + // + // All that should be left to do is save it using the associated persistence lib. + // + Status = SaveUnitTestCache (FrameworkHandle, Header, Header->SaveStateSize); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a - Could not save state! %r\n", __func__, Status)); + Status = EFI_DEVICE_ERROR; + } + + // + // Free data that was used. + // + FreePool (Header); + + return Status; +} diff --git a/UnitTestFrameworkPkg/Library/UnitTestLib/UnitTestLib.inf b/UnitTestFrameworkPkg/Library/UnitTestLib/UnitTestLib.inf index 0dabd6a6f3..6c03766d0c 100644 --- a/UnitTestFrameworkPkg/Library/UnitTestLib/UnitTestLib.inf +++ b/UnitTestFrameworkPkg/Library/UnitTestLib/UnitTestLib.inf @@ -1,37 +1,37 @@ -## @file
-# Library to support Unit Testing from PEI, DXE, SMM, and UEFI Applications.
-#
-# Copyright (c) Microsoft Corporation.<BR>
-# SPDX-License-Identifier: BSD-2-Clause-Patent
-##
-
-[Defines]
- INF_VERSION = 0x00010017
- BASE_NAME = UnitTestLib
- MODULE_UNI_FILE = UnitTestLib.uni
- FILE_GUID = 98CEF9CA-15CE-40A3-ADE8-C299953CD0F6
- VERSION_STRING = 1.0
- MODULE_TYPE = UEFI_DRIVER
- LIBRARY_CLASS = UnitTestLib|PEI_CORE PEIM DXE_CORE MM_STANDALONE DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SMM_DRIVER SMM_CORE UEFI_DRIVER UEFI_APPLICATION
-
-[Sources]
- UnitTestLib.c
- RunTests.c
- Assert.c
- Log.c
-
-[Packages]
- MdePkg/MdePkg.dec
- UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec
-
-[LibraryClasses]
- BaseLib
- BaseMemoryLib
- PcdLib
- DebugLib
- MemoryAllocationLib
- UnitTestPersistenceLib
- UnitTestResultReportLib
-
-[Pcd]
- gUnitTestFrameworkPkgTokenSpaceGuid.PcdUnitTestLogLevel ## CONSUMES
+## @file +# Library to support Unit Testing from PEI, DXE, SMM, and UEFI Applications. +# +# Copyright (c) Microsoft Corporation.<BR> +# SPDX-License-Identifier: BSD-2-Clause-Patent +## + +[Defines] + INF_VERSION = 0x00010017 + BASE_NAME = UnitTestLib + MODULE_UNI_FILE = UnitTestLib.uni + FILE_GUID = 98CEF9CA-15CE-40A3-ADE8-C299953CD0F6 + VERSION_STRING = 1.0 + MODULE_TYPE = UEFI_DRIVER + LIBRARY_CLASS = UnitTestLib|PEI_CORE PEIM DXE_CORE MM_STANDALONE DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SMM_DRIVER SMM_CORE UEFI_DRIVER UEFI_APPLICATION + +[Sources] + UnitTestLib.c + RunTests.c + Assert.c + Log.c + +[Packages] + MdePkg/MdePkg.dec + UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec + +[LibraryClasses] + BaseLib + BaseMemoryLib + PcdLib + DebugLib + MemoryAllocationLib + UnitTestPersistenceLib + UnitTestResultReportLib + +[Pcd] + gUnitTestFrameworkPkgTokenSpaceGuid.PcdUnitTestLogLevel ## CONSUMES diff --git a/UnitTestFrameworkPkg/Library/UnitTestLib/UnitTestLib.uni b/UnitTestFrameworkPkg/Library/UnitTestLib/UnitTestLib.uni index fe7c9c7f71..84f98e85f8 100644 --- a/UnitTestFrameworkPkg/Library/UnitTestLib/UnitTestLib.uni +++ b/UnitTestFrameworkPkg/Library/UnitTestLib/UnitTestLib.uni @@ -1,11 +1,11 @@ -// /** @file
-// Library to support Unit Testing from PEI, DXE, SMM, and UEFI Applications.
-//
-// Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
-// SPDX-License-Identifier: BSD-2-Clause-Patent
-//
-// **/
-
-#string STR_MODULE_ABSTRACT #language en-US "Library to support Unit Testing from PEI, DXE, SMM, and UEFI Applications"
-
-#string STR_MODULE_DESCRIPTION #language en-US "Library to support Unit Testing from PEI, DXE, SMM, and UEFI Applications."
+// /** @file +// Library to support Unit Testing from PEI, DXE, SMM, and UEFI Applications. +// +// Copyright (c) 2020, Intel Corporation. All rights reserved.<BR> +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + +#string STR_MODULE_ABSTRACT #language en-US "Library to support Unit Testing from PEI, DXE, SMM, and UEFI Applications" + +#string STR_MODULE_DESCRIPTION #language en-US "Library to support Unit Testing from PEI, DXE, SMM, and UEFI Applications." diff --git a/UnitTestFrameworkPkg/Library/UnitTestLib/UnitTestLibCmocka.inf b/UnitTestFrameworkPkg/Library/UnitTestLib/UnitTestLibCmocka.inf index b12af91576..a65916c49a 100644 --- a/UnitTestFrameworkPkg/Library/UnitTestLib/UnitTestLibCmocka.inf +++ b/UnitTestFrameworkPkg/Library/UnitTestLib/UnitTestLibCmocka.inf @@ -1,38 +1,38 @@ -## @file
-# Library to support Unit Testing from host environments using Cmocka services.
-#
-# Copyright (c) 2019 - 2020, Intel Corporation. All rights reserved.<BR>
-# SPDX-License-Identifier: BSD-2-Clause-Patent
-##
-
-[Defines]
- INF_VERSION = 0x00010017
- BASE_NAME = UnitTestLibCmocka
- MODULE_UNI_FILE = UnitTestLibCmocka.uni
- FILE_GUID = C800595F-45A3-45A1-8B50-28F01C2A5A4F
- VERSION_STRING = 1.0
- MODULE_TYPE = UEFI_DRIVER
- LIBRARY_CLASS = UnitTestLib|HOST_APPLICATION
-
-[Sources]
- UnitTestLib.c
- RunTestsCmocka.c
- AssertCmocka.c
- Log.c
-
-[Packages]
- MdePkg/MdePkg.dec
- UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec
-
-[LibraryClasses]
- BaseLib
- BaseMemoryLib
- PcdLib
- DebugLib
- MemoryAllocationLib
- UnitTestPersistenceLib
- UnitTestResultReportLib
- CmockaLib
-
-[Pcd]
- gUnitTestFrameworkPkgTokenSpaceGuid.PcdUnitTestLogLevel ## CONSUMES
+## @file +# Library to support Unit Testing from host environments using Cmocka services. +# +# Copyright (c) 2019 - 2020, Intel Corporation. All rights reserved.<BR> +# SPDX-License-Identifier: BSD-2-Clause-Patent +## + +[Defines] + INF_VERSION = 0x00010017 + BASE_NAME = UnitTestLibCmocka + MODULE_UNI_FILE = UnitTestLibCmocka.uni + FILE_GUID = C800595F-45A3-45A1-8B50-28F01C2A5A4F + VERSION_STRING = 1.0 + MODULE_TYPE = UEFI_DRIVER + LIBRARY_CLASS = UnitTestLib|HOST_APPLICATION + +[Sources] + UnitTestLib.c + RunTestsCmocka.c + AssertCmocka.c + Log.c + +[Packages] + MdePkg/MdePkg.dec + UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec + +[LibraryClasses] + BaseLib + BaseMemoryLib + PcdLib + DebugLib + MemoryAllocationLib + UnitTestPersistenceLib + UnitTestResultReportLib + CmockaLib + +[Pcd] + gUnitTestFrameworkPkgTokenSpaceGuid.PcdUnitTestLogLevel ## CONSUMES diff --git a/UnitTestFrameworkPkg/Library/UnitTestLib/UnitTestLibCmocka.uni b/UnitTestFrameworkPkg/Library/UnitTestLib/UnitTestLibCmocka.uni index aa25a44e35..7627dc0128 100644 --- a/UnitTestFrameworkPkg/Library/UnitTestLib/UnitTestLibCmocka.uni +++ b/UnitTestFrameworkPkg/Library/UnitTestLib/UnitTestLibCmocka.uni @@ -1,11 +1,11 @@ -// /** @file
-// Library to support Unit Testing from host environments using Cmocka services.
-//
-// Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
-// SPDX-License-Identifier: BSD-2-Clause-Patent
-//
-// **/
-
-#string STR_MODULE_ABSTRACT #language en-US "Library to support Unit Testing from host environments using Cmocka services"
-
-#string STR_MODULE_DESCRIPTION #language en-US "Library to support Unit Testing from host environments using Cmocka services."
+// /** @file +// Library to support Unit Testing from host environments using Cmocka services. +// +// Copyright (c) 2020, Intel Corporation. All rights reserved.<BR> +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + +#string STR_MODULE_ABSTRACT #language en-US "Library to support Unit Testing from host environments using Cmocka services" + +#string STR_MODULE_DESCRIPTION #language en-US "Library to support Unit Testing from host environments using Cmocka services." diff --git a/UnitTestFrameworkPkg/Library/UnitTestPeiServicesTablePointerLib/UnitTestPeiServicesTablePointerLib.c b/UnitTestFrameworkPkg/Library/UnitTestPeiServicesTablePointerLib/UnitTestPeiServicesTablePointerLib.c index a1b982fbae..882fe350d7 100644 --- a/UnitTestFrameworkPkg/Library/UnitTestPeiServicesTablePointerLib/UnitTestPeiServicesTablePointerLib.c +++ b/UnitTestFrameworkPkg/Library/UnitTestPeiServicesTablePointerLib/UnitTestPeiServicesTablePointerLib.c @@ -1,187 +1,187 @@ -/** @file
- This library supports a PEI Service table Pointer library implementation that
- allows code dependent upon PEI Service to operate in an isolated execution environment
- such as within the context of a host-based unit test framework.
-
- Copyright (c) 2023, Intel Corporation. All rights reserved.<BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#include "UnitTestPeiServicesTablePointerLib.h"
-
-///
-/// Pei service instance
-///
-EFI_PEI_SERVICES mPeiServices = {
- {
- PEI_SERVICES_SIGNATURE,
- PEI_SERVICES_REVISION,
- sizeof (EFI_PEI_SERVICES),
- 0,
- 0
- },
- UnitTestInstallPpi, // InstallPpi
- UnitTestReInstallPpi, // ReInstallPpi
- UnitTestLocatePpi, // LocatePpi
- UnitTestNotifyPpi, // NotifyPpi
-
- UnitTestGetBootMode, // GetBootMode
- UnitTestSetBootMode, // SetBootMode
-
- UnitTestGetHobList, // GetHobList
- UnitTestCreateHob, // CreateHob
-
- UnitTestFfsFindNextVolume, // FfsFindNextVolume
- UnitTestFfsFindNextFile, // FfsFindNextFile
- UnitTestFfsFindSectionData, // FfsFindSectionData
-
- UnitTestInstallPeiMemory, // InstallPeiMemory
- UnitTestAllocatePages, // AllocatePages
- UnitTestAllocatePool, // AllocatePool
- (EFI_PEI_COPY_MEM)CopyMem,
- (EFI_PEI_SET_MEM)SetMem,
-
- UnitTestReportStatusCode, // ReportStatusCode
- UnitTestResetSystem, // ResetSystem
-
- NULL, // CpuIo
- NULL, // PciCfg
-
- UnitTestFfsFindFileByName, // FfsFindFileByName
- UnitTestFfsGetFileInfo, // FfsGetFileInfo
- UnitTestFfsGetVolumeInfo, // FfsGetVolumeInfo
- UnitTestRegisterForShadow, // RegisterForShadow
- UnitTestFfsFindSectionData3, // FfsFindSectionData3
- UnitTestFfsGetFileInfo2, // FfsGetFileInfo2
- UnitTestResetSystem2, // ResetSystem2
- UnitTestFreePages, // FreePages
-};
-
-PEI_CORE_INSTANCE mPrivateData;
-UINT8 mHobBuffer[MAX_HOB_SIZE];
-VOID *mPeiServicesPointer;
-
-/**
- Clear Buffer For Global Data.
-**/
-VOID
-ClearGlobalData (
- VOID
- )
-{
- ZeroMem (&mPrivateData, sizeof (mPrivateData));
- mPrivateData.PpiData.PpiList.MaxCount = MAX_PPI_COUNT;
- mPrivateData.PpiData.CallbackNotifyList.MaxCount = MAX_PPI_COUNT;
- mPrivateData.PpiData.DispatchNotifyList.MaxCount = MAX_PPI_COUNT;
-
- ZeroMem (mHobBuffer, MAX_HOB_SIZE);
- mPrivateData.HobList.Raw = mHobBuffer;
- UnitTestCoreBuildHobHandoffInfoTable (0, (EFI_PHYSICAL_ADDRESS)(UINTN)mHobBuffer, MAX_HOB_SIZE);
-}
-
-/**
- Resets the entire platform.
-
- @param[in] ResetType The type of reset to perform.
- @param[in] ResetStatus The status code for the reset.
- @param[in] DataSize The size, in bytes, of ResetData.
- @param[in] ResetData For a ResetType of EfiResetCold, EfiResetWarm, or EfiResetShutdown
- the data buffer starts with a Null-terminated string, optionally
- followed by additional binary data. The string is a description
- that the caller may use to further indicate the reason for the
- system reset.
-
-**/
-VOID
-EFIAPI
-UnitTestResetSystem2 (
- IN EFI_RESET_TYPE ResetType,
- IN EFI_STATUS ResetStatus,
- IN UINTN DataSize,
- IN VOID *ResetData OPTIONAL
- )
-{
- ClearGlobalData ();
-}
-
-/**
- Retrieves the cached value of the PEI Services Table pointer.
-
- Returns the cached value of the PEI Services Table pointer in a CPU specific manner
- as specified in the CPU binding section of the Platform Initialization Pre-EFI
- Initialization Core Interface Specification.
-
- If the cached PEI Services Table pointer is NULL, then ASSERT().
-
- @return The pointer to PeiServices.
-
-**/
-CONST EFI_PEI_SERVICES **
-EFIAPI
-GetPeiServicesTablePointer (
- VOID
- )
-{
- mPeiServicesPointer = &mPeiServices;
- return (CONST EFI_PEI_SERVICES **)&mPeiServicesPointer;
-}
-
-/**
- Caches a pointer PEI Services Table.
-
- Caches the pointer to the PEI Services Table specified by PeiServicesTablePointer
- in a CPU specific manner as specified in the CPU binding section of the Platform Initialization
- Pre-EFI Initialization Core Interface Specification.
-
- If PeiServicesTablePointer is NULL, then ASSERT().
-
- @param PeiServicesTablePointer The address of PeiServices pointer.
-**/
-VOID
-EFIAPI
-SetPeiServicesTablePointer (
- IN CONST EFI_PEI_SERVICES **PeiServicesTablePointer
- )
-{
- ASSERT (FALSE);
-}
-
-/**
- Perform CPU specific actions required to migrate the PEI Services Table
- pointer from temporary RAM to permanent RAM.
-
- For IA32 CPUs, the PEI Services Table pointer is stored in the 4 bytes
- immediately preceding the Interrupt Descriptor Table (IDT) in memory.
- For X64 CPUs, the PEI Services Table pointer is stored in the 8 bytes
- immediately preceding the Interrupt Descriptor Table (IDT) in memory.
- For Itanium and ARM CPUs, a the PEI Services Table Pointer is stored in
- a dedicated CPU register. This means that there is no memory storage
- associated with storing the PEI Services Table pointer, so no additional
- migration actions are required for Itanium or ARM CPUs.
-
-**/
-VOID
-EFIAPI
-MigratePeiServicesTablePointer (
- VOID
- )
-{
- ASSERT (FALSE);
-}
-
-/**
- The constructor function init PeiServicesTable with clean buffer.
-
- @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS.
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestPeiServicesTablePointerLibConstructor (
- VOID
- )
-{
- ClearGlobalData ();
- return EFI_SUCCESS;
-}
+/** @file + This library supports a PEI Service table Pointer library implementation that + allows code dependent upon PEI Service to operate in an isolated execution environment + such as within the context of a host-based unit test framework. + + Copyright (c) 2023, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "UnitTestPeiServicesTablePointerLib.h" + +/// +/// Pei service instance +/// +EFI_PEI_SERVICES mPeiServices = { + { + PEI_SERVICES_SIGNATURE, + PEI_SERVICES_REVISION, + sizeof (EFI_PEI_SERVICES), + 0, + 0 + }, + UnitTestInstallPpi, // InstallPpi + UnitTestReInstallPpi, // ReInstallPpi + UnitTestLocatePpi, // LocatePpi + UnitTestNotifyPpi, // NotifyPpi + + UnitTestGetBootMode, // GetBootMode + UnitTestSetBootMode, // SetBootMode + + UnitTestGetHobList, // GetHobList + UnitTestCreateHob, // CreateHob + + UnitTestFfsFindNextVolume, // FfsFindNextVolume + UnitTestFfsFindNextFile, // FfsFindNextFile + UnitTestFfsFindSectionData, // FfsFindSectionData + + UnitTestInstallPeiMemory, // InstallPeiMemory + UnitTestAllocatePages, // AllocatePages + UnitTestAllocatePool, // AllocatePool + (EFI_PEI_COPY_MEM)CopyMem, + (EFI_PEI_SET_MEM)SetMem, + + UnitTestReportStatusCode, // ReportStatusCode + UnitTestResetSystem, // ResetSystem + + NULL, // CpuIo + NULL, // PciCfg + + UnitTestFfsFindFileByName, // FfsFindFileByName + UnitTestFfsGetFileInfo, // FfsGetFileInfo + UnitTestFfsGetVolumeInfo, // FfsGetVolumeInfo + UnitTestRegisterForShadow, // RegisterForShadow + UnitTestFfsFindSectionData3, // FfsFindSectionData3 + UnitTestFfsGetFileInfo2, // FfsGetFileInfo2 + UnitTestResetSystem2, // ResetSystem2 + UnitTestFreePages, // FreePages +}; + +PEI_CORE_INSTANCE mPrivateData; +UINT8 mHobBuffer[MAX_HOB_SIZE]; +VOID *mPeiServicesPointer; + +/** + Clear Buffer For Global Data. +**/ +VOID +ClearGlobalData ( + VOID + ) +{ + ZeroMem (&mPrivateData, sizeof (mPrivateData)); + mPrivateData.PpiData.PpiList.MaxCount = MAX_PPI_COUNT; + mPrivateData.PpiData.CallbackNotifyList.MaxCount = MAX_PPI_COUNT; + mPrivateData.PpiData.DispatchNotifyList.MaxCount = MAX_PPI_COUNT; + + ZeroMem (mHobBuffer, MAX_HOB_SIZE); + mPrivateData.HobList.Raw = mHobBuffer; + UnitTestCoreBuildHobHandoffInfoTable (0, (EFI_PHYSICAL_ADDRESS)(UINTN)mHobBuffer, MAX_HOB_SIZE); +} + +/** + Resets the entire platform. + + @param[in] ResetType The type of reset to perform. + @param[in] ResetStatus The status code for the reset. + @param[in] DataSize The size, in bytes, of ResetData. + @param[in] ResetData For a ResetType of EfiResetCold, EfiResetWarm, or EfiResetShutdown + the data buffer starts with a Null-terminated string, optionally + followed by additional binary data. The string is a description + that the caller may use to further indicate the reason for the + system reset. + +**/ +VOID +EFIAPI +UnitTestResetSystem2 ( + IN EFI_RESET_TYPE ResetType, + IN EFI_STATUS ResetStatus, + IN UINTN DataSize, + IN VOID *ResetData OPTIONAL + ) +{ + ClearGlobalData (); +} + +/** + Retrieves the cached value of the PEI Services Table pointer. + + Returns the cached value of the PEI Services Table pointer in a CPU specific manner + as specified in the CPU binding section of the Platform Initialization Pre-EFI + Initialization Core Interface Specification. + + If the cached PEI Services Table pointer is NULL, then ASSERT(). + + @return The pointer to PeiServices. + +**/ +CONST EFI_PEI_SERVICES ** +EFIAPI +GetPeiServicesTablePointer ( + VOID + ) +{ + mPeiServicesPointer = &mPeiServices; + return (CONST EFI_PEI_SERVICES **)&mPeiServicesPointer; +} + +/** + Caches a pointer PEI Services Table. + + Caches the pointer to the PEI Services Table specified by PeiServicesTablePointer + in a CPU specific manner as specified in the CPU binding section of the Platform Initialization + Pre-EFI Initialization Core Interface Specification. + + If PeiServicesTablePointer is NULL, then ASSERT(). + + @param PeiServicesTablePointer The address of PeiServices pointer. +**/ +VOID +EFIAPI +SetPeiServicesTablePointer ( + IN CONST EFI_PEI_SERVICES **PeiServicesTablePointer + ) +{ + ASSERT (FALSE); +} + +/** + Perform CPU specific actions required to migrate the PEI Services Table + pointer from temporary RAM to permanent RAM. + + For IA32 CPUs, the PEI Services Table pointer is stored in the 4 bytes + immediately preceding the Interrupt Descriptor Table (IDT) in memory. + For X64 CPUs, the PEI Services Table pointer is stored in the 8 bytes + immediately preceding the Interrupt Descriptor Table (IDT) in memory. + For Itanium and ARM CPUs, a the PEI Services Table Pointer is stored in + a dedicated CPU register. This means that there is no memory storage + associated with storing the PEI Services Table pointer, so no additional + migration actions are required for Itanium or ARM CPUs. + +**/ +VOID +EFIAPI +MigratePeiServicesTablePointer ( + VOID + ) +{ + ASSERT (FALSE); +} + +/** + The constructor function init PeiServicesTable with clean buffer. + + @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS. + +**/ +EFI_STATUS +EFIAPI +UnitTestPeiServicesTablePointerLibConstructor ( + VOID + ) +{ + ClearGlobalData (); + return EFI_SUCCESS; +} diff --git a/UnitTestFrameworkPkg/Library/UnitTestPeiServicesTablePointerLib/UnitTestPeiServicesTablePointerLib.h b/UnitTestFrameworkPkg/Library/UnitTestPeiServicesTablePointerLib/UnitTestPeiServicesTablePointerLib.h index e411d08a86..ece9b69eab 100644 --- a/UnitTestFrameworkPkg/Library/UnitTestPeiServicesTablePointerLib/UnitTestPeiServicesTablePointerLib.h +++ b/UnitTestFrameworkPkg/Library/UnitTestPeiServicesTablePointerLib/UnitTestPeiServicesTablePointerLib.h @@ -1,653 +1,653 @@ -/** @file
- An internal header file for the Unit Test instance of the PEI services Table Pointer Library.
-
- Copyright (c) 2023, Intel Corporation. All rights reserved.<BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#ifndef PEI_SERVICES_TABLE_POINTER_LIB_UNIT_TEST_H_
-#define PEI_SERVICES_TABLE_POINTER_LIB_UNIT_TEST_H_
-
-#include <Base.h>
-#include <PiPei.h>
-#include <Pi/PiMultiPhase.h>
-#include <Library/BaseLib.h>
-#include <Library/BaseMemoryLib.h>
-#include <Library/DebugLib.h>
-#include <Library/UnitTestLib.h>
-#include <Library/PeiServicesTablePointerLib.h>
-#include <Uefi.h>
-
-#define MAX_PPI_COUNT 100
-#define MAX_HOB_SIZE SIZE_32MB
-
-///
-/// Forward declaration for PEI_CORE_INSTANCE
-///
-typedef struct _PEI_CORE_INSTANCE PEI_CORE_INSTANCE;
-
-///
-/// Pei Core private data structures
-///
-typedef union {
- EFI_PEI_PPI_DESCRIPTOR *Ppi;
- EFI_PEI_NOTIFY_DESCRIPTOR *Notify;
- VOID *Raw;
-} PEI_PPI_LIST_POINTERS;
-
-typedef struct {
- UINTN CurrentCount;
- UINTN MaxCount;
- UINTN LastDispatchedCount;
- ///
- /// MaxCount number of entries.
- ///
- PEI_PPI_LIST_POINTERS PpiPtrs[MAX_PPI_COUNT];
-} PEI_PPI_LIST;
-
-typedef struct {
- UINTN CurrentCount;
- UINTN MaxCount;
- ///
- /// MaxCount number of entries.
- ///
- PEI_PPI_LIST_POINTERS NotifyPtrs[MAX_PPI_COUNT];
-} PEI_CALLBACK_NOTIFY_LIST;
-
-typedef struct {
- UINTN CurrentCount;
- UINTN MaxCount;
- UINTN LastDispatchedCount;
- ///
- /// MaxCount number of entries.
- ///
- PEI_PPI_LIST_POINTERS NotifyPtrs[MAX_PPI_COUNT];
-} PEI_DISPATCH_NOTIFY_LIST;
-
-///
-/// PPI database structure which contains three links:
-/// PpiList, CallbackNotifyList and DispatchNotifyList.
-///
-typedef struct {
- ///
- /// PPI List.
- ///
- PEI_PPI_LIST PpiList;
- ///
- /// Notify List at dispatch level.
- ///
- PEI_CALLBACK_NOTIFY_LIST CallbackNotifyList;
- ///
- /// Notify List at callback level.
- ///
- PEI_DISPATCH_NOTIFY_LIST DispatchNotifyList;
-} PEI_PPI_DATABASE;
-
-///
-/// Pei Core private data structure instance
-///
-struct _PEI_CORE_INSTANCE {
- PEI_PPI_DATABASE PpiData;
- EFI_PEI_HOB_POINTERS HobList;
-};
-
-extern PEI_CORE_INSTANCE mPrivateData;
-#define PEI_CORE_INSTANCE_FROM_PS_THIS(a) &mPrivateData
-
-VOID
-ProcessNotify (
- IN PEI_CORE_INSTANCE *PrivateData,
- IN UINTN NotifyType,
- IN INTN InstallStartIndex,
- IN INTN InstallStopIndex,
- IN INTN NotifyStartIndex,
- IN INTN NotifyStopIndex
- );
-
-/**
-
- This function installs an interface in the PEI PPI database by GUID.
- The purpose of the service is to publish an interface that other parties
- can use to call additional PEIMs.
-
- @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
- @param PpiList Pointer to a list of PEI PPI Descriptors.
-
- @retval EFI_SUCCESS if all PPIs in PpiList are successfully installed.
- @retval EFI_INVALID_PARAMETER if PpiList is NULL pointer
- if any PPI in PpiList is not valid
- @retval EFI_OUT_OF_RESOURCES if there is no more memory resource to install PPI
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestInstallPpi (
- IN CONST EFI_PEI_SERVICES **PeiServices,
- IN CONST EFI_PEI_PPI_DESCRIPTOR *PpiList
- );
-
-/**
-
- This function reinstalls an interface in the PEI PPI database by GUID.
- The purpose of the service is to publish an interface that other parties can
- use to replace an interface of the same name in the protocol database with a
- different interface.
-
- @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
- @param OldPpi Pointer to the old PEI PPI Descriptors.
- @param NewPpi Pointer to the new PEI PPI Descriptors.
-
- @retval EFI_SUCCESS if the operation was successful
- @retval EFI_INVALID_PARAMETER if OldPpi or NewPpi is NULL
- @retval EFI_INVALID_PARAMETER if NewPpi is not valid
- @retval EFI_NOT_FOUND if the PPI was not in the database
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestReInstallPpi (
- IN CONST EFI_PEI_SERVICES **PeiServices,
- IN CONST EFI_PEI_PPI_DESCRIPTOR *OldPpi,
- IN CONST EFI_PEI_PPI_DESCRIPTOR *NewPpi
- );
-
-/**
-
- Locate a given named PPI.
-
-
- @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
- @param Guid Pointer to GUID of the PPI.
- @param Instance Instance Number to discover.
- @param PpiDescriptor Pointer to reference the found descriptor. If not NULL,
- returns a pointer to the descriptor (includes flags, etc)
- @param Ppi Pointer to reference the found PPI
-
- @retval EFI_SUCCESS if the PPI is in the database
- @retval EFI_NOT_FOUND if the PPI is not in the database
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestLocatePpi (
- IN CONST EFI_PEI_SERVICES **PeiServices,
- IN CONST EFI_GUID *Guid,
- IN UINTN Instance,
- IN OUT EFI_PEI_PPI_DESCRIPTOR **PpiDescriptor,
- IN OUT VOID **Ppi
- );
-
-/**
-
- This function installs a notification service to be called back when a given
- interface is installed or reinstalled. The purpose of the service is to publish
- an interface that other parties can use to call additional PPIs that may materialize later.
-
- @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
- @param NotifyList Pointer to list of Descriptors to notify upon.
-
- @retval EFI_SUCCESS if successful
- @retval EFI_OUT_OF_RESOURCES if no space in the database
- @retval EFI_INVALID_PARAMETER if not a good descriptor
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestNotifyPpi (
- IN CONST EFI_PEI_SERVICES **PeiServices,
- IN CONST EFI_PEI_NOTIFY_DESCRIPTOR *NotifyList
- );
-
-/**
- Gets the pointer to the HOB List.
-
- @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
- @param HobList Pointer to the HOB List.
-
- @retval EFI_SUCCESS Get the pointer of HOB List
- @retval EFI_NOT_AVAILABLE_YET the HOB List is not yet published
- @retval EFI_INVALID_PARAMETER HobList is NULL (in debug mode)
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestGetHobList (
- IN CONST EFI_PEI_SERVICES **PeiServices,
- IN OUT VOID **HobList
- );
-
-/**
- Add a new HOB to the HOB List.
-
- @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
- @param Type Type of the new HOB.
- @param Length Length of the new HOB to allocate.
- @param Hob Pointer to the new HOB.
-
- @return EFI_SUCCESS Success to create HOB.
- @retval EFI_INVALID_PARAMETER if Hob is NULL
- @retval EFI_NOT_AVAILABLE_YET if HobList is still not available.
- @retval EFI_OUT_OF_RESOURCES if there is no more memory to grow the Hoblist.
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestCreateHob (
- IN CONST EFI_PEI_SERVICES **PeiServices,
- IN UINT16 Type,
- IN UINT16 Length,
- IN OUT VOID **Hob
- );
-
-/**
-
- Builds a Handoff Information Table HOB
-
- @param BootMode - Current Bootmode
- @param MemoryBegin - Start Memory Address.
- @param MemoryLength - Length of Memory.
-
- @return EFI_SUCCESS Always success to initialize HOB.
-
-**/
-EFI_STATUS
-UnitTestCoreBuildHobHandoffInfoTable (
- IN EFI_BOOT_MODE BootMode,
- IN EFI_PHYSICAL_ADDRESS MemoryBegin,
- IN UINT64 MemoryLength
- );
-
-/**
- Resets the entire platform.
-
- @param[in] ResetType The type of reset to perform.
- @param[in] ResetStatus The status code for the reset.
- @param[in] DataSize The size, in bytes, of ResetData.
- @param[in] ResetData For a ResetType of EfiResetCold, EfiResetWarm, or EfiResetShutdown
- the data buffer starts with a Null-terminated string, optionally
- followed by additional binary data. The string is a description
- that the caller may use to further indicate the reason for the
- system reset.
-
-**/
-VOID
-EFIAPI
-UnitTestResetSystem2 (
- IN EFI_RESET_TYPE ResetType,
- IN EFI_STATUS ResetStatus,
- IN UINTN DataSize,
- IN VOID *ResetData OPTIONAL
- );
-
-/**
- This service enables PEIMs to ascertain the present value of the boot mode.
-
- @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
- @param BootMode A pointer to contain the value of the boot mode.
-
- @retval EFI_SUCCESS The boot mode was returned successfully.
- @retval EFI_INVALID_PARAMETER BootMode is NULL.
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestGetBootMode (
- IN CONST EFI_PEI_SERVICES **PeiServices,
- IN OUT EFI_BOOT_MODE *BootMode
- );
-
-/**
- This service enables PEIMs to update the boot mode variable.
-
-
- @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
- @param BootMode The value of the boot mode to set.
-
- @return EFI_SUCCESS The value was successfully updated
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestSetBootMode (
- IN CONST EFI_PEI_SERVICES **PeiServices,
- IN EFI_BOOT_MODE BootMode
- );
-
-/**
- Search the firmware volumes by index
-
- @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation
- @param Instance This instance of the firmware volume to find. The value 0 is the Boot Firmware
- Volume (BFV).
- @param VolumeHandle On exit, points to the next volume handle or NULL if it does not exist.
-
- @retval EFI_INVALID_PARAMETER VolumeHandle is NULL
- @retval EFI_NOT_FOUND The volume was not found.
- @retval EFI_SUCCESS The volume was found.
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestFfsFindNextVolume (
- IN CONST EFI_PEI_SERVICES **PeiServices,
- IN UINTN Instance,
- IN OUT EFI_PEI_FV_HANDLE *VolumeHandle
- );
-
-/**
- Searches for the next matching file in the firmware volume.
-
- @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
- @param SearchType Filter to find only files of this type.
- Type EFI_FV_FILETYPE_ALL causes no filtering to be done.
- @param FvHandle Handle of firmware volume in which to search.
- @param FileHandle On entry, points to the current handle from which to begin searching or NULL to start
- at the beginning of the firmware volume. On exit, points the file handle of the next file
- in the volume or NULL if there are no more files.
-
- @retval EFI_NOT_FOUND The file was not found.
- @retval EFI_NOT_FOUND The header checksum was not zero.
- @retval EFI_SUCCESS The file was found.
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestFfsFindNextFile (
- IN CONST EFI_PEI_SERVICES **PeiServices,
- IN UINT8 SearchType,
- IN EFI_PEI_FV_HANDLE FvHandle,
- IN OUT EFI_PEI_FILE_HANDLE *FileHandle
- );
-
-/**
- Searches for the next matching section within the specified file.
-
- @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation
- @param SectionType Filter to find only sections of this type.
- @param FileHandle Pointer to the current file to search.
- @param SectionData A pointer to the discovered section, if successful.
- NULL if section not found
-
- @retval EFI_NOT_FOUND The section was not found.
- @retval EFI_SUCCESS The section was found.
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestFfsFindSectionData (
- IN CONST EFI_PEI_SERVICES **PeiServices,
- IN EFI_SECTION_TYPE SectionType,
- IN EFI_PEI_FILE_HANDLE FileHandle,
- OUT VOID **SectionData
- );
-
-/**
-
- This function registers the found memory configuration with the PEI Foundation.
-
- The usage model is that the PEIM that discovers the permanent memory shall invoke this service.
- This routine will hold discoveried memory information into PeiCore's private data,
- and set SwitchStackSignal flag. After PEIM who discovery memory is dispatched,
- PeiDispatcher will migrate temporary memory to permanent memory.
-
- @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
- @param MemoryBegin Start of memory address.
- @param MemoryLength Length of memory.
-
- @return EFI_SUCCESS Always success.
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestInstallPeiMemory (
- IN CONST EFI_PEI_SERVICES **PeiServices,
- IN EFI_PHYSICAL_ADDRESS MemoryBegin,
- IN UINT64 MemoryLength
- );
-
-/**
- The purpose of the service is to publish an interface that allows
- PEIMs to allocate memory ranges that are managed by the PEI Foundation.
-
- Prior to InstallPeiMemory() being called, PEI will allocate pages from the heap.
- After InstallPeiMemory() is called, PEI will allocate pages within the region
- of memory provided by InstallPeiMemory() service in a best-effort fashion.
- Location-specific allocations are not managed by the PEI foundation code.
-
- @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
- @param MemoryType The type of memory to allocate.
- @param Pages The number of contiguous 4 KB pages to allocate.
- @param Memory Pointer to a physical address. On output, the address is set to the base
- of the page range that was allocated.
-
- @retval EFI_SUCCESS The memory range was successfully allocated.
- @retval EFI_OUT_OF_RESOURCES The pages could not be allocated.
- @retval EFI_INVALID_PARAMETER Type is not equal to EfiLoaderCode, EfiLoaderData, EfiRuntimeServicesCode,
- EfiRuntimeServicesData, EfiBootServicesCode, EfiBootServicesData,
- EfiACPIReclaimMemory, EfiReservedMemoryType, or EfiACPIMemoryNVS.
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestAllocatePages (
- IN CONST EFI_PEI_SERVICES **PeiServices,
- IN EFI_MEMORY_TYPE MemoryType,
- IN UINTN Pages,
- OUT EFI_PHYSICAL_ADDRESS *Memory
- );
-
-/**
-
- Pool allocation service. Before permanent memory is discovered, the pool will
- be allocated in the heap in temporary memory. Generally, the size of the heap in temporary
- memory does not exceed 64K, so the biggest pool size could be allocated is
- 64K.
-
- @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
- @param Size Amount of memory required
- @param Buffer Address of pointer to the buffer
-
- @retval EFI_SUCCESS The allocation was successful
- @retval EFI_OUT_OF_RESOURCES There is not enough heap to satisfy the requirement
- to allocate the requested size.
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestAllocatePool (
- IN CONST EFI_PEI_SERVICES **PeiServices,
- IN UINTN Size,
- OUT VOID **Buffer
- );
-
-/**
-
- Core version of the Status Code reporter
-
-
- @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
- @param CodeType Type of Status Code.
- @param Value Value to output for Status Code.
- @param Instance Instance Number of this status code.
- @param CallerId ID of the caller of this status code.
- @param Data Optional data associated with this status code.
-
- @retval EFI_SUCCESS if status code is successfully reported
- @retval EFI_NOT_AVAILABLE_YET if StatusCodePpi has not been installed
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestReportStatusCode (
- IN CONST EFI_PEI_SERVICES **PeiServices,
- IN EFI_STATUS_CODE_TYPE CodeType,
- IN EFI_STATUS_CODE_VALUE Value,
- IN UINT32 Instance,
- IN CONST EFI_GUID *CallerId,
- IN CONST EFI_STATUS_CODE_DATA *Data OPTIONAL
- );
-
-/**
-
-Core version of the Reset System
-
-
-@param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
-
-@retval EFI_NOT_AVAILABLE_YET PPI not available yet.
-@retval EFI_DEVICE_ERROR Did not reset system.
- Otherwise, resets the system.
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestResetSystem (
- IN CONST EFI_PEI_SERVICES **PeiServices
- );
-
-/**
- Find a file within a volume by its name.
-
- @param FileName A pointer to the name of the file to find within the firmware volume.
- @param VolumeHandle The firmware volume to search
- @param FileHandle Upon exit, points to the found file's handle
- or NULL if it could not be found.
-
- @retval EFI_SUCCESS File was found.
- @retval EFI_NOT_FOUND File was not found.
- @retval EFI_INVALID_PARAMETER VolumeHandle or FileHandle or FileName was NULL.
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestFfsFindFileByName (
- IN CONST EFI_GUID *FileName,
- IN EFI_PEI_FV_HANDLE VolumeHandle,
- OUT EFI_PEI_FILE_HANDLE *FileHandle
- );
-
-/**
- Returns information about a specific file.
-
- @param FileHandle Handle of the file.
- @param FileInfo Upon exit, points to the file's information.
-
- @retval EFI_INVALID_PARAMETER If FileInfo is NULL.
- @retval EFI_INVALID_PARAMETER If FileHandle does not represent a valid file.
- @retval EFI_SUCCESS File information returned.
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestFfsGetFileInfo (
- IN EFI_PEI_FILE_HANDLE FileHandle,
- OUT EFI_FV_FILE_INFO *FileInfo
- );
-
-/**
- Returns information about the specified volume.
-
- This function returns information about a specific firmware
- volume, including its name, type, attributes, starting address
- and size.
-
- @param VolumeHandle Handle of the volume.
- @param VolumeInfo Upon exit, points to the volume's information.
-
- @retval EFI_SUCCESS Volume information returned.
- @retval EFI_INVALID_PARAMETER If VolumeHandle does not represent a valid volume.
- @retval EFI_INVALID_PARAMETER If VolumeHandle is NULL.
- @retval EFI_SUCCESS Information successfully returned.
- @retval EFI_INVALID_PARAMETER The volume designated by the VolumeHandle is not available.
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestFfsGetVolumeInfo (
- IN EFI_PEI_FV_HANDLE VolumeHandle,
- OUT EFI_FV_INFO *VolumeInfo
- );
-
-/**
-This routine enables a PEIM to register itself for shadow when the PEI Foundation
-discovers permanent memory.
-
-@param FileHandle File handle of a PEIM.
-
-@retval EFI_NOT_FOUND The file handle doesn't point to PEIM itself.
-@retval EFI_ALREADY_STARTED Indicate that the PEIM has been registered itself.
-@retval EFI_SUCCESS Successfully to register itself.
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestRegisterForShadow (
- IN EFI_PEI_FILE_HANDLE FileHandle
- );
-
-/**
-Searches for the next matching section within the specified file.
-
-@param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
-@param SectionType The value of the section type to find.
-@param SectionInstance Section instance to find.
-@param FileHandle Handle of the firmware file to search.
-@param SectionData A pointer to the discovered section, if successful.
-@param AuthenticationStatus A pointer to the authentication status for this section.
-
-@retval EFI_SUCCESS The section was found.
-@retval EFI_NOT_FOUND The section was not found.
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestFfsFindSectionData3 (
- IN CONST EFI_PEI_SERVICES **PeiServices,
- IN EFI_SECTION_TYPE SectionType,
- IN UINTN SectionInstance,
- IN EFI_PEI_FILE_HANDLE FileHandle,
- OUT VOID **SectionData,
- OUT UINT32 *AuthenticationStatus
- );
-
-/**
-Returns information about a specific file.
-
-@param FileHandle Handle of the file.
-@param FileInfo Upon exit, points to the file's information.
-
-@retval EFI_INVALID_PARAMETER If FileInfo is NULL.
-@retval EFI_INVALID_PARAMETER If FileHandle does not represent a valid file.
-@retval EFI_SUCCESS File information returned.
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestFfsGetFileInfo2 (
- IN EFI_PEI_FILE_HANDLE FileHandle,
- OUT EFI_FV_FILE_INFO2 *FileInfo
- );
-
-/**
-Frees memory pages.
-
-@param[in] PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
-@param[in] Memory The base physical address of the pages to be freed.
-@param[in] Pages The number of contiguous 4 KB pages to free.
-
-@retval EFI_SUCCESS The requested pages were freed.
-@retval EFI_INVALID_PARAMETER Memory is not a page-aligned address or Pages is invalid.
-@retval EFI_NOT_FOUND The requested memory pages were not allocated with
- AllocatePages().
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestFreePages (
- IN CONST EFI_PEI_SERVICES **PeiServices,
- IN EFI_PHYSICAL_ADDRESS Memory,
- IN UINTN Pages
- );
-
-#endif
+/** @file + An internal header file for the Unit Test instance of the PEI services Table Pointer Library. + + Copyright (c) 2023, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef PEI_SERVICES_TABLE_POINTER_LIB_UNIT_TEST_H_ +#define PEI_SERVICES_TABLE_POINTER_LIB_UNIT_TEST_H_ + +#include <Base.h> +#include <PiPei.h> +#include <Pi/PiMultiPhase.h> +#include <Library/BaseLib.h> +#include <Library/BaseMemoryLib.h> +#include <Library/DebugLib.h> +#include <Library/UnitTestLib.h> +#include <Library/PeiServicesTablePointerLib.h> +#include <Uefi.h> + +#define MAX_PPI_COUNT 100 +#define MAX_HOB_SIZE SIZE_32MB + +/// +/// Forward declaration for PEI_CORE_INSTANCE +/// +typedef struct _PEI_CORE_INSTANCE PEI_CORE_INSTANCE; + +/// +/// Pei Core private data structures +/// +typedef union { + EFI_PEI_PPI_DESCRIPTOR *Ppi; + EFI_PEI_NOTIFY_DESCRIPTOR *Notify; + VOID *Raw; +} PEI_PPI_LIST_POINTERS; + +typedef struct { + UINTN CurrentCount; + UINTN MaxCount; + UINTN LastDispatchedCount; + /// + /// MaxCount number of entries. + /// + PEI_PPI_LIST_POINTERS PpiPtrs[MAX_PPI_COUNT]; +} PEI_PPI_LIST; + +typedef struct { + UINTN CurrentCount; + UINTN MaxCount; + /// + /// MaxCount number of entries. + /// + PEI_PPI_LIST_POINTERS NotifyPtrs[MAX_PPI_COUNT]; +} PEI_CALLBACK_NOTIFY_LIST; + +typedef struct { + UINTN CurrentCount; + UINTN MaxCount; + UINTN LastDispatchedCount; + /// + /// MaxCount number of entries. + /// + PEI_PPI_LIST_POINTERS NotifyPtrs[MAX_PPI_COUNT]; +} PEI_DISPATCH_NOTIFY_LIST; + +/// +/// PPI database structure which contains three links: +/// PpiList, CallbackNotifyList and DispatchNotifyList. +/// +typedef struct { + /// + /// PPI List. + /// + PEI_PPI_LIST PpiList; + /// + /// Notify List at dispatch level. + /// + PEI_CALLBACK_NOTIFY_LIST CallbackNotifyList; + /// + /// Notify List at callback level. + /// + PEI_DISPATCH_NOTIFY_LIST DispatchNotifyList; +} PEI_PPI_DATABASE; + +/// +/// Pei Core private data structure instance +/// +struct _PEI_CORE_INSTANCE { + PEI_PPI_DATABASE PpiData; + EFI_PEI_HOB_POINTERS HobList; +}; + +extern PEI_CORE_INSTANCE mPrivateData; +#define PEI_CORE_INSTANCE_FROM_PS_THIS(a) &mPrivateData + +VOID +ProcessNotify ( + IN PEI_CORE_INSTANCE *PrivateData, + IN UINTN NotifyType, + IN INTN InstallStartIndex, + IN INTN InstallStopIndex, + IN INTN NotifyStartIndex, + IN INTN NotifyStopIndex + ); + +/** + + This function installs an interface in the PEI PPI database by GUID. + The purpose of the service is to publish an interface that other parties + can use to call additional PEIMs. + + @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation. + @param PpiList Pointer to a list of PEI PPI Descriptors. + + @retval EFI_SUCCESS if all PPIs in PpiList are successfully installed. + @retval EFI_INVALID_PARAMETER if PpiList is NULL pointer + if any PPI in PpiList is not valid + @retval EFI_OUT_OF_RESOURCES if there is no more memory resource to install PPI + +**/ +EFI_STATUS +EFIAPI +UnitTestInstallPpi ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN CONST EFI_PEI_PPI_DESCRIPTOR *PpiList + ); + +/** + + This function reinstalls an interface in the PEI PPI database by GUID. + The purpose of the service is to publish an interface that other parties can + use to replace an interface of the same name in the protocol database with a + different interface. + + @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation. + @param OldPpi Pointer to the old PEI PPI Descriptors. + @param NewPpi Pointer to the new PEI PPI Descriptors. + + @retval EFI_SUCCESS if the operation was successful + @retval EFI_INVALID_PARAMETER if OldPpi or NewPpi is NULL + @retval EFI_INVALID_PARAMETER if NewPpi is not valid + @retval EFI_NOT_FOUND if the PPI was not in the database + +**/ +EFI_STATUS +EFIAPI +UnitTestReInstallPpi ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN CONST EFI_PEI_PPI_DESCRIPTOR *OldPpi, + IN CONST EFI_PEI_PPI_DESCRIPTOR *NewPpi + ); + +/** + + Locate a given named PPI. + + + @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation. + @param Guid Pointer to GUID of the PPI. + @param Instance Instance Number to discover. + @param PpiDescriptor Pointer to reference the found descriptor. If not NULL, + returns a pointer to the descriptor (includes flags, etc) + @param Ppi Pointer to reference the found PPI + + @retval EFI_SUCCESS if the PPI is in the database + @retval EFI_NOT_FOUND if the PPI is not in the database + +**/ +EFI_STATUS +EFIAPI +UnitTestLocatePpi ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN CONST EFI_GUID *Guid, + IN UINTN Instance, + IN OUT EFI_PEI_PPI_DESCRIPTOR **PpiDescriptor, + IN OUT VOID **Ppi + ); + +/** + + This function installs a notification service to be called back when a given + interface is installed or reinstalled. The purpose of the service is to publish + an interface that other parties can use to call additional PPIs that may materialize later. + + @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation. + @param NotifyList Pointer to list of Descriptors to notify upon. + + @retval EFI_SUCCESS if successful + @retval EFI_OUT_OF_RESOURCES if no space in the database + @retval EFI_INVALID_PARAMETER if not a good descriptor + +**/ +EFI_STATUS +EFIAPI +UnitTestNotifyPpi ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN CONST EFI_PEI_NOTIFY_DESCRIPTOR *NotifyList + ); + +/** + Gets the pointer to the HOB List. + + @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation. + @param HobList Pointer to the HOB List. + + @retval EFI_SUCCESS Get the pointer of HOB List + @retval EFI_NOT_AVAILABLE_YET the HOB List is not yet published + @retval EFI_INVALID_PARAMETER HobList is NULL (in debug mode) + +**/ +EFI_STATUS +EFIAPI +UnitTestGetHobList ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN OUT VOID **HobList + ); + +/** + Add a new HOB to the HOB List. + + @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation. + @param Type Type of the new HOB. + @param Length Length of the new HOB to allocate. + @param Hob Pointer to the new HOB. + + @return EFI_SUCCESS Success to create HOB. + @retval EFI_INVALID_PARAMETER if Hob is NULL + @retval EFI_NOT_AVAILABLE_YET if HobList is still not available. + @retval EFI_OUT_OF_RESOURCES if there is no more memory to grow the Hoblist. + +**/ +EFI_STATUS +EFIAPI +UnitTestCreateHob ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN UINT16 Type, + IN UINT16 Length, + IN OUT VOID **Hob + ); + +/** + + Builds a Handoff Information Table HOB + + @param BootMode - Current Bootmode + @param MemoryBegin - Start Memory Address. + @param MemoryLength - Length of Memory. + + @return EFI_SUCCESS Always success to initialize HOB. + +**/ +EFI_STATUS +UnitTestCoreBuildHobHandoffInfoTable ( + IN EFI_BOOT_MODE BootMode, + IN EFI_PHYSICAL_ADDRESS MemoryBegin, + IN UINT64 MemoryLength + ); + +/** + Resets the entire platform. + + @param[in] ResetType The type of reset to perform. + @param[in] ResetStatus The status code for the reset. + @param[in] DataSize The size, in bytes, of ResetData. + @param[in] ResetData For a ResetType of EfiResetCold, EfiResetWarm, or EfiResetShutdown + the data buffer starts with a Null-terminated string, optionally + followed by additional binary data. The string is a description + that the caller may use to further indicate the reason for the + system reset. + +**/ +VOID +EFIAPI +UnitTestResetSystem2 ( + IN EFI_RESET_TYPE ResetType, + IN EFI_STATUS ResetStatus, + IN UINTN DataSize, + IN VOID *ResetData OPTIONAL + ); + +/** + This service enables PEIMs to ascertain the present value of the boot mode. + + @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation. + @param BootMode A pointer to contain the value of the boot mode. + + @retval EFI_SUCCESS The boot mode was returned successfully. + @retval EFI_INVALID_PARAMETER BootMode is NULL. + +**/ +EFI_STATUS +EFIAPI +UnitTestGetBootMode ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN OUT EFI_BOOT_MODE *BootMode + ); + +/** + This service enables PEIMs to update the boot mode variable. + + + @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation. + @param BootMode The value of the boot mode to set. + + @return EFI_SUCCESS The value was successfully updated + +**/ +EFI_STATUS +EFIAPI +UnitTestSetBootMode ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN EFI_BOOT_MODE BootMode + ); + +/** + Search the firmware volumes by index + + @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation + @param Instance This instance of the firmware volume to find. The value 0 is the Boot Firmware + Volume (BFV). + @param VolumeHandle On exit, points to the next volume handle or NULL if it does not exist. + + @retval EFI_INVALID_PARAMETER VolumeHandle is NULL + @retval EFI_NOT_FOUND The volume was not found. + @retval EFI_SUCCESS The volume was found. + +**/ +EFI_STATUS +EFIAPI +UnitTestFfsFindNextVolume ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN UINTN Instance, + IN OUT EFI_PEI_FV_HANDLE *VolumeHandle + ); + +/** + Searches for the next matching file in the firmware volume. + + @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation. + @param SearchType Filter to find only files of this type. + Type EFI_FV_FILETYPE_ALL causes no filtering to be done. + @param FvHandle Handle of firmware volume in which to search. + @param FileHandle On entry, points to the current handle from which to begin searching or NULL to start + at the beginning of the firmware volume. On exit, points the file handle of the next file + in the volume or NULL if there are no more files. + + @retval EFI_NOT_FOUND The file was not found. + @retval EFI_NOT_FOUND The header checksum was not zero. + @retval EFI_SUCCESS The file was found. + +**/ +EFI_STATUS +EFIAPI +UnitTestFfsFindNextFile ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN UINT8 SearchType, + IN EFI_PEI_FV_HANDLE FvHandle, + IN OUT EFI_PEI_FILE_HANDLE *FileHandle + ); + +/** + Searches for the next matching section within the specified file. + + @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation + @param SectionType Filter to find only sections of this type. + @param FileHandle Pointer to the current file to search. + @param SectionData A pointer to the discovered section, if successful. + NULL if section not found + + @retval EFI_NOT_FOUND The section was not found. + @retval EFI_SUCCESS The section was found. + +**/ +EFI_STATUS +EFIAPI +UnitTestFfsFindSectionData ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN EFI_SECTION_TYPE SectionType, + IN EFI_PEI_FILE_HANDLE FileHandle, + OUT VOID **SectionData + ); + +/** + + This function registers the found memory configuration with the PEI Foundation. + + The usage model is that the PEIM that discovers the permanent memory shall invoke this service. + This routine will hold discoveried memory information into PeiCore's private data, + and set SwitchStackSignal flag. After PEIM who discovery memory is dispatched, + PeiDispatcher will migrate temporary memory to permanent memory. + + @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation. + @param MemoryBegin Start of memory address. + @param MemoryLength Length of memory. + + @return EFI_SUCCESS Always success. + +**/ +EFI_STATUS +EFIAPI +UnitTestInstallPeiMemory ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN EFI_PHYSICAL_ADDRESS MemoryBegin, + IN UINT64 MemoryLength + ); + +/** + The purpose of the service is to publish an interface that allows + PEIMs to allocate memory ranges that are managed by the PEI Foundation. + + Prior to InstallPeiMemory() being called, PEI will allocate pages from the heap. + After InstallPeiMemory() is called, PEI will allocate pages within the region + of memory provided by InstallPeiMemory() service in a best-effort fashion. + Location-specific allocations are not managed by the PEI foundation code. + + @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation. + @param MemoryType The type of memory to allocate. + @param Pages The number of contiguous 4 KB pages to allocate. + @param Memory Pointer to a physical address. On output, the address is set to the base + of the page range that was allocated. + + @retval EFI_SUCCESS The memory range was successfully allocated. + @retval EFI_OUT_OF_RESOURCES The pages could not be allocated. + @retval EFI_INVALID_PARAMETER Type is not equal to EfiLoaderCode, EfiLoaderData, EfiRuntimeServicesCode, + EfiRuntimeServicesData, EfiBootServicesCode, EfiBootServicesData, + EfiACPIReclaimMemory, EfiReservedMemoryType, or EfiACPIMemoryNVS. + +**/ +EFI_STATUS +EFIAPI +UnitTestAllocatePages ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN EFI_MEMORY_TYPE MemoryType, + IN UINTN Pages, + OUT EFI_PHYSICAL_ADDRESS *Memory + ); + +/** + + Pool allocation service. Before permanent memory is discovered, the pool will + be allocated in the heap in temporary memory. Generally, the size of the heap in temporary + memory does not exceed 64K, so the biggest pool size could be allocated is + 64K. + + @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation. + @param Size Amount of memory required + @param Buffer Address of pointer to the buffer + + @retval EFI_SUCCESS The allocation was successful + @retval EFI_OUT_OF_RESOURCES There is not enough heap to satisfy the requirement + to allocate the requested size. + +**/ +EFI_STATUS +EFIAPI +UnitTestAllocatePool ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN UINTN Size, + OUT VOID **Buffer + ); + +/** + + Core version of the Status Code reporter + + + @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation. + @param CodeType Type of Status Code. + @param Value Value to output for Status Code. + @param Instance Instance Number of this status code. + @param CallerId ID of the caller of this status code. + @param Data Optional data associated with this status code. + + @retval EFI_SUCCESS if status code is successfully reported + @retval EFI_NOT_AVAILABLE_YET if StatusCodePpi has not been installed + +**/ +EFI_STATUS +EFIAPI +UnitTestReportStatusCode ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN EFI_STATUS_CODE_TYPE CodeType, + IN EFI_STATUS_CODE_VALUE Value, + IN UINT32 Instance, + IN CONST EFI_GUID *CallerId, + IN CONST EFI_STATUS_CODE_DATA *Data OPTIONAL + ); + +/** + +Core version of the Reset System + + +@param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation. + +@retval EFI_NOT_AVAILABLE_YET PPI not available yet. +@retval EFI_DEVICE_ERROR Did not reset system. + Otherwise, resets the system. + +**/ +EFI_STATUS +EFIAPI +UnitTestResetSystem ( + IN CONST EFI_PEI_SERVICES **PeiServices + ); + +/** + Find a file within a volume by its name. + + @param FileName A pointer to the name of the file to find within the firmware volume. + @param VolumeHandle The firmware volume to search + @param FileHandle Upon exit, points to the found file's handle + or NULL if it could not be found. + + @retval EFI_SUCCESS File was found. + @retval EFI_NOT_FOUND File was not found. + @retval EFI_INVALID_PARAMETER VolumeHandle or FileHandle or FileName was NULL. + +**/ +EFI_STATUS +EFIAPI +UnitTestFfsFindFileByName ( + IN CONST EFI_GUID *FileName, + IN EFI_PEI_FV_HANDLE VolumeHandle, + OUT EFI_PEI_FILE_HANDLE *FileHandle + ); + +/** + Returns information about a specific file. + + @param FileHandle Handle of the file. + @param FileInfo Upon exit, points to the file's information. + + @retval EFI_INVALID_PARAMETER If FileInfo is NULL. + @retval EFI_INVALID_PARAMETER If FileHandle does not represent a valid file. + @retval EFI_SUCCESS File information returned. + +**/ +EFI_STATUS +EFIAPI +UnitTestFfsGetFileInfo ( + IN EFI_PEI_FILE_HANDLE FileHandle, + OUT EFI_FV_FILE_INFO *FileInfo + ); + +/** + Returns information about the specified volume. + + This function returns information about a specific firmware + volume, including its name, type, attributes, starting address + and size. + + @param VolumeHandle Handle of the volume. + @param VolumeInfo Upon exit, points to the volume's information. + + @retval EFI_SUCCESS Volume information returned. + @retval EFI_INVALID_PARAMETER If VolumeHandle does not represent a valid volume. + @retval EFI_INVALID_PARAMETER If VolumeHandle is NULL. + @retval EFI_SUCCESS Information successfully returned. + @retval EFI_INVALID_PARAMETER The volume designated by the VolumeHandle is not available. + +**/ +EFI_STATUS +EFIAPI +UnitTestFfsGetVolumeInfo ( + IN EFI_PEI_FV_HANDLE VolumeHandle, + OUT EFI_FV_INFO *VolumeInfo + ); + +/** +This routine enables a PEIM to register itself for shadow when the PEI Foundation +discovers permanent memory. + +@param FileHandle File handle of a PEIM. + +@retval EFI_NOT_FOUND The file handle doesn't point to PEIM itself. +@retval EFI_ALREADY_STARTED Indicate that the PEIM has been registered itself. +@retval EFI_SUCCESS Successfully to register itself. + +**/ +EFI_STATUS +EFIAPI +UnitTestRegisterForShadow ( + IN EFI_PEI_FILE_HANDLE FileHandle + ); + +/** +Searches for the next matching section within the specified file. + +@param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation. +@param SectionType The value of the section type to find. +@param SectionInstance Section instance to find. +@param FileHandle Handle of the firmware file to search. +@param SectionData A pointer to the discovered section, if successful. +@param AuthenticationStatus A pointer to the authentication status for this section. + +@retval EFI_SUCCESS The section was found. +@retval EFI_NOT_FOUND The section was not found. + +**/ +EFI_STATUS +EFIAPI +UnitTestFfsFindSectionData3 ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN EFI_SECTION_TYPE SectionType, + IN UINTN SectionInstance, + IN EFI_PEI_FILE_HANDLE FileHandle, + OUT VOID **SectionData, + OUT UINT32 *AuthenticationStatus + ); + +/** +Returns information about a specific file. + +@param FileHandle Handle of the file. +@param FileInfo Upon exit, points to the file's information. + +@retval EFI_INVALID_PARAMETER If FileInfo is NULL. +@retval EFI_INVALID_PARAMETER If FileHandle does not represent a valid file. +@retval EFI_SUCCESS File information returned. + +**/ +EFI_STATUS +EFIAPI +UnitTestFfsGetFileInfo2 ( + IN EFI_PEI_FILE_HANDLE FileHandle, + OUT EFI_FV_FILE_INFO2 *FileInfo + ); + +/** +Frees memory pages. + +@param[in] PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation. +@param[in] Memory The base physical address of the pages to be freed. +@param[in] Pages The number of contiguous 4 KB pages to free. + +@retval EFI_SUCCESS The requested pages were freed. +@retval EFI_INVALID_PARAMETER Memory is not a page-aligned address or Pages is invalid. +@retval EFI_NOT_FOUND The requested memory pages were not allocated with + AllocatePages(). + +**/ +EFI_STATUS +EFIAPI +UnitTestFreePages ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN EFI_PHYSICAL_ADDRESS Memory, + IN UINTN Pages + ); + +#endif diff --git a/UnitTestFrameworkPkg/Library/UnitTestPeiServicesTablePointerLib/UnitTestPeiServicesTablePointerLib.inf b/UnitTestFrameworkPkg/Library/UnitTestPeiServicesTablePointerLib/UnitTestPeiServicesTablePointerLib.inf index 59d86c9db8..0b183f686f 100644 --- a/UnitTestFrameworkPkg/Library/UnitTestPeiServicesTablePointerLib/UnitTestPeiServicesTablePointerLib.inf +++ b/UnitTestFrameworkPkg/Library/UnitTestPeiServicesTablePointerLib/UnitTestPeiServicesTablePointerLib.inf @@ -1,37 +1,37 @@ -## @file
-# Pei Services Table Pointer Lib for unit tests implementation.
-#
-# Copyright (c) 2023, Intel Corporation. All rights reserved.<BR>
-# SPDX-License-Identifier: BSD-2-Clause-Patent
-#
-##
-
-[Defines]
- INF_VERSION = 0x00010005
- BASE_NAME = UnitTestPeiServicesTablePointerLib
- MODULE_UNI_FILE = UnitTestPeiServicesTablePointerLib.uni
- FILE_GUID = 55F23CD2-9BB1-41EE-AB10-550B638210E1
- MODULE_TYPE = BASE
- VERSION_STRING = 1.0
- LIBRARY_CLASS = PeiServicesTablePointerLib
-
- CONSTRUCTOR = UnitTestPeiServicesTablePointerLibConstructor
-#
-# VALID_ARCHITECTURES = IA32 X64 EBC
-#
-
-[Sources]
- UnitTestPeiServicesTablePointerLib.h
- UnitTestPeiServicesTablePointerLib.c
- UnitTestPeiServicesTablePointerLibMisc.c
- UnitTestPeiServicesTablePointerLibPpi.c
- UnitTestPeiServicesTablePointerLibHob.c
-
-[Packages]
- MdePkg/MdePkg.dec
-
-[LibraryClasses]
- BaseLib
- BaseMemoryLib
- DebugLib
- UnitTestLib
+## @file +# Pei Services Table Pointer Lib for unit tests implementation. +# +# Copyright (c) 2023, Intel Corporation. All rights reserved.<BR> +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = UnitTestPeiServicesTablePointerLib + MODULE_UNI_FILE = UnitTestPeiServicesTablePointerLib.uni + FILE_GUID = 55F23CD2-9BB1-41EE-AB10-550B638210E1 + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = PeiServicesTablePointerLib + + CONSTRUCTOR = UnitTestPeiServicesTablePointerLibConstructor +# +# VALID_ARCHITECTURES = IA32 X64 EBC +# + +[Sources] + UnitTestPeiServicesTablePointerLib.h + UnitTestPeiServicesTablePointerLib.c + UnitTestPeiServicesTablePointerLibMisc.c + UnitTestPeiServicesTablePointerLibPpi.c + UnitTestPeiServicesTablePointerLibHob.c + +[Packages] + MdePkg/MdePkg.dec + +[LibraryClasses] + BaseLib + BaseMemoryLib + DebugLib + UnitTestLib diff --git a/UnitTestFrameworkPkg/Library/UnitTestPeiServicesTablePointerLib/UnitTestPeiServicesTablePointerLib.uni b/UnitTestFrameworkPkg/Library/UnitTestPeiServicesTablePointerLib/UnitTestPeiServicesTablePointerLib.uni index ca2118533a..edea68ca1f 100644 --- a/UnitTestFrameworkPkg/Library/UnitTestPeiServicesTablePointerLib/UnitTestPeiServicesTablePointerLib.uni +++ b/UnitTestFrameworkPkg/Library/UnitTestPeiServicesTablePointerLib/UnitTestPeiServicesTablePointerLib.uni @@ -1,12 +1,12 @@ -// /** @file
-// Pei Services Table Pointer Lib for unit tests implementation.
-//
-// Copyright (c) 2023, Intel Corporation. All rights reserved.<BR>
-//
-// SPDX-License-Identifier: BSD-2-Clause-Patent
-//
-// **/
-
-#string STR_MODULE_ABSTRACT #language en-US "Pei Services Table Pointer Lib for unit tests."
-
-#string STR_MODULE_DESCRIPTION #language en-US "Pei Services Table Pointer Lib for unit tests."
+// /** @file +// Pei Services Table Pointer Lib for unit tests implementation. +// +// Copyright (c) 2023, Intel Corporation. All rights reserved.<BR> +// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + +#string STR_MODULE_ABSTRACT #language en-US "Pei Services Table Pointer Lib for unit tests." + +#string STR_MODULE_DESCRIPTION #language en-US "Pei Services Table Pointer Lib for unit tests." diff --git a/UnitTestFrameworkPkg/Library/UnitTestPeiServicesTablePointerLib/UnitTestPeiServicesTablePointerLibHob.c b/UnitTestFrameworkPkg/Library/UnitTestPeiServicesTablePointerLib/UnitTestPeiServicesTablePointerLibHob.c index 1a5a1bef1f..aa48a37d85 100644 --- a/UnitTestFrameworkPkg/Library/UnitTestPeiServicesTablePointerLib/UnitTestPeiServicesTablePointerLibHob.c +++ b/UnitTestFrameworkPkg/Library/UnitTestPeiServicesTablePointerLib/UnitTestPeiServicesTablePointerLibHob.c @@ -1,155 +1,155 @@ -/** @file
- This file implements some PEI services about Hob.
-
- Copyright (c) 2023, Intel Corporation. All rights reserved.<BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#include "UnitTestPeiServicesTablePointerLib.h"
-
-/**
-
- Gets the pointer to the HOB List.
-
- @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
- @param HobList Pointer to the HOB List.
-
- @retval EFI_SUCCESS Get the pointer of HOB List
- @retval EFI_NOT_AVAILABLE_YET the HOB List is not yet published
- @retval EFI_INVALID_PARAMETER HobList is NULL (in debug mode)
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestGetHobList (
- IN CONST EFI_PEI_SERVICES **PeiServices,
- IN OUT VOID **HobList
- )
-{
- PEI_CORE_INSTANCE *PrivateData;
-
- if (HobList == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);
-
- *HobList = PrivateData->HobList.Raw;
-
- return EFI_SUCCESS;
-}
-
-/**
- Add a new HOB to the HOB List.
-
- @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
- @param Type Type of the new HOB.
- @param Length Length of the new HOB to allocate.
- @param Hob Pointer to the new HOB.
-
- @return EFI_SUCCESS Success to create HOB.
- @retval EFI_INVALID_PARAMETER if Hob is NULL
- @retval EFI_NOT_AVAILABLE_YET if HobList is still not available.
- @retval EFI_OUT_OF_RESOURCES if there is no more memory to grow the Hoblist.
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestCreateHob (
- IN CONST EFI_PEI_SERVICES **PeiServices,
- IN UINT16 Type,
- IN UINT16 Length,
- IN OUT VOID **Hob
- )
-{
- EFI_STATUS Status;
- EFI_HOB_HANDOFF_INFO_TABLE *HandOffHob;
- EFI_HOB_GENERIC_HEADER *HobEnd;
- EFI_PHYSICAL_ADDRESS FreeMemory;
-
- Status = UnitTestGetHobList (PeiServices, Hob);
- if (EFI_ERROR (Status)) {
- return Status;
- }
-
- HandOffHob = *Hob;
-
- //
- // Check Length to avoid data overflow.
- //
- if (0x10000 - Length <= 0x7) {
- return EFI_INVALID_PARAMETER;
- }
-
- Length = (UINT16)((Length + 0x7) & (~0x7));
-
- FreeMemory = HandOffHob->EfiFreeMemoryTop -
- HandOffHob->EfiFreeMemoryBottom;
-
- if (FreeMemory < Length) {
- DEBUG ((DEBUG_ERROR, "PeiCreateHob fail: Length - 0x%08x\n", (UINTN)Length));
- DEBUG ((DEBUG_ERROR, " FreeMemoryTop - 0x%08x\n", (UINTN)HandOffHob->EfiFreeMemoryTop));
- DEBUG ((DEBUG_ERROR, " FreeMemoryBottom - 0x%08x\n", (UINTN)HandOffHob->EfiFreeMemoryBottom));
- return EFI_OUT_OF_RESOURCES;
- }
-
- *Hob = (VOID *)(UINTN)HandOffHob->EfiEndOfHobList;
- ((EFI_HOB_GENERIC_HEADER *)*Hob)->HobType = Type;
- ((EFI_HOB_GENERIC_HEADER *)*Hob)->HobLength = Length;
- ((EFI_HOB_GENERIC_HEADER *)*Hob)->Reserved = 0;
-
- HobEnd = (EFI_HOB_GENERIC_HEADER *)((UINTN)*Hob + Length);
- HandOffHob->EfiEndOfHobList = (EFI_PHYSICAL_ADDRESS)(UINTN)HobEnd;
-
- HobEnd->HobType = EFI_HOB_TYPE_END_OF_HOB_LIST;
- HobEnd->HobLength = (UINT16)sizeof (EFI_HOB_GENERIC_HEADER);
- HobEnd->Reserved = 0;
- HobEnd++;
- HandOffHob->EfiFreeMemoryBottom = (EFI_PHYSICAL_ADDRESS)(UINTN)HobEnd;
-
- return EFI_SUCCESS;
-}
-
-/**
-
- Builds a Handoff Information Table HOB
-
- @param BootMode - Current Bootmode
- @param MemoryBegin - Start Memory Address.
- @param MemoryLength - Length of Memory.
-
- @return EFI_SUCCESS Always success to initialize HOB.
-
-**/
-EFI_STATUS
-UnitTestCoreBuildHobHandoffInfoTable (
- IN EFI_BOOT_MODE BootMode,
- IN EFI_PHYSICAL_ADDRESS MemoryBegin,
- IN UINT64 MemoryLength
- )
-{
- EFI_HOB_HANDOFF_INFO_TABLE *Hob;
- EFI_HOB_GENERIC_HEADER *HobEnd;
-
- Hob = (VOID *)(UINTN)MemoryBegin;
- HobEnd = (EFI_HOB_GENERIC_HEADER *)(Hob+1);
- Hob->Header.HobType = EFI_HOB_TYPE_HANDOFF;
- Hob->Header.HobLength = (UINT16)sizeof (EFI_HOB_HANDOFF_INFO_TABLE);
- Hob->Header.Reserved = 0;
-
- HobEnd->HobType = EFI_HOB_TYPE_END_OF_HOB_LIST;
- HobEnd->HobLength = (UINT16)sizeof (EFI_HOB_GENERIC_HEADER);
- HobEnd->Reserved = 0;
-
- Hob->Version = EFI_HOB_HANDOFF_TABLE_VERSION;
- Hob->BootMode = BootMode;
-
- Hob->EfiMemoryTop = MemoryBegin + MemoryLength;
- Hob->EfiMemoryBottom = MemoryBegin;
- Hob->EfiFreeMemoryTop = MemoryBegin + MemoryLength;
- Hob->EfiFreeMemoryBottom = (EFI_PHYSICAL_ADDRESS)(UINTN)(HobEnd + 1);
- Hob->EfiEndOfHobList = (EFI_PHYSICAL_ADDRESS)(UINTN)HobEnd;
-
- return EFI_SUCCESS;
-}
+/** @file + This file implements some PEI services about Hob. + + Copyright (c) 2023, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "UnitTestPeiServicesTablePointerLib.h" + +/** + + Gets the pointer to the HOB List. + + @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation. + @param HobList Pointer to the HOB List. + + @retval EFI_SUCCESS Get the pointer of HOB List + @retval EFI_NOT_AVAILABLE_YET the HOB List is not yet published + @retval EFI_INVALID_PARAMETER HobList is NULL (in debug mode) + +**/ +EFI_STATUS +EFIAPI +UnitTestGetHobList ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN OUT VOID **HobList + ) +{ + PEI_CORE_INSTANCE *PrivateData; + + if (HobList == NULL) { + return EFI_INVALID_PARAMETER; + } + + PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices); + + *HobList = PrivateData->HobList.Raw; + + return EFI_SUCCESS; +} + +/** + Add a new HOB to the HOB List. + + @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation. + @param Type Type of the new HOB. + @param Length Length of the new HOB to allocate. + @param Hob Pointer to the new HOB. + + @return EFI_SUCCESS Success to create HOB. + @retval EFI_INVALID_PARAMETER if Hob is NULL + @retval EFI_NOT_AVAILABLE_YET if HobList is still not available. + @retval EFI_OUT_OF_RESOURCES if there is no more memory to grow the Hoblist. + +**/ +EFI_STATUS +EFIAPI +UnitTestCreateHob ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN UINT16 Type, + IN UINT16 Length, + IN OUT VOID **Hob + ) +{ + EFI_STATUS Status; + EFI_HOB_HANDOFF_INFO_TABLE *HandOffHob; + EFI_HOB_GENERIC_HEADER *HobEnd; + EFI_PHYSICAL_ADDRESS FreeMemory; + + Status = UnitTestGetHobList (PeiServices, Hob); + if (EFI_ERROR (Status)) { + return Status; + } + + HandOffHob = *Hob; + + // + // Check Length to avoid data overflow. + // + if (0x10000 - Length <= 0x7) { + return EFI_INVALID_PARAMETER; + } + + Length = (UINT16)((Length + 0x7) & (~0x7)); + + FreeMemory = HandOffHob->EfiFreeMemoryTop - + HandOffHob->EfiFreeMemoryBottom; + + if (FreeMemory < Length) { + DEBUG ((DEBUG_ERROR, "PeiCreateHob fail: Length - 0x%08x\n", (UINTN)Length)); + DEBUG ((DEBUG_ERROR, " FreeMemoryTop - 0x%08x\n", (UINTN)HandOffHob->EfiFreeMemoryTop)); + DEBUG ((DEBUG_ERROR, " FreeMemoryBottom - 0x%08x\n", (UINTN)HandOffHob->EfiFreeMemoryBottom)); + return EFI_OUT_OF_RESOURCES; + } + + *Hob = (VOID *)(UINTN)HandOffHob->EfiEndOfHobList; + ((EFI_HOB_GENERIC_HEADER *)*Hob)->HobType = Type; + ((EFI_HOB_GENERIC_HEADER *)*Hob)->HobLength = Length; + ((EFI_HOB_GENERIC_HEADER *)*Hob)->Reserved = 0; + + HobEnd = (EFI_HOB_GENERIC_HEADER *)((UINTN)*Hob + Length); + HandOffHob->EfiEndOfHobList = (EFI_PHYSICAL_ADDRESS)(UINTN)HobEnd; + + HobEnd->HobType = EFI_HOB_TYPE_END_OF_HOB_LIST; + HobEnd->HobLength = (UINT16)sizeof (EFI_HOB_GENERIC_HEADER); + HobEnd->Reserved = 0; + HobEnd++; + HandOffHob->EfiFreeMemoryBottom = (EFI_PHYSICAL_ADDRESS)(UINTN)HobEnd; + + return EFI_SUCCESS; +} + +/** + + Builds a Handoff Information Table HOB + + @param BootMode - Current Bootmode + @param MemoryBegin - Start Memory Address. + @param MemoryLength - Length of Memory. + + @return EFI_SUCCESS Always success to initialize HOB. + +**/ +EFI_STATUS +UnitTestCoreBuildHobHandoffInfoTable ( + IN EFI_BOOT_MODE BootMode, + IN EFI_PHYSICAL_ADDRESS MemoryBegin, + IN UINT64 MemoryLength + ) +{ + EFI_HOB_HANDOFF_INFO_TABLE *Hob; + EFI_HOB_GENERIC_HEADER *HobEnd; + + Hob = (VOID *)(UINTN)MemoryBegin; + HobEnd = (EFI_HOB_GENERIC_HEADER *)(Hob+1); + Hob->Header.HobType = EFI_HOB_TYPE_HANDOFF; + Hob->Header.HobLength = (UINT16)sizeof (EFI_HOB_HANDOFF_INFO_TABLE); + Hob->Header.Reserved = 0; + + HobEnd->HobType = EFI_HOB_TYPE_END_OF_HOB_LIST; + HobEnd->HobLength = (UINT16)sizeof (EFI_HOB_GENERIC_HEADER); + HobEnd->Reserved = 0; + + Hob->Version = EFI_HOB_HANDOFF_TABLE_VERSION; + Hob->BootMode = BootMode; + + Hob->EfiMemoryTop = MemoryBegin + MemoryLength; + Hob->EfiMemoryBottom = MemoryBegin; + Hob->EfiFreeMemoryTop = MemoryBegin + MemoryLength; + Hob->EfiFreeMemoryBottom = (EFI_PHYSICAL_ADDRESS)(UINTN)(HobEnd + 1); + Hob->EfiEndOfHobList = (EFI_PHYSICAL_ADDRESS)(UINTN)HobEnd; + + return EFI_SUCCESS; +} diff --git a/UnitTestFrameworkPkg/Library/UnitTestPeiServicesTablePointerLib/UnitTestPeiServicesTablePointerLibMisc.c b/UnitTestFrameworkPkg/Library/UnitTestPeiServicesTablePointerLib/UnitTestPeiServicesTablePointerLibMisc.c index 90955bf482..6f2b50745c 100644 --- a/UnitTestFrameworkPkg/Library/UnitTestPeiServicesTablePointerLib/UnitTestPeiServicesTablePointerLibMisc.c +++ b/UnitTestFrameworkPkg/Library/UnitTestPeiServicesTablePointerLib/UnitTestPeiServicesTablePointerLibMisc.c @@ -1,430 +1,430 @@ -/** @file
- This file implements some PEI services.
-
- Copyright (c) 2023, Intel Corporation. All rights reserved.<BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#include "UnitTestPeiServicesTablePointerLib.h"
-
-/**
- This service enables PEIMs to ascertain the present value of the boot mode.
-
- @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
- @param BootMode A pointer to contain the value of the boot mode.
-
- @retval EFI_SUCCESS The boot mode was returned successfully.
- @retval EFI_INVALID_PARAMETER BootMode is NULL.
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestGetBootMode (
- IN CONST EFI_PEI_SERVICES **PeiServices,
- IN OUT EFI_BOOT_MODE *BootMode
- )
-{
- return EFI_NOT_AVAILABLE_YET;
-}
-
-/**
- This service enables PEIMs to update the boot mode variable.
-
-
- @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
- @param BootMode The value of the boot mode to set.
-
- @return EFI_SUCCESS The value was successfully updated
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestSetBootMode (
- IN CONST EFI_PEI_SERVICES **PeiServices,
- IN EFI_BOOT_MODE BootMode
- )
-{
- return EFI_NOT_AVAILABLE_YET;
-}
-
-/**
- Search the firmware volumes by index
-
- @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation
- @param Instance This instance of the firmware volume to find. The value 0 is the Boot Firmware
- Volume (BFV).
- @param VolumeHandle On exit, points to the next volume handle or NULL if it does not exist.
-
- @retval EFI_INVALID_PARAMETER VolumeHandle is NULL
- @retval EFI_NOT_FOUND The volume was not found.
- @retval EFI_SUCCESS The volume was found.
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestFfsFindNextVolume (
- IN CONST EFI_PEI_SERVICES **PeiServices,
- IN UINTN Instance,
- IN OUT EFI_PEI_FV_HANDLE *VolumeHandle
- )
-{
- return EFI_NOT_AVAILABLE_YET;
-}
-
-/**
- Searches for the next matching file in the firmware volume.
-
- @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
- @param SearchType Filter to find only files of this type.
- Type EFI_FV_FILETYPE_ALL causes no filtering to be done.
- @param FvHandle Handle of firmware volume in which to search.
- @param FileHandle On entry, points to the current handle from which to begin searching or NULL to start
- at the beginning of the firmware volume. On exit, points the file handle of the next file
- in the volume or NULL if there are no more files.
-
- @retval EFI_NOT_FOUND The file was not found.
- @retval EFI_NOT_FOUND The header checksum was not zero.
- @retval EFI_SUCCESS The file was found.
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestFfsFindNextFile (
- IN CONST EFI_PEI_SERVICES **PeiServices,
- IN UINT8 SearchType,
- IN EFI_PEI_FV_HANDLE FvHandle,
- IN OUT EFI_PEI_FILE_HANDLE *FileHandle
- )
-{
- return EFI_NOT_AVAILABLE_YET;
-}
-
-/**
- Searches for the next matching section within the specified file.
-
- @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation
- @param SectionType Filter to find only sections of this type.
- @param FileHandle Pointer to the current file to search.
- @param SectionData A pointer to the discovered section, if successful.
- NULL if section not found
-
- @retval EFI_NOT_FOUND The section was not found.
- @retval EFI_SUCCESS The section was found.
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestFfsFindSectionData (
- IN CONST EFI_PEI_SERVICES **PeiServices,
- IN EFI_SECTION_TYPE SectionType,
- IN EFI_PEI_FILE_HANDLE FileHandle,
- OUT VOID **SectionData
- )
-{
- return EFI_NOT_AVAILABLE_YET;
-}
-
-/**
-
- This function registers the found memory configuration with the PEI Foundation.
-
- The usage model is that the PEIM that discovers the permanent memory shall invoke this service.
- This routine will hold discoveried memory information into PeiCore's private data,
- and set SwitchStackSignal flag. After PEIM who discovery memory is dispatched,
- PeiDispatcher will migrate temporary memory to permanent memory.
-
- @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
- @param MemoryBegin Start of memory address.
- @param MemoryLength Length of memory.
-
- @return EFI_SUCCESS Always success.
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestInstallPeiMemory (
- IN CONST EFI_PEI_SERVICES **PeiServices,
- IN EFI_PHYSICAL_ADDRESS MemoryBegin,
- IN UINT64 MemoryLength
- )
-{
- return EFI_NOT_AVAILABLE_YET;
-}
-
-/**
- The purpose of the service is to publish an interface that allows
- PEIMs to allocate memory ranges that are managed by the PEI Foundation.
-
- Prior to InstallPeiMemory() being called, PEI will allocate pages from the heap.
- After InstallPeiMemory() is called, PEI will allocate pages within the region
- of memory provided by InstallPeiMemory() service in a best-effort fashion.
- Location-specific allocations are not managed by the PEI foundation code.
-
- @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
- @param MemoryType The type of memory to allocate.
- @param Pages The number of contiguous 4 KB pages to allocate.
- @param Memory Pointer to a physical address. On output, the address is set to the base
- of the page range that was allocated.
-
- @retval EFI_SUCCESS The memory range was successfully allocated.
- @retval EFI_OUT_OF_RESOURCES The pages could not be allocated.
- @retval EFI_INVALID_PARAMETER Type is not equal to EfiLoaderCode, EfiLoaderData, EfiRuntimeServicesCode,
- EfiRuntimeServicesData, EfiBootServicesCode, EfiBootServicesData,
- EfiACPIReclaimMemory, EfiReservedMemoryType, or EfiACPIMemoryNVS.
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestAllocatePages (
- IN CONST EFI_PEI_SERVICES **PeiServices,
- IN EFI_MEMORY_TYPE MemoryType,
- IN UINTN Pages,
- OUT EFI_PHYSICAL_ADDRESS *Memory
- )
-{
- return EFI_NOT_AVAILABLE_YET;
-}
-
-/**
-
- Pool allocation service. Before permanent memory is discovered, the pool will
- be allocated in the heap in temporary memory. Generally, the size of the heap in temporary
- memory does not exceed 64K, so the biggest pool size could be allocated is
- 64K.
-
- @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
- @param Size Amount of memory required
- @param Buffer Address of pointer to the buffer
-
- @retval EFI_SUCCESS The allocation was successful
- @retval EFI_OUT_OF_RESOURCES There is not enough heap to satisfy the requirement
- to allocate the requested size.
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestAllocatePool (
- IN CONST EFI_PEI_SERVICES **PeiServices,
- IN UINTN Size,
- OUT VOID **Buffer
- )
-{
- return EFI_NOT_AVAILABLE_YET;
-}
-
-/**
-
- Core version of the Status Code reporter
-
-
- @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
- @param CodeType Type of Status Code.
- @param Value Value to output for Status Code.
- @param Instance Instance Number of this status code.
- @param CallerId ID of the caller of this status code.
- @param Data Optional data associated with this status code.
-
- @retval EFI_SUCCESS if status code is successfully reported
- @retval EFI_NOT_AVAILABLE_YET if StatusCodePpi has not been installed
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestReportStatusCode (
- IN CONST EFI_PEI_SERVICES **PeiServices,
- IN EFI_STATUS_CODE_TYPE CodeType,
- IN EFI_STATUS_CODE_VALUE Value,
- IN UINT32 Instance,
- IN CONST EFI_GUID *CallerId,
- IN CONST EFI_STATUS_CODE_DATA *Data OPTIONAL
- )
-{
- return EFI_NOT_AVAILABLE_YET;
-}
-
-/**
-
-Core version of the Reset System
-
-
-@param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
-
-@retval EFI_NOT_AVAILABLE_YET PPI not available yet.
-@retval EFI_DEVICE_ERROR Did not reset system.
- Otherwise, resets the system.
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestResetSystem (
- IN CONST EFI_PEI_SERVICES **PeiServices
- )
-{
- return EFI_NOT_AVAILABLE_YET;
-}
-
-/**
- Find a file within a volume by its name.
-
- @param FileName A pointer to the name of the file to find within the firmware volume.
- @param VolumeHandle The firmware volume to search
- @param FileHandle Upon exit, points to the found file's handle
- or NULL if it could not be found.
-
- @retval EFI_SUCCESS File was found.
- @retval EFI_NOT_FOUND File was not found.
- @retval EFI_INVALID_PARAMETER VolumeHandle or FileHandle or FileName was NULL.
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestFfsFindFileByName (
- IN CONST EFI_GUID *FileName,
- IN EFI_PEI_FV_HANDLE VolumeHandle,
- OUT EFI_PEI_FILE_HANDLE *FileHandle
- )
-{
- return EFI_NOT_AVAILABLE_YET;
-}
-
-/**
- Returns information about a specific file.
-
- @param FileHandle Handle of the file.
- @param FileInfo Upon exit, points to the file's information.
-
- @retval EFI_INVALID_PARAMETER If FileInfo is NULL.
- @retval EFI_INVALID_PARAMETER If FileHandle does not represent a valid file.
- @retval EFI_SUCCESS File information returned.
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestFfsGetFileInfo (
- IN EFI_PEI_FILE_HANDLE FileHandle,
- OUT EFI_FV_FILE_INFO *FileInfo
- )
-{
- return EFI_NOT_AVAILABLE_YET;
-}
-
-/**
- Returns information about the specified volume.
-
- This function returns information about a specific firmware
- volume, including its name, type, attributes, starting address
- and size.
-
- @param VolumeHandle Handle of the volume.
- @param VolumeInfo Upon exit, points to the volume's information.
-
- @retval EFI_SUCCESS Volume information returned.
- @retval EFI_INVALID_PARAMETER If VolumeHandle does not represent a valid volume.
- @retval EFI_INVALID_PARAMETER If VolumeHandle is NULL.
- @retval EFI_SUCCESS Information successfully returned.
- @retval EFI_INVALID_PARAMETER The volume designated by the VolumeHandle is not available.
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestFfsGetVolumeInfo (
- IN EFI_PEI_FV_HANDLE VolumeHandle,
- OUT EFI_FV_INFO *VolumeInfo
- )
-{
- return EFI_NOT_AVAILABLE_YET;
-}
-
-/**
-This routine enables a PEIM to register itself for shadow when the PEI Foundation
-discovers permanent memory.
-
-@param FileHandle File handle of a PEIM.
-
-@retval EFI_NOT_FOUND The file handle doesn't point to PEIM itself.
-@retval EFI_ALREADY_STARTED Indicate that the PEIM has been registered itself.
-@retval EFI_SUCCESS Successfully to register itself.
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestRegisterForShadow (
- IN EFI_PEI_FILE_HANDLE FileHandle
- )
-{
- return EFI_NOT_AVAILABLE_YET;
-}
-
-/**
-Searches for the next matching section within the specified file.
-
-@param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
-@param SectionType The value of the section type to find.
-@param SectionInstance Section instance to find.
-@param FileHandle Handle of the firmware file to search.
-@param SectionData A pointer to the discovered section, if successful.
-@param AuthenticationStatus A pointer to the authentication status for this section.
-
-@retval EFI_SUCCESS The section was found.
-@retval EFI_NOT_FOUND The section was not found.
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestFfsFindSectionData3 (
- IN CONST EFI_PEI_SERVICES **PeiServices,
- IN EFI_SECTION_TYPE SectionType,
- IN UINTN SectionInstance,
- IN EFI_PEI_FILE_HANDLE FileHandle,
- OUT VOID **SectionData,
- OUT UINT32 *AuthenticationStatus
- )
-{
- return EFI_NOT_AVAILABLE_YET;
-}
-
-/**
-Returns information about a specific file.
-
-@param FileHandle Handle of the file.
-@param FileInfo Upon exit, points to the file's information.
-
-@retval EFI_INVALID_PARAMETER If FileInfo is NULL.
-@retval EFI_INVALID_PARAMETER If FileHandle does not represent a valid file.
-@retval EFI_SUCCESS File information returned.
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestFfsGetFileInfo2 (
- IN EFI_PEI_FILE_HANDLE FileHandle,
- OUT EFI_FV_FILE_INFO2 *FileInfo
- )
-{
- return EFI_NOT_AVAILABLE_YET;
-}
-
-/**
-Frees memory pages.
-
-@param[in] PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
-@param[in] Memory The base physical address of the pages to be freed.
-@param[in] Pages The number of contiguous 4 KB pages to free.
-
-@retval EFI_SUCCESS The requested pages were freed.
-@retval EFI_INVALID_PARAMETER Memory is not a page-aligned address or Pages is invalid.
-@retval EFI_NOT_FOUND The requested memory pages were not allocated with
- AllocatePages().
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestFreePages (
- IN CONST EFI_PEI_SERVICES **PeiServices,
- IN EFI_PHYSICAL_ADDRESS Memory,
- IN UINTN Pages
- )
-{
- return EFI_NOT_AVAILABLE_YET;
-}
+/** @file + This file implements some PEI services. + + Copyright (c) 2023, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "UnitTestPeiServicesTablePointerLib.h" + +/** + This service enables PEIMs to ascertain the present value of the boot mode. + + @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation. + @param BootMode A pointer to contain the value of the boot mode. + + @retval EFI_SUCCESS The boot mode was returned successfully. + @retval EFI_INVALID_PARAMETER BootMode is NULL. + +**/ +EFI_STATUS +EFIAPI +UnitTestGetBootMode ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN OUT EFI_BOOT_MODE *BootMode + ) +{ + return EFI_NOT_AVAILABLE_YET; +} + +/** + This service enables PEIMs to update the boot mode variable. + + + @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation. + @param BootMode The value of the boot mode to set. + + @return EFI_SUCCESS The value was successfully updated + +**/ +EFI_STATUS +EFIAPI +UnitTestSetBootMode ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN EFI_BOOT_MODE BootMode + ) +{ + return EFI_NOT_AVAILABLE_YET; +} + +/** + Search the firmware volumes by index + + @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation + @param Instance This instance of the firmware volume to find. The value 0 is the Boot Firmware + Volume (BFV). + @param VolumeHandle On exit, points to the next volume handle or NULL if it does not exist. + + @retval EFI_INVALID_PARAMETER VolumeHandle is NULL + @retval EFI_NOT_FOUND The volume was not found. + @retval EFI_SUCCESS The volume was found. + +**/ +EFI_STATUS +EFIAPI +UnitTestFfsFindNextVolume ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN UINTN Instance, + IN OUT EFI_PEI_FV_HANDLE *VolumeHandle + ) +{ + return EFI_NOT_AVAILABLE_YET; +} + +/** + Searches for the next matching file in the firmware volume. + + @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation. + @param SearchType Filter to find only files of this type. + Type EFI_FV_FILETYPE_ALL causes no filtering to be done. + @param FvHandle Handle of firmware volume in which to search. + @param FileHandle On entry, points to the current handle from which to begin searching or NULL to start + at the beginning of the firmware volume. On exit, points the file handle of the next file + in the volume or NULL if there are no more files. + + @retval EFI_NOT_FOUND The file was not found. + @retval EFI_NOT_FOUND The header checksum was not zero. + @retval EFI_SUCCESS The file was found. + +**/ +EFI_STATUS +EFIAPI +UnitTestFfsFindNextFile ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN UINT8 SearchType, + IN EFI_PEI_FV_HANDLE FvHandle, + IN OUT EFI_PEI_FILE_HANDLE *FileHandle + ) +{ + return EFI_NOT_AVAILABLE_YET; +} + +/** + Searches for the next matching section within the specified file. + + @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation + @param SectionType Filter to find only sections of this type. + @param FileHandle Pointer to the current file to search. + @param SectionData A pointer to the discovered section, if successful. + NULL if section not found + + @retval EFI_NOT_FOUND The section was not found. + @retval EFI_SUCCESS The section was found. + +**/ +EFI_STATUS +EFIAPI +UnitTestFfsFindSectionData ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN EFI_SECTION_TYPE SectionType, + IN EFI_PEI_FILE_HANDLE FileHandle, + OUT VOID **SectionData + ) +{ + return EFI_NOT_AVAILABLE_YET; +} + +/** + + This function registers the found memory configuration with the PEI Foundation. + + The usage model is that the PEIM that discovers the permanent memory shall invoke this service. + This routine will hold discoveried memory information into PeiCore's private data, + and set SwitchStackSignal flag. After PEIM who discovery memory is dispatched, + PeiDispatcher will migrate temporary memory to permanent memory. + + @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation. + @param MemoryBegin Start of memory address. + @param MemoryLength Length of memory. + + @return EFI_SUCCESS Always success. + +**/ +EFI_STATUS +EFIAPI +UnitTestInstallPeiMemory ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN EFI_PHYSICAL_ADDRESS MemoryBegin, + IN UINT64 MemoryLength + ) +{ + return EFI_NOT_AVAILABLE_YET; +} + +/** + The purpose of the service is to publish an interface that allows + PEIMs to allocate memory ranges that are managed by the PEI Foundation. + + Prior to InstallPeiMemory() being called, PEI will allocate pages from the heap. + After InstallPeiMemory() is called, PEI will allocate pages within the region + of memory provided by InstallPeiMemory() service in a best-effort fashion. + Location-specific allocations are not managed by the PEI foundation code. + + @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation. + @param MemoryType The type of memory to allocate. + @param Pages The number of contiguous 4 KB pages to allocate. + @param Memory Pointer to a physical address. On output, the address is set to the base + of the page range that was allocated. + + @retval EFI_SUCCESS The memory range was successfully allocated. + @retval EFI_OUT_OF_RESOURCES The pages could not be allocated. + @retval EFI_INVALID_PARAMETER Type is not equal to EfiLoaderCode, EfiLoaderData, EfiRuntimeServicesCode, + EfiRuntimeServicesData, EfiBootServicesCode, EfiBootServicesData, + EfiACPIReclaimMemory, EfiReservedMemoryType, or EfiACPIMemoryNVS. + +**/ +EFI_STATUS +EFIAPI +UnitTestAllocatePages ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN EFI_MEMORY_TYPE MemoryType, + IN UINTN Pages, + OUT EFI_PHYSICAL_ADDRESS *Memory + ) +{ + return EFI_NOT_AVAILABLE_YET; +} + +/** + + Pool allocation service. Before permanent memory is discovered, the pool will + be allocated in the heap in temporary memory. Generally, the size of the heap in temporary + memory does not exceed 64K, so the biggest pool size could be allocated is + 64K. + + @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation. + @param Size Amount of memory required + @param Buffer Address of pointer to the buffer + + @retval EFI_SUCCESS The allocation was successful + @retval EFI_OUT_OF_RESOURCES There is not enough heap to satisfy the requirement + to allocate the requested size. + +**/ +EFI_STATUS +EFIAPI +UnitTestAllocatePool ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN UINTN Size, + OUT VOID **Buffer + ) +{ + return EFI_NOT_AVAILABLE_YET; +} + +/** + + Core version of the Status Code reporter + + + @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation. + @param CodeType Type of Status Code. + @param Value Value to output for Status Code. + @param Instance Instance Number of this status code. + @param CallerId ID of the caller of this status code. + @param Data Optional data associated with this status code. + + @retval EFI_SUCCESS if status code is successfully reported + @retval EFI_NOT_AVAILABLE_YET if StatusCodePpi has not been installed + +**/ +EFI_STATUS +EFIAPI +UnitTestReportStatusCode ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN EFI_STATUS_CODE_TYPE CodeType, + IN EFI_STATUS_CODE_VALUE Value, + IN UINT32 Instance, + IN CONST EFI_GUID *CallerId, + IN CONST EFI_STATUS_CODE_DATA *Data OPTIONAL + ) +{ + return EFI_NOT_AVAILABLE_YET; +} + +/** + +Core version of the Reset System + + +@param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation. + +@retval EFI_NOT_AVAILABLE_YET PPI not available yet. +@retval EFI_DEVICE_ERROR Did not reset system. + Otherwise, resets the system. + +**/ +EFI_STATUS +EFIAPI +UnitTestResetSystem ( + IN CONST EFI_PEI_SERVICES **PeiServices + ) +{ + return EFI_NOT_AVAILABLE_YET; +} + +/** + Find a file within a volume by its name. + + @param FileName A pointer to the name of the file to find within the firmware volume. + @param VolumeHandle The firmware volume to search + @param FileHandle Upon exit, points to the found file's handle + or NULL if it could not be found. + + @retval EFI_SUCCESS File was found. + @retval EFI_NOT_FOUND File was not found. + @retval EFI_INVALID_PARAMETER VolumeHandle or FileHandle or FileName was NULL. + +**/ +EFI_STATUS +EFIAPI +UnitTestFfsFindFileByName ( + IN CONST EFI_GUID *FileName, + IN EFI_PEI_FV_HANDLE VolumeHandle, + OUT EFI_PEI_FILE_HANDLE *FileHandle + ) +{ + return EFI_NOT_AVAILABLE_YET; +} + +/** + Returns information about a specific file. + + @param FileHandle Handle of the file. + @param FileInfo Upon exit, points to the file's information. + + @retval EFI_INVALID_PARAMETER If FileInfo is NULL. + @retval EFI_INVALID_PARAMETER If FileHandle does not represent a valid file. + @retval EFI_SUCCESS File information returned. + +**/ +EFI_STATUS +EFIAPI +UnitTestFfsGetFileInfo ( + IN EFI_PEI_FILE_HANDLE FileHandle, + OUT EFI_FV_FILE_INFO *FileInfo + ) +{ + return EFI_NOT_AVAILABLE_YET; +} + +/** + Returns information about the specified volume. + + This function returns information about a specific firmware + volume, including its name, type, attributes, starting address + and size. + + @param VolumeHandle Handle of the volume. + @param VolumeInfo Upon exit, points to the volume's information. + + @retval EFI_SUCCESS Volume information returned. + @retval EFI_INVALID_PARAMETER If VolumeHandle does not represent a valid volume. + @retval EFI_INVALID_PARAMETER If VolumeHandle is NULL. + @retval EFI_SUCCESS Information successfully returned. + @retval EFI_INVALID_PARAMETER The volume designated by the VolumeHandle is not available. + +**/ +EFI_STATUS +EFIAPI +UnitTestFfsGetVolumeInfo ( + IN EFI_PEI_FV_HANDLE VolumeHandle, + OUT EFI_FV_INFO *VolumeInfo + ) +{ + return EFI_NOT_AVAILABLE_YET; +} + +/** +This routine enables a PEIM to register itself for shadow when the PEI Foundation +discovers permanent memory. + +@param FileHandle File handle of a PEIM. + +@retval EFI_NOT_FOUND The file handle doesn't point to PEIM itself. +@retval EFI_ALREADY_STARTED Indicate that the PEIM has been registered itself. +@retval EFI_SUCCESS Successfully to register itself. + +**/ +EFI_STATUS +EFIAPI +UnitTestRegisterForShadow ( + IN EFI_PEI_FILE_HANDLE FileHandle + ) +{ + return EFI_NOT_AVAILABLE_YET; +} + +/** +Searches for the next matching section within the specified file. + +@param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation. +@param SectionType The value of the section type to find. +@param SectionInstance Section instance to find. +@param FileHandle Handle of the firmware file to search. +@param SectionData A pointer to the discovered section, if successful. +@param AuthenticationStatus A pointer to the authentication status for this section. + +@retval EFI_SUCCESS The section was found. +@retval EFI_NOT_FOUND The section was not found. + +**/ +EFI_STATUS +EFIAPI +UnitTestFfsFindSectionData3 ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN EFI_SECTION_TYPE SectionType, + IN UINTN SectionInstance, + IN EFI_PEI_FILE_HANDLE FileHandle, + OUT VOID **SectionData, + OUT UINT32 *AuthenticationStatus + ) +{ + return EFI_NOT_AVAILABLE_YET; +} + +/** +Returns information about a specific file. + +@param FileHandle Handle of the file. +@param FileInfo Upon exit, points to the file's information. + +@retval EFI_INVALID_PARAMETER If FileInfo is NULL. +@retval EFI_INVALID_PARAMETER If FileHandle does not represent a valid file. +@retval EFI_SUCCESS File information returned. + +**/ +EFI_STATUS +EFIAPI +UnitTestFfsGetFileInfo2 ( + IN EFI_PEI_FILE_HANDLE FileHandle, + OUT EFI_FV_FILE_INFO2 *FileInfo + ) +{ + return EFI_NOT_AVAILABLE_YET; +} + +/** +Frees memory pages. + +@param[in] PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation. +@param[in] Memory The base physical address of the pages to be freed. +@param[in] Pages The number of contiguous 4 KB pages to free. + +@retval EFI_SUCCESS The requested pages were freed. +@retval EFI_INVALID_PARAMETER Memory is not a page-aligned address or Pages is invalid. +@retval EFI_NOT_FOUND The requested memory pages were not allocated with + AllocatePages(). + +**/ +EFI_STATUS +EFIAPI +UnitTestFreePages ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN EFI_PHYSICAL_ADDRESS Memory, + IN UINTN Pages + ) +{ + return EFI_NOT_AVAILABLE_YET; +} diff --git a/UnitTestFrameworkPkg/Library/UnitTestPeiServicesTablePointerLib/UnitTestPeiServicesTablePointerLibPpi.c b/UnitTestFrameworkPkg/Library/UnitTestPeiServicesTablePointerLib/UnitTestPeiServicesTablePointerLibPpi.c index 09f4094dad..91070ef847 100644 --- a/UnitTestFrameworkPkg/Library/UnitTestPeiServicesTablePointerLib/UnitTestPeiServicesTablePointerLibPpi.c +++ b/UnitTestFrameworkPkg/Library/UnitTestPeiServicesTablePointerLib/UnitTestPeiServicesTablePointerLibPpi.c @@ -1,485 +1,485 @@ -/** @file
- This file implements some PEI services about PPI.
-
- Copyright (c) 2023, Intel Corporation. All rights reserved.<BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#include "UnitTestPeiServicesTablePointerLib.h"
-
-/**
-
- This function installs an interface in the PEI PPI database by GUID.
- The purpose of the service is to publish an interface that other parties
- can use to call additional PEIMs.
-
- @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
- @param PpiList Pointer to a list of PEI PPI Descriptors.
- @param Single TRUE if only single entry in the PpiList.
- FALSE if the PpiList is ended with an entry which has the
- EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST flag set in its Flags field.
-
- @retval EFI_SUCCESS if all PPIs in PpiList are successfully installed.
- @retval EFI_INVALID_PARAMETER if PpiList is NULL pointer
- if any PPI in PpiList is not valid
- @retval EFI_OUT_OF_RESOURCES if there is no more memory resource to install PPI
-
-**/
-EFI_STATUS
-InternalPeiInstallPpi (
- IN CONST EFI_PEI_SERVICES **PeiServices,
- IN CONST EFI_PEI_PPI_DESCRIPTOR *PpiList,
- IN BOOLEAN Single
- )
-{
- PEI_CORE_INSTANCE *PrivateData;
- PEI_PPI_LIST *PpiListPointer;
- UINTN Index;
- UINTN LastCount;
-
- if (PpiList == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);
-
- PpiListPointer = &PrivateData->PpiData.PpiList;
- Index = PpiListPointer->CurrentCount;
- LastCount = Index;
-
- //
- // This is loop installs all PPI descriptors in the PpiList. It is terminated
- // by the EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST being set in the last
- // EFI_PEI_PPI_DESCRIPTOR in the list.
- //
-
- for ( ; ;) {
- //
- // Check if it is a valid PPI.
- // If not, rollback list to exclude all in this list.
- // Try to indicate which item failed.
- //
- if ((PpiList->Flags & EFI_PEI_PPI_DESCRIPTOR_PPI) == 0) {
- PpiListPointer->CurrentCount = LastCount;
- DEBUG ((DEBUG_ERROR, "ERROR -> InstallPpi: %g %p\n", PpiList->Guid, PpiList->Ppi));
- return EFI_INVALID_PARAMETER;
- }
-
- if (Index >= PpiListPointer->MaxCount) {
- //
- // Run out of room, assert.
- //
- ASSERT (Index < PpiListPointer->MaxCount);
- }
-
- DEBUG ((DEBUG_INFO, "Install PPI: %g\n", PpiList->Guid));
- PpiListPointer->PpiPtrs[Index].Ppi = (EFI_PEI_PPI_DESCRIPTOR *)PpiList;
- Index++;
- PpiListPointer->CurrentCount++;
-
- if (Single) {
- //
- // Only single entry in the PpiList.
- //
- break;
- } else if ((PpiList->Flags & EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST) ==
- EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST)
- {
- //
- // Continue until the end of the PPI List.
- //
- break;
- }
-
- //
- // Go to the next descriptor.
- //
- PpiList++;
- }
-
- //
- // Process any callback level notifies for newly installed PPIs.
- //
- ProcessNotify (
- PrivateData,
- EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK,
- LastCount,
- PpiListPointer->CurrentCount,
- 0,
- PrivateData->PpiData.CallbackNotifyList.CurrentCount
- );
-
- return EFI_SUCCESS;
-}
-
-/**
-
- This function installs an interface in the PEI PPI database by GUID.
- The purpose of the service is to publish an interface that other parties
- can use to call additional PEIMs.
-
- @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
- @param PpiList Pointer to a list of PEI PPI Descriptors.
-
- @retval EFI_SUCCESS if all PPIs in PpiList are successfully installed.
- @retval EFI_INVALID_PARAMETER if PpiList is NULL pointer
- if any PPI in PpiList is not valid
- @retval EFI_OUT_OF_RESOURCES if there is no more memory resource to install PPI
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestInstallPpi (
- IN CONST EFI_PEI_SERVICES **PeiServices,
- IN CONST EFI_PEI_PPI_DESCRIPTOR *PpiList
- )
-{
- return InternalPeiInstallPpi (PeiServices, PpiList, FALSE);
-}
-
-/**
-
- This function reinstalls an interface in the PEI PPI database by GUID.
- The purpose of the service is to publish an interface that other parties can
- use to replace an interface of the same name in the protocol database with a
- different interface.
-
- @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
- @param OldPpi Pointer to the old PEI PPI Descriptors.
- @param NewPpi Pointer to the new PEI PPI Descriptors.
-
- @retval EFI_SUCCESS if the operation was successful
- @retval EFI_INVALID_PARAMETER if OldPpi or NewPpi is NULL
- @retval EFI_INVALID_PARAMETER if NewPpi is not valid
- @retval EFI_NOT_FOUND if the PPI was not in the database
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestReInstallPpi (
- IN CONST EFI_PEI_SERVICES **PeiServices,
- IN CONST EFI_PEI_PPI_DESCRIPTOR *OldPpi,
- IN CONST EFI_PEI_PPI_DESCRIPTOR *NewPpi
- )
-{
- PEI_CORE_INSTANCE *PrivateData;
- UINTN Index;
-
- if ((OldPpi == NULL) || (NewPpi == NULL)) {
- return EFI_INVALID_PARAMETER;
- }
-
- if ((NewPpi->Flags & EFI_PEI_PPI_DESCRIPTOR_PPI) == 0) {
- return EFI_INVALID_PARAMETER;
- }
-
- PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);
-
- //
- // Find the old PPI instance in the database. If we can not find it,
- // return the EFI_NOT_FOUND error.
- //
- for (Index = 0; Index < PrivateData->PpiData.PpiList.CurrentCount; Index++) {
- if (OldPpi == PrivateData->PpiData.PpiList.PpiPtrs[Index].Ppi) {
- break;
- }
- }
-
- if (Index == PrivateData->PpiData.PpiList.CurrentCount) {
- return EFI_NOT_FOUND;
- }
-
- //
- // Replace the old PPI with the new one.
- //
- DEBUG ((DEBUG_INFO, "Reinstall PPI: %g\n", NewPpi->Guid));
- PrivateData->PpiData.PpiList.PpiPtrs[Index].Ppi = (EFI_PEI_PPI_DESCRIPTOR *)NewPpi;
-
- //
- // Process any callback level notifies for the newly installed PPI.
- //
- ProcessNotify (
- PrivateData,
- EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK,
- Index,
- Index+1,
- 0,
- PrivateData->PpiData.CallbackNotifyList.CurrentCount
- );
-
- return EFI_SUCCESS;
-}
-
-/**
-
- Locate a given named PPI.
-
-
- @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
- @param Guid Pointer to GUID of the PPI.
- @param Instance Instance Number to discover.
- @param PpiDescriptor Pointer to reference the found descriptor. If not NULL,
- returns a pointer to the descriptor (includes flags, etc)
- @param Ppi Pointer to reference the found PPI
-
- @retval EFI_SUCCESS if the PPI is in the database
- @retval EFI_NOT_FOUND if the PPI is not in the database
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestLocatePpi (
- IN CONST EFI_PEI_SERVICES **PeiServices,
- IN CONST EFI_GUID *Guid,
- IN UINTN Instance,
- IN OUT EFI_PEI_PPI_DESCRIPTOR **PpiDescriptor,
- IN OUT VOID **Ppi
- )
-{
- PEI_CORE_INSTANCE *PrivateData;
- UINTN Index;
- EFI_GUID *CheckGuid;
- EFI_PEI_PPI_DESCRIPTOR *TempPtr;
-
- PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);
-
- //
- // Search the data base for the matching instance of the GUIDed PPI.
- //
- for (Index = 0; Index < PrivateData->PpiData.PpiList.CurrentCount; Index++) {
- TempPtr = PrivateData->PpiData.PpiList.PpiPtrs[Index].Ppi;
- CheckGuid = TempPtr->Guid;
-
- //
- // Don't use CompareGuid function here for performance reasons.
- // Instead we compare the GUID as INT32 at a time and branch
- // on the first failed comparison.
- //
- if ((((INT32 *)Guid)[0] == ((INT32 *)CheckGuid)[0]) &&
- (((INT32 *)Guid)[1] == ((INT32 *)CheckGuid)[1]) &&
- (((INT32 *)Guid)[2] == ((INT32 *)CheckGuid)[2]) &&
- (((INT32 *)Guid)[3] == ((INT32 *)CheckGuid)[3]))
- {
- if (Instance == 0) {
- if (PpiDescriptor != NULL) {
- *PpiDescriptor = TempPtr;
- }
-
- if (Ppi != NULL) {
- *Ppi = TempPtr->Ppi;
- }
-
- return EFI_SUCCESS;
- }
-
- Instance--;
- }
- }
-
- return EFI_NOT_FOUND;
-}
-
-/**
-
- This function installs a notification service to be called back when a given
- interface is installed or reinstalled. The purpose of the service is to publish
- an interface that other parties can use to call additional PPIs that may materialize later.
-
- @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
- @param NotifyList Pointer to list of Descriptors to notify upon.
- @param Single TRUE if only single entry in the NotifyList.
- FALSE if the NotifyList is ended with an entry which has the
- EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST flag set in its Flags field.
-
- @retval EFI_SUCCESS if successful
- @retval EFI_OUT_OF_RESOURCES if no space in the database
- @retval EFI_INVALID_PARAMETER if not a good descriptor
-
-**/
-EFI_STATUS
-InternalPeiNotifyPpi (
- IN CONST EFI_PEI_SERVICES **PeiServices,
- IN CONST EFI_PEI_NOTIFY_DESCRIPTOR *NotifyList,
- IN BOOLEAN Single
- )
-{
- PEI_CORE_INSTANCE *PrivateData;
- PEI_CALLBACK_NOTIFY_LIST *CallbackNotifyListPointer;
- UINTN CallbackNotifyIndex;
- UINTN LastCallbackNotifyCount;
- PEI_DISPATCH_NOTIFY_LIST *DispatchNotifyListPointer;
- UINTN DispatchNotifyIndex;
- UINTN LastDispatchNotifyCount;
-
- if (NotifyList == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);
-
- CallbackNotifyListPointer = &PrivateData->PpiData.CallbackNotifyList;
- CallbackNotifyIndex = CallbackNotifyListPointer->CurrentCount;
- LastCallbackNotifyCount = CallbackNotifyIndex;
-
- DispatchNotifyListPointer = &PrivateData->PpiData.DispatchNotifyList;
- DispatchNotifyIndex = DispatchNotifyListPointer->CurrentCount;
- LastDispatchNotifyCount = DispatchNotifyIndex;
-
- //
- // This is loop installs all Notify descriptors in the NotifyList. It is
- // terminated by the EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST being set in the last
- // EFI_PEI_NOTIFY_DESCRIPTOR in the list.
- //
-
- for ( ; ;) {
- //
- // If some of the PPI data is invalid restore original Notify PPI database value
- //
- if ((NotifyList->Flags & EFI_PEI_PPI_DESCRIPTOR_NOTIFY_TYPES) == 0) {
- CallbackNotifyListPointer->CurrentCount = LastCallbackNotifyCount;
- DispatchNotifyListPointer->CurrentCount = LastDispatchNotifyCount;
- DEBUG ((DEBUG_ERROR, "ERROR -> NotifyPpi: %g %p\n", NotifyList->Guid, NotifyList->Notify));
- return EFI_INVALID_PARAMETER;
- }
-
- if ((NotifyList->Flags & EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK) != 0) {
- if (CallbackNotifyIndex >= CallbackNotifyListPointer->MaxCount) {
- //
- // Run out of room, assert.
- //
- ASSERT (CallbackNotifyIndex < CallbackNotifyListPointer->MaxCount);
- }
-
- CallbackNotifyListPointer->NotifyPtrs[CallbackNotifyIndex].Notify = (EFI_PEI_NOTIFY_DESCRIPTOR *)NotifyList;
- CallbackNotifyIndex++;
- CallbackNotifyListPointer->CurrentCount++;
- } else {
- ASSERT ((NotifyList->Flags & EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK) != 0);
- }
-
- DEBUG ((DEBUG_INFO, "Register PPI Notify: %g\n", NotifyList->Guid));
-
- if (Single) {
- //
- // Only single entry in the NotifyList.
- //
- break;
- } else if ((NotifyList->Flags & EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST) ==
- EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST)
- {
- //
- // Continue until the end of the Notify List.
- //
- break;
- }
-
- //
- // Go to the next descriptor.
- //
- NotifyList++;
- }
-
- //
- // Process any callback level notifies for all previously installed PPIs.
- //
- ProcessNotify (
- PrivateData,
- EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK,
- 0,
- PrivateData->PpiData.PpiList.CurrentCount,
- LastCallbackNotifyCount,
- CallbackNotifyListPointer->CurrentCount
- );
-
- return EFI_SUCCESS;
-}
-
-/**
-
- This function installs a notification service to be called back when a given
- interface is installed or reinstalled. The purpose of the service is to publish
- an interface that other parties can use to call additional PPIs that may materialize later.
-
- @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
- @param NotifyList Pointer to list of Descriptors to notify upon.
-
- @retval EFI_SUCCESS if successful
- @retval EFI_OUT_OF_RESOURCES if no space in the database
- @retval EFI_INVALID_PARAMETER if not a good descriptor
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestNotifyPpi (
- IN CONST EFI_PEI_SERVICES **PeiServices,
- IN CONST EFI_PEI_NOTIFY_DESCRIPTOR *NotifyList
- )
-{
- return InternalPeiNotifyPpi (PeiServices, NotifyList, FALSE);
-}
-
-/**
-
- Process notifications.
-
- @param PrivateData PeiCore's private data structure
- @param NotifyType Type of notify to fire.
- @param InstallStartIndex Install Beginning index.
- @param InstallStopIndex Install Ending index.
- @param NotifyStartIndex Notify Beginning index.
- @param NotifyStopIndex Notify Ending index.
-
-**/
-VOID
-ProcessNotify (
- IN PEI_CORE_INSTANCE *PrivateData,
- IN UINTN NotifyType,
- IN INTN InstallStartIndex,
- IN INTN InstallStopIndex,
- IN INTN NotifyStartIndex,
- IN INTN NotifyStopIndex
- )
-{
- INTN Index1;
- INTN Index2;
- EFI_GUID *SearchGuid;
- EFI_GUID *CheckGuid;
- EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor;
-
- for (Index1 = NotifyStartIndex; Index1 < NotifyStopIndex; Index1++) {
- if (NotifyType == EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK) {
- NotifyDescriptor = PrivateData->PpiData.CallbackNotifyList.NotifyPtrs[Index1].Notify;
- } else {
- NotifyDescriptor = PrivateData->PpiData.DispatchNotifyList.NotifyPtrs[Index1].Notify;
- }
-
- CheckGuid = NotifyDescriptor->Guid;
-
- for (Index2 = InstallStartIndex; Index2 < InstallStopIndex; Index2++) {
- SearchGuid = PrivateData->PpiData.PpiList.PpiPtrs[Index2].Ppi->Guid;
- //
- // Don't use CompareGuid function here for performance reasons.
- // Instead we compare the GUID as INT32 at a time and branch
- // on the first failed comparison.
- //
- if ((((INT32 *)SearchGuid)[0] == ((INT32 *)CheckGuid)[0]) &&
- (((INT32 *)SearchGuid)[1] == ((INT32 *)CheckGuid)[1]) &&
- (((INT32 *)SearchGuid)[2] == ((INT32 *)CheckGuid)[2]) &&
- (((INT32 *)SearchGuid)[3] == ((INT32 *)CheckGuid)[3]))
- {
- DEBUG ((
- DEBUG_INFO,
- "Notify: PPI Guid: %g, Peim notify entry point: %p\n",
- SearchGuid,
- NotifyDescriptor->Notify
- ));
- NotifyDescriptor->Notify (
- (EFI_PEI_SERVICES **)GetPeiServicesTablePointer (),
- NotifyDescriptor,
- (PrivateData->PpiData.PpiList.PpiPtrs[Index2].Ppi)->Ppi
- );
- }
- }
- }
-}
+/** @file + This file implements some PEI services about PPI. + + Copyright (c) 2023, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "UnitTestPeiServicesTablePointerLib.h" + +/** + + This function installs an interface in the PEI PPI database by GUID. + The purpose of the service is to publish an interface that other parties + can use to call additional PEIMs. + + @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation. + @param PpiList Pointer to a list of PEI PPI Descriptors. + @param Single TRUE if only single entry in the PpiList. + FALSE if the PpiList is ended with an entry which has the + EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST flag set in its Flags field. + + @retval EFI_SUCCESS if all PPIs in PpiList are successfully installed. + @retval EFI_INVALID_PARAMETER if PpiList is NULL pointer + if any PPI in PpiList is not valid + @retval EFI_OUT_OF_RESOURCES if there is no more memory resource to install PPI + +**/ +EFI_STATUS +InternalPeiInstallPpi ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN CONST EFI_PEI_PPI_DESCRIPTOR *PpiList, + IN BOOLEAN Single + ) +{ + PEI_CORE_INSTANCE *PrivateData; + PEI_PPI_LIST *PpiListPointer; + UINTN Index; + UINTN LastCount; + + if (PpiList == NULL) { + return EFI_INVALID_PARAMETER; + } + + PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices); + + PpiListPointer = &PrivateData->PpiData.PpiList; + Index = PpiListPointer->CurrentCount; + LastCount = Index; + + // + // This is loop installs all PPI descriptors in the PpiList. It is terminated + // by the EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST being set in the last + // EFI_PEI_PPI_DESCRIPTOR in the list. + // + + for ( ; ;) { + // + // Check if it is a valid PPI. + // If not, rollback list to exclude all in this list. + // Try to indicate which item failed. + // + if ((PpiList->Flags & EFI_PEI_PPI_DESCRIPTOR_PPI) == 0) { + PpiListPointer->CurrentCount = LastCount; + DEBUG ((DEBUG_ERROR, "ERROR -> InstallPpi: %g %p\n", PpiList->Guid, PpiList->Ppi)); + return EFI_INVALID_PARAMETER; + } + + if (Index >= PpiListPointer->MaxCount) { + // + // Run out of room, assert. + // + ASSERT (Index < PpiListPointer->MaxCount); + } + + DEBUG ((DEBUG_INFO, "Install PPI: %g\n", PpiList->Guid)); + PpiListPointer->PpiPtrs[Index].Ppi = (EFI_PEI_PPI_DESCRIPTOR *)PpiList; + Index++; + PpiListPointer->CurrentCount++; + + if (Single) { + // + // Only single entry in the PpiList. + // + break; + } else if ((PpiList->Flags & EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST) == + EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST) + { + // + // Continue until the end of the PPI List. + // + break; + } + + // + // Go to the next descriptor. + // + PpiList++; + } + + // + // Process any callback level notifies for newly installed PPIs. + // + ProcessNotify ( + PrivateData, + EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK, + LastCount, + PpiListPointer->CurrentCount, + 0, + PrivateData->PpiData.CallbackNotifyList.CurrentCount + ); + + return EFI_SUCCESS; +} + +/** + + This function installs an interface in the PEI PPI database by GUID. + The purpose of the service is to publish an interface that other parties + can use to call additional PEIMs. + + @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation. + @param PpiList Pointer to a list of PEI PPI Descriptors. + + @retval EFI_SUCCESS if all PPIs in PpiList are successfully installed. + @retval EFI_INVALID_PARAMETER if PpiList is NULL pointer + if any PPI in PpiList is not valid + @retval EFI_OUT_OF_RESOURCES if there is no more memory resource to install PPI + +**/ +EFI_STATUS +EFIAPI +UnitTestInstallPpi ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN CONST EFI_PEI_PPI_DESCRIPTOR *PpiList + ) +{ + return InternalPeiInstallPpi (PeiServices, PpiList, FALSE); +} + +/** + + This function reinstalls an interface in the PEI PPI database by GUID. + The purpose of the service is to publish an interface that other parties can + use to replace an interface of the same name in the protocol database with a + different interface. + + @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation. + @param OldPpi Pointer to the old PEI PPI Descriptors. + @param NewPpi Pointer to the new PEI PPI Descriptors. + + @retval EFI_SUCCESS if the operation was successful + @retval EFI_INVALID_PARAMETER if OldPpi or NewPpi is NULL + @retval EFI_INVALID_PARAMETER if NewPpi is not valid + @retval EFI_NOT_FOUND if the PPI was not in the database + +**/ +EFI_STATUS +EFIAPI +UnitTestReInstallPpi ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN CONST EFI_PEI_PPI_DESCRIPTOR *OldPpi, + IN CONST EFI_PEI_PPI_DESCRIPTOR *NewPpi + ) +{ + PEI_CORE_INSTANCE *PrivateData; + UINTN Index; + + if ((OldPpi == NULL) || (NewPpi == NULL)) { + return EFI_INVALID_PARAMETER; + } + + if ((NewPpi->Flags & EFI_PEI_PPI_DESCRIPTOR_PPI) == 0) { + return EFI_INVALID_PARAMETER; + } + + PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices); + + // + // Find the old PPI instance in the database. If we can not find it, + // return the EFI_NOT_FOUND error. + // + for (Index = 0; Index < PrivateData->PpiData.PpiList.CurrentCount; Index++) { + if (OldPpi == PrivateData->PpiData.PpiList.PpiPtrs[Index].Ppi) { + break; + } + } + + if (Index == PrivateData->PpiData.PpiList.CurrentCount) { + return EFI_NOT_FOUND; + } + + // + // Replace the old PPI with the new one. + // + DEBUG ((DEBUG_INFO, "Reinstall PPI: %g\n", NewPpi->Guid)); + PrivateData->PpiData.PpiList.PpiPtrs[Index].Ppi = (EFI_PEI_PPI_DESCRIPTOR *)NewPpi; + + // + // Process any callback level notifies for the newly installed PPI. + // + ProcessNotify ( + PrivateData, + EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK, + Index, + Index+1, + 0, + PrivateData->PpiData.CallbackNotifyList.CurrentCount + ); + + return EFI_SUCCESS; +} + +/** + + Locate a given named PPI. + + + @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation. + @param Guid Pointer to GUID of the PPI. + @param Instance Instance Number to discover. + @param PpiDescriptor Pointer to reference the found descriptor. If not NULL, + returns a pointer to the descriptor (includes flags, etc) + @param Ppi Pointer to reference the found PPI + + @retval EFI_SUCCESS if the PPI is in the database + @retval EFI_NOT_FOUND if the PPI is not in the database + +**/ +EFI_STATUS +EFIAPI +UnitTestLocatePpi ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN CONST EFI_GUID *Guid, + IN UINTN Instance, + IN OUT EFI_PEI_PPI_DESCRIPTOR **PpiDescriptor, + IN OUT VOID **Ppi + ) +{ + PEI_CORE_INSTANCE *PrivateData; + UINTN Index; + EFI_GUID *CheckGuid; + EFI_PEI_PPI_DESCRIPTOR *TempPtr; + + PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices); + + // + // Search the data base for the matching instance of the GUIDed PPI. + // + for (Index = 0; Index < PrivateData->PpiData.PpiList.CurrentCount; Index++) { + TempPtr = PrivateData->PpiData.PpiList.PpiPtrs[Index].Ppi; + CheckGuid = TempPtr->Guid; + + // + // Don't use CompareGuid function here for performance reasons. + // Instead we compare the GUID as INT32 at a time and branch + // on the first failed comparison. + // + if ((((INT32 *)Guid)[0] == ((INT32 *)CheckGuid)[0]) && + (((INT32 *)Guid)[1] == ((INT32 *)CheckGuid)[1]) && + (((INT32 *)Guid)[2] == ((INT32 *)CheckGuid)[2]) && + (((INT32 *)Guid)[3] == ((INT32 *)CheckGuid)[3])) + { + if (Instance == 0) { + if (PpiDescriptor != NULL) { + *PpiDescriptor = TempPtr; + } + + if (Ppi != NULL) { + *Ppi = TempPtr->Ppi; + } + + return EFI_SUCCESS; + } + + Instance--; + } + } + + return EFI_NOT_FOUND; +} + +/** + + This function installs a notification service to be called back when a given + interface is installed or reinstalled. The purpose of the service is to publish + an interface that other parties can use to call additional PPIs that may materialize later. + + @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation. + @param NotifyList Pointer to list of Descriptors to notify upon. + @param Single TRUE if only single entry in the NotifyList. + FALSE if the NotifyList is ended with an entry which has the + EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST flag set in its Flags field. + + @retval EFI_SUCCESS if successful + @retval EFI_OUT_OF_RESOURCES if no space in the database + @retval EFI_INVALID_PARAMETER if not a good descriptor + +**/ +EFI_STATUS +InternalPeiNotifyPpi ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN CONST EFI_PEI_NOTIFY_DESCRIPTOR *NotifyList, + IN BOOLEAN Single + ) +{ + PEI_CORE_INSTANCE *PrivateData; + PEI_CALLBACK_NOTIFY_LIST *CallbackNotifyListPointer; + UINTN CallbackNotifyIndex; + UINTN LastCallbackNotifyCount; + PEI_DISPATCH_NOTIFY_LIST *DispatchNotifyListPointer; + UINTN DispatchNotifyIndex; + UINTN LastDispatchNotifyCount; + + if (NotifyList == NULL) { + return EFI_INVALID_PARAMETER; + } + + PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices); + + CallbackNotifyListPointer = &PrivateData->PpiData.CallbackNotifyList; + CallbackNotifyIndex = CallbackNotifyListPointer->CurrentCount; + LastCallbackNotifyCount = CallbackNotifyIndex; + + DispatchNotifyListPointer = &PrivateData->PpiData.DispatchNotifyList; + DispatchNotifyIndex = DispatchNotifyListPointer->CurrentCount; + LastDispatchNotifyCount = DispatchNotifyIndex; + + // + // This is loop installs all Notify descriptors in the NotifyList. It is + // terminated by the EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST being set in the last + // EFI_PEI_NOTIFY_DESCRIPTOR in the list. + // + + for ( ; ;) { + // + // If some of the PPI data is invalid restore original Notify PPI database value + // + if ((NotifyList->Flags & EFI_PEI_PPI_DESCRIPTOR_NOTIFY_TYPES) == 0) { + CallbackNotifyListPointer->CurrentCount = LastCallbackNotifyCount; + DispatchNotifyListPointer->CurrentCount = LastDispatchNotifyCount; + DEBUG ((DEBUG_ERROR, "ERROR -> NotifyPpi: %g %p\n", NotifyList->Guid, NotifyList->Notify)); + return EFI_INVALID_PARAMETER; + } + + if ((NotifyList->Flags & EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK) != 0) { + if (CallbackNotifyIndex >= CallbackNotifyListPointer->MaxCount) { + // + // Run out of room, assert. + // + ASSERT (CallbackNotifyIndex < CallbackNotifyListPointer->MaxCount); + } + + CallbackNotifyListPointer->NotifyPtrs[CallbackNotifyIndex].Notify = (EFI_PEI_NOTIFY_DESCRIPTOR *)NotifyList; + CallbackNotifyIndex++; + CallbackNotifyListPointer->CurrentCount++; + } else { + ASSERT ((NotifyList->Flags & EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK) != 0); + } + + DEBUG ((DEBUG_INFO, "Register PPI Notify: %g\n", NotifyList->Guid)); + + if (Single) { + // + // Only single entry in the NotifyList. + // + break; + } else if ((NotifyList->Flags & EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST) == + EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST) + { + // + // Continue until the end of the Notify List. + // + break; + } + + // + // Go to the next descriptor. + // + NotifyList++; + } + + // + // Process any callback level notifies for all previously installed PPIs. + // + ProcessNotify ( + PrivateData, + EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK, + 0, + PrivateData->PpiData.PpiList.CurrentCount, + LastCallbackNotifyCount, + CallbackNotifyListPointer->CurrentCount + ); + + return EFI_SUCCESS; +} + +/** + + This function installs a notification service to be called back when a given + interface is installed or reinstalled. The purpose of the service is to publish + an interface that other parties can use to call additional PPIs that may materialize later. + + @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation. + @param NotifyList Pointer to list of Descriptors to notify upon. + + @retval EFI_SUCCESS if successful + @retval EFI_OUT_OF_RESOURCES if no space in the database + @retval EFI_INVALID_PARAMETER if not a good descriptor + +**/ +EFI_STATUS +EFIAPI +UnitTestNotifyPpi ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN CONST EFI_PEI_NOTIFY_DESCRIPTOR *NotifyList + ) +{ + return InternalPeiNotifyPpi (PeiServices, NotifyList, FALSE); +} + +/** + + Process notifications. + + @param PrivateData PeiCore's private data structure + @param NotifyType Type of notify to fire. + @param InstallStartIndex Install Beginning index. + @param InstallStopIndex Install Ending index. + @param NotifyStartIndex Notify Beginning index. + @param NotifyStopIndex Notify Ending index. + +**/ +VOID +ProcessNotify ( + IN PEI_CORE_INSTANCE *PrivateData, + IN UINTN NotifyType, + IN INTN InstallStartIndex, + IN INTN InstallStopIndex, + IN INTN NotifyStartIndex, + IN INTN NotifyStopIndex + ) +{ + INTN Index1; + INTN Index2; + EFI_GUID *SearchGuid; + EFI_GUID *CheckGuid; + EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor; + + for (Index1 = NotifyStartIndex; Index1 < NotifyStopIndex; Index1++) { + if (NotifyType == EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK) { + NotifyDescriptor = PrivateData->PpiData.CallbackNotifyList.NotifyPtrs[Index1].Notify; + } else { + NotifyDescriptor = PrivateData->PpiData.DispatchNotifyList.NotifyPtrs[Index1].Notify; + } + + CheckGuid = NotifyDescriptor->Guid; + + for (Index2 = InstallStartIndex; Index2 < InstallStopIndex; Index2++) { + SearchGuid = PrivateData->PpiData.PpiList.PpiPtrs[Index2].Ppi->Guid; + // + // Don't use CompareGuid function here for performance reasons. + // Instead we compare the GUID as INT32 at a time and branch + // on the first failed comparison. + // + if ((((INT32 *)SearchGuid)[0] == ((INT32 *)CheckGuid)[0]) && + (((INT32 *)SearchGuid)[1] == ((INT32 *)CheckGuid)[1]) && + (((INT32 *)SearchGuid)[2] == ((INT32 *)CheckGuid)[2]) && + (((INT32 *)SearchGuid)[3] == ((INT32 *)CheckGuid)[3])) + { + DEBUG (( + DEBUG_INFO, + "Notify: PPI Guid: %g, Peim notify entry point: %p\n", + SearchGuid, + NotifyDescriptor->Notify + )); + NotifyDescriptor->Notify ( + (EFI_PEI_SERVICES **)GetPeiServicesTablePointer (), + NotifyDescriptor, + (PrivateData->PpiData.PpiList.PpiPtrs[Index2].Ppi)->Ppi + ); + } + } + } +} diff --git a/UnitTestFrameworkPkg/Library/UnitTestPersistenceLibNull/UnitTestPersistenceLibNull.c b/UnitTestFrameworkPkg/Library/UnitTestPersistenceLibNull/UnitTestPersistenceLibNull.c index abb24cff98..9eb7e708eb 100644 --- a/UnitTestFrameworkPkg/Library/UnitTestPersistenceLibNull/UnitTestPersistenceLibNull.c +++ b/UnitTestFrameworkPkg/Library/UnitTestPersistenceLibNull/UnitTestPersistenceLibNull.c @@ -1,80 +1,80 @@ -/** @file
- This is an instance of the Unit Test Persistence Lib that does nothing.
-
- Copyright (c) Microsoft Corporation.<BR>
- Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
-**/
-
-#include <Uefi.h>
-#include <Library/UnitTestPersistenceLib.h>
-
-/**
- Determines whether a persistence cache already exists for
- the given framework.
-
- @param[in] FrameworkHandle A pointer to the framework that is being persisted.
-
- @retval TRUE
- @retval FALSE Cache doesn't exist or an error occurred.
-
-**/
-BOOLEAN
-EFIAPI
-DoesCacheExist (
- IN UNIT_TEST_FRAMEWORK_HANDLE FrameworkHandle
- )
-{
- return FALSE;
-}
-
-/**
- Will save the data associated with an internal Unit Test Framework
- state in a manner that can persist a Unit Test Application quit or
- even a system reboot.
-
- @param[in] FrameworkHandle A pointer to the framework that is being persisted.
- @param[in] SaveData A pointer to the buffer containing the serialized
- framework internal state.
- @param[in] SaveStateSize The size of SaveData in bytes.
-
- @retval EFI_SUCCESS Data is persisted and the test can be safely quit.
- @retval Others Data is not persisted and test cannot be resumed upon exit.
-
-**/
-EFI_STATUS
-EFIAPI
-SaveUnitTestCache (
- IN UNIT_TEST_FRAMEWORK_HANDLE FrameworkHandle,
- IN VOID *SaveData,
- IN UINTN SaveStateSize
- )
-{
- return EFI_UNSUPPORTED;
-}
-
-/**
- Will retrieve any cached state associated with the given framework.
- Will allocate a buffer to hold the loaded data.
-
- @param[in] FrameworkHandle A pointer to the framework that is being persisted.
- @param[out] SaveData A pointer pointer that will be updated with the address
- of the loaded data buffer.
- @param[out] SaveStateSize Return the size of SaveData in bytes.
-
- @retval EFI_SUCCESS Data has been loaded successfully and SaveData is updated
- with a pointer to the buffer.
- @retval Others An error has occurred and no data has been loaded. SaveData
- is set to NULL.
-
-**/
-EFI_STATUS
-EFIAPI
-LoadUnitTestCache (
- IN UNIT_TEST_FRAMEWORK_HANDLE FrameworkHandle,
- OUT VOID **SaveData,
- OUT UINTN *SaveStateSize
- )
-{
- return EFI_UNSUPPORTED;
-}
+/** @file + This is an instance of the Unit Test Persistence Lib that does nothing. + + Copyright (c) Microsoft Corporation.<BR> + Copyright (c) 2022, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include <Uefi.h> +#include <Library/UnitTestPersistenceLib.h> + +/** + Determines whether a persistence cache already exists for + the given framework. + + @param[in] FrameworkHandle A pointer to the framework that is being persisted. + + @retval TRUE + @retval FALSE Cache doesn't exist or an error occurred. + +**/ +BOOLEAN +EFIAPI +DoesCacheExist ( + IN UNIT_TEST_FRAMEWORK_HANDLE FrameworkHandle + ) +{ + return FALSE; +} + +/** + Will save the data associated with an internal Unit Test Framework + state in a manner that can persist a Unit Test Application quit or + even a system reboot. + + @param[in] FrameworkHandle A pointer to the framework that is being persisted. + @param[in] SaveData A pointer to the buffer containing the serialized + framework internal state. + @param[in] SaveStateSize The size of SaveData in bytes. + + @retval EFI_SUCCESS Data is persisted and the test can be safely quit. + @retval Others Data is not persisted and test cannot be resumed upon exit. + +**/ +EFI_STATUS +EFIAPI +SaveUnitTestCache ( + IN UNIT_TEST_FRAMEWORK_HANDLE FrameworkHandle, + IN VOID *SaveData, + IN UINTN SaveStateSize + ) +{ + return EFI_UNSUPPORTED; +} + +/** + Will retrieve any cached state associated with the given framework. + Will allocate a buffer to hold the loaded data. + + @param[in] FrameworkHandle A pointer to the framework that is being persisted. + @param[out] SaveData A pointer pointer that will be updated with the address + of the loaded data buffer. + @param[out] SaveStateSize Return the size of SaveData in bytes. + + @retval EFI_SUCCESS Data has been loaded successfully and SaveData is updated + with a pointer to the buffer. + @retval Others An error has occurred and no data has been loaded. SaveData + is set to NULL. + +**/ +EFI_STATUS +EFIAPI +LoadUnitTestCache ( + IN UNIT_TEST_FRAMEWORK_HANDLE FrameworkHandle, + OUT VOID **SaveData, + OUT UINTN *SaveStateSize + ) +{ + return EFI_UNSUPPORTED; +} diff --git a/UnitTestFrameworkPkg/Library/UnitTestPersistenceLibNull/UnitTestPersistenceLibNull.inf b/UnitTestFrameworkPkg/Library/UnitTestPersistenceLibNull/UnitTestPersistenceLibNull.inf index 1175772662..11a9d17370 100644 --- a/UnitTestFrameworkPkg/Library/UnitTestPersistenceLibNull/UnitTestPersistenceLibNull.inf +++ b/UnitTestFrameworkPkg/Library/UnitTestPersistenceLibNull/UnitTestPersistenceLibNull.inf @@ -1,28 +1,28 @@ -## @file
-# This is an instance of the Unit Test Persistence Lib does nothing.
-#
-# Copyright (c) Microsoft Corporation.<BR>
-# SPDX-License-Identifier: BSD-2-Clause-Patent
-##
-
-[Defines]
- INF_VERSION = 0x00010017
- BASE_NAME = UnitTestPersistenceLibNull
- MODULE_UNI_FILE = UnitTestPersistenceLibNull.uni
- FILE_GUID = B8553C7A-0B0B-4BBD-9DF3-825804BF26AB
- VERSION_STRING = 1.0
- MODULE_TYPE = UEFI_DRIVER
- LIBRARY_CLASS = UnitTestPersistenceLib
-
-#
-# The following information is for reference only and not required by the build tools.
-#
-# VALID_ARCHITECTURES = IA32 X64
-#
-
-[Sources]
- UnitTestPersistenceLibNull.c
-
-[Packages]
- MdePkg/MdePkg.dec
- UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec
+## @file +# This is an instance of the Unit Test Persistence Lib does nothing. +# +# Copyright (c) Microsoft Corporation.<BR> +# SPDX-License-Identifier: BSD-2-Clause-Patent +## + +[Defines] + INF_VERSION = 0x00010017 + BASE_NAME = UnitTestPersistenceLibNull + MODULE_UNI_FILE = UnitTestPersistenceLibNull.uni + FILE_GUID = B8553C7A-0B0B-4BBD-9DF3-825804BF26AB + VERSION_STRING = 1.0 + MODULE_TYPE = UEFI_DRIVER + LIBRARY_CLASS = UnitTestPersistenceLib + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 +# + +[Sources] + UnitTestPersistenceLibNull.c + +[Packages] + MdePkg/MdePkg.dec + UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec diff --git a/UnitTestFrameworkPkg/Library/UnitTestPersistenceLibNull/UnitTestPersistenceLibNull.uni b/UnitTestFrameworkPkg/Library/UnitTestPersistenceLibNull/UnitTestPersistenceLibNull.uni index 00f7d8d7f0..4db1aa6940 100644 --- a/UnitTestFrameworkPkg/Library/UnitTestPersistenceLibNull/UnitTestPersistenceLibNull.uni +++ b/UnitTestFrameworkPkg/Library/UnitTestPersistenceLibNull/UnitTestPersistenceLibNull.uni @@ -1,11 +1,11 @@ -// /** @file
-// NULL library for Unit Test Persistence Lib.
-//
-// Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
-// SPDX-License-Identifier: BSD-2-Clause-Patent
-//
-// **/
-
-#string STR_MODULE_ABSTRACT #language en-US "NULL library for Unit Test Persistence Lib"
-
-#string STR_MODULE_DESCRIPTION #language en-US "NULL library for Unit Test Persistence Lib."
+// /** @file +// NULL library for Unit Test Persistence Lib. +// +// Copyright (c) 2020, Intel Corporation. All rights reserved.<BR> +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + +#string STR_MODULE_ABSTRACT #language en-US "NULL library for Unit Test Persistence Lib" + +#string STR_MODULE_DESCRIPTION #language en-US "NULL library for Unit Test Persistence Lib." diff --git a/UnitTestFrameworkPkg/Library/UnitTestPersistenceLibSimpleFileSystem/UnitTestPersistenceLibSimpleFileSystem.c b/UnitTestFrameworkPkg/Library/UnitTestPersistenceLibSimpleFileSystem/UnitTestPersistenceLibSimpleFileSystem.c index 8f7f03646c..25b84c2740 100644 --- a/UnitTestFrameworkPkg/Library/UnitTestPersistenceLibSimpleFileSystem/UnitTestPersistenceLibSimpleFileSystem.c +++ b/UnitTestFrameworkPkg/Library/UnitTestPersistenceLibSimpleFileSystem/UnitTestPersistenceLibSimpleFileSystem.c @@ -1,510 +1,510 @@ -/** @file
- This is an instance of the Unit Test Persistence Lib that will utilize
- the filesystem that a test application is running from to save a serialized
- version of the internal test state in case the test needs to quit and restore.
-
- Copyright (c) Microsoft Corporation.<BR>
- Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
-**/
-
-#include <PiDxe.h>
-#include <Library/UnitTestPersistenceLib.h>
-#include <Library/BaseLib.h>
-#include <Library/DebugLib.h>
-#include <Library/MemoryAllocationLib.h>
-#include <Library/UefiBootServicesTableLib.h>
-#include <Library/DevicePathLib.h>
-#include <Library/ShellLib.h>
-#include <Library/UefiLib.h>
-#include <Protocol/LoadedImage.h>
-#include <UnitTestFrameworkTypes.h>
-
-#define CACHE_FILE_SUFFIX L"_Cache.dat"
-
-CHAR16 *mCachePath = NULL;
-
-/**
- Generate the file name and path to the cache file.
-
- @param[in] FrameworkHandle A pointer to the framework that is being persisted.
-
- @retval !NULL A pointer to the EFI_FILE protocol instance for the filesystem.
- @retval NULL Filesystem could not be found or an error occurred.
-
-**/
-STATIC
-CHAR16 *
-GetCacheFileName (
- IN UNIT_TEST_FRAMEWORK_HANDLE FrameworkHandle
- )
-{
- EFI_STATUS Status;
- UNIT_TEST_FRAMEWORK *Framework;
- EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;
- CHAR16 *AppPath;
- CHAR16 *CacheFilePath;
- CHAR16 *TestName;
- UINTN DirectorySlashOffset;
- UINTN CacheFilePathLength;
-
- Framework = (UNIT_TEST_FRAMEWORK *)FrameworkHandle;
- AppPath = NULL;
- CacheFilePath = NULL;
- TestName = NULL;
-
- //
- // First, we need to get some information from the loaded image.
- //
- Status = gBS->HandleProtocol (
- gImageHandle,
- &gEfiLoadedImageProtocolGuid,
- (VOID **)&LoadedImage
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_WARN, "%a - Failed to locate DevicePath for loaded image. %r\n", __func__, Status));
- return NULL;
- }
-
- //
- // Before we can start, change test name from ASCII to Unicode.
- //
- CacheFilePathLength = AsciiStrLen (Framework->ShortTitle) + 1;
- TestName = AllocatePool (CacheFilePathLength * sizeof (CHAR16));
- if (!TestName) {
- goto Exit;
- }
-
- AsciiStrToUnicodeStrS (Framework->ShortTitle, TestName, CacheFilePathLength);
-
- //
- // Now we should have the device path of the root device and a file path for the rest.
- // In order to target the directory for the test application, we must process
- // the file path a little.
- //
- // NOTE: This may not be necessary... Path processing functions exist...
- // PathCleanUpDirectories (FileNameCopy);
- // if (PathRemoveLastItem (FileNameCopy)) {
- //
- if (mCachePath == NULL) {
- AppPath = ConvertDevicePathToText (LoadedImage->FilePath, TRUE, TRUE); // NOTE: This must be freed.
- if (AppPath == NULL) {
- goto Exit;
- }
-
- DirectorySlashOffset = StrLen (AppPath);
- //
- // Make sure we didn't get any weird data.
- //
- if (DirectorySlashOffset == 0) {
- DEBUG ((DEBUG_ERROR, "%a - Weird 0-length string when processing app path.\n", __func__));
- goto Exit;
- }
-
- //
- // Now that we know we have a decent string, let's take a deeper look.
- //
- do {
- if (AppPath[DirectorySlashOffset] == L'\\') {
- break;
- }
-
- DirectorySlashOffset--;
- } while (DirectorySlashOffset > 0);
-
- //
- // After that little maneuver, DirectorySlashOffset should be pointing at the last '\' in AppString.
- // That would be the path to the parent directory that the test app is executing from.
- // Let's check and make sure that's right.
- //
- if (AppPath[DirectorySlashOffset] != L'\\') {
- DEBUG ((DEBUG_ERROR, "%a - Could not find a single directory separator in app path.\n", __func__));
- goto Exit;
- }
- } else {
- AppPath = FullyQualifyPath (mCachePath); // NOTE: This must be freed.
- if (AppPath == NULL) {
- goto Exit;
- }
-
- DirectorySlashOffset = StrLen (AppPath);
-
- if (AppPath[DirectorySlashOffset - 1] != L'\\') {
- // Set the slash if user did not specify it on the newly allocated pool
- AppPath = ReallocatePool (
- (DirectorySlashOffset + 1) * sizeof (CHAR16),
- (DirectorySlashOffset + 2) * sizeof (CHAR16),
- AppPath
- );
- AppPath[DirectorySlashOffset] = L'\\';
- AppPath[DirectorySlashOffset + 1] = L'\0';
- } else {
- // Otherwise the user input is good enough to go, mostly
- DirectorySlashOffset--;
- }
- }
-
- //
- // Now we know some things, we're ready to produce our output string, I think.
- //
- CacheFilePathLength = DirectorySlashOffset + 1;
- CacheFilePathLength += StrLen (TestName);
- CacheFilePathLength += StrLen (CACHE_FILE_SUFFIX);
- CacheFilePathLength += 1; // Don't forget the NULL terminator.
- CacheFilePath = AllocateZeroPool (CacheFilePathLength * sizeof (CHAR16));
- if (!CacheFilePath) {
- goto Exit;
- }
-
- //
- // Let's produce our final path string, shall we?
- //
- StrnCpyS (CacheFilePath, CacheFilePathLength, AppPath, DirectorySlashOffset + 1); // Copy the path for the parent directory.
- StrCatS (CacheFilePath, CacheFilePathLength, TestName); // Copy the base name for the test cache.
- StrCatS (CacheFilePath, CacheFilePathLength, CACHE_FILE_SUFFIX); // Copy the file suffix.
-
-Exit:
- //
- // Free allocated buffers.
- //
- if (AppPath != NULL) {
- FreePool (AppPath);
- }
-
- if (TestName != NULL) {
- FreePool (TestName);
- }
-
- return CacheFilePath;
-}
-
-/**
- Determines whether a persistence cache already exists for
- the given framework.
-
- @param[in] FrameworkHandle A pointer to the framework that is being persisted.
-
- @retval TRUE
- @retval FALSE Cache doesn't exist or an error occurred.
-
-**/
-BOOLEAN
-EFIAPI
-DoesCacheExist (
- IN UNIT_TEST_FRAMEWORK_HANDLE FrameworkHandle
- )
-{
- CHAR16 *FileName;
- EFI_STATUS Status;
- SHELL_FILE_HANDLE FileHandle;
-
- //
- // NOTE: This devpath is allocated and must be freed.
- //
- FileName = GetCacheFileName (FrameworkHandle);
- if (FileName == NULL) {
- return FALSE;
- }
-
- //
- // Check to see whether the file exists. If the file can be opened for
- // reading, it exists. Otherwise, probably not.
- //
- Status = ShellOpenFileByName (
- FileName,
- &FileHandle,
- EFI_FILE_MODE_READ,
- 0
- );
- if (!EFI_ERROR (Status)) {
- ShellCloseFile (&FileHandle);
- }
-
- if (FileName != NULL) {
- FreePool (FileName);
- }
-
- DEBUG ((DEBUG_VERBOSE, "%a - Returning %d\n", __func__, !EFI_ERROR (Status)));
-
- return (!EFI_ERROR (Status));
-}
-
-/**
- Will save the data associated with an internal Unit Test Framework
- state in a manner that can persist a Unit Test Application quit or
- even a system reboot.
-
- @param[in] FrameworkHandle A pointer to the framework that is being persisted.
- @param[in] SaveData A pointer to the buffer containing the serialized
- framework internal state.
- @param[in] SaveStateSize The size of SaveData in bytes.
-
- @retval EFI_SUCCESS Data is persisted and the test can be safely quit.
- @retval Others Data is not persisted and test cannot be resumed upon exit.
-
-**/
-EFI_STATUS
-EFIAPI
-SaveUnitTestCache (
- IN UNIT_TEST_FRAMEWORK_HANDLE FrameworkHandle,
- IN VOID *SaveData,
- IN UINTN SaveStateSize
- )
-{
- CHAR16 *FileName;
- EFI_STATUS Status;
- SHELL_FILE_HANDLE FileHandle;
- UINTN WriteCount;
-
- //
- // Check the inputs for sanity.
- //
- if ((FrameworkHandle == NULL) || (SaveData == NULL)) {
- return EFI_INVALID_PARAMETER;
- }
-
- //
- // Determine the path for the cache file.
- // NOTE: This devpath is allocated and must be freed.
- //
- FileName = GetCacheFileName (FrameworkHandle);
- if (FileName == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- //
- // First lets open the file if it exists so we can delete it...This is the work around for truncation
- //
- Status = ShellOpenFileByName (
- FileName,
- &FileHandle,
- (EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE),
- 0
- );
-
- if (!EFI_ERROR (Status)) {
- //
- // If file handle above was opened it will be closed by the delete.
- //
- Status = ShellDeleteFile (&FileHandle);
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a failed to delete file %r\n", __func__, Status));
- }
- }
-
- //
- // Now that we know the path to the file... let's open it for writing.
- //
- Status = ShellOpenFileByName (
- FileName,
- &FileHandle,
- (EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE),
- 0
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a - Opening file for writing failed! %r\n", __func__, Status));
- goto Exit;
- }
-
- //
- // Write the data to the file.
- //
- WriteCount = SaveStateSize;
- DEBUG ((DEBUG_INFO, "%a - Writing %d bytes to file...\n", __func__, WriteCount));
- Status = ShellWriteFile (
- FileHandle,
- &WriteCount,
- SaveData
- );
-
- if (EFI_ERROR (Status) || (WriteCount != SaveStateSize)) {
- DEBUG ((DEBUG_ERROR, "%a - Writing to file failed! %r\n", __func__, Status));
- } else {
- DEBUG ((DEBUG_INFO, "%a - SUCCESS!\n", __func__));
- }
-
- //
- // No matter what, we should probably close the file.
- //
- ShellCloseFile (&FileHandle);
-
-Exit:
- if (FileName != NULL) {
- FreePool (FileName);
- }
-
- return Status;
-}
-
-/**
- Will retrieve any cached state associated with the given framework.
- Will allocate a buffer to hold the loaded data.
-
- @param[in] FrameworkHandle A pointer to the framework that is being persisted.
- @param[out] SaveData A pointer pointer that will be updated with the address
- of the loaded data buffer.
- @param[out] SaveStateSize Return the size of SaveData in bytes.
-
- @retval EFI_SUCCESS Data has been loaded successfully and SaveData is updated
- with a pointer to the buffer.
- @retval Others An error has occurred and no data has been loaded. SaveData
- is set to NULL.
-
-**/
-EFI_STATUS
-EFIAPI
-LoadUnitTestCache (
- IN UNIT_TEST_FRAMEWORK_HANDLE FrameworkHandle,
- OUT VOID **SaveData,
- OUT UINTN *SaveStateSize
- )
-{
- EFI_STATUS Status;
- CHAR16 *FileName;
- SHELL_FILE_HANDLE FileHandle;
- BOOLEAN IsFileOpened;
- UINT64 LargeFileSize;
- UINTN FileSize;
- VOID *Buffer;
-
- IsFileOpened = FALSE;
- Buffer = NULL;
-
- //
- // Check the inputs for sanity.
- //
- if ((FrameworkHandle == NULL) || (SaveData == NULL)) {
- return EFI_INVALID_PARAMETER;
- }
-
- //
- // Determine the path for the cache file.
- // NOTE: This devpath is allocated and must be freed.
- //
- FileName = GetCacheFileName (FrameworkHandle);
- if (FileName == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- //
- // Now that we know the path to the file... let's open it for writing.
- //
- Status = ShellOpenFileByName (
- FileName,
- &FileHandle,
- EFI_FILE_MODE_READ,
- 0
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a - Opening file for writing failed! %r\n", __func__, Status));
- goto Exit;
- } else {
- IsFileOpened = TRUE;
- }
-
- //
- // Now that the file is opened, we need to determine how large a buffer we need.
- //
- Status = ShellGetFileSize (FileHandle, &LargeFileSize);
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a - Failed to determine file size! %r\n", __func__, Status));
- goto Exit;
- }
-
- //
- // Now that we know the size, let's allocated a buffer to hold the contents.
- //
- FileSize = (UINTN)LargeFileSize; // You know what... if it's too large, this lib don't care.
- *SaveStateSize = FileSize;
- Buffer = AllocatePool (FileSize);
- if (Buffer == NULL) {
- DEBUG ((DEBUG_ERROR, "%a - Failed to allocate a pool to hold the file contents! %r\n", __func__, Status));
- Status = EFI_OUT_OF_RESOURCES;
- goto Exit;
- }
-
- //
- // Finally, let's read the data.
- //
- Status = ShellReadFile (FileHandle, &FileSize, Buffer);
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "%a - Failed to read the file contents! %r\n", __func__, Status));
- }
-
-Exit:
- //
- // Free allocated buffers
- //
- if (FileName != NULL) {
- FreePool (FileName);
- }
-
- if (IsFileOpened) {
- ShellCloseFile (&FileHandle);
- }
-
- //
- // If we're returning an error, make sure
- // the state is sane.
- if (EFI_ERROR (Status) && (Buffer != NULL)) {
- FreePool (Buffer);
- Buffer = NULL;
- }
-
- *SaveData = Buffer;
- return Status;
-}
-
-/**
- Shell based UnitTestPersistenceLib library constructor.
-
- @param[in] ImageHandle The firmware allocated handle for the EFI image.
- @param[in] SystemTable A pointer to the EFI System Table.
-
- @retval EFI_SUCCESS The constructor finished successfully.
- @retval Others Error codes returned from gBS->HandleProtocol.
- **/
-EFI_STATUS
-EFIAPI
-UnitTestPersistenceLibConstructor (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- )
-{
- UINTN Index;
- UINTN Argc;
- CHAR16 **Argv;
- EFI_STATUS Status;
- EFI_SHELL_PARAMETERS_PROTOCOL *ShellParameters;
-
- Status = gBS->HandleProtocol (
- gImageHandle,
- &gEfiShellParametersProtocolGuid,
- (VOID **)&ShellParameters
- );
- if (EFI_ERROR (Status)) {
- ASSERT_EFI_ERROR (Status);
- goto Done;
- }
-
- Argc = ShellParameters->Argc;
- Argv = ShellParameters->Argv;
-
- Status = EFI_SUCCESS;
- if ((Argc > 1) && (Argv != NULL)) {
- // This might be our cue, check for whether we need to do anything
- for (Index = 1; Index < Argc; Index++) {
- if (StrCmp (Argv[Index], L"--CachePath") == 0) {
- // Need to update the potential cache path to designated path
- if (Index < Argc - 1) {
- mCachePath = Argv[Index + 1];
- } else {
- Print (L" --CachePath <Path of where to save unit test cache files, i.e. FS0:TestFolder>\n");
- }
- }
- }
- }
-
-Done:
- return Status;
-}
+/** @file + This is an instance of the Unit Test Persistence Lib that will utilize + the filesystem that a test application is running from to save a serialized + version of the internal test state in case the test needs to quit and restore. + + Copyright (c) Microsoft Corporation.<BR> + Copyright (c) 2022, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include <PiDxe.h> +#include <Library/UnitTestPersistenceLib.h> +#include <Library/BaseLib.h> +#include <Library/DebugLib.h> +#include <Library/MemoryAllocationLib.h> +#include <Library/UefiBootServicesTableLib.h> +#include <Library/DevicePathLib.h> +#include <Library/ShellLib.h> +#include <Library/UefiLib.h> +#include <Protocol/LoadedImage.h> +#include <UnitTestFrameworkTypes.h> + +#define CACHE_FILE_SUFFIX L"_Cache.dat" + +CHAR16 *mCachePath = NULL; + +/** + Generate the file name and path to the cache file. + + @param[in] FrameworkHandle A pointer to the framework that is being persisted. + + @retval !NULL A pointer to the EFI_FILE protocol instance for the filesystem. + @retval NULL Filesystem could not be found or an error occurred. + +**/ +STATIC +CHAR16 * +GetCacheFileName ( + IN UNIT_TEST_FRAMEWORK_HANDLE FrameworkHandle + ) +{ + EFI_STATUS Status; + UNIT_TEST_FRAMEWORK *Framework; + EFI_LOADED_IMAGE_PROTOCOL *LoadedImage; + CHAR16 *AppPath; + CHAR16 *CacheFilePath; + CHAR16 *TestName; + UINTN DirectorySlashOffset; + UINTN CacheFilePathLength; + + Framework = (UNIT_TEST_FRAMEWORK *)FrameworkHandle; + AppPath = NULL; + CacheFilePath = NULL; + TestName = NULL; + + // + // First, we need to get some information from the loaded image. + // + Status = gBS->HandleProtocol ( + gImageHandle, + &gEfiLoadedImageProtocolGuid, + (VOID **)&LoadedImage + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_WARN, "%a - Failed to locate DevicePath for loaded image. %r\n", __func__, Status)); + return NULL; + } + + // + // Before we can start, change test name from ASCII to Unicode. + // + CacheFilePathLength = AsciiStrLen (Framework->ShortTitle) + 1; + TestName = AllocatePool (CacheFilePathLength * sizeof (CHAR16)); + if (!TestName) { + goto Exit; + } + + AsciiStrToUnicodeStrS (Framework->ShortTitle, TestName, CacheFilePathLength); + + // + // Now we should have the device path of the root device and a file path for the rest. + // In order to target the directory for the test application, we must process + // the file path a little. + // + // NOTE: This may not be necessary... Path processing functions exist... + // PathCleanUpDirectories (FileNameCopy); + // if (PathRemoveLastItem (FileNameCopy)) { + // + if (mCachePath == NULL) { + AppPath = ConvertDevicePathToText (LoadedImage->FilePath, TRUE, TRUE); // NOTE: This must be freed. + if (AppPath == NULL) { + goto Exit; + } + + DirectorySlashOffset = StrLen (AppPath); + // + // Make sure we didn't get any weird data. + // + if (DirectorySlashOffset == 0) { + DEBUG ((DEBUG_ERROR, "%a - Weird 0-length string when processing app path.\n", __func__)); + goto Exit; + } + + // + // Now that we know we have a decent string, let's take a deeper look. + // + do { + if (AppPath[DirectorySlashOffset] == L'\\') { + break; + } + + DirectorySlashOffset--; + } while (DirectorySlashOffset > 0); + + // + // After that little maneuver, DirectorySlashOffset should be pointing at the last '\' in AppString. + // That would be the path to the parent directory that the test app is executing from. + // Let's check and make sure that's right. + // + if (AppPath[DirectorySlashOffset] != L'\\') { + DEBUG ((DEBUG_ERROR, "%a - Could not find a single directory separator in app path.\n", __func__)); + goto Exit; + } + } else { + AppPath = FullyQualifyPath (mCachePath); // NOTE: This must be freed. + if (AppPath == NULL) { + goto Exit; + } + + DirectorySlashOffset = StrLen (AppPath); + + if (AppPath[DirectorySlashOffset - 1] != L'\\') { + // Set the slash if user did not specify it on the newly allocated pool + AppPath = ReallocatePool ( + (DirectorySlashOffset + 1) * sizeof (CHAR16), + (DirectorySlashOffset + 2) * sizeof (CHAR16), + AppPath + ); + AppPath[DirectorySlashOffset] = L'\\'; + AppPath[DirectorySlashOffset + 1] = L'\0'; + } else { + // Otherwise the user input is good enough to go, mostly + DirectorySlashOffset--; + } + } + + // + // Now we know some things, we're ready to produce our output string, I think. + // + CacheFilePathLength = DirectorySlashOffset + 1; + CacheFilePathLength += StrLen (TestName); + CacheFilePathLength += StrLen (CACHE_FILE_SUFFIX); + CacheFilePathLength += 1; // Don't forget the NULL terminator. + CacheFilePath = AllocateZeroPool (CacheFilePathLength * sizeof (CHAR16)); + if (!CacheFilePath) { + goto Exit; + } + + // + // Let's produce our final path string, shall we? + // + StrnCpyS (CacheFilePath, CacheFilePathLength, AppPath, DirectorySlashOffset + 1); // Copy the path for the parent directory. + StrCatS (CacheFilePath, CacheFilePathLength, TestName); // Copy the base name for the test cache. + StrCatS (CacheFilePath, CacheFilePathLength, CACHE_FILE_SUFFIX); // Copy the file suffix. + +Exit: + // + // Free allocated buffers. + // + if (AppPath != NULL) { + FreePool (AppPath); + } + + if (TestName != NULL) { + FreePool (TestName); + } + + return CacheFilePath; +} + +/** + Determines whether a persistence cache already exists for + the given framework. + + @param[in] FrameworkHandle A pointer to the framework that is being persisted. + + @retval TRUE + @retval FALSE Cache doesn't exist or an error occurred. + +**/ +BOOLEAN +EFIAPI +DoesCacheExist ( + IN UNIT_TEST_FRAMEWORK_HANDLE FrameworkHandle + ) +{ + CHAR16 *FileName; + EFI_STATUS Status; + SHELL_FILE_HANDLE FileHandle; + + // + // NOTE: This devpath is allocated and must be freed. + // + FileName = GetCacheFileName (FrameworkHandle); + if (FileName == NULL) { + return FALSE; + } + + // + // Check to see whether the file exists. If the file can be opened for + // reading, it exists. Otherwise, probably not. + // + Status = ShellOpenFileByName ( + FileName, + &FileHandle, + EFI_FILE_MODE_READ, + 0 + ); + if (!EFI_ERROR (Status)) { + ShellCloseFile (&FileHandle); + } + + if (FileName != NULL) { + FreePool (FileName); + } + + DEBUG ((DEBUG_VERBOSE, "%a - Returning %d\n", __func__, !EFI_ERROR (Status))); + + return (!EFI_ERROR (Status)); +} + +/** + Will save the data associated with an internal Unit Test Framework + state in a manner that can persist a Unit Test Application quit or + even a system reboot. + + @param[in] FrameworkHandle A pointer to the framework that is being persisted. + @param[in] SaveData A pointer to the buffer containing the serialized + framework internal state. + @param[in] SaveStateSize The size of SaveData in bytes. + + @retval EFI_SUCCESS Data is persisted and the test can be safely quit. + @retval Others Data is not persisted and test cannot be resumed upon exit. + +**/ +EFI_STATUS +EFIAPI +SaveUnitTestCache ( + IN UNIT_TEST_FRAMEWORK_HANDLE FrameworkHandle, + IN VOID *SaveData, + IN UINTN SaveStateSize + ) +{ + CHAR16 *FileName; + EFI_STATUS Status; + SHELL_FILE_HANDLE FileHandle; + UINTN WriteCount; + + // + // Check the inputs for sanity. + // + if ((FrameworkHandle == NULL) || (SaveData == NULL)) { + return EFI_INVALID_PARAMETER; + } + + // + // Determine the path for the cache file. + // NOTE: This devpath is allocated and must be freed. + // + FileName = GetCacheFileName (FrameworkHandle); + if (FileName == NULL) { + return EFI_INVALID_PARAMETER; + } + + // + // First lets open the file if it exists so we can delete it...This is the work around for truncation + // + Status = ShellOpenFileByName ( + FileName, + &FileHandle, + (EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE), + 0 + ); + + if (!EFI_ERROR (Status)) { + // + // If file handle above was opened it will be closed by the delete. + // + Status = ShellDeleteFile (&FileHandle); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a failed to delete file %r\n", __func__, Status)); + } + } + + // + // Now that we know the path to the file... let's open it for writing. + // + Status = ShellOpenFileByName ( + FileName, + &FileHandle, + (EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE), + 0 + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a - Opening file for writing failed! %r\n", __func__, Status)); + goto Exit; + } + + // + // Write the data to the file. + // + WriteCount = SaveStateSize; + DEBUG ((DEBUG_INFO, "%a - Writing %d bytes to file...\n", __func__, WriteCount)); + Status = ShellWriteFile ( + FileHandle, + &WriteCount, + SaveData + ); + + if (EFI_ERROR (Status) || (WriteCount != SaveStateSize)) { + DEBUG ((DEBUG_ERROR, "%a - Writing to file failed! %r\n", __func__, Status)); + } else { + DEBUG ((DEBUG_INFO, "%a - SUCCESS!\n", __func__)); + } + + // + // No matter what, we should probably close the file. + // + ShellCloseFile (&FileHandle); + +Exit: + if (FileName != NULL) { + FreePool (FileName); + } + + return Status; +} + +/** + Will retrieve any cached state associated with the given framework. + Will allocate a buffer to hold the loaded data. + + @param[in] FrameworkHandle A pointer to the framework that is being persisted. + @param[out] SaveData A pointer pointer that will be updated with the address + of the loaded data buffer. + @param[out] SaveStateSize Return the size of SaveData in bytes. + + @retval EFI_SUCCESS Data has been loaded successfully and SaveData is updated + with a pointer to the buffer. + @retval Others An error has occurred and no data has been loaded. SaveData + is set to NULL. + +**/ +EFI_STATUS +EFIAPI +LoadUnitTestCache ( + IN UNIT_TEST_FRAMEWORK_HANDLE FrameworkHandle, + OUT VOID **SaveData, + OUT UINTN *SaveStateSize + ) +{ + EFI_STATUS Status; + CHAR16 *FileName; + SHELL_FILE_HANDLE FileHandle; + BOOLEAN IsFileOpened; + UINT64 LargeFileSize; + UINTN FileSize; + VOID *Buffer; + + IsFileOpened = FALSE; + Buffer = NULL; + + // + // Check the inputs for sanity. + // + if ((FrameworkHandle == NULL) || (SaveData == NULL)) { + return EFI_INVALID_PARAMETER; + } + + // + // Determine the path for the cache file. + // NOTE: This devpath is allocated and must be freed. + // + FileName = GetCacheFileName (FrameworkHandle); + if (FileName == NULL) { + return EFI_INVALID_PARAMETER; + } + + // + // Now that we know the path to the file... let's open it for writing. + // + Status = ShellOpenFileByName ( + FileName, + &FileHandle, + EFI_FILE_MODE_READ, + 0 + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a - Opening file for writing failed! %r\n", __func__, Status)); + goto Exit; + } else { + IsFileOpened = TRUE; + } + + // + // Now that the file is opened, we need to determine how large a buffer we need. + // + Status = ShellGetFileSize (FileHandle, &LargeFileSize); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a - Failed to determine file size! %r\n", __func__, Status)); + goto Exit; + } + + // + // Now that we know the size, let's allocated a buffer to hold the contents. + // + FileSize = (UINTN)LargeFileSize; // You know what... if it's too large, this lib don't care. + *SaveStateSize = FileSize; + Buffer = AllocatePool (FileSize); + if (Buffer == NULL) { + DEBUG ((DEBUG_ERROR, "%a - Failed to allocate a pool to hold the file contents! %r\n", __func__, Status)); + Status = EFI_OUT_OF_RESOURCES; + goto Exit; + } + + // + // Finally, let's read the data. + // + Status = ShellReadFile (FileHandle, &FileSize, Buffer); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a - Failed to read the file contents! %r\n", __func__, Status)); + } + +Exit: + // + // Free allocated buffers + // + if (FileName != NULL) { + FreePool (FileName); + } + + if (IsFileOpened) { + ShellCloseFile (&FileHandle); + } + + // + // If we're returning an error, make sure + // the state is sane. + if (EFI_ERROR (Status) && (Buffer != NULL)) { + FreePool (Buffer); + Buffer = NULL; + } + + *SaveData = Buffer; + return Status; +} + +/** + Shell based UnitTestPersistenceLib library constructor. + + @param[in] ImageHandle The firmware allocated handle for the EFI image. + @param[in] SystemTable A pointer to the EFI System Table. + + @retval EFI_SUCCESS The constructor finished successfully. + @retval Others Error codes returned from gBS->HandleProtocol. + **/ +EFI_STATUS +EFIAPI +UnitTestPersistenceLibConstructor ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + UINTN Index; + UINTN Argc; + CHAR16 **Argv; + EFI_STATUS Status; + EFI_SHELL_PARAMETERS_PROTOCOL *ShellParameters; + + Status = gBS->HandleProtocol ( + gImageHandle, + &gEfiShellParametersProtocolGuid, + (VOID **)&ShellParameters + ); + if (EFI_ERROR (Status)) { + ASSERT_EFI_ERROR (Status); + goto Done; + } + + Argc = ShellParameters->Argc; + Argv = ShellParameters->Argv; + + Status = EFI_SUCCESS; + if ((Argc > 1) && (Argv != NULL)) { + // This might be our cue, check for whether we need to do anything + for (Index = 1; Index < Argc; Index++) { + if (StrCmp (Argv[Index], L"--CachePath") == 0) { + // Need to update the potential cache path to designated path + if (Index < Argc - 1) { + mCachePath = Argv[Index + 1]; + } else { + Print (L" --CachePath <Path of where to save unit test cache files, i.e. FS0:TestFolder>\n"); + } + } + } + } + +Done: + return Status; +} diff --git a/UnitTestFrameworkPkg/Library/UnitTestPersistenceLibSimpleFileSystem/UnitTestPersistenceLibSimpleFileSystem.inf b/UnitTestFrameworkPkg/Library/UnitTestPersistenceLibSimpleFileSystem/UnitTestPersistenceLibSimpleFileSystem.inf index c518c4e5ce..1b212b20df 100644 --- a/UnitTestFrameworkPkg/Library/UnitTestPersistenceLibSimpleFileSystem/UnitTestPersistenceLibSimpleFileSystem.inf +++ b/UnitTestFrameworkPkg/Library/UnitTestPersistenceLibSimpleFileSystem/UnitTestPersistenceLibSimpleFileSystem.inf @@ -1,47 +1,47 @@ -## @file
-# UEFI Simple File System based version of the Unit Test Persistence Lib
-#
-# Instance of the Unit Test Persistence Lib that utilizes the UEFI filesystem
-# that a test application is running from to save a serialized version of the
-# internal test state in case the test needs to quit and restore.
-#
-# Copyright (c) Microsoft Corporation.<BR>
-# SPDX-License-Identifier: BSD-2-Clause-Patent
-##
-
-[Defines]
- INF_VERSION = 0x00010017
- BASE_NAME = UnitTestPersistenceLibSimpleFileSystem
- MODULE_UNI_FILE = UnitTestPersistenceLibSimpleFileSystem.uni
- FILE_GUID = 9200844A-CDFD-4368-B4BD-106354702605
- VERSION_STRING = 1.0
- MODULE_TYPE = UEFI_APPLICATION
- LIBRARY_CLASS = UnitTestPersistenceLib
-
-#
-# The following information is for reference only and not required by the build tools.
-#
-# VALID_ARCHITECTURES = IA32 X64
-#
-
-[Sources]
- UnitTestPersistenceLibSimpleFileSystem.c
-
-[Packages]
- MdePkg/MdePkg.dec
- UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec
- ShellPkg/ShellPkg.dec
-
-[LibraryClasses]
- DebugLib
- UefiBootServicesTableLib
- BaseLib
- ShellLib
-
-[Protocols]
- gEfiLoadedImageProtocolGuid
- gEfiSimpleFileSystemProtocolGuid
-
-[Guids]
- gEfiFileInfoGuid
- gEfiFileSystemInfoGuid
+## @file +# UEFI Simple File System based version of the Unit Test Persistence Lib +# +# Instance of the Unit Test Persistence Lib that utilizes the UEFI filesystem +# that a test application is running from to save a serialized version of the +# internal test state in case the test needs to quit and restore. +# +# Copyright (c) Microsoft Corporation.<BR> +# SPDX-License-Identifier: BSD-2-Clause-Patent +## + +[Defines] + INF_VERSION = 0x00010017 + BASE_NAME = UnitTestPersistenceLibSimpleFileSystem + MODULE_UNI_FILE = UnitTestPersistenceLibSimpleFileSystem.uni + FILE_GUID = 9200844A-CDFD-4368-B4BD-106354702605 + VERSION_STRING = 1.0 + MODULE_TYPE = UEFI_APPLICATION + LIBRARY_CLASS = UnitTestPersistenceLib + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 +# + +[Sources] + UnitTestPersistenceLibSimpleFileSystem.c + +[Packages] + MdePkg/MdePkg.dec + UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec + ShellPkg/ShellPkg.dec + +[LibraryClasses] + DebugLib + UefiBootServicesTableLib + BaseLib + ShellLib + +[Protocols] + gEfiLoadedImageProtocolGuid + gEfiSimpleFileSystemProtocolGuid + +[Guids] + gEfiFileInfoGuid + gEfiFileSystemInfoGuid diff --git a/UnitTestFrameworkPkg/Library/UnitTestPersistenceLibSimpleFileSystem/UnitTestPersistenceLibSimpleFileSystem.uni b/UnitTestFrameworkPkg/Library/UnitTestPersistenceLibSimpleFileSystem/UnitTestPersistenceLibSimpleFileSystem.uni index e6593be137..402a0142bf 100644 --- a/UnitTestFrameworkPkg/Library/UnitTestPersistenceLibSimpleFileSystem/UnitTestPersistenceLibSimpleFileSystem.uni +++ b/UnitTestFrameworkPkg/Library/UnitTestPersistenceLibSimpleFileSystem/UnitTestPersistenceLibSimpleFileSystem.uni @@ -1,15 +1,15 @@ -// /** @file
-// UEFI Simple File System based version of the Unit Test Persistence Lib
-//
-// Instance of the Unit Test Persistence Lib that utilizes the UEFI filesystem
-// that a test application is running from to save a serialized version of the
-// internal test state in case the test needs to quit and restore.
-//
-// Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
-// SPDX-License-Identifier: BSD-2-Clause-Patent
-//
-// **/
-
-#string STR_MODULE_ABSTRACT #language en-US "UEFI Simple File System based version of the Unit Test Persistence Lib"
-
-#string STR_MODULE_DESCRIPTION #language en-US "UEFI Simple File System based version of the Unit Test Persistence Lib."
+// /** @file +// UEFI Simple File System based version of the Unit Test Persistence Lib +// +// Instance of the Unit Test Persistence Lib that utilizes the UEFI filesystem +// that a test application is running from to save a serialized version of the +// internal test state in case the test needs to quit and restore. +// +// Copyright (c) 2020, Intel Corporation. All rights reserved.<BR> +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + +#string STR_MODULE_ABSTRACT #language en-US "UEFI Simple File System based version of the Unit Test Persistence Lib" + +#string STR_MODULE_DESCRIPTION #language en-US "UEFI Simple File System based version of the Unit Test Persistence Lib." diff --git a/UnitTestFrameworkPkg/Library/UnitTestResultReportLib/UnitTestResultReportLib.c b/UnitTestFrameworkPkg/Library/UnitTestResultReportLib/UnitTestResultReportLib.c index 5e2973beb3..95adaa5613 100644 --- a/UnitTestFrameworkPkg/Library/UnitTestResultReportLib/UnitTestResultReportLib.c +++ b/UnitTestFrameworkPkg/Library/UnitTestResultReportLib/UnitTestResultReportLib.c @@ -1,221 +1,221 @@ -/** @file
- Implement UnitTestResultReportLib doing plain txt out to console
-
- Copyright (c) Microsoft Corporation.<BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
-**/
-
-#include <Uefi.h>
-#include <Library/UnitTestResultReportLib.h>
-#include <Library/BaseLib.h>
-#include <Library/DebugLib.h>
-
-VOID
-EFIAPI
-ReportPrint (
- IN CONST CHAR8 *Format,
- ...
- );
-
-VOID
-ReportOutput (
- IN CONST CHAR8 *Output
- );
-
-struct _UNIT_TEST_STATUS_STRING {
- UNIT_TEST_STATUS Status;
- CHAR8 *String;
-};
-
-struct _UNIT_TEST_FAILURE_TYPE_STRING {
- FAILURE_TYPE Type;
- CHAR8 *String;
-};
-
-struct _UNIT_TEST_STATUS_STRING mStatusStrings[] = {
- { UNIT_TEST_PASSED, "PASSED" },
- { UNIT_TEST_ERROR_PREREQUISITE_NOT_MET, "NOT RUN - PREREQUISITE FAILED" },
- { UNIT_TEST_ERROR_TEST_FAILED, "FAILED" },
- { UNIT_TEST_RUNNING, "RUNNING" },
- { UNIT_TEST_PENDING, "PENDING" },
- { 0, "**UNKNOWN**" }
-};
-
-struct _UNIT_TEST_FAILURE_TYPE_STRING mFailureTypeStrings[] = {
- { FAILURETYPE_NOFAILURE, "NO FAILURE" },
- { FAILURETYPE_OTHER, "OTHER FAILURE" },
- { FAILURETYPE_ASSERTTRUE, "ASSERT_TRUE FAILURE" },
- { FAILURETYPE_ASSERTFALSE, "ASSERT_FALSE FAILURE" },
- { FAILURETYPE_ASSERTEQUAL, "ASSERT_EQUAL FAILURE" },
- { FAILURETYPE_ASSERTNOTEQUAL, "ASSERT_NOTEQUAL FAILURE" },
- { FAILURETYPE_ASSERTNOTEFIERROR, "ASSERT_NOTEFIERROR FAILURE" },
- { FAILURETYPE_ASSERTSTATUSEQUAL, "ASSERT_STATUSEQUAL FAILURE" },
- { FAILURETYPE_ASSERTNOTNULL, "ASSERT_NOTNULL FAILURE" },
- { FAILURETYPE_EXPECTASSERT, "EXPECT_ASSERT FAILURE" },
- { 0, "*UNKNOWN* Failure" }
-};
-
-//
-// TEST REPORTING FUNCTIONS
-//
-
-STATIC
-CONST CHAR8 *
-GetStringForUnitTestStatus (
- IN UNIT_TEST_STATUS Status
- )
-{
- UINTN Index;
-
- for (Index = 0; Index < ARRAY_SIZE (mStatusStrings) - 1; Index++) {
- if (mStatusStrings[Index].Status == Status) {
- //
- // Return string from matching entry
- //
- return mStatusStrings[Index].String;
- }
- }
-
- //
- // Return last entry if no match found.
- //
- return mStatusStrings[Index].String;
-}
-
-STATIC
-CONST CHAR8 *
-GetStringForFailureType (
- IN FAILURE_TYPE Failure
- )
-{
- UINTN Index;
-
- for (Index = 0; Index < ARRAY_SIZE (mFailureTypeStrings) - 1; Index++) {
- if (mFailureTypeStrings[Index].Type == Failure) {
- //
- // Return string from matching entry
- //
- return mFailureTypeStrings[Index].String;
- }
- }
-
- //
- // Return last entry if no match found.
- //
- DEBUG ((DEBUG_INFO, "%a Failure Type does not have string defined 0x%X\n", __func__, (UINT32)Failure));
- return mFailureTypeStrings[Index].String;
-}
-
-/*
- Method to print the Unit Test run results
-
- @retval Success
-*/
-EFI_STATUS
-EFIAPI
-OutputUnitTestFrameworkReport (
- IN UNIT_TEST_FRAMEWORK_HANDLE FrameworkHandle
- )
-{
- UNIT_TEST_FRAMEWORK *Framework;
- INTN Passed;
- INTN Failed;
- INTN NotRun;
- UNIT_TEST_SUITE_LIST_ENTRY *Suite;
- UNIT_TEST_LIST_ENTRY *Test;
- INTN SPassed;
- INTN SFailed;
- INTN SNotRun;
-
- Passed = 0;
- Failed = 0;
- NotRun = 0;
- Suite = NULL;
-
- Framework = (UNIT_TEST_FRAMEWORK *)FrameworkHandle;
- if (Framework == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- ReportPrint ("---------------------------------------------------------\n");
- ReportPrint ("------------- UNIT TEST FRAMEWORK RESULTS ---------------\n");
- ReportPrint ("---------------------------------------------------------\n");
-
- // print the version and time
-
- //
- // Iterate all suites
- //
- for (Suite = (UNIT_TEST_SUITE_LIST_ENTRY *)GetFirstNode (&Framework->TestSuiteList);
- (LIST_ENTRY *)Suite != &Framework->TestSuiteList;
- Suite = (UNIT_TEST_SUITE_LIST_ENTRY *)GetNextNode (&Framework->TestSuiteList, (LIST_ENTRY *)Suite))
- {
- Test = NULL;
- SPassed = 0;
- SFailed = 0;
- SNotRun = 0;
-
- ReportPrint ("/////////////////////////////////////////////////////////\n");
- ReportPrint (" SUITE: %a\n", Suite->UTS.Title);
- ReportPrint (" PACKAGE: %a\n", Suite->UTS.Name);
- ReportPrint ("/////////////////////////////////////////////////////////\n");
-
- //
- // Iterate all tests within the suite
- //
- for (Test = (UNIT_TEST_LIST_ENTRY *)GetFirstNode (&(Suite->UTS.TestCaseList));
- (LIST_ENTRY *)Test != &(Suite->UTS.TestCaseList);
- Test = (UNIT_TEST_LIST_ENTRY *)GetNextNode (&(Suite->UTS.TestCaseList), (LIST_ENTRY *)Test))
- {
- ReportPrint ("*********************************************************\n");
- ReportPrint (" CLASS NAME: %a\n", Test->UT.Name);
- ReportPrint (" TEST: %a\n", Test->UT.Description);
- ReportPrint (" STATUS: %a\n", GetStringForUnitTestStatus (Test->UT.Result));
- ReportPrint (" FAILURE: %a\n", GetStringForFailureType (Test->UT.FailureType));
- ReportPrint (" FAILURE MESSAGE:\n%a\n", Test->UT.FailureMessage);
-
- if (Test->UT.Log != NULL) {
- ReportPrint (" LOG:\n");
- ReportOutput (Test->UT.Log);
- }
-
- switch (Test->UT.Result) {
- case UNIT_TEST_PASSED:
- SPassed++;
- break;
- case UNIT_TEST_ERROR_TEST_FAILED:
- SFailed++;
- break;
- case UNIT_TEST_PENDING: // Fall through...
- case UNIT_TEST_RUNNING: // Fall through...
- case UNIT_TEST_ERROR_PREREQUISITE_NOT_MET:
- SNotRun++;
- break;
- default:
- break;
- }
-
- ReportPrint ("**********************************************************\n");
- } // End Test iteration
-
- ReportPrint ("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n");
- ReportPrint ("Suite Stats\n");
- ReportPrint (" Passed: %d (%d%%)\n", SPassed, (SPassed * 100)/(SPassed+SFailed+SNotRun));
- ReportPrint (" Failed: %d (%d%%)\n", SFailed, (SFailed * 100) / (SPassed + SFailed + SNotRun));
- ReportPrint (" Not Run: %d (%d%%)\n", SNotRun, (SNotRun * 100) / (SPassed + SFailed + SNotRun));
- ReportPrint ("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n");
-
- Passed += SPassed; // add to global counters
- Failed += SFailed; // add to global counters
- NotRun += SNotRun; // add to global counters
- }// End Suite iteration
-
- ReportPrint ("=========================================================\n");
- ReportPrint ("Total Stats\n");
- ReportPrint (" Passed: %d (%d%%)\n", Passed, (Passed * 100) / (Passed + Failed + NotRun));
- ReportPrint (" Failed: %d (%d%%)\n", Failed, (Failed * 100) / (Passed + Failed + NotRun));
- ReportPrint (" Not Run: %d (%d%%)\n", NotRun, (NotRun * 100) / (Passed + Failed + NotRun));
- ReportPrint ("=========================================================\n");
-
- return EFI_SUCCESS;
-}
+/** @file + Implement UnitTestResultReportLib doing plain txt out to console + + Copyright (c) Microsoft Corporation.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include <Uefi.h> +#include <Library/UnitTestResultReportLib.h> +#include <Library/BaseLib.h> +#include <Library/DebugLib.h> + +VOID +EFIAPI +ReportPrint ( + IN CONST CHAR8 *Format, + ... + ); + +VOID +ReportOutput ( + IN CONST CHAR8 *Output + ); + +struct _UNIT_TEST_STATUS_STRING { + UNIT_TEST_STATUS Status; + CHAR8 *String; +}; + +struct _UNIT_TEST_FAILURE_TYPE_STRING { + FAILURE_TYPE Type; + CHAR8 *String; +}; + +struct _UNIT_TEST_STATUS_STRING mStatusStrings[] = { + { UNIT_TEST_PASSED, "PASSED" }, + { UNIT_TEST_ERROR_PREREQUISITE_NOT_MET, "NOT RUN - PREREQUISITE FAILED" }, + { UNIT_TEST_ERROR_TEST_FAILED, "FAILED" }, + { UNIT_TEST_RUNNING, "RUNNING" }, + { UNIT_TEST_PENDING, "PENDING" }, + { 0, "**UNKNOWN**" } +}; + +struct _UNIT_TEST_FAILURE_TYPE_STRING mFailureTypeStrings[] = { + { FAILURETYPE_NOFAILURE, "NO FAILURE" }, + { FAILURETYPE_OTHER, "OTHER FAILURE" }, + { FAILURETYPE_ASSERTTRUE, "ASSERT_TRUE FAILURE" }, + { FAILURETYPE_ASSERTFALSE, "ASSERT_FALSE FAILURE" }, + { FAILURETYPE_ASSERTEQUAL, "ASSERT_EQUAL FAILURE" }, + { FAILURETYPE_ASSERTNOTEQUAL, "ASSERT_NOTEQUAL FAILURE" }, + { FAILURETYPE_ASSERTNOTEFIERROR, "ASSERT_NOTEFIERROR FAILURE" }, + { FAILURETYPE_ASSERTSTATUSEQUAL, "ASSERT_STATUSEQUAL FAILURE" }, + { FAILURETYPE_ASSERTNOTNULL, "ASSERT_NOTNULL FAILURE" }, + { FAILURETYPE_EXPECTASSERT, "EXPECT_ASSERT FAILURE" }, + { 0, "*UNKNOWN* Failure" } +}; + +// +// TEST REPORTING FUNCTIONS +// + +STATIC +CONST CHAR8 * +GetStringForUnitTestStatus ( + IN UNIT_TEST_STATUS Status + ) +{ + UINTN Index; + + for (Index = 0; Index < ARRAY_SIZE (mStatusStrings) - 1; Index++) { + if (mStatusStrings[Index].Status == Status) { + // + // Return string from matching entry + // + return mStatusStrings[Index].String; + } + } + + // + // Return last entry if no match found. + // + return mStatusStrings[Index].String; +} + +STATIC +CONST CHAR8 * +GetStringForFailureType ( + IN FAILURE_TYPE Failure + ) +{ + UINTN Index; + + for (Index = 0; Index < ARRAY_SIZE (mFailureTypeStrings) - 1; Index++) { + if (mFailureTypeStrings[Index].Type == Failure) { + // + // Return string from matching entry + // + return mFailureTypeStrings[Index].String; + } + } + + // + // Return last entry if no match found. + // + DEBUG ((DEBUG_INFO, "%a Failure Type does not have string defined 0x%X\n", __func__, (UINT32)Failure)); + return mFailureTypeStrings[Index].String; +} + +/* + Method to print the Unit Test run results + + @retval Success +*/ +EFI_STATUS +EFIAPI +OutputUnitTestFrameworkReport ( + IN UNIT_TEST_FRAMEWORK_HANDLE FrameworkHandle + ) +{ + UNIT_TEST_FRAMEWORK *Framework; + INTN Passed; + INTN Failed; + INTN NotRun; + UNIT_TEST_SUITE_LIST_ENTRY *Suite; + UNIT_TEST_LIST_ENTRY *Test; + INTN SPassed; + INTN SFailed; + INTN SNotRun; + + Passed = 0; + Failed = 0; + NotRun = 0; + Suite = NULL; + + Framework = (UNIT_TEST_FRAMEWORK *)FrameworkHandle; + if (Framework == NULL) { + return EFI_INVALID_PARAMETER; + } + + ReportPrint ("---------------------------------------------------------\n"); + ReportPrint ("------------- UNIT TEST FRAMEWORK RESULTS ---------------\n"); + ReportPrint ("---------------------------------------------------------\n"); + + // print the version and time + + // + // Iterate all suites + // + for (Suite = (UNIT_TEST_SUITE_LIST_ENTRY *)GetFirstNode (&Framework->TestSuiteList); + (LIST_ENTRY *)Suite != &Framework->TestSuiteList; + Suite = (UNIT_TEST_SUITE_LIST_ENTRY *)GetNextNode (&Framework->TestSuiteList, (LIST_ENTRY *)Suite)) + { + Test = NULL; + SPassed = 0; + SFailed = 0; + SNotRun = 0; + + ReportPrint ("/////////////////////////////////////////////////////////\n"); + ReportPrint (" SUITE: %a\n", Suite->UTS.Title); + ReportPrint (" PACKAGE: %a\n", Suite->UTS.Name); + ReportPrint ("/////////////////////////////////////////////////////////\n"); + + // + // Iterate all tests within the suite + // + for (Test = (UNIT_TEST_LIST_ENTRY *)GetFirstNode (&(Suite->UTS.TestCaseList)); + (LIST_ENTRY *)Test != &(Suite->UTS.TestCaseList); + Test = (UNIT_TEST_LIST_ENTRY *)GetNextNode (&(Suite->UTS.TestCaseList), (LIST_ENTRY *)Test)) + { + ReportPrint ("*********************************************************\n"); + ReportPrint (" CLASS NAME: %a\n", Test->UT.Name); + ReportPrint (" TEST: %a\n", Test->UT.Description); + ReportPrint (" STATUS: %a\n", GetStringForUnitTestStatus (Test->UT.Result)); + ReportPrint (" FAILURE: %a\n", GetStringForFailureType (Test->UT.FailureType)); + ReportPrint (" FAILURE MESSAGE:\n%a\n", Test->UT.FailureMessage); + + if (Test->UT.Log != NULL) { + ReportPrint (" LOG:\n"); + ReportOutput (Test->UT.Log); + } + + switch (Test->UT.Result) { + case UNIT_TEST_PASSED: + SPassed++; + break; + case UNIT_TEST_ERROR_TEST_FAILED: + SFailed++; + break; + case UNIT_TEST_PENDING: // Fall through... + case UNIT_TEST_RUNNING: // Fall through... + case UNIT_TEST_ERROR_PREREQUISITE_NOT_MET: + SNotRun++; + break; + default: + break; + } + + ReportPrint ("**********************************************************\n"); + } // End Test iteration + + ReportPrint ("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n"); + ReportPrint ("Suite Stats\n"); + ReportPrint (" Passed: %d (%d%%)\n", SPassed, (SPassed * 100)/(SPassed+SFailed+SNotRun)); + ReportPrint (" Failed: %d (%d%%)\n", SFailed, (SFailed * 100) / (SPassed + SFailed + SNotRun)); + ReportPrint (" Not Run: %d (%d%%)\n", SNotRun, (SNotRun * 100) / (SPassed + SFailed + SNotRun)); + ReportPrint ("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n"); + + Passed += SPassed; // add to global counters + Failed += SFailed; // add to global counters + NotRun += SNotRun; // add to global counters + }// End Suite iteration + + ReportPrint ("=========================================================\n"); + ReportPrint ("Total Stats\n"); + ReportPrint (" Passed: %d (%d%%)\n", Passed, (Passed * 100) / (Passed + Failed + NotRun)); + ReportPrint (" Failed: %d (%d%%)\n", Failed, (Failed * 100) / (Passed + Failed + NotRun)); + ReportPrint (" Not Run: %d (%d%%)\n", NotRun, (NotRun * 100) / (Passed + Failed + NotRun)); + ReportPrint ("=========================================================\n"); + + return EFI_SUCCESS; +} diff --git a/UnitTestFrameworkPkg/Library/UnitTestResultReportLib/UnitTestResultReportLibConOut.c b/UnitTestFrameworkPkg/Library/UnitTestResultReportLib/UnitTestResultReportLibConOut.c index 3bcbf557a1..e92ab433e5 100644 --- a/UnitTestFrameworkPkg/Library/UnitTestResultReportLib/UnitTestResultReportLibConOut.c +++ b/UnitTestFrameworkPkg/Library/UnitTestResultReportLib/UnitTestResultReportLibConOut.c @@ -1,50 +1,50 @@ -/** @file
- Implement UnitTestResultReportLib doing plain txt out to console
-
- Copyright (c) Microsoft Corporation.<BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
-**/
-
-#include <Uefi.h>
-#include <Library/BaseLib.h>
-#include <Library/PrintLib.h>
-#include <Library/UefiBootServicesTableLib.h>
-#include <Library/DebugLib.h>
-
-VOID
-EFIAPI
-ReportPrint (
- IN CONST CHAR8 *Format,
- ...
- )
-{
- VA_LIST Marker;
- CHAR16 String[256];
- UINTN Length;
-
- VA_START (Marker, Format);
- Length = UnicodeVSPrintAsciiFormat (String, sizeof (String), Format, Marker);
- if (Length == 0) {
- DEBUG ((DEBUG_ERROR, "%a formatted string is too long\n", __func__));
- } else {
- gST->ConOut->OutputString (gST->ConOut, String);
- }
-
- VA_END (Marker);
-}
-
-VOID
-ReportOutput (
- IN CONST CHAR8 *Output
- )
-{
- CHAR8 AsciiString[128];
- UINTN Length;
- UINTN Index;
-
- Length = AsciiStrLen (Output);
- for (Index = 0; Index < Length; Index += (sizeof (AsciiString) - 1)) {
- AsciiStrnCpyS (AsciiString, sizeof (AsciiString), &Output[Index], sizeof (AsciiString) - 1);
- ReportPrint ("%a", AsciiString);
- }
-}
+/** @file + Implement UnitTestResultReportLib doing plain txt out to console + + Copyright (c) Microsoft Corporation.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include <Uefi.h> +#include <Library/BaseLib.h> +#include <Library/PrintLib.h> +#include <Library/UefiBootServicesTableLib.h> +#include <Library/DebugLib.h> + +VOID +EFIAPI +ReportPrint ( + IN CONST CHAR8 *Format, + ... + ) +{ + VA_LIST Marker; + CHAR16 String[256]; + UINTN Length; + + VA_START (Marker, Format); + Length = UnicodeVSPrintAsciiFormat (String, sizeof (String), Format, Marker); + if (Length == 0) { + DEBUG ((DEBUG_ERROR, "%a formatted string is too long\n", __func__)); + } else { + gST->ConOut->OutputString (gST->ConOut, String); + } + + VA_END (Marker); +} + +VOID +ReportOutput ( + IN CONST CHAR8 *Output + ) +{ + CHAR8 AsciiString[128]; + UINTN Length; + UINTN Index; + + Length = AsciiStrLen (Output); + for (Index = 0; Index < Length; Index += (sizeof (AsciiString) - 1)) { + AsciiStrnCpyS (AsciiString, sizeof (AsciiString), &Output[Index], sizeof (AsciiString) - 1); + ReportPrint ("%a", AsciiString); + } +} diff --git a/UnitTestFrameworkPkg/Library/UnitTestResultReportLib/UnitTestResultReportLibConOut.inf b/UnitTestFrameworkPkg/Library/UnitTestResultReportLib/UnitTestResultReportLibConOut.inf index 4382199fbc..619593be18 100644 --- a/UnitTestFrameworkPkg/Library/UnitTestResultReportLib/UnitTestResultReportLibConOut.inf +++ b/UnitTestFrameworkPkg/Library/UnitTestResultReportLib/UnitTestResultReportLibConOut.inf @@ -1,29 +1,29 @@ -## @file
-# Library to support printing out the unit test report to a UEFI console
-#
-# Copyright (c) Microsoft Corporation.<BR>
-# SPDX-License-Identifier: BSD-2-Clause-Patent
-##
-
-[Defines]
- INF_VERSION = 0x00010017
- BASE_NAME = UnitTestResultReportLibConOut
- MODULE_UNI_FILE = UnitTestResultReportLibConOut.uni
- FILE_GUID = C659641D-BA1F-4B58-946E-B1E1103903F9
- VERSION_STRING = 1.0
- MODULE_TYPE = UEFI_DRIVER
- LIBRARY_CLASS = UnitTestResultReportLib
-
-[LibraryClasses]
- BaseLib
- DebugLib
- UefiBootServicesTableLib
- PrintLib
-
-[Packages]
- MdePkg/MdePkg.dec
- UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec
-
-[Sources]
- UnitTestResultReportLib.c
- UnitTestResultReportLibConOut.c
+## @file +# Library to support printing out the unit test report to a UEFI console +# +# Copyright (c) Microsoft Corporation.<BR> +# SPDX-License-Identifier: BSD-2-Clause-Patent +## + +[Defines] + INF_VERSION = 0x00010017 + BASE_NAME = UnitTestResultReportLibConOut + MODULE_UNI_FILE = UnitTestResultReportLibConOut.uni + FILE_GUID = C659641D-BA1F-4B58-946E-B1E1103903F9 + VERSION_STRING = 1.0 + MODULE_TYPE = UEFI_DRIVER + LIBRARY_CLASS = UnitTestResultReportLib + +[LibraryClasses] + BaseLib + DebugLib + UefiBootServicesTableLib + PrintLib + +[Packages] + MdePkg/MdePkg.dec + UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec + +[Sources] + UnitTestResultReportLib.c + UnitTestResultReportLibConOut.c diff --git a/UnitTestFrameworkPkg/Library/UnitTestResultReportLib/UnitTestResultReportLibConOut.uni b/UnitTestFrameworkPkg/Library/UnitTestResultReportLib/UnitTestResultReportLibConOut.uni index 92ba1b84da..d54d9b29fd 100644 --- a/UnitTestFrameworkPkg/Library/UnitTestResultReportLib/UnitTestResultReportLibConOut.uni +++ b/UnitTestFrameworkPkg/Library/UnitTestResultReportLib/UnitTestResultReportLibConOut.uni @@ -1,11 +1,11 @@ -// /** @file
-// Library to support printing out the unit test report to a UEFI console
-//
-// Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
-// SPDX-License-Identifier: BSD-2-Clause-Patent
-//
-// **/
-
-#string STR_MODULE_ABSTRACT #language en-US "Library to support printing out the unit test report to a UEFI console"
-
-#string STR_MODULE_DESCRIPTION #language en-US "Library to support printing out the unit test report to a UEFI console."
+// /** @file +// Library to support printing out the unit test report to a UEFI console +// +// Copyright (c) 2020, Intel Corporation. All rights reserved.<BR> +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + +#string STR_MODULE_ABSTRACT #language en-US "Library to support printing out the unit test report to a UEFI console" + +#string STR_MODULE_DESCRIPTION #language en-US "Library to support printing out the unit test report to a UEFI console." diff --git a/UnitTestFrameworkPkg/Library/UnitTestResultReportLib/UnitTestResultReportLibDebugLib.c b/UnitTestFrameworkPkg/Library/UnitTestResultReportLib/UnitTestResultReportLibDebugLib.c index eb78554f91..22e276ffae 100644 --- a/UnitTestFrameworkPkg/Library/UnitTestResultReportLib/UnitTestResultReportLibDebugLib.c +++ b/UnitTestFrameworkPkg/Library/UnitTestResultReportLib/UnitTestResultReportLibDebugLib.c @@ -1,49 +1,49 @@ -/** @file
- Implement UnitTestResultReportLib doing plain txt out to console
-
- Copyright (c) Microsoft Corporation.<BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
-**/
-
-#include <Uefi.h>
-#include <Library/BaseLib.h>
-#include <Library/PrintLib.h>
-#include <Library/DebugLib.h>
-
-VOID
-EFIAPI
-ReportPrint (
- IN CONST CHAR8 *Format,
- ...
- )
-{
- VA_LIST Marker;
- CHAR8 String[256];
- UINTN Length;
-
- VA_START (Marker, Format);
- Length = AsciiVSPrint (String, sizeof (String), Format, Marker);
- if (Length == 0) {
- DEBUG ((DEBUG_ERROR, "%a formatted string is too long\n", __func__));
- } else {
- DEBUG ((DEBUG_INFO, String));
- }
-
- VA_END (Marker);
-}
-
-VOID
-ReportOutput (
- IN CONST CHAR8 *Output
- )
-{
- CHAR8 AsciiString[128];
- UINTN Length;
- UINTN Index;
-
- Length = AsciiStrLen (Output);
- for (Index = 0; Index < Length; Index += (sizeof (AsciiString) - 1)) {
- AsciiStrnCpyS (AsciiString, sizeof (AsciiString), &Output[Index], sizeof (AsciiString) - 1);
- DEBUG ((DEBUG_INFO, AsciiString));
- }
-}
+/** @file + Implement UnitTestResultReportLib doing plain txt out to console + + Copyright (c) Microsoft Corporation.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include <Uefi.h> +#include <Library/BaseLib.h> +#include <Library/PrintLib.h> +#include <Library/DebugLib.h> + +VOID +EFIAPI +ReportPrint ( + IN CONST CHAR8 *Format, + ... + ) +{ + VA_LIST Marker; + CHAR8 String[256]; + UINTN Length; + + VA_START (Marker, Format); + Length = AsciiVSPrint (String, sizeof (String), Format, Marker); + if (Length == 0) { + DEBUG ((DEBUG_ERROR, "%a formatted string is too long\n", __func__)); + } else { + DEBUG ((DEBUG_INFO, String)); + } + + VA_END (Marker); +} + +VOID +ReportOutput ( + IN CONST CHAR8 *Output + ) +{ + CHAR8 AsciiString[128]; + UINTN Length; + UINTN Index; + + Length = AsciiStrLen (Output); + for (Index = 0; Index < Length; Index += (sizeof (AsciiString) - 1)) { + AsciiStrnCpyS (AsciiString, sizeof (AsciiString), &Output[Index], sizeof (AsciiString) - 1); + DEBUG ((DEBUG_INFO, AsciiString)); + } +} diff --git a/UnitTestFrameworkPkg/Library/UnitTestResultReportLib/UnitTestResultReportLibDebugLib.inf b/UnitTestFrameworkPkg/Library/UnitTestResultReportLib/UnitTestResultReportLibDebugLib.inf index a1c786a700..1a2f925e86 100644 --- a/UnitTestFrameworkPkg/Library/UnitTestResultReportLib/UnitTestResultReportLibDebugLib.inf +++ b/UnitTestFrameworkPkg/Library/UnitTestResultReportLib/UnitTestResultReportLibDebugLib.inf @@ -1,28 +1,28 @@ -## @file
-# Library to support printing out the unit test report using DEBUG() macros.
-#
-# Copyright (c) Microsoft Corporation.<BR>
-# SPDX-License-Identifier: BSD-2-Clause-Patent
-##
-
-[Defines]
- INF_VERSION = 0x00010017
- BASE_NAME = UnitTestResultReportLibDebugLib
- MODULE_UNI_FILE = UnitTestResultReportLibDebugLib.uni
- FILE_GUID = BED736D4-D197-475F-B7CE-0D828FF2C9A6
- VERSION_STRING = 1.0
- MODULE_TYPE = UEFI_DRIVER
- LIBRARY_CLASS = UnitTestResultReportLib
-
-[LibraryClasses]
- BaseLib
- DebugLib
- PrintLib
-
-[Packages]
- MdePkg/MdePkg.dec
- UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec
-
-[Sources]
- UnitTestResultReportLib.c
- UnitTestResultReportLibDebugLib.c
+## @file +# Library to support printing out the unit test report using DEBUG() macros. +# +# Copyright (c) Microsoft Corporation.<BR> +# SPDX-License-Identifier: BSD-2-Clause-Patent +## + +[Defines] + INF_VERSION = 0x00010017 + BASE_NAME = UnitTestResultReportLibDebugLib + MODULE_UNI_FILE = UnitTestResultReportLibDebugLib.uni + FILE_GUID = BED736D4-D197-475F-B7CE-0D828FF2C9A6 + VERSION_STRING = 1.0 + MODULE_TYPE = UEFI_DRIVER + LIBRARY_CLASS = UnitTestResultReportLib + +[LibraryClasses] + BaseLib + DebugLib + PrintLib + +[Packages] + MdePkg/MdePkg.dec + UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec + +[Sources] + UnitTestResultReportLib.c + UnitTestResultReportLibDebugLib.c diff --git a/UnitTestFrameworkPkg/Library/UnitTestResultReportLib/UnitTestResultReportLibDebugLib.uni b/UnitTestFrameworkPkg/Library/UnitTestResultReportLib/UnitTestResultReportLibDebugLib.uni index 4f1993417a..472903d419 100644 --- a/UnitTestFrameworkPkg/Library/UnitTestResultReportLib/UnitTestResultReportLibDebugLib.uni +++ b/UnitTestFrameworkPkg/Library/UnitTestResultReportLib/UnitTestResultReportLibDebugLib.uni @@ -1,11 +1,11 @@ -// /** @file
-// Library to support printing out the unit test report using DEBUG() macros.
-//
-// Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
-// SPDX-License-Identifier: BSD-2-Clause-Patent
-//
-// **/
-
-#string STR_MODULE_ABSTRACT #language en-US "Library to support printing out the unit test report using DEBUG() macros"
-
-#string STR_MODULE_DESCRIPTION #language en-US "Library to support printing out the unit test report using DEBUG() macros."
+// /** @file +// Library to support printing out the unit test report using DEBUG() macros. +// +// Copyright (c) 2020, Intel Corporation. All rights reserved.<BR> +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + +#string STR_MODULE_ABSTRACT #language en-US "Library to support printing out the unit test report using DEBUG() macros" + +#string STR_MODULE_DESCRIPTION #language en-US "Library to support printing out the unit test report using DEBUG() macros." diff --git a/UnitTestFrameworkPkg/Library/UnitTestUefiBootServicesTableLib/UnitTestUefiBootServicesTableLib.c b/UnitTestFrameworkPkg/Library/UnitTestUefiBootServicesTableLib/UnitTestUefiBootServicesTableLib.c index a6fc13e7d2..37401ac22f 100644 --- a/UnitTestFrameworkPkg/Library/UnitTestUefiBootServicesTableLib/UnitTestUefiBootServicesTableLib.c +++ b/UnitTestFrameworkPkg/Library/UnitTestUefiBootServicesTableLib/UnitTestUefiBootServicesTableLib.c @@ -1,119 +1,119 @@ -/** @file
- This library supports a Boot Services table library implementation that allows code dependent
- upon UefiBootServicesTableLib to operate in an isolated execution environment such as within
- the context of a host-based unit test framework.
-
- The unit test should initialize the Boot Services database with any required elements
- (e.g. protocols, events, handles, etc.) prior to the services being invoked by code under test.
-
- It is strongly recommended to clean any global databases (e.g. protocol, event, handles, etc.) after
- every unit test so the tests execute in a predictable manner from a clean state.
-
- Copyright (c) Microsoft Corporation
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#include "UnitTestUefiBootServicesTableLib.h"
-
-EFI_HANDLE gImageHandle = NULL;
-EFI_SYSTEM_TABLE *gST = NULL;
-
-STATIC EFI_BOOT_SERVICES mBootServices = {
- {
- EFI_BOOT_SERVICES_SIGNATURE, // Signature
- EFI_BOOT_SERVICES_REVISION, // Revision
- sizeof (EFI_BOOT_SERVICES), // HeaderSize
- 0, // CRC32
- 0 // Reserved
- },
- (EFI_RAISE_TPL)UnitTestRaiseTpl, // RaiseTPL
- (EFI_RESTORE_TPL)UnitTestRestoreTpl, // RestoreTPL
- (EFI_ALLOCATE_PAGES)UnitTestAllocatePages, // AllocatePages
- (EFI_FREE_PAGES)UnitTestFreePages, // FreePages
- (EFI_GET_MEMORY_MAP)UnitTestGetMemoryMap, // GetMemoryMap
- (EFI_ALLOCATE_POOL)UnitTestAllocatePool, // AllocatePool
- (EFI_FREE_POOL)UnitTestFreePool, // FreePool
- (EFI_CREATE_EVENT)UnitTestCreateEvent, // CreateEvent
- (EFI_SET_TIMER)UnitTestSetTimer, // SetTimer
- (EFI_WAIT_FOR_EVENT)UnitTestWaitForEvent, // WaitForEvent
- (EFI_SIGNAL_EVENT)UnitTestSignalEvent, // SignalEvent
- (EFI_CLOSE_EVENT)UnitTestCloseEvent, // CloseEvent
- (EFI_CHECK_EVENT)UnitTestCheckEvent, // CheckEvent
- (EFI_INSTALL_PROTOCOL_INTERFACE)UnitTestInstallProtocolInterface, // InstallProtocolInterface
- (EFI_REINSTALL_PROTOCOL_INTERFACE)UnitTestReinstallProtocolInterface, // ReinstallProtocolInterface
- (EFI_UNINSTALL_PROTOCOL_INTERFACE)UnitTestUninstallProtocolInterface, // UninstallProtocolInterface
- (EFI_HANDLE_PROTOCOL)UnitTestHandleProtocol, // HandleProtocol
- (VOID *)NULL, // Reserved
- (EFI_REGISTER_PROTOCOL_NOTIFY)UnitTestRegisterProtocolNotify, // RegisterProtocolNotify
- (EFI_LOCATE_HANDLE)UnitTestLocateHandle, // LocateHandle
- (EFI_LOCATE_DEVICE_PATH)UnitTestLocateDevicePath, // LocateDevicePath
- (EFI_INSTALL_CONFIGURATION_TABLE)UnitTestInstallConfigurationTable, // InstallConfigurationTable
- (EFI_IMAGE_LOAD)UnitTestLoadImage, // LoadImage
- (EFI_IMAGE_START)UnitTestStartImage, // StartImage
- (EFI_EXIT)UnitTestExit, // Exit
- (EFI_IMAGE_UNLOAD)UnitTestUnloadImage, // UnloadImage
- (EFI_EXIT_BOOT_SERVICES)UnitTestExitBootServices, // ExitBootServices
- (EFI_GET_NEXT_MONOTONIC_COUNT)UnitTestGetNextMonotonicCount, // GetNextMonotonicCount
- (EFI_STALL)UnitTestStall, // Stall
- (EFI_SET_WATCHDOG_TIMER)UnitTestSetWatchdogTimer, // SetWatchdogTimer
- (EFI_CONNECT_CONTROLLER)UnitTestConnectController, // ConnectController
- (EFI_DISCONNECT_CONTROLLER)UnitTestDisconnectController, // DisconnectController
- (EFI_OPEN_PROTOCOL)UnitTestOpenProtocol, // OpenProtocol
- (EFI_CLOSE_PROTOCOL)UnitTestCloseProtocol, // CloseProtocol
- (EFI_OPEN_PROTOCOL_INFORMATION)UnitTestOpenProtocolInformation, // OpenProtocolInformation
- (EFI_PROTOCOLS_PER_HANDLE)UnitTestProtocolsPerHandle, // ProtocolsPerHandle
- (EFI_LOCATE_HANDLE_BUFFER)UnitTestLocateHandleBuffer, // LocateHandleBuffer
- (EFI_LOCATE_PROTOCOL)UnitTestLocateProtocol, // LocateProtocol
- (EFI_INSTALL_MULTIPLE_PROTOCOL_INTERFACES)UnitTestInstallMultipleProtocolInterfaces, // InstallMultipleProtocolInterfaces
- (EFI_UNINSTALL_MULTIPLE_PROTOCOL_INTERFACES)UnitTestUninstallMultipleProtocolInterfaces, // UninstallMultipleProtocolInterfaces
- (EFI_CALCULATE_CRC32)UnitTestCalculateCrc32, // CalculateCrc32
- (EFI_COPY_MEM)CopyMem, // CopyMem
- (EFI_SET_MEM)SetMem, // SetMem
- (EFI_CREATE_EVENT_EX)UnitTestCreateEventEx // CreateEventEx
-};
-
-EFI_BOOT_SERVICES *gBS = &mBootServices;
-
-/**
- The constructor function caches the pointer of Boot Services Table.
-
- The constructor function caches the pointer of Boot Services Table through System Table.
- It will ASSERT() if the pointer of System Table is NULL.
- It will ASSERT() if the pointer of Boot Services Table is NULL.
- It will always return EFI_SUCCESS.
-
- @param ImageHandle The firmware allocated handle for the EFI image.
- @param SystemTable A pointer to the EFI System Table.
-
- @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS.
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestUefiBootServicesTableLibConstructor (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- )
-{
- //
- // Cache the Image Handle
- //
- gImageHandle = ImageHandle;
- ASSERT (gImageHandle != NULL);
-
- //
- // Cache pointer to the EFI System Table
- //
-
- // Note: The system table is not implemented
- gST = NULL;
-
- //
- // Cache pointer to the EFI Boot Services Table
- //
- gBS = SystemTable->BootServices;
- ASSERT (gBS != NULL);
-
- return EFI_SUCCESS;
-}
+/** @file + This library supports a Boot Services table library implementation that allows code dependent + upon UefiBootServicesTableLib to operate in an isolated execution environment such as within + the context of a host-based unit test framework. + + The unit test should initialize the Boot Services database with any required elements + (e.g. protocols, events, handles, etc.) prior to the services being invoked by code under test. + + It is strongly recommended to clean any global databases (e.g. protocol, event, handles, etc.) after + every unit test so the tests execute in a predictable manner from a clean state. + + Copyright (c) Microsoft Corporation + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "UnitTestUefiBootServicesTableLib.h" + +EFI_HANDLE gImageHandle = NULL; +EFI_SYSTEM_TABLE *gST = NULL; + +STATIC EFI_BOOT_SERVICES mBootServices = { + { + EFI_BOOT_SERVICES_SIGNATURE, // Signature + EFI_BOOT_SERVICES_REVISION, // Revision + sizeof (EFI_BOOT_SERVICES), // HeaderSize + 0, // CRC32 + 0 // Reserved + }, + (EFI_RAISE_TPL)UnitTestRaiseTpl, // RaiseTPL + (EFI_RESTORE_TPL)UnitTestRestoreTpl, // RestoreTPL + (EFI_ALLOCATE_PAGES)UnitTestAllocatePages, // AllocatePages + (EFI_FREE_PAGES)UnitTestFreePages, // FreePages + (EFI_GET_MEMORY_MAP)UnitTestGetMemoryMap, // GetMemoryMap + (EFI_ALLOCATE_POOL)UnitTestAllocatePool, // AllocatePool + (EFI_FREE_POOL)UnitTestFreePool, // FreePool + (EFI_CREATE_EVENT)UnitTestCreateEvent, // CreateEvent + (EFI_SET_TIMER)UnitTestSetTimer, // SetTimer + (EFI_WAIT_FOR_EVENT)UnitTestWaitForEvent, // WaitForEvent + (EFI_SIGNAL_EVENT)UnitTestSignalEvent, // SignalEvent + (EFI_CLOSE_EVENT)UnitTestCloseEvent, // CloseEvent + (EFI_CHECK_EVENT)UnitTestCheckEvent, // CheckEvent + (EFI_INSTALL_PROTOCOL_INTERFACE)UnitTestInstallProtocolInterface, // InstallProtocolInterface + (EFI_REINSTALL_PROTOCOL_INTERFACE)UnitTestReinstallProtocolInterface, // ReinstallProtocolInterface + (EFI_UNINSTALL_PROTOCOL_INTERFACE)UnitTestUninstallProtocolInterface, // UninstallProtocolInterface + (EFI_HANDLE_PROTOCOL)UnitTestHandleProtocol, // HandleProtocol + (VOID *)NULL, // Reserved + (EFI_REGISTER_PROTOCOL_NOTIFY)UnitTestRegisterProtocolNotify, // RegisterProtocolNotify + (EFI_LOCATE_HANDLE)UnitTestLocateHandle, // LocateHandle + (EFI_LOCATE_DEVICE_PATH)UnitTestLocateDevicePath, // LocateDevicePath + (EFI_INSTALL_CONFIGURATION_TABLE)UnitTestInstallConfigurationTable, // InstallConfigurationTable + (EFI_IMAGE_LOAD)UnitTestLoadImage, // LoadImage + (EFI_IMAGE_START)UnitTestStartImage, // StartImage + (EFI_EXIT)UnitTestExit, // Exit + (EFI_IMAGE_UNLOAD)UnitTestUnloadImage, // UnloadImage + (EFI_EXIT_BOOT_SERVICES)UnitTestExitBootServices, // ExitBootServices + (EFI_GET_NEXT_MONOTONIC_COUNT)UnitTestGetNextMonotonicCount, // GetNextMonotonicCount + (EFI_STALL)UnitTestStall, // Stall + (EFI_SET_WATCHDOG_TIMER)UnitTestSetWatchdogTimer, // SetWatchdogTimer + (EFI_CONNECT_CONTROLLER)UnitTestConnectController, // ConnectController + (EFI_DISCONNECT_CONTROLLER)UnitTestDisconnectController, // DisconnectController + (EFI_OPEN_PROTOCOL)UnitTestOpenProtocol, // OpenProtocol + (EFI_CLOSE_PROTOCOL)UnitTestCloseProtocol, // CloseProtocol + (EFI_OPEN_PROTOCOL_INFORMATION)UnitTestOpenProtocolInformation, // OpenProtocolInformation + (EFI_PROTOCOLS_PER_HANDLE)UnitTestProtocolsPerHandle, // ProtocolsPerHandle + (EFI_LOCATE_HANDLE_BUFFER)UnitTestLocateHandleBuffer, // LocateHandleBuffer + (EFI_LOCATE_PROTOCOL)UnitTestLocateProtocol, // LocateProtocol + (EFI_INSTALL_MULTIPLE_PROTOCOL_INTERFACES)UnitTestInstallMultipleProtocolInterfaces, // InstallMultipleProtocolInterfaces + (EFI_UNINSTALL_MULTIPLE_PROTOCOL_INTERFACES)UnitTestUninstallMultipleProtocolInterfaces, // UninstallMultipleProtocolInterfaces + (EFI_CALCULATE_CRC32)UnitTestCalculateCrc32, // CalculateCrc32 + (EFI_COPY_MEM)CopyMem, // CopyMem + (EFI_SET_MEM)SetMem, // SetMem + (EFI_CREATE_EVENT_EX)UnitTestCreateEventEx // CreateEventEx +}; + +EFI_BOOT_SERVICES *gBS = &mBootServices; + +/** + The constructor function caches the pointer of Boot Services Table. + + The constructor function caches the pointer of Boot Services Table through System Table. + It will ASSERT() if the pointer of System Table is NULL. + It will ASSERT() if the pointer of Boot Services Table is NULL. + It will always return EFI_SUCCESS. + + @param ImageHandle The firmware allocated handle for the EFI image. + @param SystemTable A pointer to the EFI System Table. + + @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS. + +**/ +EFI_STATUS +EFIAPI +UnitTestUefiBootServicesTableLibConstructor ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + // + // Cache the Image Handle + // + gImageHandle = ImageHandle; + ASSERT (gImageHandle != NULL); + + // + // Cache pointer to the EFI System Table + // + + // Note: The system table is not implemented + gST = NULL; + + // + // Cache pointer to the EFI Boot Services Table + // + gBS = SystemTable->BootServices; + ASSERT (gBS != NULL); + + return EFI_SUCCESS; +} diff --git a/UnitTestFrameworkPkg/Library/UnitTestUefiBootServicesTableLib/UnitTestUefiBootServicesTableLib.h b/UnitTestFrameworkPkg/Library/UnitTestUefiBootServicesTableLib/UnitTestUefiBootServicesTableLib.h index 82853bb61a..465bf32825 100644 --- a/UnitTestFrameworkPkg/Library/UnitTestUefiBootServicesTableLib/UnitTestUefiBootServicesTableLib.h +++ b/UnitTestFrameworkPkg/Library/UnitTestUefiBootServicesTableLib/UnitTestUefiBootServicesTableLib.h @@ -1,1042 +1,1042 @@ -/** @file
- An internal header file for the Unit Test instance of the UEFI Boot Services Table Library.
-
- This file includes common header files, defines internal structure and functions used by
- the library implementation.
-
-Copyright (c) Microsoft Corporation
-SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#ifndef UEFI_BOOT_SERVICES_TABLE_LIB_UNIT_TEST_H_
-#define UEFI_BOOT_SERVICES_TABLE_LIB_UNIT_TEST_H_
-
-#include <Uefi.h>
-
-#include <Pi/PiMultiPhase.h>
-#include <Library/BaseLib.h>
-#include <Library/BaseMemoryLib.h>
-#include <Library/DebugLib.h>
-#include <Library/MemoryAllocationLib.h>
-#include <Library/UnitTestLib.h>
-#include <Library/UefiBootServicesTableLib.h>
-
-/**
- Raise the task priority level to the new level.
- High level is implemented by disabling processor interrupts.
-
- @param NewTpl New task priority level
-
- @return The previous task priority level
-
-**/
-EFI_TPL
-EFIAPI
-UnitTestRaiseTpl (
- IN EFI_TPL NewTpl
- );
-
-/**
- Lowers the task priority to the previous value. If the new
- priority unmasks events at a higher priority, they are dispatched.
-
- @param NewTpl New, lower, task priority
-
-**/
-VOID
-EFIAPI
-UnitTestRestoreTpl (
- IN EFI_TPL NewTpl
- );
-
-/**
- Allocates pages from the memory map.
-
- @param Type The type of allocation to perform
- @param MemoryType The type of memory to turn the allocated pages
- into
- @param NumberOfPages The number of pages to allocate
- @param Memory A pointer to receive the base allocated memory
- address
-
- @return Status. On success, Memory is filled in with the base address allocated
- @retval EFI_INVALID_PARAMETER Parameters violate checking rules defined in
- spec.
- @retval EFI_NOT_FOUND Could not allocate pages match the requirement.
- @retval EFI_OUT_OF_RESOURCES No enough pages to allocate.
- @retval EFI_SUCCESS Pages successfully allocated.
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestAllocatePages (
- IN EFI_ALLOCATE_TYPE Type,
- IN EFI_MEMORY_TYPE MemoryType,
- IN UINTN NumberOfPages,
- IN OUT EFI_PHYSICAL_ADDRESS *Memory
- );
-
-/**
- Frees previous allocated pages.
-
- @param Memory Base address of memory being freed
- @param NumberOfPages The number of pages to free
-
- @retval EFI_NOT_FOUND Could not find the entry that covers the range
- @retval EFI_INVALID_PARAMETER Address not aligned
- @return EFI_SUCCESS -Pages successfully freed.
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestFreePages (
- IN EFI_PHYSICAL_ADDRESS Memory,
- IN UINTN NumberOfPages
- );
-
-/**
- This function returns a copy of the current memory map. The map is an array of
- memory descriptors, each of which describes a contiguous block of memory.
-
- @param MemoryMapSize A pointer to the size, in bytes, of the
- MemoryMap buffer. On input, this is the size of
- the buffer allocated by the caller. On output,
- it is the size of the buffer returned by the
- firmware if the buffer was large enough, or the
- size of the buffer needed to contain the map if
- the buffer was too small.
- @param MemoryMap A pointer to the buffer in which firmware places
- the current memory map.
- @param MapKey A pointer to the location in which firmware
- returns the key for the current memory map.
- @param DescriptorSize A pointer to the location in which firmware
- returns the size, in bytes, of an individual
- EFI_MEMORY_DESCRIPTOR.
- @param DescriptorVersion A pointer to the location in which firmware
- returns the version number associated with the
- EFI_MEMORY_DESCRIPTOR.
-
- @retval EFI_SUCCESS The memory map was returned in the MemoryMap
- buffer.
- @retval EFI_BUFFER_TOO_SMALL The MemoryMap buffer was too small. The current
- buffer size needed to hold the memory map is
- returned in MemoryMapSize.
- @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value.
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestGetMemoryMap (
- IN OUT UINTN *MemoryMapSize,
- IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap,
- OUT UINTN *MapKey,
- OUT UINTN *DescriptorSize,
- OUT UINT32 *DescriptorVersion
- );
-
-/**
- Allocate pool of a particular type.
-
- @param PoolType Type of pool to allocate
- @param Size The amount of pool to allocate
- @param Buffer The address to return a pointer to the allocated
- pool
-
- @retval EFI_INVALID_PARAMETER PoolType not valid or Buffer is NULL
- @retval EFI_OUT_OF_RESOURCES Size exceeds max pool size or allocation failed.
- @retval EFI_SUCCESS Pool successfully allocated.
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestAllocatePool (
- IN EFI_MEMORY_TYPE PoolType,
- IN UINTN Size,
- OUT VOID **Buffer
- );
-
-/**
- Frees pool.
-
- @param Buffer The allocated pool entry to free
-
- @retval EFI_INVALID_PARAMETER Buffer is not a valid value.
- @retval EFI_SUCCESS Pool successfully freed.
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestFreePool (
- IN VOID *Buffer
- );
-
-/**
- Frees pool.
-
- @param Buffer The allocated pool entry to free
- @param PoolType Pointer to pool type
-
- @retval EFI_INVALID_PARAMETER Buffer is not a valid value.
- @retval EFI_SUCCESS Pool successfully freed.
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestInternalFreePool (
- IN VOID *Buffer,
- OUT EFI_MEMORY_TYPE *PoolType OPTIONAL
- );
-
-/**
- Creates an event.
-
- @param Type The type of event to create and its mode and
- attributes
- @param NotifyTpl The task priority level of event notifications
- @param NotifyFunction Pointer to the events notification function
- @param NotifyContext Pointer to the notification functions context;
- corresponds to parameter "Context" in the
- notification function
- @param Event Pointer to the newly created event if the call
- succeeds; undefined otherwise
-
- @retval EFI_SUCCESS The event structure was created
- @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value
- @retval EFI_OUT_OF_RESOURCES The event could not be allocated
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestCreateEvent (
- IN UINT32 Type,
- IN EFI_TPL NotifyTpl,
- IN EFI_EVENT_NOTIFY NotifyFunction, OPTIONAL
- IN VOID *NotifyContext, OPTIONAL
- OUT EFI_EVENT *Event
- );
-
-/**
- Sets the type of timer and the trigger time for a timer event.
-
- @param UserEvent The timer event that is to be signaled at the
- specified time
- @param Type The type of time that is specified in
- TriggerTime
- @param TriggerTime The number of 100ns units until the timer
- expires
-
- @retval EFI_SUCCESS The event has been set to be signaled at the
- requested time
- @retval EFI_INVALID_PARAMETER Event or Type is not valid
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestSetTimer (
- IN EFI_EVENT UserEvent,
- IN EFI_TIMER_DELAY Type,
- IN UINT64 TriggerTime
- );
-
-/**
- Stops execution until an event is signaled.
-
- @param NumberOfEvents The number of events in the UserEvents array
- @param UserEvents An array of EFI_EVENT
- @param UserIndex Pointer to the index of the event which
- satisfied the wait condition
-
- @retval EFI_SUCCESS The event indicated by Index was signaled.
- @retval EFI_INVALID_PARAMETER The event indicated by Index has a notification
- function or Event was not a valid type
- @retval EFI_UNSUPPORTED The current TPL is not TPL_APPLICATION
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestWaitForEvent (
- IN UINTN NumberOfEvents,
- IN EFI_EVENT *UserEvents,
- OUT UINTN *UserIndex
- );
-
-/**
- Signals the event. Queues the event to be notified if needed.
-
- @param UserEvent The event to signal .
-
- @retval EFI_INVALID_PARAMETER Parameters are not valid.
- @retval EFI_SUCCESS The event was signaled.
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestSignalEvent (
- IN EFI_EVENT UserEvent
- );
-
-/**
- Closes an event and frees the event structure.
-
- @param UserEvent Event to close
-
- @retval EFI_INVALID_PARAMETER Parameters are not valid.
- @retval EFI_SUCCESS The event has been closed
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestCloseEvent (
- IN EFI_EVENT UserEvent
- );
-
-/**
- Check the status of an event.
-
- @param UserEvent The event to check
-
- @retval EFI_SUCCESS The event is in the signaled state
- @retval EFI_NOT_READY The event is not in the signaled state
- @retval EFI_INVALID_PARAMETER Event is of type EVT_NOTIFY_SIGNAL
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestCheckEvent (
- IN EFI_EVENT UserEvent
- );
-
-/**
- Wrapper function to UnitTestInstallProtocolInterfaceNotify. This is the public API which
- Calls the private one which contains a BOOLEAN parameter for notifications
-
- @param UserHandle The handle to install the protocol handler on,
- or NULL if a new handle is to be allocated
- @param Protocol The protocol to add to the handle
- @param InterfaceType Indicates whether Interface is supplied in
- native form.
- @param Interface The interface for the protocol being added
-
- @return Status code
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestInstallProtocolInterface (
- IN OUT EFI_HANDLE *UserHandle,
- IN EFI_GUID *Protocol,
- IN EFI_INTERFACE_TYPE InterfaceType,
- IN VOID *Interface
- );
-
-/**
- Reinstall a protocol interface on a device handle. The OldInterface for Protocol is replaced by the NewInterface.
-
- @param UserHandle Handle on which the interface is to be
- reinstalled
- @param Protocol The numeric ID of the interface
- @param OldInterface A pointer to the old interface
- @param NewInterface A pointer to the new interface
-
- @retval EFI_SUCCESS The protocol interface was installed
- @retval EFI_NOT_FOUND The OldInterface on the handle was not found
- @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestReinstallProtocolInterface (
- IN EFI_HANDLE UserHandle,
- IN EFI_GUID *Protocol,
- IN VOID *OldInterface,
- IN VOID *NewInterface
- );
-
-/**
- Uninstalls all instances of a protocol:interfacer from a handle.
- If the last protocol interface is remove from the handle, the
- handle is freed.
-
- @param UserHandle The handle to remove the protocol handler from
- @param Protocol The protocol, of protocol:interface, to remove
- @param Interface The interface, of protocol:interface, to remove
-
- @retval EFI_INVALID_PARAMETER Protocol is NULL.
- @retval EFI_SUCCESS Protocol interface successfully uninstalled.
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestUninstallProtocolInterface (
- IN EFI_HANDLE UserHandle,
- IN EFI_GUID *Protocol,
- IN VOID *Interface
- );
-
-/**
- Queries a handle to determine if it supports a specified protocol.
-
- @param UserHandle The handle being queried.
- @param Protocol The published unique identifier of the protocol.
- @param Interface Supplies the address where a pointer to the
- corresponding Protocol Interface is returned.
-
- @return The requested protocol interface for the handle
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestHandleProtocol (
- IN EFI_HANDLE UserHandle,
- IN EFI_GUID *Protocol,
- OUT VOID **Interface
- );
-
-/**
- Add a new protocol notification record for the request protocol.
-
- @param Protocol The requested protocol to add the notify
- registration
- @param Event The event to signal
- @param Registration Returns the registration record
-
- @retval EFI_INVALID_PARAMETER Invalid parameter
- @retval EFI_SUCCESS Successfully returned the registration record
- that has been added
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestRegisterProtocolNotify (
- IN EFI_GUID *Protocol,
- IN EFI_EVENT Event,
- OUT VOID **Registration
- );
-
-/**
- Locates the requested handle(s) and returns them in Buffer.
-
- @param SearchType The type of search to perform to locate the
- handles
- @param Protocol The protocol to search for
- @param SearchKey Dependant on SearchType
- @param BufferSize On input the size of Buffer. On output the
- size of data returned.
- @param Buffer The buffer to return the results in
-
- @retval EFI_BUFFER_TOO_SMALL Buffer too small, required buffer size is
- returned in BufferSize.
- @retval EFI_INVALID_PARAMETER Invalid parameter
- @retval EFI_SUCCESS Successfully found the requested handle(s) and
- returns them in Buffer.
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestLocateHandle (
- IN EFI_LOCATE_SEARCH_TYPE SearchType,
- IN EFI_GUID *Protocol OPTIONAL,
- IN VOID *SearchKey OPTIONAL,
- IN OUT UINTN *BufferSize,
- OUT EFI_HANDLE *Buffer
- );
-
-/**
- Locates the handle to a device on the device path that best matches the specified protocol.
-
- @param Protocol The protocol to search for.
- @param DevicePath On input, a pointer to a pointer to the device
- path. On output, the device path pointer is
- modified to point to the remaining part of the
- devicepath.
- @param Device A pointer to the returned device handle.
-
- @retval EFI_SUCCESS The resulting handle was returned.
- @retval EFI_NOT_FOUND No handles matched the search.
- @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value.
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestLocateDevicePath (
- IN EFI_GUID *Protocol,
- IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath,
- OUT EFI_HANDLE *Device
- );
-
-/**
- Boot Service called to add, modify, or remove a system configuration table from
- the EFI System Table.
-
- @param Guid Pointer to the GUID for the entry to add, update, or
- remove
- @param Table Pointer to the configuration table for the entry to add,
- update, or remove, may be NULL.
-
- @return EFI_SUCCESS Guid, Table pair added, updated, or removed.
- @return EFI_INVALID_PARAMETER Input GUID not valid.
- @return EFI_NOT_FOUND Attempted to delete non-existant entry
- @return EFI_OUT_OF_RESOURCES Not enough memory available
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestInstallConfigurationTable (
- IN EFI_GUID *Guid,
- IN VOID *Table
- );
-
-/**
- Loads an EFI image into memory and returns a handle to the image.
-
- @param BootPolicy If TRUE, indicates that the request originates
- from the boot manager, and that the boot
- manager is attempting to load FilePath as a
- boot selection.
- @param ParentImageHandle The caller's image handle.
- @param FilePath The specific file path from which the image is
- loaded.
- @param SourceBuffer If not NULL, a pointer to the memory location
- containing a copy of the image to be loaded.
- @param SourceSize The size in bytes of SourceBuffer.
- @param ImageHandle Pointer to the returned image handle that is
- created when the image is successfully loaded.
-
- @retval EFI_SUCCESS The image was loaded into memory.
- @retval EFI_NOT_FOUND The FilePath was not found.
- @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value.
- @retval EFI_UNSUPPORTED The image type is not supported, or the device
- path cannot be parsed to locate the proper
- protocol for loading the file.
- @retval EFI_OUT_OF_RESOURCES Image was not loaded due to insufficient
- resources.
- @retval EFI_LOAD_ERROR Image was not loaded because the image format was corrupt or not
- understood.
- @retval EFI_DEVICE_ERROR Image was not loaded because the device returned a read error.
- @retval EFI_ACCESS_DENIED Image was not loaded because the platform policy prohibits the
- image from being loaded. NULL is returned in *ImageHandle.
- @retval EFI_SECURITY_VIOLATION Image was loaded and an ImageHandle was created with a
- valid EFI_LOADED_IMAGE_PROTOCOL. However, the current
- platform policy specifies that the image should not be started.
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestLoadImage (
- IN BOOLEAN BootPolicy,
- IN EFI_HANDLE ParentImageHandle,
- IN EFI_DEVICE_PATH_PROTOCOL *FilePath,
- IN VOID *SourceBuffer OPTIONAL,
- IN UINTN SourceSize,
- OUT EFI_HANDLE *ImageHandle
- );
-
-/**
- Transfer control to a loaded image's entry point.
-
- @param ImageHandle Handle of image to be started.
- @param ExitDataSize Pointer of the size to ExitData
- @param ExitData Pointer to a pointer to a data buffer that
- includes a Null-terminated string,
- optionally followed by additional binary data.
- The string is a description that the caller may
- use to further indicate the reason for the
- image's exit.
-
- @retval EFI_INVALID_PARAMETER Invalid parameter
- @retval EFI_OUT_OF_RESOURCES No enough buffer to allocate
- @retval EFI_SECURITY_VIOLATION The current platform policy specifies that the image should not be started.
- @retval EFI_SUCCESS Successfully transfer control to the image's
- entry point.
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestStartImage (
- IN EFI_HANDLE ImageHandle,
- OUT UINTN *ExitDataSize,
- OUT CHAR16 **ExitData OPTIONAL
- );
-
-/**
- Terminates the currently loaded EFI image and returns control to boot services.
-
- @param ImageHandle Handle that identifies the image. This
- parameter is passed to the image on entry.
- @param Status The image's exit code.
- @param ExitDataSize The size, in bytes, of ExitData. Ignored if
- ExitStatus is EFI_SUCCESS.
- @param ExitData Pointer to a data buffer that includes a
- Null-terminated Unicode string, optionally
- followed by additional binary data. The string
- is a description that the caller may use to
- further indicate the reason for the image's
- exit.
-
- @retval EFI_INVALID_PARAMETER Image handle is NULL or it is not current
- image.
- @retval EFI_SUCCESS Successfully terminates the currently loaded
- EFI image.
- @retval EFI_ACCESS_DENIED Should never reach there.
- @retval EFI_OUT_OF_RESOURCES Could not allocate pool
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestExit (
- IN EFI_HANDLE ImageHandle,
- IN EFI_STATUS Status,
- IN UINTN ExitDataSize,
- IN CHAR16 *ExitData OPTIONAL
- );
-
-/**
- Unloads an image.
-
- @param ImageHandle Handle that identifies the image to be
- unloaded.
-
- @retval EFI_SUCCESS The image has been unloaded.
- @retval EFI_UNSUPPORTED The image has been started, and does not support
- unload.
- @retval EFI_INVALID_PARAMPETER ImageHandle is not a valid image handle.
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestUnloadImage (
- IN EFI_HANDLE ImageHandle
- );
-
-/**
- Terminates all boot services.
-
- @param ImageHandle Handle that identifies the exiting image.
- @param MapKey Key to the latest memory map.
-
- @retval EFI_SUCCESS Boot Services terminated
- @retval EFI_INVALID_PARAMETER MapKey is incorrect.
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestExitBootServices (
- IN EFI_HANDLE ImageHandle,
- IN UINTN MapKey
- );
-
-/**
- Returns a monotonically increasing count for the platform.
-
- @param[out] Count The pointer to returned value.
-
- @retval EFI_SUCCESS The next monotonic count was returned.
- @retval EFI_INVALID_PARAMETER Count is NULL.
- @retval EFI_DEVICE_ERROR The device is not functioning properly.
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestGetNextMonotonicCount (
- OUT UINT64 *Count
- );
-
-/**
- Introduces a fine-grained stall.
-
- @param Microseconds The number of microseconds to stall execution.
-
- @retval EFI_SUCCESS Execution was stalled for at least the requested
- amount of microseconds.
- @retval EFI_NOT_AVAILABLE_YET gMetronome is not available yet
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestStall (
- IN UINTN Microseconds
- );
-
-/**
- Sets the system's watchdog timer.
-
- @param Timeout The number of seconds to set the watchdog timer to.
- A value of zero disables the timer.
- @param WatchdogCode The numeric code to log on a watchdog timer timeout
- event. The firmware reserves codes 0x0000 to 0xFFFF.
- Loaders and operating systems may use other timeout
- codes.
- @param DataSize The size, in bytes, of WatchdogData.
- @param WatchdogData A data buffer that includes a Null-terminated Unicode
- string, optionally followed by additional binary data.
- The string is a description that the call may use to
- further indicate the reason to be logged with a
- watchdog event.
-
- @return EFI_SUCCESS Timeout has been set
- @return EFI_NOT_AVAILABLE_YET WatchdogTimer is not available yet
- @return EFI_UNSUPPORTED System does not have a timer (currently not used)
- @return EFI_DEVICE_ERROR Could not complete due to hardware error
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestSetWatchdogTimer (
- IN UINTN Timeout,
- IN UINT64 WatchdogCode,
- IN UINTN DataSize,
- IN CHAR16 *WatchdogData OPTIONAL
- );
-
-/**
- Connects one or more drivers to a controller.
-
- @param ControllerHandle The handle of the controller to which driver(s) are to be connected.
- @param DriverImageHandle A pointer to an ordered list handles that support the
- EFI_DRIVER_BINDING_PROTOCOL.
- @param RemainingDevicePath A pointer to the device path that specifies a child of the
- controller specified by ControllerHandle.
- @param Recursive If TRUE, then ConnectController() is called recursively
- until the entire tree of controllers below the controller specified
- by ControllerHandle have been created. If FALSE, then
- the tree of controllers is only expanded one level.
-
- @retval EFI_SUCCESS 1) One or more drivers were connected to ControllerHandle.
- 2) No drivers were connected to ControllerHandle, but
- RemainingDevicePath is not NULL, and it is an End Device
- Path Node.
- @retval EFI_INVALID_PARAMETER ControllerHandle is NULL.
- @retval EFI_NOT_FOUND 1) There are no EFI_DRIVER_BINDING_PROTOCOL instances
- present in the system.
- 2) No drivers were connected to ControllerHandle.
- @retval EFI_SECURITY_VIOLATION
- The user has no permission to start UEFI device drivers on the device path
- associated with the ControllerHandle or specified by the RemainingDevicePath.
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestConnectController (
- IN EFI_HANDLE ControllerHandle,
- IN EFI_HANDLE *DriverImageHandle OPTIONAL,
- IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL,
- IN BOOLEAN Recursive
- );
-
-/**
- Disconnects a controller from a driver
-
- @param ControllerHandle ControllerHandle The handle of
- the controller from which
- driver(s) are to be
- disconnected.
- @param DriverImageHandle DriverImageHandle The driver to
- disconnect from ControllerHandle.
- @param ChildHandle ChildHandle The handle of the
- child to destroy.
-
- @retval EFI_SUCCESS One or more drivers were
- disconnected from the controller.
- @retval EFI_SUCCESS On entry, no drivers are managing
- ControllerHandle.
- @retval EFI_SUCCESS DriverImageHandle is not NULL,
- and on entry DriverImageHandle is
- not managing ControllerHandle.
- @retval EFI_INVALID_PARAMETER ControllerHandle is NULL.
- @retval EFI_INVALID_PARAMETER DriverImageHandle is not NULL,
- and it is not a valid EFI_HANDLE.
- @retval EFI_INVALID_PARAMETER ChildHandle is not NULL, and it
- is not a valid EFI_HANDLE.
- @retval EFI_OUT_OF_RESOURCES There are not enough resources
- available to disconnect any
- drivers from ControllerHandle.
- @retval EFI_DEVICE_ERROR The controller could not be
- disconnected because of a device
- error.
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestDisconnectController (
- IN EFI_HANDLE ControllerHandle,
- IN EFI_HANDLE DriverImageHandle OPTIONAL,
- IN EFI_HANDLE ChildHandle OPTIONAL
- );
-
-/**
- Locates the installed protocol handler for the handle, and
- invokes it to obtain the protocol interface. Usage information
- is registered in the protocol data base.
-
- @param UserHandle The handle to obtain the protocol interface on
- @param Protocol The ID of the protocol
- @param Interface The location to return the protocol interface
- @param ImageHandle The handle of the Image that is opening the
- protocol interface specified by Protocol and
- Interface.
- @param ControllerHandle The controller handle that is requiring this
- interface.
- @param Attributes The open mode of the protocol interface
- specified by Handle and Protocol.
-
- @retval EFI_INVALID_PARAMETER Protocol is NULL.
- @retval EFI_SUCCESS Get the protocol interface.
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestOpenProtocol (
- IN EFI_HANDLE UserHandle,
- IN EFI_GUID *Protocol,
- OUT VOID **Interface OPTIONAL,
- IN EFI_HANDLE ImageHandle,
- IN EFI_HANDLE ControllerHandle,
- IN UINT32 Attributes
- );
-
-/**
- Closes a protocol on a handle that was opened using OpenProtocol().
-
- @param UserHandle The handle for the protocol interface that was
- previously opened with OpenProtocol(), and is
- now being closed.
- @param Protocol The published unique identifier of the protocol.
- It is the caller's responsibility to pass in a
- valid GUID.
- @param AgentHandle The handle of the agent that is closing the
- protocol interface.
- @param ControllerHandle If the agent that opened a protocol is a driver
- that follows the EFI Driver Model, then this
- parameter is the controller handle that required
- the protocol interface. If the agent does not
- follow the EFI Driver Model, then this parameter
- is optional and may be NULL.
-
- @retval EFI_SUCCESS The protocol instance was closed.
- @retval EFI_INVALID_PARAMETER Handle, AgentHandle or ControllerHandle is not a
- valid EFI_HANDLE.
- @retval EFI_NOT_FOUND Can not find the specified protocol or
- AgentHandle.
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestCloseProtocol (
- IN EFI_HANDLE UserHandle,
- IN EFI_GUID *Protocol,
- IN EFI_HANDLE AgentHandle,
- IN EFI_HANDLE ControllerHandle
- );
-
-/**
- Return information about Opened protocols in the system
-
- @param UserHandle The handle to close the protocol interface on
- @param Protocol The ID of the protocol
- @param EntryBuffer A pointer to a buffer of open protocol
- information in the form of
- EFI_OPEN_PROTOCOL_INFORMATION_ENTRY structures.
- @param EntryCount Number of EntryBuffer entries
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestOpenProtocolInformation (
- IN EFI_HANDLE UserHandle,
- IN EFI_GUID *Protocol,
- OUT EFI_OPEN_PROTOCOL_INFORMATION_ENTRY **EntryBuffer,
- OUT UINTN *EntryCount
- );
-
-/**
- Retrieves the list of protocol interface GUIDs that are installed on a handle in a buffer allocated
- from pool.
-
- @param UserHandle The handle from which to retrieve the list of
- protocol interface GUIDs.
- @param ProtocolBuffer A pointer to the list of protocol interface GUID
- pointers that are installed on Handle.
- @param ProtocolBufferCount A pointer to the number of GUID pointers present
- in ProtocolBuffer.
-
- @retval EFI_SUCCESS The list of protocol interface GUIDs installed
- on Handle was returned in ProtocolBuffer. The
- number of protocol interface GUIDs was returned
- in ProtocolBufferCount.
- @retval EFI_INVALID_PARAMETER Handle is NULL.
- @retval EFI_INVALID_PARAMETER Handle is not a valid EFI_HANDLE.
- @retval EFI_INVALID_PARAMETER ProtocolBuffer is NULL.
- @retval EFI_INVALID_PARAMETER ProtocolBufferCount is NULL.
- @retval EFI_OUT_OF_RESOURCES There is not enough pool memory to store the
- results.
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestProtocolsPerHandle (
- IN EFI_HANDLE UserHandle,
- OUT EFI_GUID ***ProtocolBuffer,
- OUT UINTN *ProtocolBufferCount
- );
-
-/**
- Function returns an array of handles that support the requested protocol
- in a buffer allocated from pool. This is a version of UnitTestLocateHandle()
- that allocates a buffer for the caller.
-
- @param SearchType Specifies which handle(s) are to be returned.
- @param Protocol Provides the protocol to search by. This
- parameter is only valid for SearchType
- ByProtocol.
- @param SearchKey Supplies the search key depending on the
- SearchType.
- @param NumberHandles The number of handles returned in Buffer.
- @param Buffer A pointer to the buffer to return the requested
- array of handles that support Protocol.
-
- @retval EFI_SUCCESS The result array of handles was returned.
- @retval EFI_NOT_FOUND No handles match the search.
- @retval EFI_OUT_OF_RESOURCES There is not enough pool memory to store the
- matching results.
- @retval EFI_INVALID_PARAMETER One or more parameters are not valid.
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestLocateHandleBuffer (
- IN EFI_LOCATE_SEARCH_TYPE SearchType,
- IN EFI_GUID *Protocol OPTIONAL,
- IN VOID *SearchKey OPTIONAL,
- IN OUT UINTN *NumberHandles,
- OUT EFI_HANDLE **Buffer
- );
-
-/**
- Return the first Protocol Interface that matches the Protocol GUID. If
- Registration is passed in, return a Protocol Instance that was just add
- to the system. If Registration is NULL return the first Protocol Interface
- you find.
-
- @param Protocol The protocol to search for
- @param Registration Optional Registration Key returned from
- RegisterProtocolNotify()
- @param Interface Return the Protocol interface (instance).
-
- @retval EFI_SUCCESS If a valid Interface is returned
- @retval EFI_INVALID_PARAMETER Invalid parameter
- @retval EFI_NOT_FOUND Protocol interface not found
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestLocateProtocol (
- IN EFI_GUID *Protocol,
- IN VOID *Registration OPTIONAL,
- OUT VOID **Interface
- );
-
-/**
- Installs a list of protocol interface into the boot services environment.
- This function calls InstallProtocolInterface() in a loop. If any error
- occurs all the protocols added by this function are removed. This is
- basically a lib function to save space.
-
- @param Handle The handle to install the protocol handlers on,
- or NULL if a new handle is to be allocated
- @param ... EFI_GUID followed by protocol instance. A NULL
- terminates the list. The pairs are the
- arguments to InstallProtocolInterface(). All the
- protocols are added to Handle.
-
- @retval EFI_SUCCESS All the protocol interface was installed.
- @retval EFI_OUT_OF_RESOURCES There was not enough memory in pool to install all the protocols.
- @retval EFI_ALREADY_STARTED A Device Path Protocol instance was passed in that is already present in
- the handle database.
- @retval EFI_INVALID_PARAMETER Handle is NULL.
- @retval EFI_INVALID_PARAMETER Protocol is already installed on the handle specified by Handle.
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestInstallMultipleProtocolInterfaces (
- IN OUT EFI_HANDLE *Handle,
- ...
- );
-
-/**
- Uninstalls a list of protocol interface in the boot services environment.
- This function calls UninstallProtocolInterface() in a loop. This is
- basically a lib function to save space.
-
- @param Handle The handle to uninstall the protocol
- @param ... EFI_GUID followed by protocol instance. A NULL
- terminates the list. The pairs are the
- arguments to UninstallProtocolInterface(). All
- the protocols are added to Handle.
-
- @return Status code
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestUninstallMultipleProtocolInterfaces (
- IN EFI_HANDLE Handle,
- ...
- );
-
-/**
- Computes and returns a 32-bit CRC for a data buffer.
-
- @param[in] Data A pointer to the buffer on which the 32-bit CRC is to be computed.
- @param[in] DataSize The number of bytes in the buffer Data.
- @param[out] Crc32 The 32-bit CRC that was computed for the data buffer specified by Data
- and DataSize.
-
- @retval EFI_SUCCESS The 32-bit CRC was computed for the data buffer and returned in
- Crc32.
- @retval EFI_INVALID_PARAMETER Data is NULL.
- @retval EFI_INVALID_PARAMETER Crc32 is NULL.
- @retval EFI_INVALID_PARAMETER DataSize is 0.
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestCalculateCrc32 (
- IN VOID *Data,
- IN UINTN DataSize,
- OUT UINT32 *Crc32
- );
-
-/**
- Creates an event in a group.
-
- @param Type The type of event to create and its mode and
- attributes
- @param NotifyTpl The task priority level of event notifications
- @param NotifyFunction Pointer to the events notification function
- @param NotifyContext Pointer to the notification functions context;
- corresponds to parameter "Context" in the
- notification function
- @param EventGroup GUID for EventGroup if NULL act the same as
- gBS->CreateEvent().
- @param Event Pointer to the newly created event if the call
- succeeds; undefined otherwise
-
- @retval EFI_SUCCESS The event structure was created
- @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value
- @retval EFI_OUT_OF_RESOURCES The event could not be allocated
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestCreateEventEx (
- IN UINT32 Type,
- IN EFI_TPL NotifyTpl,
- IN EFI_EVENT_NOTIFY NotifyFunction, OPTIONAL
- IN CONST VOID *NotifyContext, OPTIONAL
- IN CONST EFI_GUID *EventGroup, OPTIONAL
- OUT EFI_EVENT *Event
- );
-
-#endif
+/** @file + An internal header file for the Unit Test instance of the UEFI Boot Services Table Library. + + This file includes common header files, defines internal structure and functions used by + the library implementation. + +Copyright (c) Microsoft Corporation +SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef UEFI_BOOT_SERVICES_TABLE_LIB_UNIT_TEST_H_ +#define UEFI_BOOT_SERVICES_TABLE_LIB_UNIT_TEST_H_ + +#include <Uefi.h> + +#include <Pi/PiMultiPhase.h> +#include <Library/BaseLib.h> +#include <Library/BaseMemoryLib.h> +#include <Library/DebugLib.h> +#include <Library/MemoryAllocationLib.h> +#include <Library/UnitTestLib.h> +#include <Library/UefiBootServicesTableLib.h> + +/** + Raise the task priority level to the new level. + High level is implemented by disabling processor interrupts. + + @param NewTpl New task priority level + + @return The previous task priority level + +**/ +EFI_TPL +EFIAPI +UnitTestRaiseTpl ( + IN EFI_TPL NewTpl + ); + +/** + Lowers the task priority to the previous value. If the new + priority unmasks events at a higher priority, they are dispatched. + + @param NewTpl New, lower, task priority + +**/ +VOID +EFIAPI +UnitTestRestoreTpl ( + IN EFI_TPL NewTpl + ); + +/** + Allocates pages from the memory map. + + @param Type The type of allocation to perform + @param MemoryType The type of memory to turn the allocated pages + into + @param NumberOfPages The number of pages to allocate + @param Memory A pointer to receive the base allocated memory + address + + @return Status. On success, Memory is filled in with the base address allocated + @retval EFI_INVALID_PARAMETER Parameters violate checking rules defined in + spec. + @retval EFI_NOT_FOUND Could not allocate pages match the requirement. + @retval EFI_OUT_OF_RESOURCES No enough pages to allocate. + @retval EFI_SUCCESS Pages successfully allocated. + +**/ +EFI_STATUS +EFIAPI +UnitTestAllocatePages ( + IN EFI_ALLOCATE_TYPE Type, + IN EFI_MEMORY_TYPE MemoryType, + IN UINTN NumberOfPages, + IN OUT EFI_PHYSICAL_ADDRESS *Memory + ); + +/** + Frees previous allocated pages. + + @param Memory Base address of memory being freed + @param NumberOfPages The number of pages to free + + @retval EFI_NOT_FOUND Could not find the entry that covers the range + @retval EFI_INVALID_PARAMETER Address not aligned + @return EFI_SUCCESS -Pages successfully freed. + +**/ +EFI_STATUS +EFIAPI +UnitTestFreePages ( + IN EFI_PHYSICAL_ADDRESS Memory, + IN UINTN NumberOfPages + ); + +/** + This function returns a copy of the current memory map. The map is an array of + memory descriptors, each of which describes a contiguous block of memory. + + @param MemoryMapSize A pointer to the size, in bytes, of the + MemoryMap buffer. On input, this is the size of + the buffer allocated by the caller. On output, + it is the size of the buffer returned by the + firmware if the buffer was large enough, or the + size of the buffer needed to contain the map if + the buffer was too small. + @param MemoryMap A pointer to the buffer in which firmware places + the current memory map. + @param MapKey A pointer to the location in which firmware + returns the key for the current memory map. + @param DescriptorSize A pointer to the location in which firmware + returns the size, in bytes, of an individual + EFI_MEMORY_DESCRIPTOR. + @param DescriptorVersion A pointer to the location in which firmware + returns the version number associated with the + EFI_MEMORY_DESCRIPTOR. + + @retval EFI_SUCCESS The memory map was returned in the MemoryMap + buffer. + @retval EFI_BUFFER_TOO_SMALL The MemoryMap buffer was too small. The current + buffer size needed to hold the memory map is + returned in MemoryMapSize. + @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value. + +**/ +EFI_STATUS +EFIAPI +UnitTestGetMemoryMap ( + IN OUT UINTN *MemoryMapSize, + IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap, + OUT UINTN *MapKey, + OUT UINTN *DescriptorSize, + OUT UINT32 *DescriptorVersion + ); + +/** + Allocate pool of a particular type. + + @param PoolType Type of pool to allocate + @param Size The amount of pool to allocate + @param Buffer The address to return a pointer to the allocated + pool + + @retval EFI_INVALID_PARAMETER PoolType not valid or Buffer is NULL + @retval EFI_OUT_OF_RESOURCES Size exceeds max pool size or allocation failed. + @retval EFI_SUCCESS Pool successfully allocated. + +**/ +EFI_STATUS +EFIAPI +UnitTestAllocatePool ( + IN EFI_MEMORY_TYPE PoolType, + IN UINTN Size, + OUT VOID **Buffer + ); + +/** + Frees pool. + + @param Buffer The allocated pool entry to free + + @retval EFI_INVALID_PARAMETER Buffer is not a valid value. + @retval EFI_SUCCESS Pool successfully freed. + +**/ +EFI_STATUS +EFIAPI +UnitTestFreePool ( + IN VOID *Buffer + ); + +/** + Frees pool. + + @param Buffer The allocated pool entry to free + @param PoolType Pointer to pool type + + @retval EFI_INVALID_PARAMETER Buffer is not a valid value. + @retval EFI_SUCCESS Pool successfully freed. + +**/ +EFI_STATUS +EFIAPI +UnitTestInternalFreePool ( + IN VOID *Buffer, + OUT EFI_MEMORY_TYPE *PoolType OPTIONAL + ); + +/** + Creates an event. + + @param Type The type of event to create and its mode and + attributes + @param NotifyTpl The task priority level of event notifications + @param NotifyFunction Pointer to the events notification function + @param NotifyContext Pointer to the notification functions context; + corresponds to parameter "Context" in the + notification function + @param Event Pointer to the newly created event if the call + succeeds; undefined otherwise + + @retval EFI_SUCCESS The event structure was created + @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value + @retval EFI_OUT_OF_RESOURCES The event could not be allocated + +**/ +EFI_STATUS +EFIAPI +UnitTestCreateEvent ( + IN UINT32 Type, + IN EFI_TPL NotifyTpl, + IN EFI_EVENT_NOTIFY NotifyFunction, OPTIONAL + IN VOID *NotifyContext, OPTIONAL + OUT EFI_EVENT *Event + ); + +/** + Sets the type of timer and the trigger time for a timer event. + + @param UserEvent The timer event that is to be signaled at the + specified time + @param Type The type of time that is specified in + TriggerTime + @param TriggerTime The number of 100ns units until the timer + expires + + @retval EFI_SUCCESS The event has been set to be signaled at the + requested time + @retval EFI_INVALID_PARAMETER Event or Type is not valid + +**/ +EFI_STATUS +EFIAPI +UnitTestSetTimer ( + IN EFI_EVENT UserEvent, + IN EFI_TIMER_DELAY Type, + IN UINT64 TriggerTime + ); + +/** + Stops execution until an event is signaled. + + @param NumberOfEvents The number of events in the UserEvents array + @param UserEvents An array of EFI_EVENT + @param UserIndex Pointer to the index of the event which + satisfied the wait condition + + @retval EFI_SUCCESS The event indicated by Index was signaled. + @retval EFI_INVALID_PARAMETER The event indicated by Index has a notification + function or Event was not a valid type + @retval EFI_UNSUPPORTED The current TPL is not TPL_APPLICATION + +**/ +EFI_STATUS +EFIAPI +UnitTestWaitForEvent ( + IN UINTN NumberOfEvents, + IN EFI_EVENT *UserEvents, + OUT UINTN *UserIndex + ); + +/** + Signals the event. Queues the event to be notified if needed. + + @param UserEvent The event to signal . + + @retval EFI_INVALID_PARAMETER Parameters are not valid. + @retval EFI_SUCCESS The event was signaled. + +**/ +EFI_STATUS +EFIAPI +UnitTestSignalEvent ( + IN EFI_EVENT UserEvent + ); + +/** + Closes an event and frees the event structure. + + @param UserEvent Event to close + + @retval EFI_INVALID_PARAMETER Parameters are not valid. + @retval EFI_SUCCESS The event has been closed + +**/ +EFI_STATUS +EFIAPI +UnitTestCloseEvent ( + IN EFI_EVENT UserEvent + ); + +/** + Check the status of an event. + + @param UserEvent The event to check + + @retval EFI_SUCCESS The event is in the signaled state + @retval EFI_NOT_READY The event is not in the signaled state + @retval EFI_INVALID_PARAMETER Event is of type EVT_NOTIFY_SIGNAL + +**/ +EFI_STATUS +EFIAPI +UnitTestCheckEvent ( + IN EFI_EVENT UserEvent + ); + +/** + Wrapper function to UnitTestInstallProtocolInterfaceNotify. This is the public API which + Calls the private one which contains a BOOLEAN parameter for notifications + + @param UserHandle The handle to install the protocol handler on, + or NULL if a new handle is to be allocated + @param Protocol The protocol to add to the handle + @param InterfaceType Indicates whether Interface is supplied in + native form. + @param Interface The interface for the protocol being added + + @return Status code + +**/ +EFI_STATUS +EFIAPI +UnitTestInstallProtocolInterface ( + IN OUT EFI_HANDLE *UserHandle, + IN EFI_GUID *Protocol, + IN EFI_INTERFACE_TYPE InterfaceType, + IN VOID *Interface + ); + +/** + Reinstall a protocol interface on a device handle. The OldInterface for Protocol is replaced by the NewInterface. + + @param UserHandle Handle on which the interface is to be + reinstalled + @param Protocol The numeric ID of the interface + @param OldInterface A pointer to the old interface + @param NewInterface A pointer to the new interface + + @retval EFI_SUCCESS The protocol interface was installed + @retval EFI_NOT_FOUND The OldInterface on the handle was not found + @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value + +**/ +EFI_STATUS +EFIAPI +UnitTestReinstallProtocolInterface ( + IN EFI_HANDLE UserHandle, + IN EFI_GUID *Protocol, + IN VOID *OldInterface, + IN VOID *NewInterface + ); + +/** + Uninstalls all instances of a protocol:interfacer from a handle. + If the last protocol interface is remove from the handle, the + handle is freed. + + @param UserHandle The handle to remove the protocol handler from + @param Protocol The protocol, of protocol:interface, to remove + @param Interface The interface, of protocol:interface, to remove + + @retval EFI_INVALID_PARAMETER Protocol is NULL. + @retval EFI_SUCCESS Protocol interface successfully uninstalled. + +**/ +EFI_STATUS +EFIAPI +UnitTestUninstallProtocolInterface ( + IN EFI_HANDLE UserHandle, + IN EFI_GUID *Protocol, + IN VOID *Interface + ); + +/** + Queries a handle to determine if it supports a specified protocol. + + @param UserHandle The handle being queried. + @param Protocol The published unique identifier of the protocol. + @param Interface Supplies the address where a pointer to the + corresponding Protocol Interface is returned. + + @return The requested protocol interface for the handle + +**/ +EFI_STATUS +EFIAPI +UnitTestHandleProtocol ( + IN EFI_HANDLE UserHandle, + IN EFI_GUID *Protocol, + OUT VOID **Interface + ); + +/** + Add a new protocol notification record for the request protocol. + + @param Protocol The requested protocol to add the notify + registration + @param Event The event to signal + @param Registration Returns the registration record + + @retval EFI_INVALID_PARAMETER Invalid parameter + @retval EFI_SUCCESS Successfully returned the registration record + that has been added + +**/ +EFI_STATUS +EFIAPI +UnitTestRegisterProtocolNotify ( + IN EFI_GUID *Protocol, + IN EFI_EVENT Event, + OUT VOID **Registration + ); + +/** + Locates the requested handle(s) and returns them in Buffer. + + @param SearchType The type of search to perform to locate the + handles + @param Protocol The protocol to search for + @param SearchKey Dependant on SearchType + @param BufferSize On input the size of Buffer. On output the + size of data returned. + @param Buffer The buffer to return the results in + + @retval EFI_BUFFER_TOO_SMALL Buffer too small, required buffer size is + returned in BufferSize. + @retval EFI_INVALID_PARAMETER Invalid parameter + @retval EFI_SUCCESS Successfully found the requested handle(s) and + returns them in Buffer. + +**/ +EFI_STATUS +EFIAPI +UnitTestLocateHandle ( + IN EFI_LOCATE_SEARCH_TYPE SearchType, + IN EFI_GUID *Protocol OPTIONAL, + IN VOID *SearchKey OPTIONAL, + IN OUT UINTN *BufferSize, + OUT EFI_HANDLE *Buffer + ); + +/** + Locates the handle to a device on the device path that best matches the specified protocol. + + @param Protocol The protocol to search for. + @param DevicePath On input, a pointer to a pointer to the device + path. On output, the device path pointer is + modified to point to the remaining part of the + devicepath. + @param Device A pointer to the returned device handle. + + @retval EFI_SUCCESS The resulting handle was returned. + @retval EFI_NOT_FOUND No handles matched the search. + @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value. + +**/ +EFI_STATUS +EFIAPI +UnitTestLocateDevicePath ( + IN EFI_GUID *Protocol, + IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath, + OUT EFI_HANDLE *Device + ); + +/** + Boot Service called to add, modify, or remove a system configuration table from + the EFI System Table. + + @param Guid Pointer to the GUID for the entry to add, update, or + remove + @param Table Pointer to the configuration table for the entry to add, + update, or remove, may be NULL. + + @return EFI_SUCCESS Guid, Table pair added, updated, or removed. + @return EFI_INVALID_PARAMETER Input GUID not valid. + @return EFI_NOT_FOUND Attempted to delete non-existant entry + @return EFI_OUT_OF_RESOURCES Not enough memory available + +**/ +EFI_STATUS +EFIAPI +UnitTestInstallConfigurationTable ( + IN EFI_GUID *Guid, + IN VOID *Table + ); + +/** + Loads an EFI image into memory and returns a handle to the image. + + @param BootPolicy If TRUE, indicates that the request originates + from the boot manager, and that the boot + manager is attempting to load FilePath as a + boot selection. + @param ParentImageHandle The caller's image handle. + @param FilePath The specific file path from which the image is + loaded. + @param SourceBuffer If not NULL, a pointer to the memory location + containing a copy of the image to be loaded. + @param SourceSize The size in bytes of SourceBuffer. + @param ImageHandle Pointer to the returned image handle that is + created when the image is successfully loaded. + + @retval EFI_SUCCESS The image was loaded into memory. + @retval EFI_NOT_FOUND The FilePath was not found. + @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value. + @retval EFI_UNSUPPORTED The image type is not supported, or the device + path cannot be parsed to locate the proper + protocol for loading the file. + @retval EFI_OUT_OF_RESOURCES Image was not loaded due to insufficient + resources. + @retval EFI_LOAD_ERROR Image was not loaded because the image format was corrupt or not + understood. + @retval EFI_DEVICE_ERROR Image was not loaded because the device returned a read error. + @retval EFI_ACCESS_DENIED Image was not loaded because the platform policy prohibits the + image from being loaded. NULL is returned in *ImageHandle. + @retval EFI_SECURITY_VIOLATION Image was loaded and an ImageHandle was created with a + valid EFI_LOADED_IMAGE_PROTOCOL. However, the current + platform policy specifies that the image should not be started. + +**/ +EFI_STATUS +EFIAPI +UnitTestLoadImage ( + IN BOOLEAN BootPolicy, + IN EFI_HANDLE ParentImageHandle, + IN EFI_DEVICE_PATH_PROTOCOL *FilePath, + IN VOID *SourceBuffer OPTIONAL, + IN UINTN SourceSize, + OUT EFI_HANDLE *ImageHandle + ); + +/** + Transfer control to a loaded image's entry point. + + @param ImageHandle Handle of image to be started. + @param ExitDataSize Pointer of the size to ExitData + @param ExitData Pointer to a pointer to a data buffer that + includes a Null-terminated string, + optionally followed by additional binary data. + The string is a description that the caller may + use to further indicate the reason for the + image's exit. + + @retval EFI_INVALID_PARAMETER Invalid parameter + @retval EFI_OUT_OF_RESOURCES No enough buffer to allocate + @retval EFI_SECURITY_VIOLATION The current platform policy specifies that the image should not be started. + @retval EFI_SUCCESS Successfully transfer control to the image's + entry point. + +**/ +EFI_STATUS +EFIAPI +UnitTestStartImage ( + IN EFI_HANDLE ImageHandle, + OUT UINTN *ExitDataSize, + OUT CHAR16 **ExitData OPTIONAL + ); + +/** + Terminates the currently loaded EFI image and returns control to boot services. + + @param ImageHandle Handle that identifies the image. This + parameter is passed to the image on entry. + @param Status The image's exit code. + @param ExitDataSize The size, in bytes, of ExitData. Ignored if + ExitStatus is EFI_SUCCESS. + @param ExitData Pointer to a data buffer that includes a + Null-terminated Unicode string, optionally + followed by additional binary data. The string + is a description that the caller may use to + further indicate the reason for the image's + exit. + + @retval EFI_INVALID_PARAMETER Image handle is NULL or it is not current + image. + @retval EFI_SUCCESS Successfully terminates the currently loaded + EFI image. + @retval EFI_ACCESS_DENIED Should never reach there. + @retval EFI_OUT_OF_RESOURCES Could not allocate pool + +**/ +EFI_STATUS +EFIAPI +UnitTestExit ( + IN EFI_HANDLE ImageHandle, + IN EFI_STATUS Status, + IN UINTN ExitDataSize, + IN CHAR16 *ExitData OPTIONAL + ); + +/** + Unloads an image. + + @param ImageHandle Handle that identifies the image to be + unloaded. + + @retval EFI_SUCCESS The image has been unloaded. + @retval EFI_UNSUPPORTED The image has been started, and does not support + unload. + @retval EFI_INVALID_PARAMPETER ImageHandle is not a valid image handle. + +**/ +EFI_STATUS +EFIAPI +UnitTestUnloadImage ( + IN EFI_HANDLE ImageHandle + ); + +/** + Terminates all boot services. + + @param ImageHandle Handle that identifies the exiting image. + @param MapKey Key to the latest memory map. + + @retval EFI_SUCCESS Boot Services terminated + @retval EFI_INVALID_PARAMETER MapKey is incorrect. + +**/ +EFI_STATUS +EFIAPI +UnitTestExitBootServices ( + IN EFI_HANDLE ImageHandle, + IN UINTN MapKey + ); + +/** + Returns a monotonically increasing count for the platform. + + @param[out] Count The pointer to returned value. + + @retval EFI_SUCCESS The next monotonic count was returned. + @retval EFI_INVALID_PARAMETER Count is NULL. + @retval EFI_DEVICE_ERROR The device is not functioning properly. + +**/ +EFI_STATUS +EFIAPI +UnitTestGetNextMonotonicCount ( + OUT UINT64 *Count + ); + +/** + Introduces a fine-grained stall. + + @param Microseconds The number of microseconds to stall execution. + + @retval EFI_SUCCESS Execution was stalled for at least the requested + amount of microseconds. + @retval EFI_NOT_AVAILABLE_YET gMetronome is not available yet + +**/ +EFI_STATUS +EFIAPI +UnitTestStall ( + IN UINTN Microseconds + ); + +/** + Sets the system's watchdog timer. + + @param Timeout The number of seconds to set the watchdog timer to. + A value of zero disables the timer. + @param WatchdogCode The numeric code to log on a watchdog timer timeout + event. The firmware reserves codes 0x0000 to 0xFFFF. + Loaders and operating systems may use other timeout + codes. + @param DataSize The size, in bytes, of WatchdogData. + @param WatchdogData A data buffer that includes a Null-terminated Unicode + string, optionally followed by additional binary data. + The string is a description that the call may use to + further indicate the reason to be logged with a + watchdog event. + + @return EFI_SUCCESS Timeout has been set + @return EFI_NOT_AVAILABLE_YET WatchdogTimer is not available yet + @return EFI_UNSUPPORTED System does not have a timer (currently not used) + @return EFI_DEVICE_ERROR Could not complete due to hardware error + +**/ +EFI_STATUS +EFIAPI +UnitTestSetWatchdogTimer ( + IN UINTN Timeout, + IN UINT64 WatchdogCode, + IN UINTN DataSize, + IN CHAR16 *WatchdogData OPTIONAL + ); + +/** + Connects one or more drivers to a controller. + + @param ControllerHandle The handle of the controller to which driver(s) are to be connected. + @param DriverImageHandle A pointer to an ordered list handles that support the + EFI_DRIVER_BINDING_PROTOCOL. + @param RemainingDevicePath A pointer to the device path that specifies a child of the + controller specified by ControllerHandle. + @param Recursive If TRUE, then ConnectController() is called recursively + until the entire tree of controllers below the controller specified + by ControllerHandle have been created. If FALSE, then + the tree of controllers is only expanded one level. + + @retval EFI_SUCCESS 1) One or more drivers were connected to ControllerHandle. + 2) No drivers were connected to ControllerHandle, but + RemainingDevicePath is not NULL, and it is an End Device + Path Node. + @retval EFI_INVALID_PARAMETER ControllerHandle is NULL. + @retval EFI_NOT_FOUND 1) There are no EFI_DRIVER_BINDING_PROTOCOL instances + present in the system. + 2) No drivers were connected to ControllerHandle. + @retval EFI_SECURITY_VIOLATION + The user has no permission to start UEFI device drivers on the device path + associated with the ControllerHandle or specified by the RemainingDevicePath. + +**/ +EFI_STATUS +EFIAPI +UnitTestConnectController ( + IN EFI_HANDLE ControllerHandle, + IN EFI_HANDLE *DriverImageHandle OPTIONAL, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL, + IN BOOLEAN Recursive + ); + +/** + Disconnects a controller from a driver + + @param ControllerHandle ControllerHandle The handle of + the controller from which + driver(s) are to be + disconnected. + @param DriverImageHandle DriverImageHandle The driver to + disconnect from ControllerHandle. + @param ChildHandle ChildHandle The handle of the + child to destroy. + + @retval EFI_SUCCESS One or more drivers were + disconnected from the controller. + @retval EFI_SUCCESS On entry, no drivers are managing + ControllerHandle. + @retval EFI_SUCCESS DriverImageHandle is not NULL, + and on entry DriverImageHandle is + not managing ControllerHandle. + @retval EFI_INVALID_PARAMETER ControllerHandle is NULL. + @retval EFI_INVALID_PARAMETER DriverImageHandle is not NULL, + and it is not a valid EFI_HANDLE. + @retval EFI_INVALID_PARAMETER ChildHandle is not NULL, and it + is not a valid EFI_HANDLE. + @retval EFI_OUT_OF_RESOURCES There are not enough resources + available to disconnect any + drivers from ControllerHandle. + @retval EFI_DEVICE_ERROR The controller could not be + disconnected because of a device + error. + +**/ +EFI_STATUS +EFIAPI +UnitTestDisconnectController ( + IN EFI_HANDLE ControllerHandle, + IN EFI_HANDLE DriverImageHandle OPTIONAL, + IN EFI_HANDLE ChildHandle OPTIONAL + ); + +/** + Locates the installed protocol handler for the handle, and + invokes it to obtain the protocol interface. Usage information + is registered in the protocol data base. + + @param UserHandle The handle to obtain the protocol interface on + @param Protocol The ID of the protocol + @param Interface The location to return the protocol interface + @param ImageHandle The handle of the Image that is opening the + protocol interface specified by Protocol and + Interface. + @param ControllerHandle The controller handle that is requiring this + interface. + @param Attributes The open mode of the protocol interface + specified by Handle and Protocol. + + @retval EFI_INVALID_PARAMETER Protocol is NULL. + @retval EFI_SUCCESS Get the protocol interface. + +**/ +EFI_STATUS +EFIAPI +UnitTestOpenProtocol ( + IN EFI_HANDLE UserHandle, + IN EFI_GUID *Protocol, + OUT VOID **Interface OPTIONAL, + IN EFI_HANDLE ImageHandle, + IN EFI_HANDLE ControllerHandle, + IN UINT32 Attributes + ); + +/** + Closes a protocol on a handle that was opened using OpenProtocol(). + + @param UserHandle The handle for the protocol interface that was + previously opened with OpenProtocol(), and is + now being closed. + @param Protocol The published unique identifier of the protocol. + It is the caller's responsibility to pass in a + valid GUID. + @param AgentHandle The handle of the agent that is closing the + protocol interface. + @param ControllerHandle If the agent that opened a protocol is a driver + that follows the EFI Driver Model, then this + parameter is the controller handle that required + the protocol interface. If the agent does not + follow the EFI Driver Model, then this parameter + is optional and may be NULL. + + @retval EFI_SUCCESS The protocol instance was closed. + @retval EFI_INVALID_PARAMETER Handle, AgentHandle or ControllerHandle is not a + valid EFI_HANDLE. + @retval EFI_NOT_FOUND Can not find the specified protocol or + AgentHandle. + +**/ +EFI_STATUS +EFIAPI +UnitTestCloseProtocol ( + IN EFI_HANDLE UserHandle, + IN EFI_GUID *Protocol, + IN EFI_HANDLE AgentHandle, + IN EFI_HANDLE ControllerHandle + ); + +/** + Return information about Opened protocols in the system + + @param UserHandle The handle to close the protocol interface on + @param Protocol The ID of the protocol + @param EntryBuffer A pointer to a buffer of open protocol + information in the form of + EFI_OPEN_PROTOCOL_INFORMATION_ENTRY structures. + @param EntryCount Number of EntryBuffer entries + +**/ +EFI_STATUS +EFIAPI +UnitTestOpenProtocolInformation ( + IN EFI_HANDLE UserHandle, + IN EFI_GUID *Protocol, + OUT EFI_OPEN_PROTOCOL_INFORMATION_ENTRY **EntryBuffer, + OUT UINTN *EntryCount + ); + +/** + Retrieves the list of protocol interface GUIDs that are installed on a handle in a buffer allocated + from pool. + + @param UserHandle The handle from which to retrieve the list of + protocol interface GUIDs. + @param ProtocolBuffer A pointer to the list of protocol interface GUID + pointers that are installed on Handle. + @param ProtocolBufferCount A pointer to the number of GUID pointers present + in ProtocolBuffer. + + @retval EFI_SUCCESS The list of protocol interface GUIDs installed + on Handle was returned in ProtocolBuffer. The + number of protocol interface GUIDs was returned + in ProtocolBufferCount. + @retval EFI_INVALID_PARAMETER Handle is NULL. + @retval EFI_INVALID_PARAMETER Handle is not a valid EFI_HANDLE. + @retval EFI_INVALID_PARAMETER ProtocolBuffer is NULL. + @retval EFI_INVALID_PARAMETER ProtocolBufferCount is NULL. + @retval EFI_OUT_OF_RESOURCES There is not enough pool memory to store the + results. + +**/ +EFI_STATUS +EFIAPI +UnitTestProtocolsPerHandle ( + IN EFI_HANDLE UserHandle, + OUT EFI_GUID ***ProtocolBuffer, + OUT UINTN *ProtocolBufferCount + ); + +/** + Function returns an array of handles that support the requested protocol + in a buffer allocated from pool. This is a version of UnitTestLocateHandle() + that allocates a buffer for the caller. + + @param SearchType Specifies which handle(s) are to be returned. + @param Protocol Provides the protocol to search by. This + parameter is only valid for SearchType + ByProtocol. + @param SearchKey Supplies the search key depending on the + SearchType. + @param NumberHandles The number of handles returned in Buffer. + @param Buffer A pointer to the buffer to return the requested + array of handles that support Protocol. + + @retval EFI_SUCCESS The result array of handles was returned. + @retval EFI_NOT_FOUND No handles match the search. + @retval EFI_OUT_OF_RESOURCES There is not enough pool memory to store the + matching results. + @retval EFI_INVALID_PARAMETER One or more parameters are not valid. + +**/ +EFI_STATUS +EFIAPI +UnitTestLocateHandleBuffer ( + IN EFI_LOCATE_SEARCH_TYPE SearchType, + IN EFI_GUID *Protocol OPTIONAL, + IN VOID *SearchKey OPTIONAL, + IN OUT UINTN *NumberHandles, + OUT EFI_HANDLE **Buffer + ); + +/** + Return the first Protocol Interface that matches the Protocol GUID. If + Registration is passed in, return a Protocol Instance that was just add + to the system. If Registration is NULL return the first Protocol Interface + you find. + + @param Protocol The protocol to search for + @param Registration Optional Registration Key returned from + RegisterProtocolNotify() + @param Interface Return the Protocol interface (instance). + + @retval EFI_SUCCESS If a valid Interface is returned + @retval EFI_INVALID_PARAMETER Invalid parameter + @retval EFI_NOT_FOUND Protocol interface not found + +**/ +EFI_STATUS +EFIAPI +UnitTestLocateProtocol ( + IN EFI_GUID *Protocol, + IN VOID *Registration OPTIONAL, + OUT VOID **Interface + ); + +/** + Installs a list of protocol interface into the boot services environment. + This function calls InstallProtocolInterface() in a loop. If any error + occurs all the protocols added by this function are removed. This is + basically a lib function to save space. + + @param Handle The handle to install the protocol handlers on, + or NULL if a new handle is to be allocated + @param ... EFI_GUID followed by protocol instance. A NULL + terminates the list. The pairs are the + arguments to InstallProtocolInterface(). All the + protocols are added to Handle. + + @retval EFI_SUCCESS All the protocol interface was installed. + @retval EFI_OUT_OF_RESOURCES There was not enough memory in pool to install all the protocols. + @retval EFI_ALREADY_STARTED A Device Path Protocol instance was passed in that is already present in + the handle database. + @retval EFI_INVALID_PARAMETER Handle is NULL. + @retval EFI_INVALID_PARAMETER Protocol is already installed on the handle specified by Handle. + +**/ +EFI_STATUS +EFIAPI +UnitTestInstallMultipleProtocolInterfaces ( + IN OUT EFI_HANDLE *Handle, + ... + ); + +/** + Uninstalls a list of protocol interface in the boot services environment. + This function calls UninstallProtocolInterface() in a loop. This is + basically a lib function to save space. + + @param Handle The handle to uninstall the protocol + @param ... EFI_GUID followed by protocol instance. A NULL + terminates the list. The pairs are the + arguments to UninstallProtocolInterface(). All + the protocols are added to Handle. + + @return Status code + +**/ +EFI_STATUS +EFIAPI +UnitTestUninstallMultipleProtocolInterfaces ( + IN EFI_HANDLE Handle, + ... + ); + +/** + Computes and returns a 32-bit CRC for a data buffer. + + @param[in] Data A pointer to the buffer on which the 32-bit CRC is to be computed. + @param[in] DataSize The number of bytes in the buffer Data. + @param[out] Crc32 The 32-bit CRC that was computed for the data buffer specified by Data + and DataSize. + + @retval EFI_SUCCESS The 32-bit CRC was computed for the data buffer and returned in + Crc32. + @retval EFI_INVALID_PARAMETER Data is NULL. + @retval EFI_INVALID_PARAMETER Crc32 is NULL. + @retval EFI_INVALID_PARAMETER DataSize is 0. + +**/ +EFI_STATUS +EFIAPI +UnitTestCalculateCrc32 ( + IN VOID *Data, + IN UINTN DataSize, + OUT UINT32 *Crc32 + ); + +/** + Creates an event in a group. + + @param Type The type of event to create and its mode and + attributes + @param NotifyTpl The task priority level of event notifications + @param NotifyFunction Pointer to the events notification function + @param NotifyContext Pointer to the notification functions context; + corresponds to parameter "Context" in the + notification function + @param EventGroup GUID for EventGroup if NULL act the same as + gBS->CreateEvent(). + @param Event Pointer to the newly created event if the call + succeeds; undefined otherwise + + @retval EFI_SUCCESS The event structure was created + @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value + @retval EFI_OUT_OF_RESOURCES The event could not be allocated + +**/ +EFI_STATUS +EFIAPI +UnitTestCreateEventEx ( + IN UINT32 Type, + IN EFI_TPL NotifyTpl, + IN EFI_EVENT_NOTIFY NotifyFunction, OPTIONAL + IN CONST VOID *NotifyContext, OPTIONAL + IN CONST EFI_GUID *EventGroup, OPTIONAL + OUT EFI_EVENT *Event + ); + +#endif diff --git a/UnitTestFrameworkPkg/Library/UnitTestUefiBootServicesTableLib/UnitTestUefiBootServicesTableLib.inf b/UnitTestFrameworkPkg/Library/UnitTestUefiBootServicesTableLib/UnitTestUefiBootServicesTableLib.inf index b694dd0232..c759d6dd53 100644 --- a/UnitTestFrameworkPkg/Library/UnitTestUefiBootServicesTableLib/UnitTestUefiBootServicesTableLib.inf +++ b/UnitTestFrameworkPkg/Library/UnitTestUefiBootServicesTableLib/UnitTestUefiBootServicesTableLib.inf @@ -1,46 +1,46 @@ -## @file
-# UEFI Boot Services Table Library for unit tests implementation.
-#
-# Copyright (c) Microsoft Corporation
-# SPDX-License-Identifier: BSD-2-Clause-Patent
-#
-##
-
-[Defines]
- INF_VERSION = 0x00010005
- BASE_NAME = UnitTestUefiBootServicesTableLib
- MODULE_UNI_FILE = UefiBootServicesTableLibTest.uni
- FILE_GUID = AA3A0651-89EB-4951-9D68-50F27360EBC2
- MODULE_TYPE = UEFI_DRIVER
- VERSION_STRING = 1.0
- LIBRARY_CLASS = UefiBootServicesTableLib|DXE_CORE DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SMM_DRIVER UEFI_APPLICATION UEFI_DRIVER SMM_CORE
-
- CONSTRUCTOR = UnitTestUefiBootServicesTableLibConstructor
-
-#
-# VALID_ARCHITECTURES = IA32 X64 EBC
-#
-
-[Sources]
- UnitTestUefiBootServicesTableLib.h
- UnitTestUefiBootServicesTableLib.c
- UnitTestUefiBootServicesTableLibEventTimer.c
- UnitTestUefiBootServicesTableLibImage.c
- UnitTestUefiBootServicesTableLibMemory.c
- UnitTestUefiBootServicesTableLibProtocol.h
- UnitTestUefiBootServicesTableLibProtocol.c
- UnitTestUefiBootServicesTableLibMisc.c
- UnitTestUefiBootServicesTableLibTpl.c
-
-[Packages]
- MdePkg/MdePkg.dec
-
-[LibraryClasses]
- BaseLib
- BaseMemoryLib
- DebugLib
- MemoryAllocationLib
- UnitTestLib
-
-[UserExtensions.TianoCore."ExtraFiles"]
- TimerExtra.uni
+## @file +# UEFI Boot Services Table Library for unit tests implementation. +# +# Copyright (c) Microsoft Corporation +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = UnitTestUefiBootServicesTableLib + MODULE_UNI_FILE = UefiBootServicesTableLibTest.uni + FILE_GUID = AA3A0651-89EB-4951-9D68-50F27360EBC2 + MODULE_TYPE = UEFI_DRIVER + VERSION_STRING = 1.0 + LIBRARY_CLASS = UefiBootServicesTableLib|DXE_CORE DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SMM_DRIVER UEFI_APPLICATION UEFI_DRIVER SMM_CORE + + CONSTRUCTOR = UnitTestUefiBootServicesTableLibConstructor + +# +# VALID_ARCHITECTURES = IA32 X64 EBC +# + +[Sources] + UnitTestUefiBootServicesTableLib.h + UnitTestUefiBootServicesTableLib.c + UnitTestUefiBootServicesTableLibEventTimer.c + UnitTestUefiBootServicesTableLibImage.c + UnitTestUefiBootServicesTableLibMemory.c + UnitTestUefiBootServicesTableLibProtocol.h + UnitTestUefiBootServicesTableLibProtocol.c + UnitTestUefiBootServicesTableLibMisc.c + UnitTestUefiBootServicesTableLibTpl.c + +[Packages] + MdePkg/MdePkg.dec + +[LibraryClasses] + BaseLib + BaseMemoryLib + DebugLib + MemoryAllocationLib + UnitTestLib + +[UserExtensions.TianoCore."ExtraFiles"] + TimerExtra.uni diff --git a/UnitTestFrameworkPkg/Library/UnitTestUefiBootServicesTableLib/UnitTestUefiBootServicesTableLib.uni b/UnitTestFrameworkPkg/Library/UnitTestUefiBootServicesTableLib/UnitTestUefiBootServicesTableLib.uni index 1f742bb6d8..1cc94c0c66 100644 --- a/UnitTestFrameworkPkg/Library/UnitTestUefiBootServicesTableLib/UnitTestUefiBootServicesTableLib.uni +++ b/UnitTestFrameworkPkg/Library/UnitTestUefiBootServicesTableLib/UnitTestUefiBootServicesTableLib.uni @@ -1,12 +1,12 @@ -// /** @file
-// UEFI Boot Services Table Library for unit tests implementation.
-//
-// Copyright (c) Microsoft Corporation
-//
-// SPDX-License-Identifier: BSD-2-Clause-Patent
-//
-// **/
-
-#string STR_MODULE_ABSTRACT #language en-US "UEFI Boot Services Table Library for unit tests"
-
-#string STR_MODULE_DESCRIPTION #language en-US "UEFI Boot Services Table Library for unit tests."
+// /** @file +// UEFI Boot Services Table Library for unit tests implementation. +// +// Copyright (c) Microsoft Corporation +// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + +#string STR_MODULE_ABSTRACT #language en-US "UEFI Boot Services Table Library for unit tests" + +#string STR_MODULE_DESCRIPTION #language en-US "UEFI Boot Services Table Library for unit tests." diff --git a/UnitTestFrameworkPkg/Library/UnitTestUefiBootServicesTableLib/UnitTestUefiBootServicesTableLibEventTimer.c b/UnitTestFrameworkPkg/Library/UnitTestUefiBootServicesTableLib/UnitTestUefiBootServicesTableLibEventTimer.c index dc02c4ef9a..8645466e08 100644 --- a/UnitTestFrameworkPkg/Library/UnitTestUefiBootServicesTableLib/UnitTestUefiBootServicesTableLibEventTimer.c +++ b/UnitTestFrameworkPkg/Library/UnitTestUefiBootServicesTableLib/UnitTestUefiBootServicesTableLibEventTimer.c @@ -1,180 +1,180 @@ -/** @file
- Implementation of event and timer related services in the UEFI Boot Services table for use in unit tests.
-
-Copyright (c) Microsoft Corporation
-SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#include "UnitTestUefiBootServicesTableLib.h"
-
-/**
- Creates an event.
-
- @param Type The type of event to create and its mode and
- attributes
- @param NotifyTpl The task priority level of event notifications
- @param NotifyFunction Pointer to the events notification function
- @param NotifyContext Pointer to the notification functions context
- corresponds to parameter "Context" in the
- notification function
- @param Event Pointer to the newly created event if the call
- succeeds undefined otherwise
-
- @retval EFI_SUCCESS The event structure was created
- @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value
- @retval EFI_OUT_OF_RESOURCES The event could not be allocated
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestCreateEvent (
- IN UINT32 Type,
- IN EFI_TPL NotifyTpl,
- IN EFI_EVENT_NOTIFY NotifyFunction, OPTIONAL
- IN VOID *NotifyContext, OPTIONAL
- OUT EFI_EVENT *Event
- )
-{
- return EFI_NOT_AVAILABLE_YET;
-}
-
-/**
- Sets the type of timer and the trigger time for a timer event.
-
- @param UserEvent The timer event that is to be signaled at the
- specified time
- @param Type The type of time that is specified in
- TriggerTime
- @param TriggerTime The number of 100ns units until the timer
- expires
-
- @retval EFI_SUCCESS The event has been set to be signaled at the
- requested time
- @retval EFI_INVALID_PARAMETER Event or Type is not valid
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestSetTimer (
- IN EFI_EVENT UserEvent,
- IN EFI_TIMER_DELAY Type,
- IN UINT64 TriggerTime
- )
-{
- return EFI_NOT_AVAILABLE_YET;
-}
-
-/**
- Stops execution until an event is signaled.
-
- @param NumberOfEvents The number of events in the UserEvents array
- @param UserEvents An array of EFI_EVENT
- @param UserIndex Pointer to the index of the event which
- satisfied the wait condition
-
- @retval EFI_SUCCESS The event indicated by Index was signaled.
- @retval EFI_INVALID_PARAMETER The event indicated by Index has a notification
- function or Event was not a valid type
- @retval EFI_UNSUPPORTED The current TPL is not TPL_APPLICATION
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestWaitForEvent (
- IN UINTN NumberOfEvents,
- IN EFI_EVENT *UserEvents,
- OUT UINTN *UserIndex
- )
-{
- return EFI_NOT_AVAILABLE_YET;
-}
-
-/**
- Signals the event. Queues the event to be notified if needed.
-
- @param UserEvent The event to signal .
-
- @retval EFI_INVALID_PARAMETER Parameters are not valid.
- @retval EFI_SUCCESS The event was signaled.
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestSignalEvent (
- IN EFI_EVENT UserEvent
- )
-{
- return EFI_NOT_AVAILABLE_YET;
-}
-
-/**
- Closes an event and frees the event structure.
-
- @param UserEvent Event to close
-
- @retval EFI_INVALID_PARAMETER Parameters are not valid.
- @retval EFI_SUCCESS The event has been closed
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestCloseEvent (
- IN EFI_EVENT UserEvent
- )
-{
- return EFI_NOT_AVAILABLE_YET;
-}
-
-/**
- Check the status of an event.
-
- @param UserEvent The event to check
-
- @retval EFI_SUCCESS The event is in the signaled state
- @retval EFI_NOT_READY The event is not in the signaled state
- @retval EFI_INVALID_PARAMETER Event is of type EVT_NOTIFY_SIGNAL
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestCheckEvent (
- IN EFI_EVENT UserEvent
- )
-{
- return EFI_NOT_AVAILABLE_YET;
-}
-
-/**
- Creates an event in a group.
-
- @param Type The type of event to create and its mode and
- attributes
- @param NotifyTpl The task priority level of event notifications
- @param NotifyFunction Pointer to the events notification function
- @param NotifyContext Pointer to the notification functions context
- corresponds to parameter "Context" in the
- notification function
- @param EventGroup GUID for EventGroup if NULL act the same as
- gBS->CreateEvent().
- @param Event Pointer to the newly created event if the call
- succeeds undefined otherwise
-
- @retval EFI_SUCCESS The event structure was created
- @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value
- @retval EFI_OUT_OF_RESOURCES The event could not be allocated
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestCreateEventEx (
- IN UINT32 Type,
- IN EFI_TPL NotifyTpl,
- IN EFI_EVENT_NOTIFY NotifyFunction, OPTIONAL
- IN CONST VOID *NotifyContext, OPTIONAL
- IN CONST EFI_GUID *EventGroup, OPTIONAL
- OUT EFI_EVENT *Event
- )
-{
- return EFI_NOT_AVAILABLE_YET;
-}
+/** @file + Implementation of event and timer related services in the UEFI Boot Services table for use in unit tests. + +Copyright (c) Microsoft Corporation +SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "UnitTestUefiBootServicesTableLib.h" + +/** + Creates an event. + + @param Type The type of event to create and its mode and + attributes + @param NotifyTpl The task priority level of event notifications + @param NotifyFunction Pointer to the events notification function + @param NotifyContext Pointer to the notification functions context + corresponds to parameter "Context" in the + notification function + @param Event Pointer to the newly created event if the call + succeeds undefined otherwise + + @retval EFI_SUCCESS The event structure was created + @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value + @retval EFI_OUT_OF_RESOURCES The event could not be allocated + +**/ +EFI_STATUS +EFIAPI +UnitTestCreateEvent ( + IN UINT32 Type, + IN EFI_TPL NotifyTpl, + IN EFI_EVENT_NOTIFY NotifyFunction, OPTIONAL + IN VOID *NotifyContext, OPTIONAL + OUT EFI_EVENT *Event + ) +{ + return EFI_NOT_AVAILABLE_YET; +} + +/** + Sets the type of timer and the trigger time for a timer event. + + @param UserEvent The timer event that is to be signaled at the + specified time + @param Type The type of time that is specified in + TriggerTime + @param TriggerTime The number of 100ns units until the timer + expires + + @retval EFI_SUCCESS The event has been set to be signaled at the + requested time + @retval EFI_INVALID_PARAMETER Event or Type is not valid + +**/ +EFI_STATUS +EFIAPI +UnitTestSetTimer ( + IN EFI_EVENT UserEvent, + IN EFI_TIMER_DELAY Type, + IN UINT64 TriggerTime + ) +{ + return EFI_NOT_AVAILABLE_YET; +} + +/** + Stops execution until an event is signaled. + + @param NumberOfEvents The number of events in the UserEvents array + @param UserEvents An array of EFI_EVENT + @param UserIndex Pointer to the index of the event which + satisfied the wait condition + + @retval EFI_SUCCESS The event indicated by Index was signaled. + @retval EFI_INVALID_PARAMETER The event indicated by Index has a notification + function or Event was not a valid type + @retval EFI_UNSUPPORTED The current TPL is not TPL_APPLICATION + +**/ +EFI_STATUS +EFIAPI +UnitTestWaitForEvent ( + IN UINTN NumberOfEvents, + IN EFI_EVENT *UserEvents, + OUT UINTN *UserIndex + ) +{ + return EFI_NOT_AVAILABLE_YET; +} + +/** + Signals the event. Queues the event to be notified if needed. + + @param UserEvent The event to signal . + + @retval EFI_INVALID_PARAMETER Parameters are not valid. + @retval EFI_SUCCESS The event was signaled. + +**/ +EFI_STATUS +EFIAPI +UnitTestSignalEvent ( + IN EFI_EVENT UserEvent + ) +{ + return EFI_NOT_AVAILABLE_YET; +} + +/** + Closes an event and frees the event structure. + + @param UserEvent Event to close + + @retval EFI_INVALID_PARAMETER Parameters are not valid. + @retval EFI_SUCCESS The event has been closed + +**/ +EFI_STATUS +EFIAPI +UnitTestCloseEvent ( + IN EFI_EVENT UserEvent + ) +{ + return EFI_NOT_AVAILABLE_YET; +} + +/** + Check the status of an event. + + @param UserEvent The event to check + + @retval EFI_SUCCESS The event is in the signaled state + @retval EFI_NOT_READY The event is not in the signaled state + @retval EFI_INVALID_PARAMETER Event is of type EVT_NOTIFY_SIGNAL + +**/ +EFI_STATUS +EFIAPI +UnitTestCheckEvent ( + IN EFI_EVENT UserEvent + ) +{ + return EFI_NOT_AVAILABLE_YET; +} + +/** + Creates an event in a group. + + @param Type The type of event to create and its mode and + attributes + @param NotifyTpl The task priority level of event notifications + @param NotifyFunction Pointer to the events notification function + @param NotifyContext Pointer to the notification functions context + corresponds to parameter "Context" in the + notification function + @param EventGroup GUID for EventGroup if NULL act the same as + gBS->CreateEvent(). + @param Event Pointer to the newly created event if the call + succeeds undefined otherwise + + @retval EFI_SUCCESS The event structure was created + @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value + @retval EFI_OUT_OF_RESOURCES The event could not be allocated + +**/ +EFI_STATUS +EFIAPI +UnitTestCreateEventEx ( + IN UINT32 Type, + IN EFI_TPL NotifyTpl, + IN EFI_EVENT_NOTIFY NotifyFunction, OPTIONAL + IN CONST VOID *NotifyContext, OPTIONAL + IN CONST EFI_GUID *EventGroup, OPTIONAL + OUT EFI_EVENT *Event + ) +{ + return EFI_NOT_AVAILABLE_YET; +} diff --git a/UnitTestFrameworkPkg/Library/UnitTestUefiBootServicesTableLib/UnitTestUefiBootServicesTableLibImage.c b/UnitTestFrameworkPkg/Library/UnitTestUefiBootServicesTableLib/UnitTestUefiBootServicesTableLibImage.c index 144cc33e25..50501b9bae 100644 --- a/UnitTestFrameworkPkg/Library/UnitTestUefiBootServicesTableLib/UnitTestUefiBootServicesTableLibImage.c +++ b/UnitTestFrameworkPkg/Library/UnitTestUefiBootServicesTableLib/UnitTestUefiBootServicesTableLibImage.c @@ -1,163 +1,163 @@ -/** @file
- Implementation of image related services in the UEFI Boot Services table for use in unit tests.
-
-Copyright (c) Microsoft Corporation
-SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#include "UnitTestUefiBootServicesTableLib.h"
-
-/**
- Loads an EFI image into memory and returns a handle to the image.
-
- @param BootPolicy If TRUE, indicates that the request originates
- from the boot manager, and that the boot
- manager is attempting to load FilePath as a
- boot selection.
- @param ParentImageHandle The caller's image handle.
- @param FilePath The specific file path from which the image is
- loaded.
- @param SourceBuffer If not NULL, a pointer to the memory location
- containing a copy of the image to be loaded.
- @param SourceSize The size in bytes of SourceBuffer.
- @param ImageHandle Pointer to the returned image handle that is
- created when the image is successfully loaded.
-
- @retval EFI_SUCCESS The image was loaded into memory.
- @retval EFI_NOT_FOUND The FilePath was not found.
- @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value.
- @retval EFI_UNSUPPORTED The image type is not supported, or the device
- path cannot be parsed to locate the proper
- protocol for loading the file.
- @retval EFI_OUT_OF_RESOURCES Image was not loaded due to insufficient
- resources.
- @retval EFI_LOAD_ERROR Image was not loaded because the image format was corrupt or not
- understood.
- @retval EFI_DEVICE_ERROR Image was not loaded because the device returned a read error.
- @retval EFI_ACCESS_DENIED Image was not loaded because the platform policy prohibits the
- image from being loaded. NULL is returned in *ImageHandle.
- @retval EFI_SECURITY_VIOLATION Image was loaded and an ImageHandle was created with a
- valid EFI_LOADED_IMAGE_PROTOCOL. However, the current
- platform policy specifies that the image should not be started.
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestLoadImage (
- IN BOOLEAN BootPolicy,
- IN EFI_HANDLE ParentImageHandle,
- IN EFI_DEVICE_PATH_PROTOCOL *FilePath,
- IN VOID *SourceBuffer OPTIONAL,
- IN UINTN SourceSize,
- OUT EFI_HANDLE *ImageHandle
- )
-{
- return EFI_NOT_AVAILABLE_YET;
-}
-
-/**
- Transfer control to a loaded image's entry point.
-
- @param ImageHandle Handle of image to be started.
- @param ExitDataSize Pointer of the size to ExitData
- @param ExitData Pointer to a pointer to a data buffer that
- includes a Null-terminated string,
- optionally followed by additional binary data.
- The string is a description that the caller may
- use to further indicate the reason for the
- image's exit.
-
- @retval EFI_INVALID_PARAMETER Invalid parameter
- @retval EFI_OUT_OF_RESOURCES No enough buffer to allocate
- @retval EFI_SECURITY_VIOLATION The current platform policy specifies that the image should not be started.
- @retval EFI_SUCCESS Successfully transfer control to the image's
- entry point.
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestStartImage (
- IN EFI_HANDLE ImageHandle,
- OUT UINTN *ExitDataSize,
- OUT CHAR16 **ExitData OPTIONAL
- )
-{
- return EFI_NOT_AVAILABLE_YET;
-}
-
-/**
- Terminates the currently loaded EFI image and returns control to boot services.
-
- @param ImageHandle Handle that identifies the image. This
- parameter is passed to the image on entry.
- @param Status The image's exit code.
- @param ExitDataSize The size, in bytes, of ExitData. Ignored if
- ExitStatus is EFI_SUCCESS.
- @param ExitData Pointer to a data buffer that includes a
- Null-terminated Unicode string, optionally
- followed by additional binary data. The string
- is a description that the caller may use to
- further indicate the reason for the image's
- exit.
-
- @retval EFI_INVALID_PARAMETER Image handle is NULL or it is not current
- image.
- @retval EFI_SUCCESS Successfully terminates the currently loaded
- EFI image.
- @retval EFI_ACCESS_DENIED Should never reach there.
- @retval EFI_OUT_OF_RESOURCES Could not allocate pool
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestExit (
- IN EFI_HANDLE ImageHandle,
- IN EFI_STATUS Status,
- IN UINTN ExitDataSize,
- IN CHAR16 *ExitData OPTIONAL
- )
-{
- return EFI_NOT_AVAILABLE_YET;
-}
-
-/**
- Unloads an image.
-
- @param ImageHandle Handle that identifies the image to be
- unloaded.
-
- @retval EFI_SUCCESS The image has been unloaded.
- @retval EFI_UNSUPPORTED The image has been started, and does not support
- unload.
- @retval EFI_INVALID_PARAMPETER ImageHandle is not a valid image handle.
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestUnloadImage (
- IN EFI_HANDLE ImageHandle
- )
-{
- return EFI_NOT_AVAILABLE_YET;
-}
-
-/**
- Terminates all boot services.
-
- @param ImageHandle Handle that identifies the exiting image.
- @param MapKey Key to the latest memory map.
-
- @retval EFI_SUCCESS Boot Services terminated
- @retval EFI_INVALID_PARAMETER MapKey is incorrect.
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestExitBootServices (
- IN EFI_HANDLE ImageHandle,
- IN UINTN MapKey
- )
-{
- return EFI_NOT_AVAILABLE_YET;
-}
+/** @file + Implementation of image related services in the UEFI Boot Services table for use in unit tests. + +Copyright (c) Microsoft Corporation +SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "UnitTestUefiBootServicesTableLib.h" + +/** + Loads an EFI image into memory and returns a handle to the image. + + @param BootPolicy If TRUE, indicates that the request originates + from the boot manager, and that the boot + manager is attempting to load FilePath as a + boot selection. + @param ParentImageHandle The caller's image handle. + @param FilePath The specific file path from which the image is + loaded. + @param SourceBuffer If not NULL, a pointer to the memory location + containing a copy of the image to be loaded. + @param SourceSize The size in bytes of SourceBuffer. + @param ImageHandle Pointer to the returned image handle that is + created when the image is successfully loaded. + + @retval EFI_SUCCESS The image was loaded into memory. + @retval EFI_NOT_FOUND The FilePath was not found. + @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value. + @retval EFI_UNSUPPORTED The image type is not supported, or the device + path cannot be parsed to locate the proper + protocol for loading the file. + @retval EFI_OUT_OF_RESOURCES Image was not loaded due to insufficient + resources. + @retval EFI_LOAD_ERROR Image was not loaded because the image format was corrupt or not + understood. + @retval EFI_DEVICE_ERROR Image was not loaded because the device returned a read error. + @retval EFI_ACCESS_DENIED Image was not loaded because the platform policy prohibits the + image from being loaded. NULL is returned in *ImageHandle. + @retval EFI_SECURITY_VIOLATION Image was loaded and an ImageHandle was created with a + valid EFI_LOADED_IMAGE_PROTOCOL. However, the current + platform policy specifies that the image should not be started. + +**/ +EFI_STATUS +EFIAPI +UnitTestLoadImage ( + IN BOOLEAN BootPolicy, + IN EFI_HANDLE ParentImageHandle, + IN EFI_DEVICE_PATH_PROTOCOL *FilePath, + IN VOID *SourceBuffer OPTIONAL, + IN UINTN SourceSize, + OUT EFI_HANDLE *ImageHandle + ) +{ + return EFI_NOT_AVAILABLE_YET; +} + +/** + Transfer control to a loaded image's entry point. + + @param ImageHandle Handle of image to be started. + @param ExitDataSize Pointer of the size to ExitData + @param ExitData Pointer to a pointer to a data buffer that + includes a Null-terminated string, + optionally followed by additional binary data. + The string is a description that the caller may + use to further indicate the reason for the + image's exit. + + @retval EFI_INVALID_PARAMETER Invalid parameter + @retval EFI_OUT_OF_RESOURCES No enough buffer to allocate + @retval EFI_SECURITY_VIOLATION The current platform policy specifies that the image should not be started. + @retval EFI_SUCCESS Successfully transfer control to the image's + entry point. + +**/ +EFI_STATUS +EFIAPI +UnitTestStartImage ( + IN EFI_HANDLE ImageHandle, + OUT UINTN *ExitDataSize, + OUT CHAR16 **ExitData OPTIONAL + ) +{ + return EFI_NOT_AVAILABLE_YET; +} + +/** + Terminates the currently loaded EFI image and returns control to boot services. + + @param ImageHandle Handle that identifies the image. This + parameter is passed to the image on entry. + @param Status The image's exit code. + @param ExitDataSize The size, in bytes, of ExitData. Ignored if + ExitStatus is EFI_SUCCESS. + @param ExitData Pointer to a data buffer that includes a + Null-terminated Unicode string, optionally + followed by additional binary data. The string + is a description that the caller may use to + further indicate the reason for the image's + exit. + + @retval EFI_INVALID_PARAMETER Image handle is NULL or it is not current + image. + @retval EFI_SUCCESS Successfully terminates the currently loaded + EFI image. + @retval EFI_ACCESS_DENIED Should never reach there. + @retval EFI_OUT_OF_RESOURCES Could not allocate pool + +**/ +EFI_STATUS +EFIAPI +UnitTestExit ( + IN EFI_HANDLE ImageHandle, + IN EFI_STATUS Status, + IN UINTN ExitDataSize, + IN CHAR16 *ExitData OPTIONAL + ) +{ + return EFI_NOT_AVAILABLE_YET; +} + +/** + Unloads an image. + + @param ImageHandle Handle that identifies the image to be + unloaded. + + @retval EFI_SUCCESS The image has been unloaded. + @retval EFI_UNSUPPORTED The image has been started, and does not support + unload. + @retval EFI_INVALID_PARAMPETER ImageHandle is not a valid image handle. + +**/ +EFI_STATUS +EFIAPI +UnitTestUnloadImage ( + IN EFI_HANDLE ImageHandle + ) +{ + return EFI_NOT_AVAILABLE_YET; +} + +/** + Terminates all boot services. + + @param ImageHandle Handle that identifies the exiting image. + @param MapKey Key to the latest memory map. + + @retval EFI_SUCCESS Boot Services terminated + @retval EFI_INVALID_PARAMETER MapKey is incorrect. + +**/ +EFI_STATUS +EFIAPI +UnitTestExitBootServices ( + IN EFI_HANDLE ImageHandle, + IN UINTN MapKey + ) +{ + return EFI_NOT_AVAILABLE_YET; +} diff --git a/UnitTestFrameworkPkg/Library/UnitTestUefiBootServicesTableLib/UnitTestUefiBootServicesTableLibMemory.c b/UnitTestFrameworkPkg/Library/UnitTestUefiBootServicesTableLib/UnitTestUefiBootServicesTableLibMemory.c index abbb12974a..b7da2dcff8 100644 --- a/UnitTestFrameworkPkg/Library/UnitTestUefiBootServicesTableLib/UnitTestUefiBootServicesTableLibMemory.c +++ b/UnitTestFrameworkPkg/Library/UnitTestUefiBootServicesTableLib/UnitTestUefiBootServicesTableLibMemory.c @@ -1,145 +1,145 @@ -/** @file
- Implementation of memory related services in the UEFI Boot Services table for use in unit tests.
-
-Copyright (c) Microsoft Corporation
-SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#include "UnitTestUefiBootServicesTableLib.h"
-
-/**
- Allocates pages from the memory map.
-
- @param Type The type of allocation to perform
- @param MemoryType The type of memory to turn the allocated pages
- into
- @param NumberOfPages The number of pages to allocate
- @param Memory A pointer to receive the base allocated memory
- address
-
- @return Status. On success, Memory is filled in with the base address allocated
- @retval EFI_INVALID_PARAMETER Parameters violate checking rules defined in
- spec.
- @retval EFI_NOT_FOUND Could not allocate pages match the requirement.
- @retval EFI_OUT_OF_RESOURCES No enough pages to allocate.
- @retval EFI_SUCCESS Pages successfully allocated.
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestAllocatePages (
- IN EFI_ALLOCATE_TYPE Type,
- IN EFI_MEMORY_TYPE MemoryType,
- IN UINTN NumberOfPages,
- IN OUT EFI_PHYSICAL_ADDRESS *Memory
- )
-{
- return EFI_NOT_AVAILABLE_YET;
-}
-
-/**
- Frees previous allocated pages.
-
- @param Memory Base address of memory being freed
- @param NumberOfPages The number of pages to free
-
- @retval EFI_NOT_FOUND Could not find the entry that covers the range
- @retval EFI_INVALID_PARAMETER Address not aligned
- @return EFI_SUCCESS -Pages successfully freed.
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestFreePages (
- IN EFI_PHYSICAL_ADDRESS Memory,
- IN UINTN NumberOfPages
- )
-{
- return EFI_NOT_AVAILABLE_YET;
-}
-
-/**
- This function returns a copy of the current memory map. The map is an array of
- memory descriptors, each of which describes a contiguous block of memory.
-
- @param MemoryMapSize A pointer to the size, in bytes, of the
- MemoryMap buffer. On input, this is the size of
- the buffer allocated by the caller. On output,
- it is the size of the buffer returned by the
- firmware if the buffer was large enough, or the
- size of the buffer needed to contain the map if
- the buffer was too small.
- @param MemoryMap A pointer to the buffer in which firmware places
- the current memory map.
- @param MapKey A pointer to the location in which firmware
- returns the key for the current memory map.
- @param DescriptorSize A pointer to the location in which firmware
- returns the size, in bytes, of an individual
- EFI_MEMORY_DESCRIPTOR.
- @param DescriptorVersion A pointer to the location in which firmware
- returns the version number associated with the
- EFI_MEMORY_DESCRIPTOR.
-
- @retval EFI_SUCCESS The memory map was returned in the MemoryMap
- buffer.
- @retval EFI_BUFFER_TOO_SMALL The MemoryMap buffer was too small. The current
- buffer size needed to hold the memory map is
- returned in MemoryMapSize.
- @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value.
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestGetMemoryMap (
- IN OUT UINTN *MemoryMapSize,
- IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap,
- OUT UINTN *MapKey,
- OUT UINTN *DescriptorSize,
- OUT UINT32 *DescriptorVersion
- )
-{
- return EFI_NOT_AVAILABLE_YET;
-}
-
-/**
- Allocate pool of a particular type.
-
- @param PoolType Type of pool to allocate
- @param Size The amount of pool to allocate
- @param Buffer The address to return a pointer to the allocated
- pool
-
- @retval EFI_INVALID_PARAMETER PoolType not valid or Buffer is NULL
- @retval EFI_OUT_OF_RESOURCES Size exceeds max pool size or allocation failed.
- @retval EFI_SUCCESS Pool successfully allocated.
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestAllocatePool (
- IN EFI_MEMORY_TYPE PoolType,
- IN UINTN Size,
- OUT VOID **Buffer
- )
-{
- return EFI_NOT_AVAILABLE_YET;
-}
-
-/**
- Frees pool.
-
- @param Buffer The allocated pool entry to free
-
- @retval EFI_INVALID_PARAMETER Buffer is not a valid value.
- @retval EFI_SUCCESS Pool successfully freed.
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestFreePool (
- IN VOID *Buffer
- )
-{
- return EFI_NOT_AVAILABLE_YET;
-}
+/** @file + Implementation of memory related services in the UEFI Boot Services table for use in unit tests. + +Copyright (c) Microsoft Corporation +SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "UnitTestUefiBootServicesTableLib.h" + +/** + Allocates pages from the memory map. + + @param Type The type of allocation to perform + @param MemoryType The type of memory to turn the allocated pages + into + @param NumberOfPages The number of pages to allocate + @param Memory A pointer to receive the base allocated memory + address + + @return Status. On success, Memory is filled in with the base address allocated + @retval EFI_INVALID_PARAMETER Parameters violate checking rules defined in + spec. + @retval EFI_NOT_FOUND Could not allocate pages match the requirement. + @retval EFI_OUT_OF_RESOURCES No enough pages to allocate. + @retval EFI_SUCCESS Pages successfully allocated. + +**/ +EFI_STATUS +EFIAPI +UnitTestAllocatePages ( + IN EFI_ALLOCATE_TYPE Type, + IN EFI_MEMORY_TYPE MemoryType, + IN UINTN NumberOfPages, + IN OUT EFI_PHYSICAL_ADDRESS *Memory + ) +{ + return EFI_NOT_AVAILABLE_YET; +} + +/** + Frees previous allocated pages. + + @param Memory Base address of memory being freed + @param NumberOfPages The number of pages to free + + @retval EFI_NOT_FOUND Could not find the entry that covers the range + @retval EFI_INVALID_PARAMETER Address not aligned + @return EFI_SUCCESS -Pages successfully freed. + +**/ +EFI_STATUS +EFIAPI +UnitTestFreePages ( + IN EFI_PHYSICAL_ADDRESS Memory, + IN UINTN NumberOfPages + ) +{ + return EFI_NOT_AVAILABLE_YET; +} + +/** + This function returns a copy of the current memory map. The map is an array of + memory descriptors, each of which describes a contiguous block of memory. + + @param MemoryMapSize A pointer to the size, in bytes, of the + MemoryMap buffer. On input, this is the size of + the buffer allocated by the caller. On output, + it is the size of the buffer returned by the + firmware if the buffer was large enough, or the + size of the buffer needed to contain the map if + the buffer was too small. + @param MemoryMap A pointer to the buffer in which firmware places + the current memory map. + @param MapKey A pointer to the location in which firmware + returns the key for the current memory map. + @param DescriptorSize A pointer to the location in which firmware + returns the size, in bytes, of an individual + EFI_MEMORY_DESCRIPTOR. + @param DescriptorVersion A pointer to the location in which firmware + returns the version number associated with the + EFI_MEMORY_DESCRIPTOR. + + @retval EFI_SUCCESS The memory map was returned in the MemoryMap + buffer. + @retval EFI_BUFFER_TOO_SMALL The MemoryMap buffer was too small. The current + buffer size needed to hold the memory map is + returned in MemoryMapSize. + @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value. + +**/ +EFI_STATUS +EFIAPI +UnitTestGetMemoryMap ( + IN OUT UINTN *MemoryMapSize, + IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap, + OUT UINTN *MapKey, + OUT UINTN *DescriptorSize, + OUT UINT32 *DescriptorVersion + ) +{ + return EFI_NOT_AVAILABLE_YET; +} + +/** + Allocate pool of a particular type. + + @param PoolType Type of pool to allocate + @param Size The amount of pool to allocate + @param Buffer The address to return a pointer to the allocated + pool + + @retval EFI_INVALID_PARAMETER PoolType not valid or Buffer is NULL + @retval EFI_OUT_OF_RESOURCES Size exceeds max pool size or allocation failed. + @retval EFI_SUCCESS Pool successfully allocated. + +**/ +EFI_STATUS +EFIAPI +UnitTestAllocatePool ( + IN EFI_MEMORY_TYPE PoolType, + IN UINTN Size, + OUT VOID **Buffer + ) +{ + return EFI_NOT_AVAILABLE_YET; +} + +/** + Frees pool. + + @param Buffer The allocated pool entry to free + + @retval EFI_INVALID_PARAMETER Buffer is not a valid value. + @retval EFI_SUCCESS Pool successfully freed. + +**/ +EFI_STATUS +EFIAPI +UnitTestFreePool ( + IN VOID *Buffer + ) +{ + return EFI_NOT_AVAILABLE_YET; +} diff --git a/UnitTestFrameworkPkg/Library/UnitTestUefiBootServicesTableLib/UnitTestUefiBootServicesTableLibMisc.c b/UnitTestFrameworkPkg/Library/UnitTestUefiBootServicesTableLib/UnitTestUefiBootServicesTableLibMisc.c index 121496b3b9..384c103d71 100644 --- a/UnitTestFrameworkPkg/Library/UnitTestUefiBootServicesTableLib/UnitTestUefiBootServicesTableLibMisc.c +++ b/UnitTestFrameworkPkg/Library/UnitTestUefiBootServicesTableLib/UnitTestUefiBootServicesTableLibMisc.c @@ -1,198 +1,198 @@ -/** @file
- Implementation of miscellaneous services in the UEFI Boot Services table for use in unit tests.
-
-Copyright (c) Microsoft Corporation
-SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#include "UnitTestUefiBootServicesTableLib.h"
-
-/**
- Returns a monotonically increasing count for the platform.
-
- @param[out] Count The pointer to returned value.
-
- @retval EFI_SUCCESS The next monotonic count was returned.
- @retval EFI_INVALID_PARAMETER Count is NULL.
- @retval EFI_DEVICE_ERROR The device is not functioning properly.
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestGetNextMonotonicCount (
- OUT UINT64 *Count
- )
-{
- STATIC UINT64 StaticCount = 0;
-
- *Count = StaticCount++;
-
- return EFI_SUCCESS;
-}
-
-/**
- Introduces a fine-grained stall.
-
- @param Microseconds The number of microseconds to stall execution.
-
- @retval EFI_SUCCESS Execution was stalled for at least the requested
- amount of microseconds.
- @retval EFI_NOT_AVAILABLE_YET gMetronome is not available yet
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestStall (
- IN UINTN Microseconds
- )
-{
- return EFI_NOT_AVAILABLE_YET;
-}
-
-/**
- Sets the system's watchdog timer.
-
- @param Timeout The number of seconds to set the watchdog timer to.
- A value of zero disables the timer.
- @param WatchdogCode The numeric code to log on a watchdog timer timeout
- event. The firmware reserves codes 0x0000 to 0xFFFF.
- Loaders and operating systems may use other timeout
- codes.
- @param DataSize The size, in bytes, of WatchdogData.
- @param WatchdogData A data buffer that includes a Null-terminated Unicode
- string, optionally followed by additional binary data.
- The string is a description that the call may use to
- further indicate the reason to be logged with a
- watchdog event.
-
- @return EFI_SUCCESS Timeout has been set
- @return EFI_NOT_AVAILABLE_YET WatchdogTimer is not available yet
- @return EFI_UNSUPPORTED System does not have a timer (currently not used)
- @return EFI_DEVICE_ERROR Could not complete due to hardware error
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestSetWatchdogTimer (
- IN UINTN Timeout,
- IN UINT64 WatchdogCode,
- IN UINTN DataSize,
- IN CHAR16 *WatchdogData OPTIONAL
- )
-{
- return EFI_NOT_AVAILABLE_YET;
-}
-
-/**
- Connects one or more drivers to a controller.
-
- @param ControllerHandle The handle of the controller to which driver(s) are to be connected.
- @param DriverImageHandle A pointer to an ordered list handles that support the
- EFI_DRIVER_BINDING_PROTOCOL.
- @param RemainingDevicePath A pointer to the device path that specifies a child of the
- controller specified by ControllerHandle.
- @param Recursive If TRUE, then ConnectController() is called recursively
- until the entire tree of controllers below the controller specified
- by ControllerHandle have been created. If FALSE, then
- the tree of controllers is only expanded one level.
-
- @retval EFI_SUCCESS 1) One or more drivers were connected to ControllerHandle.
- 2) No drivers were connected to ControllerHandle, but
- RemainingDevicePath is not NULL, and it is an End Device
- Path Node.
- @retval EFI_INVALID_PARAMETER ControllerHandle is NULL.
- @retval EFI_NOT_FOUND 1) There are no EFI_DRIVER_BINDING_PROTOCOL instances
- present in the system.
- 2) No drivers were connected to ControllerHandle.
- @retval EFI_SECURITY_VIOLATION
- The user has no permission to start UEFI device drivers on the device path
- associated with the ControllerHandle or specified by the RemainingDevicePath.
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestConnectController (
- IN EFI_HANDLE ControllerHandle,
- IN EFI_HANDLE *DriverImageHandle OPTIONAL,
- IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL,
- IN BOOLEAN Recursive
- )
-{
- return EFI_SUCCESS; // Return success for now
-}
-
-/**
- Disconnects a controller from a driver
-
- @param ControllerHandle ControllerHandle The handle of
- the controller from which
- driver(s) are to be
- disconnected.
- @param DriverImageHandle DriverImageHandle The driver to
- disconnect from ControllerHandle.
- @param ChildHandle ChildHandle The handle of the
- child to destroy.
-
- @retval EFI_SUCCESS One or more drivers were
- disconnected from the controller.
- @retval EFI_SUCCESS On entry, no drivers are managing
- ControllerHandle.
- @retval EFI_SUCCESS DriverImageHandle is not NULL,
- and on entry DriverImageHandle is
- not managing ControllerHandle.
- @retval EFI_INVALID_PARAMETER ControllerHandle is NULL.
- @retval EFI_INVALID_PARAMETER DriverImageHandle is not NULL,
- and it is not a valid EFI_HANDLE.
- @retval EFI_INVALID_PARAMETER ChildHandle is not NULL, and it
- is not a valid EFI_HANDLE.
- @retval EFI_OUT_OF_RESOURCES There are not enough resources
- available to disconnect any
- drivers from ControllerHandle.
- @retval EFI_DEVICE_ERROR The controller could not be
- disconnected because of a device
- error.
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestDisconnectController (
- IN EFI_HANDLE ControllerHandle,
- IN EFI_HANDLE DriverImageHandle OPTIONAL,
- IN EFI_HANDLE ChildHandle OPTIONAL
- )
-{
- return EFI_SUCCESS; // Return success for now
-}
-
-/**
- Computes and returns a 32-bit CRC for a data buffer.
-
- @param[in] Data A pointer to the buffer on which the 32-bit CRC is to be computed.
- @param[in] DataSize The number of bytes in the buffer Data.
- @param[out] Crc32 The 32-bit CRC that was computed for the data buffer specified by Data
- and DataSize.
-
- @retval EFI_SUCCESS The 32-bit CRC was computed for the data buffer and returned in
- Crc32.
- @retval EFI_INVALID_PARAMETER Data is NULL.
- @retval EFI_INVALID_PARAMETER Crc32 is NULL.
- @retval EFI_INVALID_PARAMETER DataSize is 0.
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestCalculateCrc32 (
- IN VOID *Data,
- IN UINTN DataSize,
- OUT UINT32 *Crc32
- )
-{
- if ((Data == NULL) || (Crc32 == NULL) || (DataSize == 0)) {
- return EFI_INVALID_PARAMETER;
- }
-
- *Crc32 = CalculateCrc32 (Data, DataSize);
-
- return EFI_SUCCESS;
-}
+/** @file + Implementation of miscellaneous services in the UEFI Boot Services table for use in unit tests. + +Copyright (c) Microsoft Corporation +SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "UnitTestUefiBootServicesTableLib.h" + +/** + Returns a monotonically increasing count for the platform. + + @param[out] Count The pointer to returned value. + + @retval EFI_SUCCESS The next monotonic count was returned. + @retval EFI_INVALID_PARAMETER Count is NULL. + @retval EFI_DEVICE_ERROR The device is not functioning properly. + +**/ +EFI_STATUS +EFIAPI +UnitTestGetNextMonotonicCount ( + OUT UINT64 *Count + ) +{ + STATIC UINT64 StaticCount = 0; + + *Count = StaticCount++; + + return EFI_SUCCESS; +} + +/** + Introduces a fine-grained stall. + + @param Microseconds The number of microseconds to stall execution. + + @retval EFI_SUCCESS Execution was stalled for at least the requested + amount of microseconds. + @retval EFI_NOT_AVAILABLE_YET gMetronome is not available yet + +**/ +EFI_STATUS +EFIAPI +UnitTestStall ( + IN UINTN Microseconds + ) +{ + return EFI_NOT_AVAILABLE_YET; +} + +/** + Sets the system's watchdog timer. + + @param Timeout The number of seconds to set the watchdog timer to. + A value of zero disables the timer. + @param WatchdogCode The numeric code to log on a watchdog timer timeout + event. The firmware reserves codes 0x0000 to 0xFFFF. + Loaders and operating systems may use other timeout + codes. + @param DataSize The size, in bytes, of WatchdogData. + @param WatchdogData A data buffer that includes a Null-terminated Unicode + string, optionally followed by additional binary data. + The string is a description that the call may use to + further indicate the reason to be logged with a + watchdog event. + + @return EFI_SUCCESS Timeout has been set + @return EFI_NOT_AVAILABLE_YET WatchdogTimer is not available yet + @return EFI_UNSUPPORTED System does not have a timer (currently not used) + @return EFI_DEVICE_ERROR Could not complete due to hardware error + +**/ +EFI_STATUS +EFIAPI +UnitTestSetWatchdogTimer ( + IN UINTN Timeout, + IN UINT64 WatchdogCode, + IN UINTN DataSize, + IN CHAR16 *WatchdogData OPTIONAL + ) +{ + return EFI_NOT_AVAILABLE_YET; +} + +/** + Connects one or more drivers to a controller. + + @param ControllerHandle The handle of the controller to which driver(s) are to be connected. + @param DriverImageHandle A pointer to an ordered list handles that support the + EFI_DRIVER_BINDING_PROTOCOL. + @param RemainingDevicePath A pointer to the device path that specifies a child of the + controller specified by ControllerHandle. + @param Recursive If TRUE, then ConnectController() is called recursively + until the entire tree of controllers below the controller specified + by ControllerHandle have been created. If FALSE, then + the tree of controllers is only expanded one level. + + @retval EFI_SUCCESS 1) One or more drivers were connected to ControllerHandle. + 2) No drivers were connected to ControllerHandle, but + RemainingDevicePath is not NULL, and it is an End Device + Path Node. + @retval EFI_INVALID_PARAMETER ControllerHandle is NULL. + @retval EFI_NOT_FOUND 1) There are no EFI_DRIVER_BINDING_PROTOCOL instances + present in the system. + 2) No drivers were connected to ControllerHandle. + @retval EFI_SECURITY_VIOLATION + The user has no permission to start UEFI device drivers on the device path + associated with the ControllerHandle or specified by the RemainingDevicePath. + +**/ +EFI_STATUS +EFIAPI +UnitTestConnectController ( + IN EFI_HANDLE ControllerHandle, + IN EFI_HANDLE *DriverImageHandle OPTIONAL, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL, + IN BOOLEAN Recursive + ) +{ + return EFI_SUCCESS; // Return success for now +} + +/** + Disconnects a controller from a driver + + @param ControllerHandle ControllerHandle The handle of + the controller from which + driver(s) are to be + disconnected. + @param DriverImageHandle DriverImageHandle The driver to + disconnect from ControllerHandle. + @param ChildHandle ChildHandle The handle of the + child to destroy. + + @retval EFI_SUCCESS One or more drivers were + disconnected from the controller. + @retval EFI_SUCCESS On entry, no drivers are managing + ControllerHandle. + @retval EFI_SUCCESS DriverImageHandle is not NULL, + and on entry DriverImageHandle is + not managing ControllerHandle. + @retval EFI_INVALID_PARAMETER ControllerHandle is NULL. + @retval EFI_INVALID_PARAMETER DriverImageHandle is not NULL, + and it is not a valid EFI_HANDLE. + @retval EFI_INVALID_PARAMETER ChildHandle is not NULL, and it + is not a valid EFI_HANDLE. + @retval EFI_OUT_OF_RESOURCES There are not enough resources + available to disconnect any + drivers from ControllerHandle. + @retval EFI_DEVICE_ERROR The controller could not be + disconnected because of a device + error. + +**/ +EFI_STATUS +EFIAPI +UnitTestDisconnectController ( + IN EFI_HANDLE ControllerHandle, + IN EFI_HANDLE DriverImageHandle OPTIONAL, + IN EFI_HANDLE ChildHandle OPTIONAL + ) +{ + return EFI_SUCCESS; // Return success for now +} + +/** + Computes and returns a 32-bit CRC for a data buffer. + + @param[in] Data A pointer to the buffer on which the 32-bit CRC is to be computed. + @param[in] DataSize The number of bytes in the buffer Data. + @param[out] Crc32 The 32-bit CRC that was computed for the data buffer specified by Data + and DataSize. + + @retval EFI_SUCCESS The 32-bit CRC was computed for the data buffer and returned in + Crc32. + @retval EFI_INVALID_PARAMETER Data is NULL. + @retval EFI_INVALID_PARAMETER Crc32 is NULL. + @retval EFI_INVALID_PARAMETER DataSize is 0. + +**/ +EFI_STATUS +EFIAPI +UnitTestCalculateCrc32 ( + IN VOID *Data, + IN UINTN DataSize, + OUT UINT32 *Crc32 + ) +{ + if ((Data == NULL) || (Crc32 == NULL) || (DataSize == 0)) { + return EFI_INVALID_PARAMETER; + } + + *Crc32 = CalculateCrc32 (Data, DataSize); + + return EFI_SUCCESS; +} diff --git a/UnitTestFrameworkPkg/Library/UnitTestUefiBootServicesTableLib/UnitTestUefiBootServicesTableLibProtocol.c b/UnitTestFrameworkPkg/Library/UnitTestUefiBootServicesTableLib/UnitTestUefiBootServicesTableLibProtocol.c index 437082d516..ca963c061f 100644 --- a/UnitTestFrameworkPkg/Library/UnitTestUefiBootServicesTableLib/UnitTestUefiBootServicesTableLibProtocol.c +++ b/UnitTestFrameworkPkg/Library/UnitTestUefiBootServicesTableLib/UnitTestUefiBootServicesTableLibProtocol.c @@ -1,1650 +1,1650 @@ -/** @file
- Implementation of protocol related services in the UEFI Boot Services table for use in unit tests.
-
-Copyright (c) Microsoft Corporation
-SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#include "UnitTestUefiBootServicesTableLibProtocol.h"
-
-STATIC LIST_ENTRY mProtocolDatabase = INITIALIZE_LIST_HEAD_VARIABLE (mProtocolDatabase);
-STATIC LIST_ENTRY gHandleList = INITIALIZE_LIST_HEAD_VARIABLE (gHandleList);
-STATIC UINT64 gHandleDatabaseKey = 0;
-STATIC UINTN mEfiLocateHandleRequest = 0;
-
-//
-// Helper Functions
-//
-
-/**
- Check whether a handle is a valid EFI_HANDLE
-
- @param UserHandle The handle to check
-
- @retval EFI_INVALID_PARAMETER The handle is NULL or not a valid EFI_HANDLE.
- @retval EFI_SUCCESS The handle is valid EFI_HANDLE.
-
-**/
-EFI_STATUS
-UnitTestValidateHandle (
- IN EFI_HANDLE UserHandle
- )
-{
- IHANDLE *Handle;
- LIST_ENTRY *Link;
-
- if (UserHandle == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- for (Link = gHandleList.BackLink; Link != &gHandleList; Link = Link->BackLink) {
- Handle = CR (Link, IHANDLE, AllHandles, EFI_HANDLE_SIGNATURE);
- if (Handle == (IHANDLE *)UserHandle) {
- return EFI_SUCCESS;
- }
- }
-
- return EFI_INVALID_PARAMETER;
-}
-
-/**
- Finds the protocol entry for the requested protocol.
-
- @param Protocol The ID of the protocol
- @param Create Create a new entry if not found
-
- @return Protocol entry
-
-**/
-PROTOCOL_ENTRY *
-UnitTestFindProtocolEntry (
- IN EFI_GUID *Protocol,
- IN BOOLEAN Create
- )
-{
- LIST_ENTRY *Link;
- PROTOCOL_ENTRY *Item;
- PROTOCOL_ENTRY *ProtEntry;
-
- //
- // Search the database for the matching GUID
- //
-
- ProtEntry = NULL;
- for (Link = mProtocolDatabase.ForwardLink;
- Link != &mProtocolDatabase;
- Link = Link->ForwardLink)
- {
- Item = CR (Link, PROTOCOL_ENTRY, AllEntries, PROTOCOL_ENTRY_SIGNATURE);
- if (CompareGuid (&Item->ProtocolID, Protocol)) {
- //
- // This is the protocol entry
- //
-
- ProtEntry = Item;
- break;
- }
- }
-
- //
- // If the protocol entry was not found and Create is TRUE, then
- // allocate a new entry
- //
- if ((ProtEntry == NULL) && Create) {
- ProtEntry = AllocatePool (sizeof (PROTOCOL_ENTRY));
-
- if (ProtEntry != NULL) {
- //
- // Initialize new protocol entry structure
- //
- ProtEntry->Signature = PROTOCOL_ENTRY_SIGNATURE;
- CopyGuid ((VOID *)&ProtEntry->ProtocolID, Protocol);
- InitializeListHead (&ProtEntry->Protocols);
- InitializeListHead (&ProtEntry->Notify);
-
- //
- // Add it to protocol database
- //
- InsertTailList (&mProtocolDatabase, &ProtEntry->AllEntries);
- }
- }
-
- return ProtEntry;
-}
-
-/**
- Finds the protocol instance for the requested handle and protocol.
- Note: This function doesn't do parameters checking, it's caller's responsibility
- to pass in valid parameters.
-
- @param Handle The handle to search the protocol on
- @param Protocol GUID of the protocol
- @param Interface The interface for the protocol being searched
-
- @return Protocol instance (NULL: Not found)
-
-**/
-PROTOCOL_INTERFACE *
-UnitTestFindProtocolInterface (
- IN IHANDLE *Handle,
- IN EFI_GUID *Protocol,
- IN VOID *Interface
- )
-{
- PROTOCOL_INTERFACE *Prot;
- PROTOCOL_ENTRY *ProtEntry;
- LIST_ENTRY *Link;
-
- Prot = NULL;
-
- //
- // Lookup the protocol entry for this protocol ID
- //
-
- ProtEntry = UnitTestFindProtocolEntry (Protocol, FALSE);
- if (ProtEntry != NULL) {
- //
- // Look at each protocol interface for any matches
- //
- for (Link = Handle->Protocols.ForwardLink; Link != &Handle->Protocols; Link = Link->ForwardLink) {
- //
- // If this protocol interface matches, remove it
- //
- Prot = CR (Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE);
- if ((Prot->Interface == Interface) && (Prot->Protocol == ProtEntry)) {
- break;
- }
-
- Prot = NULL;
- }
- }
-
- return Prot;
-}
-
-/**
- Signal event for every protocol in protocol entry.
-
- @param ProtEntry Protocol entry
-
-**/
-VOID
-UnitTestNotifyProtocolEntry (
- IN PROTOCOL_ENTRY *ProtEntry
- )
-{
- PROTOCOL_NOTIFY *ProtNotify;
- LIST_ENTRY *Link;
-
- for (Link = ProtEntry->Notify.ForwardLink; Link != &ProtEntry->Notify; Link = Link->ForwardLink) {
- ProtNotify = CR (Link, PROTOCOL_NOTIFY, Link, PROTOCOL_NOTIFY_SIGNATURE);
- UnitTestSignalEvent (ProtNotify->Event);
- }
-}
-
-/**
- Routine to get the next Handle, when you are searching for all handles.
-
- @param Position Information about which Handle to seach for.
- @param Interface Return the interface structure for the matching
- protocol.
-
- @return An pointer to IHANDLE if the next Position is not the end of the list.
- Otherwise,NULL is returned.
-
-**/
-IHANDLE *
-UnitTestGetNextLocateAllHandles (
- IN OUT LOCATE_POSITION *Position,
- OUT VOID **Interface
- )
-{
- IHANDLE *Handle;
-
- //
- // Next handle
- //
- Position->Position = Position->Position->ForwardLink;
-
- //
- // If not at the end of the list, get the handle
- //
- Handle = NULL;
- *Interface = NULL;
- if (Position->Position != &gHandleList) {
- Handle = CR (Position->Position, IHANDLE, AllHandles, EFI_HANDLE_SIGNATURE);
- }
-
- return Handle;
-}
-
-/**
- Routine to get the next Handle, when you are searching for register protocol
- notifies.
-
- @param Position Information about which Handle to seach for.
- @param Interface Return the interface structure for the matching
- protocol.
-
- @return An pointer to IHANDLE if the next Position is not the end of the list.
- Otherwise,NULL is returned.
-
-**/
-IHANDLE *
-UnitTestGetNextLocateByRegisterNotify (
- IN OUT LOCATE_POSITION *Position,
- OUT VOID **Interface
- )
-{
- IHANDLE *Handle;
- PROTOCOL_NOTIFY *ProtNotify;
- PROTOCOL_INTERFACE *Prot;
- LIST_ENTRY *Link;
-
- Handle = NULL;
- *Interface = NULL;
- ProtNotify = Position->SearchKey;
-
- //
- // If this is the first request, get the next handle
- //
- if (ProtNotify != NULL) {
- ASSERT (ProtNotify->Signature == PROTOCOL_NOTIFY_SIGNATURE);
- Position->SearchKey = NULL;
-
- //
- // If not at the end of the list, get the next handle
- //
- Link = ProtNotify->Position->ForwardLink;
- if (Link != &ProtNotify->Protocol->Protocols) {
- Prot = CR (Link, PROTOCOL_INTERFACE, ByProtocol, PROTOCOL_INTERFACE_SIGNATURE);
- Handle = Prot->Handle;
- *Interface = Prot->Interface;
- }
- }
-
- return Handle;
-}
-
-/**
- Routine to get the next Handle, when you are searching for a given protocol.
-
- @param Position Information about which Handle to seach for.
- @param Interface Return the interface structure for the matching
- protocol.
-
- @return An pointer to IHANDLE if the next Position is not the end of the list.
- Otherwise,NULL is returned.
-
-**/
-IHANDLE *
-UnitTestGetNextLocateByProtocol (
- IN OUT LOCATE_POSITION *Position,
- OUT VOID **Interface
- )
-{
- IHANDLE *Handle;
- LIST_ENTRY *Link;
- PROTOCOL_INTERFACE *Prot;
-
- Handle = NULL;
- *Interface = NULL;
- for ( ; ;) {
- //
- // Next entry
- //
- Link = Position->Position->ForwardLink;
- Position->Position = Link;
-
- //
- // If not at the end, return the handle
- //
- if (Link == &Position->ProtEntry->Protocols) {
- Handle = NULL;
- break;
- }
-
- //
- // Get the handle
- //
- Prot = CR (Link, PROTOCOL_INTERFACE, ByProtocol, PROTOCOL_INTERFACE_SIGNATURE);
- Handle = Prot->Handle;
- *Interface = Prot->Interface;
-
- //
- // If this handle has not been returned this request, then
- // return it now
- //
- if (Handle->LocateRequest != mEfiLocateHandleRequest) {
- Handle->LocateRequest = mEfiLocateHandleRequest;
- break;
- }
- }
-
- return Handle;
-}
-
-/**
- Attempts to disconnect all drivers that are using the protocol interface being queried.
- If failed, reconnect all drivers disconnected.
- Note: This function doesn't do parameters checking, it's caller's responsibility
- to pass in valid parameters.
-
- @param UserHandle The handle on which the protocol is installed
- @param Prot The protocol to disconnect drivers from
-
- @retval EFI_SUCCESS Drivers using the protocol interface are all
- disconnected
- @retval EFI_ACCESS_DENIED Failed to disconnect one or all of the drivers
-
-**/
-EFI_STATUS
-UnitTestDisconnectControllersUsingProtocolInterface (
- IN EFI_HANDLE UserHandle,
- IN PROTOCOL_INTERFACE *Prot
- )
-{
- EFI_STATUS Status;
- BOOLEAN ItemFound;
- LIST_ENTRY *Link;
- OPEN_PROTOCOL_DATA *OpenData;
-
- Status = EFI_SUCCESS;
-
- //
- // Attempt to disconnect all drivers from this protocol interface
- //
- do {
- ItemFound = FALSE;
- for (Link = Prot->OpenList.ForwardLink; Link != &Prot->OpenList; Link = Link->ForwardLink) {
- OpenData = CR (Link, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE);
- if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) != 0) {
- Status = UnitTestDisconnectController (UserHandle, OpenData->AgentHandle, NULL);
- if (!EFI_ERROR (Status)) {
- ItemFound = TRUE;
- }
-
- break;
- }
- }
- } while (ItemFound);
-
- if (!EFI_ERROR (Status)) {
- //
- // Attempt to remove BY_HANDLE_PROTOCOL and GET_PROTOCOL and TEST_PROTOCOL Open List items
- //
- for (Link = Prot->OpenList.ForwardLink; Link != &Prot->OpenList;) {
- OpenData = CR (Link, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE);
- if ((OpenData->Attributes &
- (EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL | EFI_OPEN_PROTOCOL_GET_PROTOCOL | EFI_OPEN_PROTOCOL_TEST_PROTOCOL)) != 0)
- {
- Link = RemoveEntryList (&OpenData->Link);
- Prot->OpenListCount--;
- FreePool (OpenData);
- } else {
- Link = Link->ForwardLink;
- }
- }
- }
-
- //
- // If there are errors or still has open items in the list, then reconnect all the drivers and return an error
- //
- if (EFI_ERROR (Status) || (Prot->OpenListCount > 0)) {
- UnitTestConnectController (UserHandle, NULL, NULL, TRUE);
- Status = EFI_ACCESS_DENIED;
- }
-
- return Status;
-}
-
-/**
- Removes Protocol from the protocol list (but not the handle list).
-
- @param Handle The handle to remove protocol on.
- @param Protocol GUID of the protocol to be moved
- @param Interface The interface of the protocol
-
- @return Protocol Entry
-
-**/
-PROTOCOL_INTERFACE *
-UnitTestRemoveInterfaceFromProtocol (
- IN IHANDLE *Handle,
- IN EFI_GUID *Protocol,
- IN VOID *Interface
- )
-{
- PROTOCOL_INTERFACE *Prot;
- PROTOCOL_NOTIFY *ProtNotify;
- PROTOCOL_ENTRY *ProtEntry;
- LIST_ENTRY *Link;
-
- Prot = UnitTestFindProtocolInterface (Handle, Protocol, Interface);
- if (Prot != NULL) {
- ProtEntry = Prot->Protocol;
-
- //
- // If there's a protocol notify location pointing to this entry, back it up one
- //
- for (Link = ProtEntry->Notify.ForwardLink; Link != &ProtEntry->Notify; Link = Link->ForwardLink) {
- ProtNotify = CR (Link, PROTOCOL_NOTIFY, Link, PROTOCOL_NOTIFY_SIGNATURE);
-
- if (ProtNotify->Position == &Prot->ByProtocol) {
- ProtNotify->Position = Prot->ByProtocol.BackLink;
- }
- }
-
- //
- // Remove the protocol interface entry
- //
- RemoveEntryList (&Prot->ByProtocol);
- }
-
- return Prot;
-}
-
-//
-// Boot Services Function Implementation
-//
-
-/**
- Locate a certain GUID protocol interface in a Handle's protocols.
-
- @param UserHandle The handle to obtain the protocol interface on
- @param Protocol The GUID of the protocol
-
- @return The requested protocol interface for the handle
-
-**/
-PROTOCOL_INTERFACE *
-UnitTestGetProtocolInterface (
- IN EFI_HANDLE UserHandle,
- IN EFI_GUID *Protocol
- )
-{
- EFI_STATUS Status;
- PROTOCOL_ENTRY *ProtEntry;
- PROTOCOL_INTERFACE *Prot;
- IHANDLE *Handle;
- LIST_ENTRY *Link;
-
- Status = UnitTestValidateHandle (UserHandle);
- if (EFI_ERROR (Status)) {
- return NULL;
- }
-
- Handle = (IHANDLE *)UserHandle;
-
- //
- // Look at each protocol interface for a match
- //
- for (Link = Handle->Protocols.ForwardLink; Link != &Handle->Protocols; Link = Link->ForwardLink) {
- Prot = CR (Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE);
- ProtEntry = Prot->Protocol;
- if (CompareGuid (&ProtEntry->ProtocolID, Protocol)) {
- return Prot;
- }
- }
-
- return NULL;
-}
-
-/**
- Installs a protocol interface into the boot services environment.
-
- @param UserHandle The handle to install the protocol handler on,
- or NULL if a new handle is to be allocated
- @param Protocol The protocol to add to the handle
- @param InterfaceType Indicates whether Interface is supplied in
- native form.
- @param Interface The interface for the protocol being added
- @param Notify indicates whether notify the notification list
- for this protocol
-
- @retval EFI_INVALID_PARAMETER Invalid parameter
- @retval EFI_OUT_OF_RESOURCES No enough buffer to allocate
- @retval EFI_SUCCESS Protocol interface successfully installed
-
-**/
-EFI_STATUS
-UnitTestInstallProtocolInterfaceNotify (
- IN OUT EFI_HANDLE *UserHandle,
- IN EFI_GUID *Protocol,
- IN EFI_INTERFACE_TYPE InterfaceType,
- IN VOID *Interface,
- IN BOOLEAN Notify
- )
-{
- PROTOCOL_INTERFACE *Prot;
- PROTOCOL_ENTRY *ProtEntry;
- IHANDLE *Handle;
- EFI_STATUS Status;
- VOID *ExistingInterface;
-
- //
- // returns EFI_INVALID_PARAMETER if InterfaceType is invalid.
- // Also added check for invalid UserHandle and Protocol pointers.
- //
- if ((UserHandle == NULL) || (Protocol == NULL)) {
- return EFI_INVALID_PARAMETER;
- }
-
- if (InterfaceType != EFI_NATIVE_INTERFACE) {
- return EFI_INVALID_PARAMETER;
- }
-
- //
- // Print debug message
- //
- UT_LOG_INFO ("InstallProtocolInterface: %g %p\n", Protocol, Interface);
-
- Status = EFI_OUT_OF_RESOURCES;
- Prot = NULL;
- Handle = NULL;
-
- if (*UserHandle != NULL) {
- Status = UnitTestHandleProtocol (*UserHandle, Protocol, (VOID **)&ExistingInterface);
- if (!EFI_ERROR (Status)) {
- return EFI_INVALID_PARAMETER;
- }
- }
-
- //
- // Lookup the Protocol Entry for the requested protocol
- //
- ProtEntry = UnitTestFindProtocolEntry (Protocol, TRUE);
- if (ProtEntry == NULL) {
- goto Done;
- }
-
- //
- // Allocate a new protocol interface structure
- //
- Prot = AllocateZeroPool (sizeof (PROTOCOL_INTERFACE));
- if (Prot == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- goto Done;
- }
-
- //
- // If caller didn't supply a handle, allocate a new one
- //
- Handle = (IHANDLE *)*UserHandle;
- if (Handle == NULL) {
- Handle = AllocateZeroPool (sizeof (IHANDLE));
- if (Handle == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- goto Done;
- }
-
- //
- // Initialize new handler structure
- //
- Handle->Signature = EFI_HANDLE_SIGNATURE;
- InitializeListHead (&Handle->Protocols);
-
- //
- // Initialize the Key to show that the handle has been created/modified
- //
- gHandleDatabaseKey++;
- Handle->Key = gHandleDatabaseKey;
-
- //
- // Add this handle to the list global list of all handles
- // in the system
- //
- InsertTailList (&gHandleList, &Handle->AllHandles);
- } else {
- Status = UnitTestValidateHandle (Handle);
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "InstallProtocolInterface: input handle at 0x%x is invalid\n", Handle));
- goto Done;
- }
- }
-
- //
- // Each interface that is added must be unique
- //
- ASSERT (UnitTestFindProtocolInterface (Handle, Protocol, Interface) == NULL);
-
- //
- // Initialize the protocol interface structure
- //
- Prot->Signature = PROTOCOL_INTERFACE_SIGNATURE;
- Prot->Handle = Handle;
- Prot->Protocol = ProtEntry;
- Prot->Interface = Interface;
-
- //
- // Initialize OpenProtocol Data base
- //
- InitializeListHead (&Prot->OpenList);
- Prot->OpenListCount = 0;
-
- //
- // Add this protocol interface to the head of the supported
- // protocol list for this handle
- //
- InsertHeadList (&Handle->Protocols, &Prot->Link);
-
- //
- // Add this protocol interface to the tail of the
- // protocol entry
- //
- InsertTailList (&ProtEntry->Protocols, &Prot->ByProtocol);
-
- //
- // Notify the notification list for this protocol
- //
- if (Notify) {
- UnitTestNotifyProtocolEntry (ProtEntry);
- }
-
- Status = EFI_SUCCESS;
-
-Done:
- if (!EFI_ERROR (Status)) {
- //
- // Return the new handle back to the caller
- //
- *UserHandle = Handle;
- } else {
- //
- // There was an error, clean up
- //
- if (Prot != NULL) {
- UnitTestFreePool (Prot);
- }
-
- DEBUG ((DEBUG_ERROR, "InstallProtocolInterface: %g %p failed with %r\n", Protocol, Interface, Status));
- }
-
- return Status;
-}
-
-/**
- Wrapper function to UnitTestInstallProtocolInterfaceNotify. This is the public API which
- Calls the private one which contains a BOOLEAN parameter for notifications
-
- @param UserHandle The handle to install the protocol handler on,
- or NULL if a new handle is to be allocated
- @param Protocol The protocol to add to the handle
- @param InterfaceType Indicates whether Interface is supplied in
- native form.
- @param Interface The interface for the protocol being added
-
- @return Status code
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestInstallProtocolInterface (
- IN OUT EFI_HANDLE *UserHandle,
- IN EFI_GUID *Protocol,
- IN EFI_INTERFACE_TYPE InterfaceType,
- IN VOID *Interface
- )
-{
- return UnitTestInstallProtocolInterfaceNotify (
- UserHandle,
- Protocol,
- InterfaceType,
- Interface,
- TRUE
- );
-}
-
-/**
- Reinstall a protocol interface on a device handle. The OldInterface for Protocol is replaced by the NewInterface.
-
- @param UserHandle Handle on which the interface is to be
- reinstalled
- @param Protocol The numeric ID of the interface
- @param OldInterface A pointer to the old interface
- @param NewInterface A pointer to the new interface
-
- @retval EFI_SUCCESS The protocol interface was installed
- @retval EFI_NOT_FOUND The OldInterface on the handle was not found
- @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestReinstallProtocolInterface (
- IN EFI_HANDLE UserHandle,
- IN EFI_GUID *Protocol,
- IN VOID *OldInterface,
- IN VOID *NewInterface
- )
-{
- return EFI_NOT_AVAILABLE_YET;
-}
-
-/**
- Uninstalls all instances of a protocol:interfacer from a handle.
- If the last protocol interface is remove from the handle, the
- handle is freed.
-
- @param UserHandle The handle to remove the protocol handler from
- @param Protocol The protocol, of protocol:interface, to remove
- @param Interface The interface, of protocol:interface, to remove
-
- @retval EFI_INVALID_PARAMETER Protocol is NULL.
- @retval EFI_SUCCESS Protocol interface successfully uninstalled.
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestUninstallProtocolInterface (
- IN EFI_HANDLE UserHandle,
- IN EFI_GUID *Protocol,
- IN VOID *Interface
- )
-{
- EFI_STATUS Status;
- IHANDLE *Handle;
- PROTOCOL_INTERFACE *Prot;
-
- //
- // Check that Protocol is valid
- //
- if (Protocol == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- //
- // Check that UserHandle is a valid handle
- //
- Status = UnitTestValidateHandle (UserHandle);
- if (EFI_ERROR (Status)) {
- return Status;
- }
-
- //
- // Check that Protocol exists on UserHandle, and Interface matches the interface in the database
- //
- Prot = UnitTestFindProtocolInterface (UserHandle, Protocol, Interface);
- if (Prot == NULL) {
- Status = EFI_NOT_FOUND;
- goto Done;
- }
-
- //
- // Attempt to disconnect all drivers that are using the protocol interface that is about to be removed
- //
- Status = UnitTestDisconnectControllersUsingProtocolInterface (
- UserHandle,
- Prot
- );
- if (EFI_ERROR (Status)) {
- //
- // One or more drivers refused to release, so return the error
- //
- goto Done;
- }
-
- //
- // Remove the protocol interface from the protocol
- //
- Status = EFI_NOT_FOUND;
- Handle = (IHANDLE *)UserHandle;
- Prot = UnitTestRemoveInterfaceFromProtocol (Handle, Protocol, Interface);
-
- if (Prot != NULL) {
- //
- // Update the Key to show that the handle has been created/modified
- //
- gHandleDatabaseKey++;
- Handle->Key = gHandleDatabaseKey;
-
- //
- // Remove the protocol interface from the handle
- //
- RemoveEntryList (&Prot->Link);
-
- //
- // Free the memory
- //
- Prot->Signature = 0;
- FreePool (Prot);
- Status = EFI_SUCCESS;
- }
-
- //
- // If there are no more handlers for the handle, free the handle
- //
- if (IsListEmpty (&Handle->Protocols)) {
- Handle->Signature = 0;
- RemoveEntryList (&Handle->AllHandles);
- FreePool (Handle);
- }
-
-Done:
- return Status;
-}
-
-/**
- Queries a handle to determine if it supports a specified protocol.
-
- @param UserHandle The handle being queried.
- @param Protocol The published unique identifier of the protocol.
- @param Interface Supplies the address where a pointer to the
- corresponding Protocol Interface is returned.
-
- @return The requested protocol interface for the handle
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestHandleProtocol (
- IN EFI_HANDLE UserHandle,
- IN EFI_GUID *Protocol,
- OUT VOID **Interface
- )
-{
- return UnitTestOpenProtocol (
- UserHandle,
- Protocol,
- Interface,
- gImageHandle,
- NULL,
- EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL
- );
-}
-
-/**
- Add a new protocol notification record for the request protocol.
-
- @param Protocol The requested protocol to add the notify
- registration
- @param Event The event to signal
- @param Registration Returns the registration record
-
- @retval EFI_INVALID_PARAMETER Invalid parameter
- @retval EFI_SUCCESS Successfully returned the registration record
- that has been added
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestRegisterProtocolNotify (
- IN EFI_GUID *Protocol,
- IN EFI_EVENT Event,
- OUT VOID **Registration
- )
-{
- return EFI_NOT_AVAILABLE_YET;
-}
-
-/**
- Locates the requested handle(s) and returns them in Buffer.
-
- @param SearchType The type of search to perform to locate the
- handles
- @param Protocol The protocol to search for
- @param SearchKey Dependant on SearchType
- @param BufferSize On input the size of Buffer. On output the
- size of data returned.
- @param Buffer The buffer to return the results in
-
- @retval EFI_BUFFER_TOO_SMALL Buffer too small, required buffer size is
- returned in BufferSize.
- @retval EFI_INVALID_PARAMETER Invalid parameter
- @retval EFI_SUCCESS Successfully found the requested handle(s) and
- returns them in Buffer.
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestLocateHandle (
- IN EFI_LOCATE_SEARCH_TYPE SearchType,
- IN EFI_GUID *Protocol OPTIONAL,
- IN VOID *SearchKey OPTIONAL,
- IN OUT UINTN *BufferSize,
- OUT EFI_HANDLE *Buffer
- )
-{
- EFI_STATUS Status;
- LOCATE_POSITION Position;
- PROTOCOL_NOTIFY *ProtNotify;
- UNIT_TEST_GET_NEXT GetNext;
- UINTN ResultSize;
- IHANDLE *Handle;
- IHANDLE **ResultBuffer;
- VOID *Interface;
-
- if (BufferSize == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- if ((*BufferSize > 0) && (Buffer == NULL)) {
- return EFI_INVALID_PARAMETER;
- }
-
- GetNext = NULL;
-
- //
- // Set initial position
- //
- Position.Protocol = Protocol;
- Position.SearchKey = SearchKey;
- Position.Position = &gHandleList;
-
- ResultSize = 0;
- ResultBuffer = (IHANDLE **)Buffer;
- Status = EFI_SUCCESS;
-
- //
- // Get the search function based on type
- //
- switch (SearchType) {
- case AllHandles:
- GetNext = UnitTestGetNextLocateAllHandles;
- break;
-
- case ByRegisterNotify:
- //
- // Must have SearchKey for locate ByRegisterNotify
- //
- if (SearchKey == NULL) {
- Status = EFI_INVALID_PARAMETER;
- break;
- }
-
- GetNext = UnitTestGetNextLocateByRegisterNotify;
- break;
-
- case ByProtocol:
- GetNext = UnitTestGetNextLocateByProtocol;
- if (Protocol == NULL) {
- Status = EFI_INVALID_PARAMETER;
- break;
- }
-
- //
- // Look up the protocol entry and set the head pointer
- //
- Position.ProtEntry = UnitTestFindProtocolEntry (Protocol, FALSE);
- if (Position.ProtEntry == NULL) {
- Status = EFI_NOT_FOUND;
- break;
- }
-
- Position.Position = &Position.ProtEntry->Protocols;
- break;
-
- default:
- Status = EFI_INVALID_PARAMETER;
- break;
- }
-
- if (EFI_ERROR (Status)) {
- return Status;
- }
-
- ASSERT (GetNext != NULL);
- //
- // Enumerate out the matching handles
- //
- mEfiLocateHandleRequest += 1;
- for ( ; ;) {
- //
- // Get the next handle. If no more handles, stop
- //
- Handle = GetNext (&Position, &Interface);
- if (NULL == Handle) {
- break;
- }
-
- //
- // Increase the resulting buffer size, and if this handle
- // fits return it
- //
- ResultSize += sizeof (Handle);
- if (ResultSize <= *BufferSize) {
- *ResultBuffer = Handle;
- ResultBuffer += 1;
- }
- }
-
- //
- // If the result is a zero length buffer, then there were no
- // matching handles
- //
- if (ResultSize == 0) {
- Status = EFI_NOT_FOUND;
- } else {
- //
- // Return the resulting buffer size. If it's larger than what
- // was passed, then set the error code
- //
- if (ResultSize > *BufferSize) {
- Status = EFI_BUFFER_TOO_SMALL;
- }
-
- *BufferSize = ResultSize;
-
- if ((SearchType == ByRegisterNotify) && !EFI_ERROR (Status)) {
- //
- // If this is a search by register notify and a handle was
- // returned, update the register notification position
- //
- ASSERT (SearchKey != NULL);
- ProtNotify = SearchKey;
- ProtNotify->Position = ProtNotify->Position->ForwardLink;
- }
- }
-
- return Status;
-}
-
-/**
- Locates the handle to a device on the device path that best matches the specified protocol.
-
- @param Protocol The protocol to search for.
- @param DevicePath On input, a pointer to a pointer to the device
- path. On output, the device path pointer is
- modified to point to the remaining part of the
- devicepath.
- @param Device A pointer to the returned device handle.
-
- @retval EFI_SUCCESS The resulting handle was returned.
- @retval EFI_NOT_FOUND No handles matched the search.
- @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value.
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestLocateDevicePath (
- IN EFI_GUID *Protocol,
- IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath,
- OUT EFI_HANDLE *Device
- )
-{
- return EFI_NOT_AVAILABLE_YET;
-}
-
-/**
- Boot Service called to add, modify, or remove a system configuration table from
- the EFI System Table.
-
- @param Guid Pointer to the GUID for the entry to add, update, or
- remove
- @param Table Pointer to the configuration table for the entry to add,
- update, or remove, may be NULL.
-
- @return EFI_SUCCESS Guid, Table pair added, updated, or removed.
- @return EFI_INVALID_PARAMETER Input GUID not valid.
- @return EFI_NOT_FOUND Attempted to delete non-existant entry
- @return EFI_OUT_OF_RESOURCES Not enough memory available
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestInstallConfigurationTable (
- IN EFI_GUID *Guid,
- IN VOID *Table
- )
-{
- return EFI_NOT_AVAILABLE_YET;
-}
-
-/**
- Locates the installed protocol handler for the handle, and
- invokes it to obtain the protocol interface. Usage information
- is registered in the protocol data base.
-
- @param UserHandle The handle to obtain the protocol interface on
- @param Protocol The ID of the protocol
- @param Interface The location to return the protocol interface
- @param ImageHandle The handle of the Image that is opening the
- protocol interface specified by Protocol and
- Interface.
- @param ControllerHandle The controller handle that is requiring this
- interface.
- @param Attributes The open mode of the protocol interface
- specified by Handle and Protocol.
-
- @retval EFI_INVALID_PARAMETER Protocol is NULL.
- @retval EFI_SUCCESS Get the protocol interface.
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestOpenProtocol (
- IN EFI_HANDLE UserHandle,
- IN EFI_GUID *Protocol,
- OUT VOID **Interface OPTIONAL,
- IN EFI_HANDLE ImageHandle,
- IN EFI_HANDLE ControllerHandle,
- IN UINT32 Attributes
- )
-{
- EFI_STATUS Status;
- PROTOCOL_INTERFACE *Prot;
- LIST_ENTRY *Link;
- OPEN_PROTOCOL_DATA *OpenData;
- BOOLEAN ByDriver;
- BOOLEAN Exclusive;
- BOOLEAN Disconnect;
- BOOLEAN ExactMatch;
-
- //
- // Check for invalid Protocol
- //
- if (Protocol == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- //
- // Check for invalid Interface
- //
- if ((Attributes != EFI_OPEN_PROTOCOL_TEST_PROTOCOL) && (Interface == NULL)) {
- return EFI_INVALID_PARAMETER;
- }
-
- //
- // Check for invalid UserHandle
- //
- Status = UnitTestValidateHandle (UserHandle);
- if (EFI_ERROR (Status)) {
- return Status;
- }
-
- //
- // Check for invalid Attributes
- //
- switch (Attributes) {
- case EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER:
- Status = UnitTestValidateHandle (ImageHandle);
- if (EFI_ERROR (Status)) {
- return Status;
- }
-
- Status = UnitTestValidateHandle (ControllerHandle);
- if (EFI_ERROR (Status)) {
- return Status;
- }
-
- if (UserHandle == ControllerHandle) {
- return EFI_INVALID_PARAMETER;
- }
-
- break;
- case EFI_OPEN_PROTOCOL_BY_DRIVER:
- case EFI_OPEN_PROTOCOL_BY_DRIVER | EFI_OPEN_PROTOCOL_EXCLUSIVE:
- Status = UnitTestValidateHandle (ImageHandle);
- if (EFI_ERROR (Status)) {
- return Status;
- }
-
- Status = UnitTestValidateHandle (ControllerHandle);
- if (EFI_ERROR (Status)) {
- return Status;
- }
-
- break;
- case EFI_OPEN_PROTOCOL_EXCLUSIVE:
- Status = UnitTestValidateHandle (ImageHandle);
- if (EFI_ERROR (Status)) {
- return Status;
- }
-
- break;
- case EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL:
- case EFI_OPEN_PROTOCOL_GET_PROTOCOL:
- case EFI_OPEN_PROTOCOL_TEST_PROTOCOL:
- break;
- default:
- return EFI_INVALID_PARAMETER;
- }
-
- //
- // Look at each protocol interface for a match
- //
- Prot = UnitTestGetProtocolInterface (UserHandle, Protocol);
- if (Prot == NULL) {
- Status = EFI_UNSUPPORTED;
- goto Done;
- }
-
- Status = EFI_SUCCESS;
-
- ByDriver = FALSE;
- Exclusive = FALSE;
- for ( Link = Prot->OpenList.ForwardLink; Link != &Prot->OpenList; Link = Link->ForwardLink) {
- OpenData = CR (Link, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE);
- ExactMatch = (BOOLEAN)((OpenData->AgentHandle == ImageHandle) &&
- (OpenData->Attributes == Attributes) &&
- (OpenData->ControllerHandle == ControllerHandle));
- if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) != 0) {
- ByDriver = TRUE;
- if (ExactMatch) {
- Status = EFI_ALREADY_STARTED;
- goto Done;
- }
- }
-
- if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_EXCLUSIVE) != 0) {
- Exclusive = TRUE;
- } else if (ExactMatch) {
- OpenData->OpenCount++;
- Status = EFI_SUCCESS;
- goto Done;
- }
- }
-
- //
- // ByDriver TRUE -> A driver is managing (UserHandle, Protocol)
- // ByDriver FALSE -> There are no drivers managing (UserHandle, Protocol)
- // Exclusive TRUE -> Something has exclusive access to (UserHandle, Protocol)
- // Exclusive FALSE -> Nothing has exclusive access to (UserHandle, Protocol)
- //
-
- switch (Attributes) {
- case EFI_OPEN_PROTOCOL_BY_DRIVER:
- if (Exclusive || ByDriver) {
- Status = EFI_ACCESS_DENIED;
- goto Done;
- }
-
- break;
- case EFI_OPEN_PROTOCOL_BY_DRIVER | EFI_OPEN_PROTOCOL_EXCLUSIVE:
- case EFI_OPEN_PROTOCOL_EXCLUSIVE:
- if (Exclusive) {
- Status = EFI_ACCESS_DENIED;
- goto Done;
- }
-
- if (ByDriver) {
- do {
- Disconnect = FALSE;
- for (Link = Prot->OpenList.ForwardLink; Link != &Prot->OpenList; Link = Link->ForwardLink) {
- OpenData = CR (Link, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE);
- if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) != 0) {
- Disconnect = TRUE;
- Status = UnitTestDisconnectController (UserHandle, OpenData->AgentHandle, NULL);
- if (EFI_ERROR (Status)) {
- Status = EFI_ACCESS_DENIED;
- goto Done;
- } else {
- break;
- }
- }
- }
- } while (Disconnect);
- }
-
- break;
- case EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER:
- case EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL:
- case EFI_OPEN_PROTOCOL_GET_PROTOCOL:
- case EFI_OPEN_PROTOCOL_TEST_PROTOCOL:
- break;
- }
-
- if (ImageHandle == NULL) {
- Status = EFI_SUCCESS;
- goto Done;
- }
-
- //
- // Create new entry
- //
- OpenData = AllocatePool (sizeof (OPEN_PROTOCOL_DATA));
- if (OpenData == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- } else {
- OpenData->Signature = OPEN_PROTOCOL_DATA_SIGNATURE;
- OpenData->AgentHandle = ImageHandle;
- OpenData->ControllerHandle = ControllerHandle;
- OpenData->Attributes = Attributes;
- OpenData->OpenCount = 1;
- InsertTailList (&Prot->OpenList, &OpenData->Link);
- Prot->OpenListCount++;
- Status = EFI_SUCCESS;
- }
-
-Done:
-
- if (Attributes != EFI_OPEN_PROTOCOL_TEST_PROTOCOL) {
- //
- // Keep Interface unmodified in case of any Error
- // except EFI_ALREADY_STARTED and EFI_UNSUPPORTED.
- //
- if (!EFI_ERROR (Status) || (Status == EFI_ALREADY_STARTED)) {
- //
- // According to above logic, if 'Prot' is NULL, then the 'Status' must be
- // EFI_UNSUPPORTED. Here the 'Status' is not EFI_UNSUPPORTED, so 'Prot'
- // must be not NULL.
- //
- // The ASSERT here is for addressing a false positive NULL pointer
- // dereference issue raised from static analysis.
- //
- ASSERT (Prot != NULL);
- //
- // EFI_ALREADY_STARTED is not an error for bus driver.
- // Return the corresponding protocol interface.
- //
- *Interface = Prot->Interface;
- } else if (Status == EFI_UNSUPPORTED) {
- //
- // Return NULL Interface if Unsupported Protocol.
- //
- *Interface = NULL;
- }
- }
-
- return Status;
-}
-
-/**
- Closes a protocol on a handle that was opened using OpenProtocol().
-
- @param UserHandle The handle for the protocol interface that was
- previously opened with OpenProtocol(), and is
- now being closed.
- @param Protocol The published unique identifier of the protocol.
- It is the caller's responsibility to pass in a
- valid GUID.
- @param AgentHandle The handle of the agent that is closing the
- protocol interface.
- @param ControllerHandle If the agent that opened a protocol is a driver
- that follows the EFI Driver Model, then this
- parameter is the controller handle that required
- the protocol interface. If the agent does not
- follow the EFI Driver Model, then this parameter
- is optional and may be NULL.
-
- @retval EFI_SUCCESS The protocol instance was closed.
- @retval EFI_INVALID_PARAMETER Handle, AgentHandle or ControllerHandle is not a
- valid EFI_HANDLE.
- @retval EFI_NOT_FOUND Can not find the specified protocol or
- AgentHandle.
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestCloseProtocol (
- IN EFI_HANDLE UserHandle,
- IN EFI_GUID *Protocol,
- IN EFI_HANDLE AgentHandle,
- IN EFI_HANDLE ControllerHandle
- )
-{
- return EFI_NOT_AVAILABLE_YET;
-}
-
-/**
- Return information about Opened protocols in the system
-
- @param UserHandle The handle to close the protocol interface on
- @param Protocol The ID of the protocol
- @param EntryBuffer A pointer to a buffer of open protocol
- information in the form of
- EFI_OPEN_PROTOCOL_INFORMATION_ENTRY structures.
- @param EntryCount Number of EntryBuffer entries
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestOpenProtocolInformation (
- IN EFI_HANDLE UserHandle,
- IN EFI_GUID *Protocol,
- OUT EFI_OPEN_PROTOCOL_INFORMATION_ENTRY **EntryBuffer,
- OUT UINTN *EntryCount
- )
-{
- return EFI_NOT_AVAILABLE_YET;
-}
-
-/**
- Retrieves the list of protocol interface GUIDs that are installed on a handle in a buffer allocated
- from pool.
-
- @param UserHandle The handle from which to retrieve the list of
- protocol interface GUIDs.
- @param ProtocolBuffer A pointer to the list of protocol interface GUID
- pointers that are installed on Handle.
- @param ProtocolBufferCount A pointer to the number of GUID pointers present
- in ProtocolBuffer.
-
- @retval EFI_SUCCESS The list of protocol interface GUIDs installed
- on Handle was returned in ProtocolBuffer. The
- number of protocol interface GUIDs was returned
- in ProtocolBufferCount.
- @retval EFI_INVALID_PARAMETER Handle is NULL.
- @retval EFI_INVALID_PARAMETER Handle is not a valid EFI_HANDLE.
- @retval EFI_INVALID_PARAMETER ProtocolBuffer is NULL.
- @retval EFI_INVALID_PARAMETER ProtocolBufferCount is NULL.
- @retval EFI_OUT_OF_RESOURCES There is not enough pool memory to store the
- results.
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestProtocolsPerHandle (
- IN EFI_HANDLE UserHandle,
- OUT EFI_GUID ***ProtocolBuffer,
- OUT UINTN *ProtocolBufferCount
- )
-{
- return EFI_NOT_AVAILABLE_YET;
-}
-
-/**
- Function returns an array of handles that support the requested protocol
- in a buffer allocated from pool. This is a version of UnitTestLocateHandle()
- that allocates a buffer for the caller.
-
- @param SearchType Specifies which handle(s) are to be returned.
- @param Protocol Provides the protocol to search by. This
- parameter is only valid for SearchType
- ByProtocol.
- @param SearchKey Supplies the search key depending on the
- SearchType.
- @param NumberHandles The number of handles returned in Buffer.
- @param Buffer A pointer to the buffer to return the requested
- array of handles that support Protocol.
-
- @retval EFI_SUCCESS The result array of handles was returned.
- @retval EFI_NOT_FOUND No handles match the search.
- @retval EFI_OUT_OF_RESOURCES There is not enough pool memory to store the
- matching results.
- @retval EFI_INVALID_PARAMETER One or more parameters are not valid.
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestLocateHandleBuffer (
- IN EFI_LOCATE_SEARCH_TYPE SearchType,
- IN EFI_GUID *Protocol OPTIONAL,
- IN VOID *SearchKey OPTIONAL,
- IN OUT UINTN *NumberHandles,
- OUT EFI_HANDLE **Buffer
- )
-{
- EFI_STATUS Status;
- UINTN BufferSize;
-
- if (NumberHandles == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- if (Buffer == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- BufferSize = 0;
- *NumberHandles = 0;
- *Buffer = NULL;
- Status = UnitTestLocateHandle (
- SearchType,
- Protocol,
- SearchKey,
- &BufferSize,
- *Buffer
- );
- //
- // LocateHandleBuffer() returns incorrect status code if SearchType is
- // invalid.
- //
- // Add code to correctly handle expected errors from UnitTestLocateHandle().
- //
- if (EFI_ERROR (Status) && (Status != EFI_BUFFER_TOO_SMALL)) {
- if (Status != EFI_INVALID_PARAMETER) {
- Status = EFI_NOT_FOUND;
- }
-
- return Status;
- }
-
- *Buffer = AllocatePool (BufferSize);
- if (*Buffer == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- Status = UnitTestLocateHandle (
- SearchType,
- Protocol,
- SearchKey,
- &BufferSize,
- *Buffer
- );
-
- *NumberHandles = BufferSize / sizeof (EFI_HANDLE);
- if (EFI_ERROR (Status)) {
- *NumberHandles = 0;
- }
-
- return Status;
-}
-
-/**
- Return the first Protocol Interface that matches the Protocol GUID. If
- Registration is passed in, return a Protocol Instance that was just add
- to the system. If Registration is NULL return the first Protocol Interface
- you find.
-
- @param Protocol The protocol to search for
- @param Registration Optional Registration Key returned from
- RegisterProtocolNotify()
- @param Interface Return the Protocol interface (instance).
-
- @retval EFI_SUCCESS If a valid Interface is returned
- @retval EFI_INVALID_PARAMETER Invalid parameter
- @retval EFI_NOT_FOUND Protocol interface not found
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestLocateProtocol (
- IN EFI_GUID *Protocol,
- IN VOID *Registration OPTIONAL,
- OUT VOID **Interface
- )
-{
- return EFI_NOT_AVAILABLE_YET;
-}
-
-/**
- Installs a list of protocol interface into the boot services environment.
- This function calls InstallProtocolInterface() in a loop. If any error
- occurs all the protocols added by this function are removed. This is
- basically a lib function to save space.
-
- @param Handle The handle to install the protocol handlers on,
- or NULL if a new handle is to be allocated
- @param ... EFI_GUID followed by protocol instance. A NULL
- terminates the list. The pairs are the
- arguments to InstallProtocolInterface(). All the
- protocols are added to Handle.
-
- @retval EFI_SUCCESS All the protocol interface was installed.
- @retval EFI_OUT_OF_RESOURCES There was not enough memory in pool to install all the protocols.
- @retval EFI_ALREADY_STARTED A Device Path Protocol instance was passed in that is already present in
- the handle database.
- @retval EFI_INVALID_PARAMETER Handle is NULL.
- @retval EFI_INVALID_PARAMETER Protocol is already installed on the handle specified by Handle.
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestInstallMultipleProtocolInterfaces (
- IN OUT EFI_HANDLE *Handle,
- ...
- )
-{
- return EFI_NOT_AVAILABLE_YET;
-}
-
-/**
- Uninstalls a list of protocol interface in the boot services environment.
- This function calls UninstallProtocolInterface() in a loop. This is
- basically a lib function to save space.
-
- @param Handle The handle to uninstall the protocol
- @param ... EFI_GUID followed by protocol instance. A NULL
- terminates the list. The pairs are the
- arguments to UninstallProtocolInterface(). All
- the protocols are added to Handle.
-
- @return Status code
-
-**/
-EFI_STATUS
-EFIAPI
-UnitTestUninstallMultipleProtocolInterfaces (
- IN EFI_HANDLE Handle,
- ...
- )
-{
- EFI_STATUS Status;
- VA_LIST Args;
- EFI_GUID *Protocol;
- VOID *Interface;
- UINTN Index;
-
- VA_START (Args, Handle);
- for (Index = 0, Status = EFI_SUCCESS; !EFI_ERROR (Status); Index++) {
- //
- // If protocol is NULL, then it's the end of the list
- //
- Protocol = VA_ARG (Args, EFI_GUID *);
- if (Protocol == NULL) {
- break;
- }
-
- Interface = VA_ARG (Args, VOID *);
-
- //
- // Uninstall it
- //
- Status = UnitTestUninstallProtocolInterface (Handle, Protocol, Interface);
- }
-
- VA_END (Args);
-
- //
- // If there was an error, add all the interfaces that were
- // uninstalled without any errors
- //
- if (EFI_ERROR (Status)) {
- //
- // Reset the va_arg back to the first argument.
- //
- VA_START (Args, Handle);
- for ( ; Index > 1; Index--) {
- Protocol = VA_ARG (Args, EFI_GUID *);
- Interface = VA_ARG (Args, VOID *);
- UnitTestInstallProtocolInterface (&Handle, Protocol, EFI_NATIVE_INTERFACE, Interface);
- }
-
- VA_END (Args);
- Status = EFI_INVALID_PARAMETER;
- }
-
- return Status;
-}
+/** @file + Implementation of protocol related services in the UEFI Boot Services table for use in unit tests. + +Copyright (c) Microsoft Corporation +SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "UnitTestUefiBootServicesTableLibProtocol.h" + +STATIC LIST_ENTRY mProtocolDatabase = INITIALIZE_LIST_HEAD_VARIABLE (mProtocolDatabase); +STATIC LIST_ENTRY gHandleList = INITIALIZE_LIST_HEAD_VARIABLE (gHandleList); +STATIC UINT64 gHandleDatabaseKey = 0; +STATIC UINTN mEfiLocateHandleRequest = 0; + +// +// Helper Functions +// + +/** + Check whether a handle is a valid EFI_HANDLE + + @param UserHandle The handle to check + + @retval EFI_INVALID_PARAMETER The handle is NULL or not a valid EFI_HANDLE. + @retval EFI_SUCCESS The handle is valid EFI_HANDLE. + +**/ +EFI_STATUS +UnitTestValidateHandle ( + IN EFI_HANDLE UserHandle + ) +{ + IHANDLE *Handle; + LIST_ENTRY *Link; + + if (UserHandle == NULL) { + return EFI_INVALID_PARAMETER; + } + + for (Link = gHandleList.BackLink; Link != &gHandleList; Link = Link->BackLink) { + Handle = CR (Link, IHANDLE, AllHandles, EFI_HANDLE_SIGNATURE); + if (Handle == (IHANDLE *)UserHandle) { + return EFI_SUCCESS; + } + } + + return EFI_INVALID_PARAMETER; +} + +/** + Finds the protocol entry for the requested protocol. + + @param Protocol The ID of the protocol + @param Create Create a new entry if not found + + @return Protocol entry + +**/ +PROTOCOL_ENTRY * +UnitTestFindProtocolEntry ( + IN EFI_GUID *Protocol, + IN BOOLEAN Create + ) +{ + LIST_ENTRY *Link; + PROTOCOL_ENTRY *Item; + PROTOCOL_ENTRY *ProtEntry; + + // + // Search the database for the matching GUID + // + + ProtEntry = NULL; + for (Link = mProtocolDatabase.ForwardLink; + Link != &mProtocolDatabase; + Link = Link->ForwardLink) + { + Item = CR (Link, PROTOCOL_ENTRY, AllEntries, PROTOCOL_ENTRY_SIGNATURE); + if (CompareGuid (&Item->ProtocolID, Protocol)) { + // + // This is the protocol entry + // + + ProtEntry = Item; + break; + } + } + + // + // If the protocol entry was not found and Create is TRUE, then + // allocate a new entry + // + if ((ProtEntry == NULL) && Create) { + ProtEntry = AllocatePool (sizeof (PROTOCOL_ENTRY)); + + if (ProtEntry != NULL) { + // + // Initialize new protocol entry structure + // + ProtEntry->Signature = PROTOCOL_ENTRY_SIGNATURE; + CopyGuid ((VOID *)&ProtEntry->ProtocolID, Protocol); + InitializeListHead (&ProtEntry->Protocols); + InitializeListHead (&ProtEntry->Notify); + + // + // Add it to protocol database + // + InsertTailList (&mProtocolDatabase, &ProtEntry->AllEntries); + } + } + + return ProtEntry; +} + +/** + Finds the protocol instance for the requested handle and protocol. + Note: This function doesn't do parameters checking, it's caller's responsibility + to pass in valid parameters. + + @param Handle The handle to search the protocol on + @param Protocol GUID of the protocol + @param Interface The interface for the protocol being searched + + @return Protocol instance (NULL: Not found) + +**/ +PROTOCOL_INTERFACE * +UnitTestFindProtocolInterface ( + IN IHANDLE *Handle, + IN EFI_GUID *Protocol, + IN VOID *Interface + ) +{ + PROTOCOL_INTERFACE *Prot; + PROTOCOL_ENTRY *ProtEntry; + LIST_ENTRY *Link; + + Prot = NULL; + + // + // Lookup the protocol entry for this protocol ID + // + + ProtEntry = UnitTestFindProtocolEntry (Protocol, FALSE); + if (ProtEntry != NULL) { + // + // Look at each protocol interface for any matches + // + for (Link = Handle->Protocols.ForwardLink; Link != &Handle->Protocols; Link = Link->ForwardLink) { + // + // If this protocol interface matches, remove it + // + Prot = CR (Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE); + if ((Prot->Interface == Interface) && (Prot->Protocol == ProtEntry)) { + break; + } + + Prot = NULL; + } + } + + return Prot; +} + +/** + Signal event for every protocol in protocol entry. + + @param ProtEntry Protocol entry + +**/ +VOID +UnitTestNotifyProtocolEntry ( + IN PROTOCOL_ENTRY *ProtEntry + ) +{ + PROTOCOL_NOTIFY *ProtNotify; + LIST_ENTRY *Link; + + for (Link = ProtEntry->Notify.ForwardLink; Link != &ProtEntry->Notify; Link = Link->ForwardLink) { + ProtNotify = CR (Link, PROTOCOL_NOTIFY, Link, PROTOCOL_NOTIFY_SIGNATURE); + UnitTestSignalEvent (ProtNotify->Event); + } +} + +/** + Routine to get the next Handle, when you are searching for all handles. + + @param Position Information about which Handle to seach for. + @param Interface Return the interface structure for the matching + protocol. + + @return An pointer to IHANDLE if the next Position is not the end of the list. + Otherwise,NULL is returned. + +**/ +IHANDLE * +UnitTestGetNextLocateAllHandles ( + IN OUT LOCATE_POSITION *Position, + OUT VOID **Interface + ) +{ + IHANDLE *Handle; + + // + // Next handle + // + Position->Position = Position->Position->ForwardLink; + + // + // If not at the end of the list, get the handle + // + Handle = NULL; + *Interface = NULL; + if (Position->Position != &gHandleList) { + Handle = CR (Position->Position, IHANDLE, AllHandles, EFI_HANDLE_SIGNATURE); + } + + return Handle; +} + +/** + Routine to get the next Handle, when you are searching for register protocol + notifies. + + @param Position Information about which Handle to seach for. + @param Interface Return the interface structure for the matching + protocol. + + @return An pointer to IHANDLE if the next Position is not the end of the list. + Otherwise,NULL is returned. + +**/ +IHANDLE * +UnitTestGetNextLocateByRegisterNotify ( + IN OUT LOCATE_POSITION *Position, + OUT VOID **Interface + ) +{ + IHANDLE *Handle; + PROTOCOL_NOTIFY *ProtNotify; + PROTOCOL_INTERFACE *Prot; + LIST_ENTRY *Link; + + Handle = NULL; + *Interface = NULL; + ProtNotify = Position->SearchKey; + + // + // If this is the first request, get the next handle + // + if (ProtNotify != NULL) { + ASSERT (ProtNotify->Signature == PROTOCOL_NOTIFY_SIGNATURE); + Position->SearchKey = NULL; + + // + // If not at the end of the list, get the next handle + // + Link = ProtNotify->Position->ForwardLink; + if (Link != &ProtNotify->Protocol->Protocols) { + Prot = CR (Link, PROTOCOL_INTERFACE, ByProtocol, PROTOCOL_INTERFACE_SIGNATURE); + Handle = Prot->Handle; + *Interface = Prot->Interface; + } + } + + return Handle; +} + +/** + Routine to get the next Handle, when you are searching for a given protocol. + + @param Position Information about which Handle to seach for. + @param Interface Return the interface structure for the matching + protocol. + + @return An pointer to IHANDLE if the next Position is not the end of the list. + Otherwise,NULL is returned. + +**/ +IHANDLE * +UnitTestGetNextLocateByProtocol ( + IN OUT LOCATE_POSITION *Position, + OUT VOID **Interface + ) +{ + IHANDLE *Handle; + LIST_ENTRY *Link; + PROTOCOL_INTERFACE *Prot; + + Handle = NULL; + *Interface = NULL; + for ( ; ;) { + // + // Next entry + // + Link = Position->Position->ForwardLink; + Position->Position = Link; + + // + // If not at the end, return the handle + // + if (Link == &Position->ProtEntry->Protocols) { + Handle = NULL; + break; + } + + // + // Get the handle + // + Prot = CR (Link, PROTOCOL_INTERFACE, ByProtocol, PROTOCOL_INTERFACE_SIGNATURE); + Handle = Prot->Handle; + *Interface = Prot->Interface; + + // + // If this handle has not been returned this request, then + // return it now + // + if (Handle->LocateRequest != mEfiLocateHandleRequest) { + Handle->LocateRequest = mEfiLocateHandleRequest; + break; + } + } + + return Handle; +} + +/** + Attempts to disconnect all drivers that are using the protocol interface being queried. + If failed, reconnect all drivers disconnected. + Note: This function doesn't do parameters checking, it's caller's responsibility + to pass in valid parameters. + + @param UserHandle The handle on which the protocol is installed + @param Prot The protocol to disconnect drivers from + + @retval EFI_SUCCESS Drivers using the protocol interface are all + disconnected + @retval EFI_ACCESS_DENIED Failed to disconnect one or all of the drivers + +**/ +EFI_STATUS +UnitTestDisconnectControllersUsingProtocolInterface ( + IN EFI_HANDLE UserHandle, + IN PROTOCOL_INTERFACE *Prot + ) +{ + EFI_STATUS Status; + BOOLEAN ItemFound; + LIST_ENTRY *Link; + OPEN_PROTOCOL_DATA *OpenData; + + Status = EFI_SUCCESS; + + // + // Attempt to disconnect all drivers from this protocol interface + // + do { + ItemFound = FALSE; + for (Link = Prot->OpenList.ForwardLink; Link != &Prot->OpenList; Link = Link->ForwardLink) { + OpenData = CR (Link, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE); + if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) != 0) { + Status = UnitTestDisconnectController (UserHandle, OpenData->AgentHandle, NULL); + if (!EFI_ERROR (Status)) { + ItemFound = TRUE; + } + + break; + } + } + } while (ItemFound); + + if (!EFI_ERROR (Status)) { + // + // Attempt to remove BY_HANDLE_PROTOCOL and GET_PROTOCOL and TEST_PROTOCOL Open List items + // + for (Link = Prot->OpenList.ForwardLink; Link != &Prot->OpenList;) { + OpenData = CR (Link, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE); + if ((OpenData->Attributes & + (EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL | EFI_OPEN_PROTOCOL_GET_PROTOCOL | EFI_OPEN_PROTOCOL_TEST_PROTOCOL)) != 0) + { + Link = RemoveEntryList (&OpenData->Link); + Prot->OpenListCount--; + FreePool (OpenData); + } else { + Link = Link->ForwardLink; + } + } + } + + // + // If there are errors or still has open items in the list, then reconnect all the drivers and return an error + // + if (EFI_ERROR (Status) || (Prot->OpenListCount > 0)) { + UnitTestConnectController (UserHandle, NULL, NULL, TRUE); + Status = EFI_ACCESS_DENIED; + } + + return Status; +} + +/** + Removes Protocol from the protocol list (but not the handle list). + + @param Handle The handle to remove protocol on. + @param Protocol GUID of the protocol to be moved + @param Interface The interface of the protocol + + @return Protocol Entry + +**/ +PROTOCOL_INTERFACE * +UnitTestRemoveInterfaceFromProtocol ( + IN IHANDLE *Handle, + IN EFI_GUID *Protocol, + IN VOID *Interface + ) +{ + PROTOCOL_INTERFACE *Prot; + PROTOCOL_NOTIFY *ProtNotify; + PROTOCOL_ENTRY *ProtEntry; + LIST_ENTRY *Link; + + Prot = UnitTestFindProtocolInterface (Handle, Protocol, Interface); + if (Prot != NULL) { + ProtEntry = Prot->Protocol; + + // + // If there's a protocol notify location pointing to this entry, back it up one + // + for (Link = ProtEntry->Notify.ForwardLink; Link != &ProtEntry->Notify; Link = Link->ForwardLink) { + ProtNotify = CR (Link, PROTOCOL_NOTIFY, Link, PROTOCOL_NOTIFY_SIGNATURE); + + if (ProtNotify->Position == &Prot->ByProtocol) { + ProtNotify->Position = Prot->ByProtocol.BackLink; + } + } + + // + // Remove the protocol interface entry + // + RemoveEntryList (&Prot->ByProtocol); + } + + return Prot; +} + +// +// Boot Services Function Implementation +// + +/** + Locate a certain GUID protocol interface in a Handle's protocols. + + @param UserHandle The handle to obtain the protocol interface on + @param Protocol The GUID of the protocol + + @return The requested protocol interface for the handle + +**/ +PROTOCOL_INTERFACE * +UnitTestGetProtocolInterface ( + IN EFI_HANDLE UserHandle, + IN EFI_GUID *Protocol + ) +{ + EFI_STATUS Status; + PROTOCOL_ENTRY *ProtEntry; + PROTOCOL_INTERFACE *Prot; + IHANDLE *Handle; + LIST_ENTRY *Link; + + Status = UnitTestValidateHandle (UserHandle); + if (EFI_ERROR (Status)) { + return NULL; + } + + Handle = (IHANDLE *)UserHandle; + + // + // Look at each protocol interface for a match + // + for (Link = Handle->Protocols.ForwardLink; Link != &Handle->Protocols; Link = Link->ForwardLink) { + Prot = CR (Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE); + ProtEntry = Prot->Protocol; + if (CompareGuid (&ProtEntry->ProtocolID, Protocol)) { + return Prot; + } + } + + return NULL; +} + +/** + Installs a protocol interface into the boot services environment. + + @param UserHandle The handle to install the protocol handler on, + or NULL if a new handle is to be allocated + @param Protocol The protocol to add to the handle + @param InterfaceType Indicates whether Interface is supplied in + native form. + @param Interface The interface for the protocol being added + @param Notify indicates whether notify the notification list + for this protocol + + @retval EFI_INVALID_PARAMETER Invalid parameter + @retval EFI_OUT_OF_RESOURCES No enough buffer to allocate + @retval EFI_SUCCESS Protocol interface successfully installed + +**/ +EFI_STATUS +UnitTestInstallProtocolInterfaceNotify ( + IN OUT EFI_HANDLE *UserHandle, + IN EFI_GUID *Protocol, + IN EFI_INTERFACE_TYPE InterfaceType, + IN VOID *Interface, + IN BOOLEAN Notify + ) +{ + PROTOCOL_INTERFACE *Prot; + PROTOCOL_ENTRY *ProtEntry; + IHANDLE *Handle; + EFI_STATUS Status; + VOID *ExistingInterface; + + // + // returns EFI_INVALID_PARAMETER if InterfaceType is invalid. + // Also added check for invalid UserHandle and Protocol pointers. + // + if ((UserHandle == NULL) || (Protocol == NULL)) { + return EFI_INVALID_PARAMETER; + } + + if (InterfaceType != EFI_NATIVE_INTERFACE) { + return EFI_INVALID_PARAMETER; + } + + // + // Print debug message + // + UT_LOG_INFO ("InstallProtocolInterface: %g %p\n", Protocol, Interface); + + Status = EFI_OUT_OF_RESOURCES; + Prot = NULL; + Handle = NULL; + + if (*UserHandle != NULL) { + Status = UnitTestHandleProtocol (*UserHandle, Protocol, (VOID **)&ExistingInterface); + if (!EFI_ERROR (Status)) { + return EFI_INVALID_PARAMETER; + } + } + + // + // Lookup the Protocol Entry for the requested protocol + // + ProtEntry = UnitTestFindProtocolEntry (Protocol, TRUE); + if (ProtEntry == NULL) { + goto Done; + } + + // + // Allocate a new protocol interface structure + // + Prot = AllocateZeroPool (sizeof (PROTOCOL_INTERFACE)); + if (Prot == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto Done; + } + + // + // If caller didn't supply a handle, allocate a new one + // + Handle = (IHANDLE *)*UserHandle; + if (Handle == NULL) { + Handle = AllocateZeroPool (sizeof (IHANDLE)); + if (Handle == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto Done; + } + + // + // Initialize new handler structure + // + Handle->Signature = EFI_HANDLE_SIGNATURE; + InitializeListHead (&Handle->Protocols); + + // + // Initialize the Key to show that the handle has been created/modified + // + gHandleDatabaseKey++; + Handle->Key = gHandleDatabaseKey; + + // + // Add this handle to the list global list of all handles + // in the system + // + InsertTailList (&gHandleList, &Handle->AllHandles); + } else { + Status = UnitTestValidateHandle (Handle); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "InstallProtocolInterface: input handle at 0x%x is invalid\n", Handle)); + goto Done; + } + } + + // + // Each interface that is added must be unique + // + ASSERT (UnitTestFindProtocolInterface (Handle, Protocol, Interface) == NULL); + + // + // Initialize the protocol interface structure + // + Prot->Signature = PROTOCOL_INTERFACE_SIGNATURE; + Prot->Handle = Handle; + Prot->Protocol = ProtEntry; + Prot->Interface = Interface; + + // + // Initialize OpenProtocol Data base + // + InitializeListHead (&Prot->OpenList); + Prot->OpenListCount = 0; + + // + // Add this protocol interface to the head of the supported + // protocol list for this handle + // + InsertHeadList (&Handle->Protocols, &Prot->Link); + + // + // Add this protocol interface to the tail of the + // protocol entry + // + InsertTailList (&ProtEntry->Protocols, &Prot->ByProtocol); + + // + // Notify the notification list for this protocol + // + if (Notify) { + UnitTestNotifyProtocolEntry (ProtEntry); + } + + Status = EFI_SUCCESS; + +Done: + if (!EFI_ERROR (Status)) { + // + // Return the new handle back to the caller + // + *UserHandle = Handle; + } else { + // + // There was an error, clean up + // + if (Prot != NULL) { + UnitTestFreePool (Prot); + } + + DEBUG ((DEBUG_ERROR, "InstallProtocolInterface: %g %p failed with %r\n", Protocol, Interface, Status)); + } + + return Status; +} + +/** + Wrapper function to UnitTestInstallProtocolInterfaceNotify. This is the public API which + Calls the private one which contains a BOOLEAN parameter for notifications + + @param UserHandle The handle to install the protocol handler on, + or NULL if a new handle is to be allocated + @param Protocol The protocol to add to the handle + @param InterfaceType Indicates whether Interface is supplied in + native form. + @param Interface The interface for the protocol being added + + @return Status code + +**/ +EFI_STATUS +EFIAPI +UnitTestInstallProtocolInterface ( + IN OUT EFI_HANDLE *UserHandle, + IN EFI_GUID *Protocol, + IN EFI_INTERFACE_TYPE InterfaceType, + IN VOID *Interface + ) +{ + return UnitTestInstallProtocolInterfaceNotify ( + UserHandle, + Protocol, + InterfaceType, + Interface, + TRUE + ); +} + +/** + Reinstall a protocol interface on a device handle. The OldInterface for Protocol is replaced by the NewInterface. + + @param UserHandle Handle on which the interface is to be + reinstalled + @param Protocol The numeric ID of the interface + @param OldInterface A pointer to the old interface + @param NewInterface A pointer to the new interface + + @retval EFI_SUCCESS The protocol interface was installed + @retval EFI_NOT_FOUND The OldInterface on the handle was not found + @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value + +**/ +EFI_STATUS +EFIAPI +UnitTestReinstallProtocolInterface ( + IN EFI_HANDLE UserHandle, + IN EFI_GUID *Protocol, + IN VOID *OldInterface, + IN VOID *NewInterface + ) +{ + return EFI_NOT_AVAILABLE_YET; +} + +/** + Uninstalls all instances of a protocol:interfacer from a handle. + If the last protocol interface is remove from the handle, the + handle is freed. + + @param UserHandle The handle to remove the protocol handler from + @param Protocol The protocol, of protocol:interface, to remove + @param Interface The interface, of protocol:interface, to remove + + @retval EFI_INVALID_PARAMETER Protocol is NULL. + @retval EFI_SUCCESS Protocol interface successfully uninstalled. + +**/ +EFI_STATUS +EFIAPI +UnitTestUninstallProtocolInterface ( + IN EFI_HANDLE UserHandle, + IN EFI_GUID *Protocol, + IN VOID *Interface + ) +{ + EFI_STATUS Status; + IHANDLE *Handle; + PROTOCOL_INTERFACE *Prot; + + // + // Check that Protocol is valid + // + if (Protocol == NULL) { + return EFI_INVALID_PARAMETER; + } + + // + // Check that UserHandle is a valid handle + // + Status = UnitTestValidateHandle (UserHandle); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Check that Protocol exists on UserHandle, and Interface matches the interface in the database + // + Prot = UnitTestFindProtocolInterface (UserHandle, Protocol, Interface); + if (Prot == NULL) { + Status = EFI_NOT_FOUND; + goto Done; + } + + // + // Attempt to disconnect all drivers that are using the protocol interface that is about to be removed + // + Status = UnitTestDisconnectControllersUsingProtocolInterface ( + UserHandle, + Prot + ); + if (EFI_ERROR (Status)) { + // + // One or more drivers refused to release, so return the error + // + goto Done; + } + + // + // Remove the protocol interface from the protocol + // + Status = EFI_NOT_FOUND; + Handle = (IHANDLE *)UserHandle; + Prot = UnitTestRemoveInterfaceFromProtocol (Handle, Protocol, Interface); + + if (Prot != NULL) { + // + // Update the Key to show that the handle has been created/modified + // + gHandleDatabaseKey++; + Handle->Key = gHandleDatabaseKey; + + // + // Remove the protocol interface from the handle + // + RemoveEntryList (&Prot->Link); + + // + // Free the memory + // + Prot->Signature = 0; + FreePool (Prot); + Status = EFI_SUCCESS; + } + + // + // If there are no more handlers for the handle, free the handle + // + if (IsListEmpty (&Handle->Protocols)) { + Handle->Signature = 0; + RemoveEntryList (&Handle->AllHandles); + FreePool (Handle); + } + +Done: + return Status; +} + +/** + Queries a handle to determine if it supports a specified protocol. + + @param UserHandle The handle being queried. + @param Protocol The published unique identifier of the protocol. + @param Interface Supplies the address where a pointer to the + corresponding Protocol Interface is returned. + + @return The requested protocol interface for the handle + +**/ +EFI_STATUS +EFIAPI +UnitTestHandleProtocol ( + IN EFI_HANDLE UserHandle, + IN EFI_GUID *Protocol, + OUT VOID **Interface + ) +{ + return UnitTestOpenProtocol ( + UserHandle, + Protocol, + Interface, + gImageHandle, + NULL, + EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL + ); +} + +/** + Add a new protocol notification record for the request protocol. + + @param Protocol The requested protocol to add the notify + registration + @param Event The event to signal + @param Registration Returns the registration record + + @retval EFI_INVALID_PARAMETER Invalid parameter + @retval EFI_SUCCESS Successfully returned the registration record + that has been added + +**/ +EFI_STATUS +EFIAPI +UnitTestRegisterProtocolNotify ( + IN EFI_GUID *Protocol, + IN EFI_EVENT Event, + OUT VOID **Registration + ) +{ + return EFI_NOT_AVAILABLE_YET; +} + +/** + Locates the requested handle(s) and returns them in Buffer. + + @param SearchType The type of search to perform to locate the + handles + @param Protocol The protocol to search for + @param SearchKey Dependant on SearchType + @param BufferSize On input the size of Buffer. On output the + size of data returned. + @param Buffer The buffer to return the results in + + @retval EFI_BUFFER_TOO_SMALL Buffer too small, required buffer size is + returned in BufferSize. + @retval EFI_INVALID_PARAMETER Invalid parameter + @retval EFI_SUCCESS Successfully found the requested handle(s) and + returns them in Buffer. + +**/ +EFI_STATUS +EFIAPI +UnitTestLocateHandle ( + IN EFI_LOCATE_SEARCH_TYPE SearchType, + IN EFI_GUID *Protocol OPTIONAL, + IN VOID *SearchKey OPTIONAL, + IN OUT UINTN *BufferSize, + OUT EFI_HANDLE *Buffer + ) +{ + EFI_STATUS Status; + LOCATE_POSITION Position; + PROTOCOL_NOTIFY *ProtNotify; + UNIT_TEST_GET_NEXT GetNext; + UINTN ResultSize; + IHANDLE *Handle; + IHANDLE **ResultBuffer; + VOID *Interface; + + if (BufferSize == NULL) { + return EFI_INVALID_PARAMETER; + } + + if ((*BufferSize > 0) && (Buffer == NULL)) { + return EFI_INVALID_PARAMETER; + } + + GetNext = NULL; + + // + // Set initial position + // + Position.Protocol = Protocol; + Position.SearchKey = SearchKey; + Position.Position = &gHandleList; + + ResultSize = 0; + ResultBuffer = (IHANDLE **)Buffer; + Status = EFI_SUCCESS; + + // + // Get the search function based on type + // + switch (SearchType) { + case AllHandles: + GetNext = UnitTestGetNextLocateAllHandles; + break; + + case ByRegisterNotify: + // + // Must have SearchKey for locate ByRegisterNotify + // + if (SearchKey == NULL) { + Status = EFI_INVALID_PARAMETER; + break; + } + + GetNext = UnitTestGetNextLocateByRegisterNotify; + break; + + case ByProtocol: + GetNext = UnitTestGetNextLocateByProtocol; + if (Protocol == NULL) { + Status = EFI_INVALID_PARAMETER; + break; + } + + // + // Look up the protocol entry and set the head pointer + // + Position.ProtEntry = UnitTestFindProtocolEntry (Protocol, FALSE); + if (Position.ProtEntry == NULL) { + Status = EFI_NOT_FOUND; + break; + } + + Position.Position = &Position.ProtEntry->Protocols; + break; + + default: + Status = EFI_INVALID_PARAMETER; + break; + } + + if (EFI_ERROR (Status)) { + return Status; + } + + ASSERT (GetNext != NULL); + // + // Enumerate out the matching handles + // + mEfiLocateHandleRequest += 1; + for ( ; ;) { + // + // Get the next handle. If no more handles, stop + // + Handle = GetNext (&Position, &Interface); + if (NULL == Handle) { + break; + } + + // + // Increase the resulting buffer size, and if this handle + // fits return it + // + ResultSize += sizeof (Handle); + if (ResultSize <= *BufferSize) { + *ResultBuffer = Handle; + ResultBuffer += 1; + } + } + + // + // If the result is a zero length buffer, then there were no + // matching handles + // + if (ResultSize == 0) { + Status = EFI_NOT_FOUND; + } else { + // + // Return the resulting buffer size. If it's larger than what + // was passed, then set the error code + // + if (ResultSize > *BufferSize) { + Status = EFI_BUFFER_TOO_SMALL; + } + + *BufferSize = ResultSize; + + if ((SearchType == ByRegisterNotify) && !EFI_ERROR (Status)) { + // + // If this is a search by register notify and a handle was + // returned, update the register notification position + // + ASSERT (SearchKey != NULL); + ProtNotify = SearchKey; + ProtNotify->Position = ProtNotify->Position->ForwardLink; + } + } + + return Status; +} + +/** + Locates the handle to a device on the device path that best matches the specified protocol. + + @param Protocol The protocol to search for. + @param DevicePath On input, a pointer to a pointer to the device + path. On output, the device path pointer is + modified to point to the remaining part of the + devicepath. + @param Device A pointer to the returned device handle. + + @retval EFI_SUCCESS The resulting handle was returned. + @retval EFI_NOT_FOUND No handles matched the search. + @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value. + +**/ +EFI_STATUS +EFIAPI +UnitTestLocateDevicePath ( + IN EFI_GUID *Protocol, + IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath, + OUT EFI_HANDLE *Device + ) +{ + return EFI_NOT_AVAILABLE_YET; +} + +/** + Boot Service called to add, modify, or remove a system configuration table from + the EFI System Table. + + @param Guid Pointer to the GUID for the entry to add, update, or + remove + @param Table Pointer to the configuration table for the entry to add, + update, or remove, may be NULL. + + @return EFI_SUCCESS Guid, Table pair added, updated, or removed. + @return EFI_INVALID_PARAMETER Input GUID not valid. + @return EFI_NOT_FOUND Attempted to delete non-existant entry + @return EFI_OUT_OF_RESOURCES Not enough memory available + +**/ +EFI_STATUS +EFIAPI +UnitTestInstallConfigurationTable ( + IN EFI_GUID *Guid, + IN VOID *Table + ) +{ + return EFI_NOT_AVAILABLE_YET; +} + +/** + Locates the installed protocol handler for the handle, and + invokes it to obtain the protocol interface. Usage information + is registered in the protocol data base. + + @param UserHandle The handle to obtain the protocol interface on + @param Protocol The ID of the protocol + @param Interface The location to return the protocol interface + @param ImageHandle The handle of the Image that is opening the + protocol interface specified by Protocol and + Interface. + @param ControllerHandle The controller handle that is requiring this + interface. + @param Attributes The open mode of the protocol interface + specified by Handle and Protocol. + + @retval EFI_INVALID_PARAMETER Protocol is NULL. + @retval EFI_SUCCESS Get the protocol interface. + +**/ +EFI_STATUS +EFIAPI +UnitTestOpenProtocol ( + IN EFI_HANDLE UserHandle, + IN EFI_GUID *Protocol, + OUT VOID **Interface OPTIONAL, + IN EFI_HANDLE ImageHandle, + IN EFI_HANDLE ControllerHandle, + IN UINT32 Attributes + ) +{ + EFI_STATUS Status; + PROTOCOL_INTERFACE *Prot; + LIST_ENTRY *Link; + OPEN_PROTOCOL_DATA *OpenData; + BOOLEAN ByDriver; + BOOLEAN Exclusive; + BOOLEAN Disconnect; + BOOLEAN ExactMatch; + + // + // Check for invalid Protocol + // + if (Protocol == NULL) { + return EFI_INVALID_PARAMETER; + } + + // + // Check for invalid Interface + // + if ((Attributes != EFI_OPEN_PROTOCOL_TEST_PROTOCOL) && (Interface == NULL)) { + return EFI_INVALID_PARAMETER; + } + + // + // Check for invalid UserHandle + // + Status = UnitTestValidateHandle (UserHandle); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Check for invalid Attributes + // + switch (Attributes) { + case EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER: + Status = UnitTestValidateHandle (ImageHandle); + if (EFI_ERROR (Status)) { + return Status; + } + + Status = UnitTestValidateHandle (ControllerHandle); + if (EFI_ERROR (Status)) { + return Status; + } + + if (UserHandle == ControllerHandle) { + return EFI_INVALID_PARAMETER; + } + + break; + case EFI_OPEN_PROTOCOL_BY_DRIVER: + case EFI_OPEN_PROTOCOL_BY_DRIVER | EFI_OPEN_PROTOCOL_EXCLUSIVE: + Status = UnitTestValidateHandle (ImageHandle); + if (EFI_ERROR (Status)) { + return Status; + } + + Status = UnitTestValidateHandle (ControllerHandle); + if (EFI_ERROR (Status)) { + return Status; + } + + break; + case EFI_OPEN_PROTOCOL_EXCLUSIVE: + Status = UnitTestValidateHandle (ImageHandle); + if (EFI_ERROR (Status)) { + return Status; + } + + break; + case EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL: + case EFI_OPEN_PROTOCOL_GET_PROTOCOL: + case EFI_OPEN_PROTOCOL_TEST_PROTOCOL: + break; + default: + return EFI_INVALID_PARAMETER; + } + + // + // Look at each protocol interface for a match + // + Prot = UnitTestGetProtocolInterface (UserHandle, Protocol); + if (Prot == NULL) { + Status = EFI_UNSUPPORTED; + goto Done; + } + + Status = EFI_SUCCESS; + + ByDriver = FALSE; + Exclusive = FALSE; + for ( Link = Prot->OpenList.ForwardLink; Link != &Prot->OpenList; Link = Link->ForwardLink) { + OpenData = CR (Link, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE); + ExactMatch = (BOOLEAN)((OpenData->AgentHandle == ImageHandle) && + (OpenData->Attributes == Attributes) && + (OpenData->ControllerHandle == ControllerHandle)); + if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) != 0) { + ByDriver = TRUE; + if (ExactMatch) { + Status = EFI_ALREADY_STARTED; + goto Done; + } + } + + if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_EXCLUSIVE) != 0) { + Exclusive = TRUE; + } else if (ExactMatch) { + OpenData->OpenCount++; + Status = EFI_SUCCESS; + goto Done; + } + } + + // + // ByDriver TRUE -> A driver is managing (UserHandle, Protocol) + // ByDriver FALSE -> There are no drivers managing (UserHandle, Protocol) + // Exclusive TRUE -> Something has exclusive access to (UserHandle, Protocol) + // Exclusive FALSE -> Nothing has exclusive access to (UserHandle, Protocol) + // + + switch (Attributes) { + case EFI_OPEN_PROTOCOL_BY_DRIVER: + if (Exclusive || ByDriver) { + Status = EFI_ACCESS_DENIED; + goto Done; + } + + break; + case EFI_OPEN_PROTOCOL_BY_DRIVER | EFI_OPEN_PROTOCOL_EXCLUSIVE: + case EFI_OPEN_PROTOCOL_EXCLUSIVE: + if (Exclusive) { + Status = EFI_ACCESS_DENIED; + goto Done; + } + + if (ByDriver) { + do { + Disconnect = FALSE; + for (Link = Prot->OpenList.ForwardLink; Link != &Prot->OpenList; Link = Link->ForwardLink) { + OpenData = CR (Link, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE); + if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) != 0) { + Disconnect = TRUE; + Status = UnitTestDisconnectController (UserHandle, OpenData->AgentHandle, NULL); + if (EFI_ERROR (Status)) { + Status = EFI_ACCESS_DENIED; + goto Done; + } else { + break; + } + } + } + } while (Disconnect); + } + + break; + case EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER: + case EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL: + case EFI_OPEN_PROTOCOL_GET_PROTOCOL: + case EFI_OPEN_PROTOCOL_TEST_PROTOCOL: + break; + } + + if (ImageHandle == NULL) { + Status = EFI_SUCCESS; + goto Done; + } + + // + // Create new entry + // + OpenData = AllocatePool (sizeof (OPEN_PROTOCOL_DATA)); + if (OpenData == NULL) { + Status = EFI_OUT_OF_RESOURCES; + } else { + OpenData->Signature = OPEN_PROTOCOL_DATA_SIGNATURE; + OpenData->AgentHandle = ImageHandle; + OpenData->ControllerHandle = ControllerHandle; + OpenData->Attributes = Attributes; + OpenData->OpenCount = 1; + InsertTailList (&Prot->OpenList, &OpenData->Link); + Prot->OpenListCount++; + Status = EFI_SUCCESS; + } + +Done: + + if (Attributes != EFI_OPEN_PROTOCOL_TEST_PROTOCOL) { + // + // Keep Interface unmodified in case of any Error + // except EFI_ALREADY_STARTED and EFI_UNSUPPORTED. + // + if (!EFI_ERROR (Status) || (Status == EFI_ALREADY_STARTED)) { + // + // According to above logic, if 'Prot' is NULL, then the 'Status' must be + // EFI_UNSUPPORTED. Here the 'Status' is not EFI_UNSUPPORTED, so 'Prot' + // must be not NULL. + // + // The ASSERT here is for addressing a false positive NULL pointer + // dereference issue raised from static analysis. + // + ASSERT (Prot != NULL); + // + // EFI_ALREADY_STARTED is not an error for bus driver. + // Return the corresponding protocol interface. + // + *Interface = Prot->Interface; + } else if (Status == EFI_UNSUPPORTED) { + // + // Return NULL Interface if Unsupported Protocol. + // + *Interface = NULL; + } + } + + return Status; +} + +/** + Closes a protocol on a handle that was opened using OpenProtocol(). + + @param UserHandle The handle for the protocol interface that was + previously opened with OpenProtocol(), and is + now being closed. + @param Protocol The published unique identifier of the protocol. + It is the caller's responsibility to pass in a + valid GUID. + @param AgentHandle The handle of the agent that is closing the + protocol interface. + @param ControllerHandle If the agent that opened a protocol is a driver + that follows the EFI Driver Model, then this + parameter is the controller handle that required + the protocol interface. If the agent does not + follow the EFI Driver Model, then this parameter + is optional and may be NULL. + + @retval EFI_SUCCESS The protocol instance was closed. + @retval EFI_INVALID_PARAMETER Handle, AgentHandle or ControllerHandle is not a + valid EFI_HANDLE. + @retval EFI_NOT_FOUND Can not find the specified protocol or + AgentHandle. + +**/ +EFI_STATUS +EFIAPI +UnitTestCloseProtocol ( + IN EFI_HANDLE UserHandle, + IN EFI_GUID *Protocol, + IN EFI_HANDLE AgentHandle, + IN EFI_HANDLE ControllerHandle + ) +{ + return EFI_NOT_AVAILABLE_YET; +} + +/** + Return information about Opened protocols in the system + + @param UserHandle The handle to close the protocol interface on + @param Protocol The ID of the protocol + @param EntryBuffer A pointer to a buffer of open protocol + information in the form of + EFI_OPEN_PROTOCOL_INFORMATION_ENTRY structures. + @param EntryCount Number of EntryBuffer entries + +**/ +EFI_STATUS +EFIAPI +UnitTestOpenProtocolInformation ( + IN EFI_HANDLE UserHandle, + IN EFI_GUID *Protocol, + OUT EFI_OPEN_PROTOCOL_INFORMATION_ENTRY **EntryBuffer, + OUT UINTN *EntryCount + ) +{ + return EFI_NOT_AVAILABLE_YET; +} + +/** + Retrieves the list of protocol interface GUIDs that are installed on a handle in a buffer allocated + from pool. + + @param UserHandle The handle from which to retrieve the list of + protocol interface GUIDs. + @param ProtocolBuffer A pointer to the list of protocol interface GUID + pointers that are installed on Handle. + @param ProtocolBufferCount A pointer to the number of GUID pointers present + in ProtocolBuffer. + + @retval EFI_SUCCESS The list of protocol interface GUIDs installed + on Handle was returned in ProtocolBuffer. The + number of protocol interface GUIDs was returned + in ProtocolBufferCount. + @retval EFI_INVALID_PARAMETER Handle is NULL. + @retval EFI_INVALID_PARAMETER Handle is not a valid EFI_HANDLE. + @retval EFI_INVALID_PARAMETER ProtocolBuffer is NULL. + @retval EFI_INVALID_PARAMETER ProtocolBufferCount is NULL. + @retval EFI_OUT_OF_RESOURCES There is not enough pool memory to store the + results. + +**/ +EFI_STATUS +EFIAPI +UnitTestProtocolsPerHandle ( + IN EFI_HANDLE UserHandle, + OUT EFI_GUID ***ProtocolBuffer, + OUT UINTN *ProtocolBufferCount + ) +{ + return EFI_NOT_AVAILABLE_YET; +} + +/** + Function returns an array of handles that support the requested protocol + in a buffer allocated from pool. This is a version of UnitTestLocateHandle() + that allocates a buffer for the caller. + + @param SearchType Specifies which handle(s) are to be returned. + @param Protocol Provides the protocol to search by. This + parameter is only valid for SearchType + ByProtocol. + @param SearchKey Supplies the search key depending on the + SearchType. + @param NumberHandles The number of handles returned in Buffer. + @param Buffer A pointer to the buffer to return the requested + array of handles that support Protocol. + + @retval EFI_SUCCESS The result array of handles was returned. + @retval EFI_NOT_FOUND No handles match the search. + @retval EFI_OUT_OF_RESOURCES There is not enough pool memory to store the + matching results. + @retval EFI_INVALID_PARAMETER One or more parameters are not valid. + +**/ +EFI_STATUS +EFIAPI +UnitTestLocateHandleBuffer ( + IN EFI_LOCATE_SEARCH_TYPE SearchType, + IN EFI_GUID *Protocol OPTIONAL, + IN VOID *SearchKey OPTIONAL, + IN OUT UINTN *NumberHandles, + OUT EFI_HANDLE **Buffer + ) +{ + EFI_STATUS Status; + UINTN BufferSize; + + if (NumberHandles == NULL) { + return EFI_INVALID_PARAMETER; + } + + if (Buffer == NULL) { + return EFI_INVALID_PARAMETER; + } + + BufferSize = 0; + *NumberHandles = 0; + *Buffer = NULL; + Status = UnitTestLocateHandle ( + SearchType, + Protocol, + SearchKey, + &BufferSize, + *Buffer + ); + // + // LocateHandleBuffer() returns incorrect status code if SearchType is + // invalid. + // + // Add code to correctly handle expected errors from UnitTestLocateHandle(). + // + if (EFI_ERROR (Status) && (Status != EFI_BUFFER_TOO_SMALL)) { + if (Status != EFI_INVALID_PARAMETER) { + Status = EFI_NOT_FOUND; + } + + return Status; + } + + *Buffer = AllocatePool (BufferSize); + if (*Buffer == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + Status = UnitTestLocateHandle ( + SearchType, + Protocol, + SearchKey, + &BufferSize, + *Buffer + ); + + *NumberHandles = BufferSize / sizeof (EFI_HANDLE); + if (EFI_ERROR (Status)) { + *NumberHandles = 0; + } + + return Status; +} + +/** + Return the first Protocol Interface that matches the Protocol GUID. If + Registration is passed in, return a Protocol Instance that was just add + to the system. If Registration is NULL return the first Protocol Interface + you find. + + @param Protocol The protocol to search for + @param Registration Optional Registration Key returned from + RegisterProtocolNotify() + @param Interface Return the Protocol interface (instance). + + @retval EFI_SUCCESS If a valid Interface is returned + @retval EFI_INVALID_PARAMETER Invalid parameter + @retval EFI_NOT_FOUND Protocol interface not found + +**/ +EFI_STATUS +EFIAPI +UnitTestLocateProtocol ( + IN EFI_GUID *Protocol, + IN VOID *Registration OPTIONAL, + OUT VOID **Interface + ) +{ + return EFI_NOT_AVAILABLE_YET; +} + +/** + Installs a list of protocol interface into the boot services environment. + This function calls InstallProtocolInterface() in a loop. If any error + occurs all the protocols added by this function are removed. This is + basically a lib function to save space. + + @param Handle The handle to install the protocol handlers on, + or NULL if a new handle is to be allocated + @param ... EFI_GUID followed by protocol instance. A NULL + terminates the list. The pairs are the + arguments to InstallProtocolInterface(). All the + protocols are added to Handle. + + @retval EFI_SUCCESS All the protocol interface was installed. + @retval EFI_OUT_OF_RESOURCES There was not enough memory in pool to install all the protocols. + @retval EFI_ALREADY_STARTED A Device Path Protocol instance was passed in that is already present in + the handle database. + @retval EFI_INVALID_PARAMETER Handle is NULL. + @retval EFI_INVALID_PARAMETER Protocol is already installed on the handle specified by Handle. + +**/ +EFI_STATUS +EFIAPI +UnitTestInstallMultipleProtocolInterfaces ( + IN OUT EFI_HANDLE *Handle, + ... + ) +{ + return EFI_NOT_AVAILABLE_YET; +} + +/** + Uninstalls a list of protocol interface in the boot services environment. + This function calls UninstallProtocolInterface() in a loop. This is + basically a lib function to save space. + + @param Handle The handle to uninstall the protocol + @param ... EFI_GUID followed by protocol instance. A NULL + terminates the list. The pairs are the + arguments to UninstallProtocolInterface(). All + the protocols are added to Handle. + + @return Status code + +**/ +EFI_STATUS +EFIAPI +UnitTestUninstallMultipleProtocolInterfaces ( + IN EFI_HANDLE Handle, + ... + ) +{ + EFI_STATUS Status; + VA_LIST Args; + EFI_GUID *Protocol; + VOID *Interface; + UINTN Index; + + VA_START (Args, Handle); + for (Index = 0, Status = EFI_SUCCESS; !EFI_ERROR (Status); Index++) { + // + // If protocol is NULL, then it's the end of the list + // + Protocol = VA_ARG (Args, EFI_GUID *); + if (Protocol == NULL) { + break; + } + + Interface = VA_ARG (Args, VOID *); + + // + // Uninstall it + // + Status = UnitTestUninstallProtocolInterface (Handle, Protocol, Interface); + } + + VA_END (Args); + + // + // If there was an error, add all the interfaces that were + // uninstalled without any errors + // + if (EFI_ERROR (Status)) { + // + // Reset the va_arg back to the first argument. + // + VA_START (Args, Handle); + for ( ; Index > 1; Index--) { + Protocol = VA_ARG (Args, EFI_GUID *); + Interface = VA_ARG (Args, VOID *); + UnitTestInstallProtocolInterface (&Handle, Protocol, EFI_NATIVE_INTERFACE, Interface); + } + + VA_END (Args); + Status = EFI_INVALID_PARAMETER; + } + + return Status; +} diff --git a/UnitTestFrameworkPkg/Library/UnitTestUefiBootServicesTableLib/UnitTestUefiBootServicesTableLibProtocol.h b/UnitTestFrameworkPkg/Library/UnitTestUefiBootServicesTableLib/UnitTestUefiBootServicesTableLibProtocol.h index fe91e0e396..722ecb6fa7 100644 --- a/UnitTestFrameworkPkg/Library/UnitTestUefiBootServicesTableLib/UnitTestUefiBootServicesTableLibProtocol.h +++ b/UnitTestFrameworkPkg/Library/UnitTestUefiBootServicesTableLib/UnitTestUefiBootServicesTableLibProtocol.h @@ -1,120 +1,120 @@ -/** @file
- An internal header file for the Unit Test instance of the UEFI Boot Services Table Library.
-
- This file includes common header files, defines internal structure and functions used by
- the library implementation.
-
-Copyright (c) Microsoft Corporation
-SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#ifndef UEFI_BOOT_SERVICES_TABLE_LIB_UNIT_TEST_PROTOCOL_H_
-#define UEFI_BOOT_SERVICES_TABLE_LIB_UNIT_TEST_PROTOCOL_H_
-
-#include "UnitTestUefiBootServicesTableLib.h"
-
-#define EFI_HANDLE_SIGNATURE SIGNATURE_32('h','n','d','l')
-
-///
-/// IHANDLE - contains a list of protocol handles
-///
-typedef struct {
- UINTN Signature;
- /// All handles list of IHANDLE
- LIST_ENTRY AllHandles;
- /// List of PROTOCOL_INTERFACE's for this handle
- LIST_ENTRY Protocols;
- UINTN LocateRequest;
- /// The Handle Database Key value when this handle was last created or modified
- UINT64 Key;
-} IHANDLE;
-
-#define ASSERT_IS_HANDLE(a) ASSERT((a)->Signature == EFI_HANDLE_SIGNATURE)
-
-#define PROTOCOL_ENTRY_SIGNATURE SIGNATURE_32('p','r','t','e')
-
-///
-/// PROTOCOL_ENTRY - each different protocol has 1 entry in the protocol
-/// database. Each handler that supports this protocol is listed, along
-/// with a list of registered notifies.
-///
-typedef struct {
- UINTN Signature;
- /// Link Entry inserted to mProtocolDatabase
- LIST_ENTRY AllEntries;
- /// ID of the protocol
- EFI_GUID ProtocolID;
- /// All protocol interfaces
- LIST_ENTRY Protocols;
- /// Registered notification handlers
- LIST_ENTRY Notify;
-} PROTOCOL_ENTRY;
-
-#define PROTOCOL_INTERFACE_SIGNATURE SIGNATURE_32('p','i','f','c')
-
-///
-/// PROTOCOL_INTERFACE - each protocol installed on a handle is tracked
-/// with a protocol interface structure
-///
-typedef struct {
- UINTN Signature;
- /// Link on IHANDLE.Protocols
- LIST_ENTRY Link;
- /// Back pointer
- IHANDLE *Handle;
- /// Link on PROTOCOL_ENTRY.Protocols
- LIST_ENTRY ByProtocol;
- /// The protocol ID
- PROTOCOL_ENTRY *Protocol;
- /// The interface value
- VOID *Interface;
- /// OPEN_PROTOCOL_DATA list
- LIST_ENTRY OpenList;
- UINTN OpenListCount;
-} PROTOCOL_INTERFACE;
-
-#define OPEN_PROTOCOL_DATA_SIGNATURE SIGNATURE_32('p','o','d','l')
-
-typedef struct {
- UINTN Signature;
- /// Link on PROTOCOL_INTERFACE.OpenList
- LIST_ENTRY Link;
-
- EFI_HANDLE AgentHandle;
- EFI_HANDLE ControllerHandle;
- UINT32 Attributes;
- UINT32 OpenCount;
-} OPEN_PROTOCOL_DATA;
-
-#define PROTOCOL_NOTIFY_SIGNATURE SIGNATURE_32('p','r','t','n')
-
-///
-/// PROTOCOL_NOTIFY - used for each register notification for a protocol
-///
-typedef struct {
- UINTN Signature;
- PROTOCOL_ENTRY *Protocol;
- /// All notifications for this protocol
- LIST_ENTRY Link;
- /// Event to notify
- EFI_EVENT Event;
- /// Last position notified
- LIST_ENTRY *Position;
-} PROTOCOL_NOTIFY;
-
-typedef struct {
- EFI_GUID *Protocol;
- VOID *SearchKey;
- LIST_ENTRY *Position;
- PROTOCOL_ENTRY *ProtEntry;
-} LOCATE_POSITION;
-
-typedef
-IHANDLE *
-(*UNIT_TEST_GET_NEXT) (
- IN OUT LOCATE_POSITION *Position,
- OUT VOID **Interface
- );
-
-#endif
+/** @file + An internal header file for the Unit Test instance of the UEFI Boot Services Table Library. + + This file includes common header files, defines internal structure and functions used by + the library implementation. + +Copyright (c) Microsoft Corporation +SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef UEFI_BOOT_SERVICES_TABLE_LIB_UNIT_TEST_PROTOCOL_H_ +#define UEFI_BOOT_SERVICES_TABLE_LIB_UNIT_TEST_PROTOCOL_H_ + +#include "UnitTestUefiBootServicesTableLib.h" + +#define EFI_HANDLE_SIGNATURE SIGNATURE_32('h','n','d','l') + +/// +/// IHANDLE - contains a list of protocol handles +/// +typedef struct { + UINTN Signature; + /// All handles list of IHANDLE + LIST_ENTRY AllHandles; + /// List of PROTOCOL_INTERFACE's for this handle + LIST_ENTRY Protocols; + UINTN LocateRequest; + /// The Handle Database Key value when this handle was last created or modified + UINT64 Key; +} IHANDLE; + +#define ASSERT_IS_HANDLE(a) ASSERT((a)->Signature == EFI_HANDLE_SIGNATURE) + +#define PROTOCOL_ENTRY_SIGNATURE SIGNATURE_32('p','r','t','e') + +/// +/// PROTOCOL_ENTRY - each different protocol has 1 entry in the protocol +/// database. Each handler that supports this protocol is listed, along +/// with a list of registered notifies. +/// +typedef struct { + UINTN Signature; + /// Link Entry inserted to mProtocolDatabase + LIST_ENTRY AllEntries; + /// ID of the protocol + EFI_GUID ProtocolID; + /// All protocol interfaces + LIST_ENTRY Protocols; + /// Registered notification handlers + LIST_ENTRY Notify; +} PROTOCOL_ENTRY; + +#define PROTOCOL_INTERFACE_SIGNATURE SIGNATURE_32('p','i','f','c') + +/// +/// PROTOCOL_INTERFACE - each protocol installed on a handle is tracked +/// with a protocol interface structure +/// +typedef struct { + UINTN Signature; + /// Link on IHANDLE.Protocols + LIST_ENTRY Link; + /// Back pointer + IHANDLE *Handle; + /// Link on PROTOCOL_ENTRY.Protocols + LIST_ENTRY ByProtocol; + /// The protocol ID + PROTOCOL_ENTRY *Protocol; + /// The interface value + VOID *Interface; + /// OPEN_PROTOCOL_DATA list + LIST_ENTRY OpenList; + UINTN OpenListCount; +} PROTOCOL_INTERFACE; + +#define OPEN_PROTOCOL_DATA_SIGNATURE SIGNATURE_32('p','o','d','l') + +typedef struct { + UINTN Signature; + /// Link on PROTOCOL_INTERFACE.OpenList + LIST_ENTRY Link; + + EFI_HANDLE AgentHandle; + EFI_HANDLE ControllerHandle; + UINT32 Attributes; + UINT32 OpenCount; +} OPEN_PROTOCOL_DATA; + +#define PROTOCOL_NOTIFY_SIGNATURE SIGNATURE_32('p','r','t','n') + +/// +/// PROTOCOL_NOTIFY - used for each register notification for a protocol +/// +typedef struct { + UINTN Signature; + PROTOCOL_ENTRY *Protocol; + /// All notifications for this protocol + LIST_ENTRY Link; + /// Event to notify + EFI_EVENT Event; + /// Last position notified + LIST_ENTRY *Position; +} PROTOCOL_NOTIFY; + +typedef struct { + EFI_GUID *Protocol; + VOID *SearchKey; + LIST_ENTRY *Position; + PROTOCOL_ENTRY *ProtEntry; +} LOCATE_POSITION; + +typedef +IHANDLE * +(*UNIT_TEST_GET_NEXT) ( + IN OUT LOCATE_POSITION *Position, + OUT VOID **Interface + ); + +#endif diff --git a/UnitTestFrameworkPkg/Library/UnitTestUefiBootServicesTableLib/UnitTestUefiBootServicesTableLibTpl.c b/UnitTestFrameworkPkg/Library/UnitTestUefiBootServicesTableLib/UnitTestUefiBootServicesTableLibTpl.c index 2837a463aa..38fffd80cd 100644 --- a/UnitTestFrameworkPkg/Library/UnitTestUefiBootServicesTableLib/UnitTestUefiBootServicesTableLibTpl.c +++ b/UnitTestFrameworkPkg/Library/UnitTestUefiBootServicesTableLib/UnitTestUefiBootServicesTableLibTpl.c @@ -1,43 +1,43 @@ -/** @file
- Implementation of Task Priority Level (TPL) related services in the UEFI Boot Services table for use in unit tests.
-
-Copyright (c) Microsoft Corporation
-SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#include "UnitTestUefiBootServicesTableLib.h"
-
-/**
- Raise the task priority level to the new level.
- High level is implemented by disabling processor interrupts.
-
- @param NewTpl New task priority level
-
- @return The previous task priority level
-
-**/
-EFI_TPL
-EFIAPI
-UnitTestRaiseTpl (
- IN EFI_TPL NewTpl
- )
-{
- return TPL_APPLICATION;
-}
-
-/**
- Lowers the task priority to the previous value. If the new
- priority unmasks events at a higher priority, they are dispatched.
-
- @param NewTpl New, lower, task priority
-
-**/
-VOID
-EFIAPI
-UnitTestRestoreTpl (
- IN EFI_TPL NewTpl
- )
-{
- return;
-}
+/** @file + Implementation of Task Priority Level (TPL) related services in the UEFI Boot Services table for use in unit tests. + +Copyright (c) Microsoft Corporation +SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "UnitTestUefiBootServicesTableLib.h" + +/** + Raise the task priority level to the new level. + High level is implemented by disabling processor interrupts. + + @param NewTpl New task priority level + + @return The previous task priority level + +**/ +EFI_TPL +EFIAPI +UnitTestRaiseTpl ( + IN EFI_TPL NewTpl + ) +{ + return TPL_APPLICATION; +} + +/** + Lowers the task priority to the previous value. If the new + priority unmasks events at a higher priority, they are dispatched. + + @param NewTpl New, lower, task priority + +**/ +VOID +EFIAPI +UnitTestRestoreTpl ( + IN EFI_TPL NewTpl + ) +{ + return; +} |
