Translate

Archives

UEFI OS Indication Variables

Support for OS Indications was added to the UEFI specification (Version 2.3.1C) in June 2012. See section 7.5.4.

The OsIndications variable is settable by the operating system (OS) using the UEFI SetVariable call. It contains a UINT64 bitmask that used to indicate which features the OS wants the firmware to enable or which actions the OS wants the firmware to take.

The OsIndicationsSupported variable is managed by the firmware. The variable is recreated by the platform firmware every boot and cannot be modified by the OS. It also returns a UINT64 bitmask which indicates which of the OsIndications features and actions the firmware supports.

Here are the current definitions for the variable bitmasks:

#define EFI_OS_INDICATIONS_BOOT_TO_FW_UI                    0x0000000000000001
#define EFI_OS_INDICATIONS_TIMESTAMP_REVOCATION             0x0000000000000002
#define EFI_OS_INDICATIONS_FILE_CAPSULE_DELIVERY_SUPPORTED  0x0000000000000004
#define EFI_OS_INDICATIONS_FMP_CAPSULE_SUPPORTED            0x0000000000000008
#define EFI_OS_INDICATIONS_CAPSULE_RESULT_VAR_SUPPORTED     0x0000000000000010
#define EFI_OS_INDICATIONS_START_PLATFORM_RECOVERY          0x0000000000000040

Here is the source code for a UEFI shell utility which can read and print out the current values for the two OS Indications variables.

//
//  Copyright (c) 2016  Finnbarr P. Murphy.   All rights reserved.
//
//  Display UEFI OsIndications information
//
//  License: BSD License
//

#include <Uefi.h>

#include <Uefi/UefiSpec.h>
#include <Guid/GlobalVariable.h>

#include <Library/UefiLib.h>
#include <Library/ShellCEntryLib.h>
#include <Library/ShellLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/UefiBootServicesTableLib.h>

#include <Protocol/EfiShell.h>
#include <Protocol/LoadedImage.h>

#define UTILITY_VERSION L"0.1"
#undef DEBUG

#define EFI_OS_INDICATIONS_BOOT_TO_FW_UI                    0x0000000000000001
#define EFI_OS_INDICATIONS_TIMESTAMP_REVOCATION             0x0000000000000002
#define EFI_OS_INDICATIONS_FILE_CAPSULE_DELIVERY_SUPPORTED  0x0000000000000004
#define EFI_OS_INDICATIONS_FMP_CAPSULE_SUPPORTED            0x0000000000000008
#define EFI_OS_INDICATIONS_CAPSULE_RESULT_VAR_SUPPORTED     0x0000000000000010
#define EFI_OS_INDICATIONS_START_PLATFORM_RECOVERY          0x0000000000000040

extern EFI_RUNTIME_SERVICES  *gRT;


VOID
Usage(CHAR16 *Str)
{
    Print(L"Usage: %s [-V|--version]\n", Str);
}

VOID
PrintSupport(UINT64 OsInd) 
{
    BOOLEAN BootFwUi;
    BOOLEAN PlatformRecovery;
    BOOLEAN TimeStampRevocation;
    BOOLEAN FileCapsuleDelivery;
    BOOLEAN FMPCapsuleSupported; 
    BOOLEAN CapsuleResultVariable;

    BootFwUi = (BOOLEAN) ((OsInd & EFI_OS_INDICATIONS_BOOT_TO_FW_UI) != 0);
    TimeStampRevocation = (BOOLEAN) ((OsInd & EFI_OS_INDICATIONS_TIMESTAMP_REVOCATION) != 0);
    FileCapsuleDelivery = (BOOLEAN) ((OsInd & EFI_OS_INDICATIONS_FILE_CAPSULE_DELIVERY_SUPPORTED) != 0);
    FMPCapsuleSupported  = (BOOLEAN) ((OsInd & EFI_OS_INDICATIONS_FMP_CAPSULE_SUPPORTED) != 0);
    CapsuleResultVariable = (BOOLEAN) ((OsInd & EFI_OS_INDICATIONS_CAPSULE_RESULT_VAR_SUPPORTED) != 0);
    PlatformRecovery = (BOOLEAN) ((OsInd & EFI_OS_INDICATIONS_START_PLATFORM_RECOVERY) != 0);

    Print(L"\n");
    Print(L"                      Boot Firmware: %s\n", BootFwUi ? L"Yes" : L"No");
    Print(L"               Timestamp Revocation: %s\n", TimeStampRevocation ? L"Yes" : L"No");
    Print(L"    File Capsule Delivery Supported: %s\n", FileCapsuleDelivery ? L"Yes" : L"No");
    Print(L"              FMP Capsule Supported: %s\n", FMPCapsuleSupported ? L"Yes" : L"No");
    Print(L"  Capsule Result Variable Supported: %s\n", CapsuleResultVariable ? L"Yes" : L"No");
    Print(L"            Start Platform Recovery: %s\n", PlatformRecovery ? L"Yes" : L"No");
    Print(L"\n");
}


INTN
EFIAPI
ShellAppMain(UINTN Argc, CHAR16 **Argv)
{

    EFI_STATUS Status = EFI_SUCCESS;
    UINT64     OsIndicationsSupport;
    UINT64     OsIndications;
    UINTN      DataSize;
    UINT32     Attributes;


    if (Argc == 2) {
        if (!StrCmp(Argv[1], L"--version") || 
            !StrCmp(Argv[1], L"-V")) {
            Print(L"Version: %s\n", UTILITY_VERSION);
            return Status;
        }
        if (!StrCmp(Argv[1], L"--help") ||
            !StrCmp(Argv[1], L"-h") ||
            !StrCmp(Argv[1], L"-?")) {
            Usage(Argv[0]);
            return Status;
        }
    }

    // catchall for all other cases
    if (Argc > 1) {
        Usage(Argv[0]);
        return Status;
    }


    Attributes = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS;
    DataSize = sizeof(UINT64);

    Status = gRT->GetVariable( EFI_OS_INDICATIONS_SUPPORT_VARIABLE_NAME,
                               &gEfiGlobalVariableGuid,
                               &Attributes,
                               &DataSize,
                               &OsIndicationsSupport);
    if (Status == EFI_NOT_FOUND) {
        Print(L"ERROR: OSIndicationsSupport variable not found\n");
        return Status;
    }

#ifdef DEBUG
    Print(L"OSIndicationsSupport variable found: %016x\n", OsIndicationsSupport );
#endif

    Print(L"Variable: OsIndicationsSupport\n");
    Print(L"------------------------------\n");

    PrintSupport(OsIndicationsSupport);


    Attributes = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS;
    DataSize = sizeof(UINT64);

    Status = gRT->GetVariable( EFI_OS_INDICATIONS_VARIABLE_NAME,
                               &gEfiGlobalVariableGuid,
                               &Attributes,
                               &DataSize,
                               &OsIndications);
    if (Status == EFI_NOT_FOUND) {
        Print(L"ERROR: OSIndications variable not found\n");
        return Status;
    }

#ifdef DEBUG
    Print(L"OSIndications variable found: %016x\n", OsIndications);
#endif

    Print(L"Variable: OsIndications\n");
    Print(L"-----------------------\n");

    PrintSupport(OsIndications);

    return EFI_SUCCESS;
}

Here is the UDK2015 build file (INF) for this utility:

[Defines]
  INF_VERSION                    = 0x00010006
  BASE_NAME                      = ShowOSIndications 
  FILE_GUID                      = 4ea87c61-7491-4dfd-0055-747010f3ce51
  MODULE_TYPE                    = UEFI_APPLICATION
  VERSION_STRING                 = 0.1
  ENTRY_POINT                    = ShellCEntryLib
  VALID_ARCHITECTURES            = X64

[Sources]
  ShowOSIndications.c

[Packages]
  MdePkg/MdePkg.dec
  ShellPkg/ShellPkg.dec 

[LibraryClasses]
  ShellCEntryLib   
  ShellLib
  BaseLib
  BaseMemoryLib
  UefiLib
  
[Protocols]
  
[BuildOptions]

[Pcd]


This build file only supports building an X64 binary using the GCC toolchain in the UDK2015 development environment. Sorry but I do not have the time to support other tool chains such as Visual Studio, other binary formats, or other development environments.

As usual the full, possibly updated. source code for this utility can be found at GitHub.

Here is a screen shot of the output when I recently ran the utility on my Lenovo T450:

Now that UEFI firmware is firmly established in the PC and server world, it is probably time that the vendors started certifying their firmware as conforming to a specific version of the UEFI specification.

Comments are closed.