__FUNCTION__ is a pre-standard extension that gcc and Visual C++ among others support, while __func__ was standardized in C99. Since it's more standard, replace __FUNCTION__ with __func__ throughout UnitTestFrameworkPkg. Signed-off-by: Rebecca Cran <rebecca@bsdio.com> Reviewed-by: Michael D Kinney <michael.d.kinney@intel.com> Reviewed-by: Ard Biesheuvel <ardb@kernel.org>
		
			
				
	
	
		
			131 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			131 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/**
 | 
						|
  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;
 | 
						|
}
 |