From a5edf2e74916750135ceb4c8aad87b7431051aa8 Mon Sep 17 00:00:00 2001 From: Sathisha S Date: Fri, 29 May 2026 06:43:02 +0000 Subject: [PATCH] UefiDump: add EBBR profile table dump support - Add utility to dump EFI Conformance Profiles Table - Save table contents to file for ACS result collection - Write error information when table retrieval or file write fails - Fix bash formatting in build-uefi-apps.sh - Implemented a logic to dump ebbr_profile_table.log to Current Working Directory as a default directory if \\acs_results_template\\acs_results\\uefi_dump directory has not found Signed-off-by: Sathisha S Change-Id: Ic23cac6578dc54e8f1035360fd95dcd8eed531de --- .github/workflows/bbr-sct_build_checker.yml | 6 + .github/workflows/daily_build.yaml | 6 + README.md | 3 + common/scripts/build-uefi-apps.sh | 59 +- ebbr/uefi_app/UefiDump.c | 592 ++++++++++++++++++++ ebbr/uefi_app/UefiDump.dsc | 91 +++ ebbr/uefi_app/UefiDump.h | 38 ++ ebbr/uefi_app/UefiDump.inf | 56 ++ 8 files changed, 838 insertions(+), 13 deletions(-) create mode 100644 ebbr/uefi_app/UefiDump.c create mode 100644 ebbr/uefi_app/UefiDump.dsc create mode 100644 ebbr/uefi_app/UefiDump.h create mode 100644 ebbr/uefi_app/UefiDump.inf diff --git a/.github/workflows/bbr-sct_build_checker.yml b/.github/workflows/bbr-sct_build_checker.yml index 12cf38d7..0edf5c44 100644 --- a/.github/workflows/bbr-sct_build_checker.yml +++ b/.github/workflows/bbr-sct_build_checker.yml @@ -56,6 +56,12 @@ jobs: echo "CapsuleApp.efi not found for EBBR, raising an error." exit 1 fi + - name: Check for UefiDump.efi (EBBR) + run: | + if [ ! -e "bbr-acs/ebbr/scripts/edk2/Build/MdeModule/DEBUG_GCC5/AARCH64/UefiDump.efi" ]; then + echo "UefiDump.efi not found for EBBR, raising an error." + exit 1 + fi - name: Get required source codes and tools for SBBR run: | cd $GITHUB_WORKSPACE # Go back to the root directory of the repository diff --git a/.github/workflows/daily_build.yaml b/.github/workflows/daily_build.yaml index e858e5ec..664eff64 100644 --- a/.github/workflows/daily_build.yaml +++ b/.github/workflows/daily_build.yaml @@ -56,6 +56,12 @@ jobs: echo "CapsuleApp.efi not found for EBBR, raising an error." exit 1 fi + - name: Check for UefiDump.efi (EBBR) + run: | + if [ ! -e "bbr-acs/ebbr/scripts/edk2/Build/MdeModule/DEBUG_GCC5/AARCH64/UefiDump.efi" ]; then + echo "UefiDump.efi not found for EBBR, raising an error." + exit 1 + fi - name: Get required source codes and tools for SBBR run: | cd $GITHUB_WORKSPACE # Go back to the root directory of the repository diff --git a/README.md b/README.md index 4aad1c75..d098f853 100755 --- a/README.md +++ b/README.md @@ -150,6 +150,9 @@ bbr-acs//scripts/edk2-test/uefi-sct/-SCT # e.g. SBBR-SCT **Notes:** - The UEFI application `CapsuleApp.efi` is also built and can be found at: `bbr-acs//scripts/edk2/Build/MdeModule/DEBUG_GCC5/AARCH64` +- For **EBBR** builds only, `UefiDump.efi` is also built and can be found at: + `bbr-acs/ebbr/scripts/edk2/Build/MdeModule/DEBUG_GCC5/AARCH64/UefiDump.efi` + It dumps the EBBR profile table to `\acs_results_template\acs_results\uefi_dump\ebbr_profile_table.log`, and falls back to `ebbr_profile_table.log` in the current working directory if that path does not exist. - The standalone build does not include the BBSR SCT suite, as some BBSR tests depend on the KEYS_DIR. These tests are only supported when built through the arm-systemready repository. --- diff --git a/common/scripts/build-uefi-apps.sh b/common/scripts/build-uefi-apps.sh index 25d5921b..56980124 100755 --- a/common/scripts/build-uefi-apps.sh +++ b/common/scripts/build-uefi-apps.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Copyright (c) 2021, 2023-2024, Arm Limited or its affiliates. All rights reserved. +# Copyright (c) 2021, 2023-2024, 2026 Arm Limited or its affiliates. All rights reserved. # SPDX-License-Identifier : Apache-2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -84,7 +84,7 @@ do_build() fi export EDK2_TOOLCHAIN=$UEFI_TOOLCHAIN - export PACKAGES_PATH=$TOP_DIR/$UEFI_PATH + export PACKAGES_PATH=$TOP_DIR/$UEFI_PATH:$BBR_DIR export PYTHON_COMMAND=/usr/bin/python3 export WORKSPACE=$TOP_DIR/$UEFI_PATH @@ -98,6 +98,11 @@ do_build() # package and place it as EFI/BOOT/bootaa64.efi for UEFI boot. build -a AARCH64 -t GCC5 -p ShellPkg/ShellPkg.dsc fi + + # Build the standalone generic UEFI dump application. + if [[ $BUILD_PLAT = EBBR ]]; then + build -a $TARGET_ARCH -t $UEFI_TOOLCHAIN -p ebbr/uefi_app/UefiDump.dsc + fi popd } @@ -115,24 +120,52 @@ do_clean() do_package () { + BUILD_PATH="$TOP_DIR/$UEFI_PATH/Build/MdeModule" + UEFI_BUILD_DIR="$BUILD_PATH/${UEFI_BUILD_MODE}_${UEFI_TOOLCHAIN}/${TARGET_ARCH}" + CAPSULE_APP="$UEFI_BUILD_DIR/CapsuleApp.efi" + UEFIDUMP_APP="$UEFI_BUILD_DIR/UefiDump.efi" + SHELL_DIR="$TOP_DIR/$UEFI_PATH/Build/Shell/${UEFI_BUILD_MODE}_${UEFI_TOOLCHAIN}/${TARGET_ARCH}" + SHELL_APP="$SHELL_DIR/ShellPkg/Application/Shell/Shell/$UEFI_BUILD_MODE/Shell.efi" + UEFI_SCT_BOOT="$TOP_DIR/edk2-test/uefi-sct/${BUILD_PLAT}-SCT/EFI/BOOT/bootaa64.efi" + echo "Packaging CapsuleApp..."; - if [ $BUILD_TYPE = F ]; then - sbsign --key $KEYS_DIR/TestDB1.key --cert $KEYS_DIR/TestDB1.crt $TOP_DIR/$UEFI_PATH/Build/MdeModule/${UEFI_BUILD_MODE}_${UEFI_TOOLCHAIN}/${TARGET_ARCH}/CapsuleApp.efi --output $TOP_DIR/$UEFI_PATH/Build/MdeModule/${UEFI_BUILD_MODE}_${UEFI_TOOLCHAIN}/${TARGET_ARCH}/CapsuleApp.efi + if [ -f "$CAPSULE_APP" ]; then + echo "CapsuleApp.efi successfully generated at $CAPSULE_APP" + if [ "$BUILD_TYPE" = "F" ]; then + sbsign \ + --key "$KEYS_DIR/TestDB1.key" \ + --cert "$KEYS_DIR/TestDB1.crt" \ + "$CAPSULE_APP" \ + --output "$CAPSULE_APP" + fi + else + echo "Error: CapsuleApp.efi could not be generated. Please check the logs" fi - if [ -f $TOP_DIR/$UEFI_PATH/Build/MdeModule/${UEFI_BUILD_MODE}_${UEFI_TOOLCHAIN}/${TARGET_ARCH}/CapsuleApp.efi ]; then - echo "CapsuleApp.efi successfully generated at $TOP_DIR/$UEFI_PATH/Build/MdeModule/${UEFI_BUILD_MODE}_${UEFI_TOOLCHAIN}/${TARGET_ARCH}/CapsuleApp.efi" - else - echo "Error: CapsuleApp.efi could not be generated. Please check the logs" + if [[ "$BUILD_PLAT" = "EBBR" ]]; then + if [ -f "$UEFIDUMP_APP" ]; then + echo "UefiDump.efi successfully generated at $UEFIDUMP_APP" + if [ "$BUILD_TYPE" = "F" ]; then + sbsign \ + --key "$KEYS_DIR/TestDB1.key" \ + --cert "$KEYS_DIR/TestDB1.crt" \ + "$UEFIDUMP_APP" \ + --output "$UEFIDUMP_APP" + fi + else + echo "Error: UefiDump.efi could not be generated. Please check the logs" + fi fi - if [ $BUILD_TYPE = S ]; then - # Shell.efi is required to run the standalone SCT. Copy it into the SBBR/EBBR-SCT - # package and place it as EFI/BOOT/bootaa64.efi for UEFI boot. - cp $TOP_DIR/$UEFI_PATH/Build/Shell/${UEFI_BUILD_MODE}_${UEFI_TOOLCHAIN}/${TARGET_ARCH}/ShellPkg/Application/Shell/Shell/$UEFI_BUILD_MODE/Shell.efi $TOP_DIR/edk2-test/uefi-sct/${BUILD_PLAT}-SCT/EFI/BOOT/bootaa64.efi + if [ "$BUILD_TYPE" = "S" ]; then + # Shell.efi is required to run the standalone SCT. Copy it into the SBBR/EBBR-SCT + # package and place it as EFI/BOOT/bootaa64.efi for UEFI boot. + cp \ + "$SHELL_APP" \ + "$UEFI_SCT_BOOT" fi } DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd ) -source $DIR/framework.sh $@ +source "$DIR/framework.sh" "$@" diff --git a/ebbr/uefi_app/UefiDump.c b/ebbr/uefi_app/UefiDump.c new file mode 100644 index 00000000..52564c11 --- /dev/null +++ b/ebbr/uefi_app/UefiDump.c @@ -0,0 +1,592 @@ +/** @file + + Copyright 2006-2016 Unified EFI, Inc.
+ Copyright (c) 2026, Arm Ltd. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ +/*++ + +Module Name: + UefiDump.c + +Abstract: + Source file for the UEFI dump application, which currently dumps the EBBR conformance profiles table. + +--*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "UefiDump.h" + +#define MAX_CONFORMANCE_PROFILE_COUNT 256 + +/*++ + +Routine Description: + + Locates a system configuration table entry by GUID. + +Arguments: + + TableGuid - Pointer to the GUID of the configuration table. + Table - On success, receives the VendorTable pointer. + +Returns: + + EFI_SUCCESS - Table was found. + EFI_INVALID_PARAMETER - TableGuid or Table is NULL. + EFI_NOT_FOUND - Table was not found. + +--*/ +STATIC +EFI_STATUS +GetSystemConfigurationTable( + IN EFI_GUID *TableGuid, + OUT VOID **Table + ) +{ + UINTN Index; + EFI_CONFIGURATION_TABLE *ConfigTable; + + if (TableGuid == NULL || Table == NULL) { + return EFI_INVALID_PARAMETER; + } + + ConfigTable = gST->ConfigurationTable; + for (Index = 0; Index < gST->NumberOfTableEntries; Index++) { + if (CompareGuid(TableGuid, &ConfigTable[Index].VendorGuid)) { + *Table = ConfigTable[Index].VendorTable; + return EFI_SUCCESS; + } + } + + *Table = NULL; + return EFI_NOT_FOUND; +} + +/*++ + +Routine Description: + + Writes a binary buffer to a file on the loaded image's device. + +Arguments: + + ImageHandle - The loaded image handle. + FileName - The path of the file to create or overwrite. + Buffer - The data buffer to write. + BufferSize - The number of bytes to write. + +Returns: + + EFI_SUCCESS - The file was written successfully. + EFI_INVALID_PARAMETER - FileName is NULL, Buffer is NULL, or BufferSize is zero. + Other EFI_STATUS - Returned from underlying protocol operations. + +--*/ +STATIC +EFI_STATUS +GetCurrentDirectoryFallbackPath ( + OUT CHAR16 **FallbackPath + ) +{ + CONST CHAR16 *CurrentDirectory; + CONST CHAR16 *VolumeRelativeDirectory; + CONST CHAR16 *MappingSeparator; + EFI_STATUS Status; + CHAR16 *PathBuffer; + UINTN PathSize; + BOOLEAN NeedsSeparator; + + if (FallbackPath == NULL) { + return EFI_INVALID_PARAMETER; + } + + *FallbackPath = NULL; + CurrentDirectory = ShellGetCurrentDir (NULL); + if (CurrentDirectory == NULL) { + return EFI_NOT_FOUND; + } + + VolumeRelativeDirectory = CurrentDirectory; + MappingSeparator = StrStr (CurrentDirectory, L":"); + if (MappingSeparator != NULL) { + VolumeRelativeDirectory = MappingSeparator + 1; + } + + NeedsSeparator = ((*VolumeRelativeDirectory != CHAR_NULL) && + (VolumeRelativeDirectory[StrLen (VolumeRelativeDirectory) - 1] != L'\\')); + PathSize = StrSize (VolumeRelativeDirectory) + + StrSize (EBBR_PROFILE_TABLE_DUMP_FALLBACK_FILENAME); + if ((*VolumeRelativeDirectory == CHAR_NULL) || NeedsSeparator) { + PathSize += sizeof (CHAR16); + } + + Status = gBS->AllocatePool (EfiBootServicesData, PathSize, (VOID **)&PathBuffer); + if (EFI_ERROR (Status)) { + return Status; + } + + if (*VolumeRelativeDirectory == CHAR_NULL) { + UnicodeSPrint ( + PathBuffer, + PathSize, + L"\\%s", + EBBR_PROFILE_TABLE_DUMP_FALLBACK_FILENAME + ); + } else if (NeedsSeparator) { + UnicodeSPrint ( + PathBuffer, + PathSize, + L"%s\\%s", + VolumeRelativeDirectory, + EBBR_PROFILE_TABLE_DUMP_FALLBACK_FILENAME + ); + } else { + UnicodeSPrint ( + PathBuffer, + PathSize, + L"%s%s", + VolumeRelativeDirectory, + EBBR_PROFILE_TABLE_DUMP_FALLBACK_FILENAME + ); + } + + *FallbackPath = PathBuffer; + return EFI_SUCCESS; +} + +STATIC +EFI_STATUS +WriteBinaryFile( + IN EFI_HANDLE ImageHandle, + IN CONST CHAR16 *FileName, + IN VOID *Buffer, + IN UINTN BufferSize + ) +{ + EFI_STATUS Status; + EFI_LOADED_IMAGE_PROTOCOL *LoadedImage; + EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *SimpleFileSystem; + EFI_FILE_PROTOCOL *Root; + EFI_FILE_PROTOCOL *File; + EFI_FILE_INFO *FileInfo; + UINTN FileInfoSize; + UINTN FileSize; + CONST CHAR16 *TargetFileName; + CHAR16 *FallbackFilePath; + BOOLEAN UsedFallback; + + if ((FileName == NULL) || (Buffer == NULL) || (BufferSize == 0)) { + return EFI_INVALID_PARAMETER; + } + + Status = gBS->HandleProtocol( + ImageHandle, + &gEfiLoadedImageProtocolGuid, + (VOID **)&LoadedImage + ); + if (EFI_ERROR(Status)) { + return Status; + } + + Status = gBS->HandleProtocol( + LoadedImage->DeviceHandle, + &gEfiSimpleFileSystemProtocolGuid, + (VOID **)&SimpleFileSystem + ); + if (EFI_ERROR(Status)) { + return Status; + } + + Status = SimpleFileSystem->OpenVolume(SimpleFileSystem, &Root); + if (EFI_ERROR(Status)) { + return Status; + } + + TargetFileName = FileName; + FallbackFilePath = NULL; + UsedFallback = FALSE; + Status = Root->Open( + Root, + &File, + (CHAR16 *)TargetFileName, + EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE, + 0 + ); + if ((Status == EFI_NOT_FOUND) && + (StrCmp(FileName, EBBR_PROFILE_TABLE_DUMP_FALLBACK_FILENAME) != 0)) { + Status = GetCurrentDirectoryFallbackPath (&FallbackFilePath); + if (EFI_ERROR (Status)) { + TargetFileName = EBBR_PROFILE_TABLE_DUMP_FALLBACK_FILENAME; + } else { + TargetFileName = FallbackFilePath; + } + + UsedFallback = TRUE; + Status = Root->Open( + Root, + &File, + (CHAR16 *)TargetFileName, + EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE, + 0 + ); + } + + if (EFI_ERROR(Status)) { + if (FallbackFilePath != NULL) { + gBS->FreePool (FallbackFilePath); + } + + Root->Close(Root); + return Status; + } + + if (UsedFallback) { + Print( + L"EBBR Profile Table Dump: %s not found, writing %s in the current directory\n", + FileName, + TargetFileName + ); + } + + Status = File->SetPosition(File, 0); + if (EFI_ERROR(Status)) { + File->Close(File); + Root->Close(Root); + if (FallbackFilePath != NULL) { + gBS->FreePool (FallbackFilePath); + } + + return Status; + } + + FileInfo = NULL; + FileInfoSize = SIZE_OF_EFI_FILE_INFO + 200; + Status = gBS->AllocatePool(EfiBootServicesData, FileInfoSize, (VOID **)&FileInfo); + if (EFI_ERROR(Status)) { + File->Close(File); + Root->Close(Root); + if (FallbackFilePath != NULL) { + gBS->FreePool (FallbackFilePath); + } + + return Status; + } + + Status = File->GetInfo(File, &gEfiFileInfoGuid, &FileInfoSize, FileInfo); + if (EFI_ERROR(Status)) { + gBS->FreePool(FileInfo); + File->Close(File); + Root->Close(Root); + if (FallbackFilePath != NULL) { + gBS->FreePool (FallbackFilePath); + } + + return Status; + } + + FileInfo->FileSize = 0; + FileInfo->Size = FileInfoSize; + Status = File->SetInfo(File, &gEfiFileInfoGuid, FileInfoSize, FileInfo); + gBS->FreePool(FileInfo); + if (EFI_ERROR(Status)) { + File->Close(File); + Root->Close(Root); + if (FallbackFilePath != NULL) { + gBS->FreePool (FallbackFilePath); + } + + return Status; + } + + FileSize = BufferSize; + Status = File->Write(File, &FileSize, Buffer); + if (EFI_ERROR(Status)) { + File->Close(File); + Root->Close(Root); + if (FallbackFilePath != NULL) { + gBS->FreePool (FallbackFilePath); + } + + return Status; + } + + if (FileSize != BufferSize) { + File->Close(File); + Root->Close(Root); + if (FallbackFilePath != NULL) { + gBS->FreePool (FallbackFilePath); + } + + return EFI_DEVICE_ERROR; + } + + File->Close(File); + Root->Close(Root); + if (FallbackFilePath != NULL) { + gBS->FreePool (FallbackFilePath); + } + + return EFI_SUCCESS; +} + +STATIC +EFI_STATUS +WriteHexDumpFile( + IN EFI_HANDLE ImageHandle, + IN VOID *Buffer, + IN UINTN BufferSize + ) +{ + EFI_STATUS Status; + CHAR8 *Text; + CHAR8 *Cursor; + UINT8 *Data; + UINTN EstimatedSize; + UINTN Offset; + UINTN Index; + UINTN LineBytes; + UINTN Remaining; + UINTN MaxGuidCount; + UINTN GuidCount; + UINT16 Version; + UINT16 NumberOfProfiles; + + if ((Buffer == NULL) || (BufferSize == 0)) { + return EFI_INVALID_PARAMETER; + } + + MaxGuidCount = (BufferSize >= 4) ? ((BufferSize - 4) / sizeof(EFI_GUID)) : 0; + EstimatedSize = ((((BufferSize + 15) / 16) + 1) * 80) + 128 + (MaxGuidCount * 80) + 1; + Status = gBS->AllocatePool(EfiBootServicesData, EstimatedSize, (VOID **)&Text); + if (EFI_ERROR(Status)) { + return Status; + } + + Cursor = Text; + Data = (UINT8 *)Buffer; + + for (Offset = 0; Offset < BufferSize; Offset += 16) { + LineBytes = ((BufferSize - Offset) >= 16) ? 16 : (BufferSize - Offset); + Remaining = EstimatedSize - (UINTN)(Cursor - Text); + Cursor += AsciiSPrint(Cursor, Remaining, "%08X ", (UINT32)Offset); + + for (Index = 0; Index < 16; Index++) { + Remaining = EstimatedSize - (UINTN)(Cursor - Text); + if (Index < LineBytes) { + Cursor += AsciiSPrint(Cursor, Remaining, "%02X", Data[Offset + Index]); + } else { + Cursor += AsciiSPrint(Cursor, Remaining, " "); + } + + if (Index == 7) { + *Cursor++ = ' '; + } + + if (Index != 15) { + *Cursor++ = ' '; + } + } + + *Cursor++ = ' '; + *Cursor++ = ' '; + *Cursor++ = '|'; + + for (Index = 0; Index < LineBytes; Index++) { + UINT8 Byte; + + Byte = Data[Offset + Index]; + *Cursor++ = ((Byte >= 0x20) && (Byte <= 0x7E)) ? (CHAR8)Byte : '.'; + } + + *Cursor++ = '|'; + *Cursor++ = '\n'; + } + + Remaining = EstimatedSize - (UINTN)(Cursor - Text); + Cursor += AsciiSPrint(Cursor, Remaining, "%08X\n", (UINT32)BufferSize); + + Version = 0; + NumberOfProfiles = 0; + GuidCount = 0; + if (BufferSize >= 4) { + Version = (UINT16)(Data[0] | (Data[1] << 8)); + NumberOfProfiles = (UINT16)(Data[2] | (Data[3] << 8)); + GuidCount = (NumberOfProfiles <= MaxGuidCount) ? NumberOfProfiles : MaxGuidCount; + } + + Remaining = EstimatedSize - (UINTN)(Cursor - Text); + Cursor += AsciiSPrint(Cursor, Remaining, "Type: EBBR Profile Table Information\n"); + Remaining = EstimatedSize - (UINTN)(Cursor - Text); + Cursor += AsciiSPrint(Cursor, Remaining, "Version: %u\n", (UINT32)Version); + Remaining = EstimatedSize - (UINTN)(Cursor - Text); + Cursor += AsciiSPrint(Cursor, Remaining, "NumberOfProfiles: %u\n", (UINT32)NumberOfProfiles); + + for (Index = 0; Index < GuidCount; Index++) { + UINTN GuidOffset; + UINTN ByteIndex; + + GuidOffset = 4 + (Index * sizeof(EFI_GUID)); + Remaining = EstimatedSize - (UINTN)(Cursor - Text); + Cursor += AsciiSPrint(Cursor, Remaining, "EBBR profile table GUID[%u]: ", (UINT32)Index); + for (ByteIndex = 0; ByteIndex < sizeof(EFI_GUID); ByteIndex++) { + Remaining = EstimatedSize - (UINTN)(Cursor - Text); + Cursor += AsciiSPrint(Cursor, Remaining, "%02X", Data[GuidOffset + ByteIndex]); + } + *Cursor++ = '\n'; + } + + Status = WriteBinaryFile( + ImageHandle, + EBBR_PROFILE_TABLE_DUMP_FILENAME, + Text, + (UINTN)(Cursor - Text) + ); + gBS->FreePool(Text); + + return Status; +} + +STATIC +EFI_STATUS +WriteZeroedProfileTable( + IN EFI_HANDLE ImageHandle + ) +{ + UINT16 EmptyProfileTable[2]; + + EmptyProfileTable[0] = 0; + EmptyProfileTable[1] = 0; + + return WriteHexDumpFile( + ImageHandle, + EmptyProfileTable, + sizeof(EmptyProfileTable) + ); +} + +/*++ + +Routine Description: + + Retrieves the EBBR conformance profiles table and writes it to disk. + +Arguments: + + ImageHandle - The loaded image handle. + +Returns: + + EFI_SUCCESS - The table was retrieved and written successfully. + EFI_NOT_FOUND - The conformance profiles table was not found. + Other EFI_STATUS - Returned from the file write operation. + +--*/ +STATIC +EFI_STATUS +DumpEbbrProfileTable( + IN EFI_HANDLE ImageHandle + ) +{ + EFI_STATUS Status; + EFI_STATUS TableStatus; + EFI_CONFORMANCE_PROFILES_TABLE *ConfProfTable; + UINTN TableSize; + + ConfProfTable = NULL; + + Status = GetSystemConfigurationTable(&gEfiConfProfilesTableGuid, (VOID **)&ConfProfTable); + if (EFI_ERROR(Status) || (ConfProfTable == NULL)) { + TableStatus = EFI_ERROR(Status) ? Status : EFI_NOT_FOUND; + Print(L"EBBR Profile Table Dump: EFI Conformance Profiles Table not found (%r)\n", TableStatus); + + Status = WriteZeroedProfileTable(ImageHandle); + if (EFI_ERROR(Status)) { + Print(L"EBBR Profile Table Dump: Failed to write zeroed %s (%r)\n", EBBR_PROFILE_TABLE_DUMP_FILENAME, Status); + return Status; + } + + return TableStatus; + } + + if (ConfProfTable->NumberOfProfiles > MAX_CONFORMANCE_PROFILE_COUNT) { + Print(L"EBBR Profile Table Dump: Conformance Profiles Table count %u exceeds safe limit %u\n", + (UINT32)ConfProfTable->NumberOfProfiles, + (UINT32)MAX_CONFORMANCE_PROFILE_COUNT); + return EFI_COMPROMISED_DATA; + } + + if (ConfProfTable->NumberOfProfiles > ((MAX_UINTN - sizeof(*ConfProfTable)) / sizeof(EFI_GUID))) { + Print(L"EBBR Profile Table Dump: Conformance Profiles Table size overflow for count %u\n", + (UINT32)ConfProfTable->NumberOfProfiles); + return EFI_COMPROMISED_DATA; + } + + TableSize = sizeof(*ConfProfTable) + + ConfProfTable->NumberOfProfiles * sizeof(EFI_GUID); + + Status = WriteHexDumpFile( + ImageHandle, + ConfProfTable, + TableSize + ); + if (EFI_ERROR(Status)) { + Print(L"EBBR Profile Table Dump: Failed to write %s (%r)\n", EBBR_PROFILE_TABLE_DUMP_FILENAME, Status); + } + + return Status; +} + +/*++ + +Routine Description: + + UEFI application entry point for the EBBR profile table dump utility. + +Arguments: + + ImageHandle - The loaded image handle. + SystemTable - Pointer to the EFI system table. + +Returns: + + EFI_SUCCESS - The dump completed successfully. + Other EFI_STATUS - The status from DumpEbbProfileTable. + +--*/ +EFI_STATUS +EFIAPI +UefiDump( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + + Status = DumpEbbrProfileTable(ImageHandle); + if (EFI_ERROR(Status)) { + Print(L"EBBR Profile Table Dump: Failed to dump EBBR Profile table (%r)\n", Status); + } + + return Status; +} diff --git a/ebbr/uefi_app/UefiDump.dsc b/ebbr/uefi_app/UefiDump.dsc new file mode 100644 index 00000000..eb150d23 --- /dev/null +++ b/ebbr/uefi_app/UefiDump.dsc @@ -0,0 +1,91 @@ +# +# The material contained herein is not a license, either +# expressly or impliedly, to any intellectual property owned +# or controlled by any of the authors or developers of this +# material or to any contribution thereto. The material +# contained herein is provided on an "AS IS" basis and, to the +# maximum extent permitted by applicable law, this information +# is provided AS IS AND WITH ALL FAULTS, and the authors and +# developers of this material hereby disclaim all other +# warranties and conditions, either express, implied or +# statutory, including, but not limited to, any (if any) +# implied warranties, duties or conditions of merchantability, +# of fitness for a particular purpose, of accuracy or +# completeness of responses, of results, of workmanlike +# effort, of lack of viruses and of lack of negligence, all +# with regard to this material and any contribution thereto. +# Designers must not rely on the absence or characteristics of +# any features or instructions marked "reserved" or +# "undefined." The Unified EFI Forum, Inc. reserves any +# features or instructions so marked for future definition and +# shall have no responsibility whatsoever for conflicts or +# incompatibilities arising from future changes to them. ALSO, +# THERE IS NO WARRANTY OR CONDITION OF TITLE, QUIET ENJOYMENT, +# QUIET POSSESSION, CORRESPONDENCE TO DESCRIPTION OR +# NON-INFRINGEMENT WITH REGARD TO THE TEST SUITE AND ANY +# CONTRIBUTION THERETO. +# +# IN NO EVENT WILL ANY AUTHOR OR DEVELOPER OF THIS MATERIAL OR +# ANY CONTRIBUTION THERETO BE LIABLE TO ANY OTHER PARTY FOR +# THE COST OF PROCURING SUBSTITUTE GOODS OR SERVICES, LOST +# PROFITS, LOSS OF USE, LOSS OF DATA, OR ANY INCIDENTAL, +# CONSEQUENTIAL, DIRECT, INDIRECT, OR SPECIAL DAMAGES WHETHER +# UNDER CONTRACT, TORT, WARRANTY, OR OTHERWISE, ARISING IN ANY +# WAY OUT OF THIS OR ANY OTHER AGREEMENT RELATING TO THIS +# DOCUMENT, WHETHER OR NOT SUCH PARTY HAD ADVANCE NOTICE OF +# THE POSSIBILITY OF SUCH DAMAGES. +# +# Copyright 2006 - 2016 Unified EFI, Inc. All +# Rights Reserved, subject to all existing rights in all +# matters included within this Test Suite, to which United +# EFI, Inc. makes no claim of right. +# +# Copyright (c) 2026, ARM Ltd. All rights reserved.
+# +#/*++ +# +# Module Name: +# +# UefiDump.dsc +# +# Abstract: +# +# This is a build description file used to build the UEFI dump application, which currently dumps the EBBR conformance profiles table. +#--*/ + +[Defines] + PLATFORM_NAME = UefiDump + PLATFORM_GUID = 4fed62c9-b3cc-416e-82e5-0060b6b46a46 + PLATFORM_VERSION = 1.0 + DSC_SPECIFICATION = 0x00010005 + OUTPUT_DIRECTORY = Build/MdeModule + SUPPORTED_ARCHITECTURES = AARCH64 + BUILD_TARGETS = DEBUG|RELEASE + SKUID_IDENTIFIER = DEFAULT + +!include MdePkg/MdeLibs.dsc.inc + +[LibraryClasses] + UefiApplicationEntryPoint|MdePkg/Library/UefiApplicationEntryPoint/UefiApplicationEntryPoint.inf + BaseLib|MdePkg/Library/BaseLib/BaseLib.inf + BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf + PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf + SortLib|MdeModulePkg/Library/BaseSortLib/BaseSortLib.inf + PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf + DebugLib|MdePkg/Library/UefiDebugLibStdErr/UefiDebugLibStdErr.inf + DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf + ReportStatusCodeLib|MdePkg/Library/BaseReportStatusCodeLibNull/BaseReportStatusCodeLibNull.inf + UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf + UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf + UefiLib|MdePkg/Library/UefiLib/UefiLib.inf + UefiHiiServicesLib|MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiServicesLib.inf + HiiLib|MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf + DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf + FileHandleLib|MdePkg/Library/UefiFileHandleLib/UefiFileHandleLib.inf + ShellLib|ShellPkg/Library/UefiShellLib/UefiShellLib.inf + +[LibraryClasses.common.UEFI_APPLICATION] + MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf + +[Components] + ebbr/uefi_app/UefiDump.inf diff --git a/ebbr/uefi_app/UefiDump.h b/ebbr/uefi_app/UefiDump.h new file mode 100644 index 00000000..c274b2f6 --- /dev/null +++ b/ebbr/uefi_app/UefiDump.h @@ -0,0 +1,38 @@ +/** @file + + Header file for the UEFI dump application. + + Copyright 2006-2016 Unified EFI, Inc.
+ Copyright (c) 2026, Arm Ltd. All rights reserved.
+ + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef _UEFI_DUMP_H_ +#define _UEFI_DUMP_H_ + +#include +#include +#include +#include + +#define EBBR_PROFILE_TABLE_DUMP_FILENAME \ + L"\\acs_results_template\\acs_results\\uefi_dump\\ebbr_profile_table.log" +#define EBBR_PROFILE_TABLE_DUMP_FALLBACK_FILENAME \ + L"ebbr_profile_table.log" + +EFI_STATUS +EFIAPI +UefiDump( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ); + +#endif // _UEFI_DUMP_H_ diff --git a/ebbr/uefi_app/UefiDump.inf b/ebbr/uefi_app/UefiDump.inf new file mode 100644 index 00000000..ff09c103 --- /dev/null +++ b/ebbr/uefi_app/UefiDump.inf @@ -0,0 +1,56 @@ +## @file +# +# Copyright 2006 - 2016 Unified EFI, Inc.
+# Copyright (c) 2026, Arm Ltd. All rights reserved.
+# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +## +#/*++ +# +# Module Name: +# +# UefiDump.inf +# +# Abstract: +# +# Component description file for the UEFI dump application, which currently dumps the EBBR conformance profiles table. +# +#--*/ + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = UefiDump + FILE_GUID = 0e89def3-191f-44ef-ba72-3265ee9ff046 + MODULE_TYPE = UEFI_APPLICATION + ENTRY_POINT = UefiDump + VERSION_STRING = 1.0 + +[Sources] + UefiDump.c + +[Packages] + MdeModulePkg/MdeModulePkg.dec + MdePkg/MdePkg.dec + ShellPkg/ShellPkg.dec + +[LibraryClasses] + UefiApplicationEntryPoint + BaseLib + UefiBootServicesTableLib + UefiLib + ShellLib + +[Guids] + gEfiConfProfilesTableGuid + gEfiFileInfoGuid + +[Protocols] + gEfiLoadedImageProtocolGuid ## CONSUMES + gEfiSimpleFileSystemProtocolGuid ## CONSUMES