__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 EmbeddedPkg. 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> Reviewed-by: Abner Chang <abner.chang@amd.com>
		
			
				
	
	
		
			354 lines
		
	
	
		
			8.5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			354 lines
		
	
	
		
			8.5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/** @file
 | 
						|
*
 | 
						|
*  Copyright (c) 2017, Linaro, Ltd. All rights reserved.
 | 
						|
*
 | 
						|
*  SPDX-License-Identifier: BSD-2-Clause-Patent
 | 
						|
*
 | 
						|
**/
 | 
						|
 | 
						|
#include <Uefi.h>
 | 
						|
#include <IndustryStandard/Acpi.h>
 | 
						|
#include <libfdt.h>
 | 
						|
#include <Library/BaseLib.h>
 | 
						|
#include <Library/DebugLib.h>
 | 
						|
#include <Library/DevicePathLib.h>
 | 
						|
#include <Library/HiiLib.h>
 | 
						|
#include <Library/UefiBootServicesTableLib.h>
 | 
						|
#include <Library/UefiBootServicesTableLib.h>
 | 
						|
#include <Library/UefiDriverEntryPoint.h>
 | 
						|
#include <Library/UefiLib.h>
 | 
						|
#include <Library/UefiRuntimeServicesTableLib.h>
 | 
						|
 | 
						|
#include <Protocol/AcpiTable.h>
 | 
						|
#include <Protocol/AcpiSystemDescriptionTable.h>
 | 
						|
 | 
						|
#include "ConsolePrefDxe.h"
 | 
						|
 | 
						|
#define SPCR_SIG  EFI_ACPI_2_0_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_SIGNATURE
 | 
						|
 | 
						|
extern  UINT8  ConsolePrefHiiBin[];
 | 
						|
extern  UINT8  ConsolePrefDxeStrings[];
 | 
						|
 | 
						|
typedef struct {
 | 
						|
  VENDOR_DEVICE_PATH          VendorDevicePath;
 | 
						|
  EFI_DEVICE_PATH_PROTOCOL    End;
 | 
						|
} HII_VENDOR_DEVICE_PATH;
 | 
						|
 | 
						|
STATIC HII_VENDOR_DEVICE_PATH  mConsolePrefDxeVendorDevicePath = {
 | 
						|
  {
 | 
						|
    {
 | 
						|
      HARDWARE_DEVICE_PATH,
 | 
						|
      HW_VENDOR_DP,
 | 
						|
      {
 | 
						|
        (UINT8)(sizeof (VENDOR_DEVICE_PATH)),
 | 
						|
        (UINT8)((sizeof (VENDOR_DEVICE_PATH)) >> 8)
 | 
						|
      }
 | 
						|
    },
 | 
						|
    CONSOLE_PREF_FORMSET_GUID
 | 
						|
  },
 | 
						|
  {
 | 
						|
    END_DEVICE_PATH_TYPE,
 | 
						|
    END_ENTIRE_DEVICE_PATH_SUBTYPE,
 | 
						|
    {
 | 
						|
      (UINT8)(END_DEVICE_PATH_LENGTH),
 | 
						|
      (UINT8)((END_DEVICE_PATH_LENGTH) >> 8)
 | 
						|
    }
 | 
						|
  }
 | 
						|
};
 | 
						|
 | 
						|
STATIC EFI_EVENT  mReadyToBootEvent;
 | 
						|
 | 
						|
STATIC
 | 
						|
EFI_STATUS
 | 
						|
InstallHiiPages (
 | 
						|
  VOID
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS      Status;
 | 
						|
  EFI_HII_HANDLE  HiiHandle;
 | 
						|
  EFI_HANDLE      DriverHandle;
 | 
						|
 | 
						|
  DriverHandle = NULL;
 | 
						|
  Status       = gBS->InstallMultipleProtocolInterfaces (
 | 
						|
                        &DriverHandle,
 | 
						|
                        &gEfiDevicePathProtocolGuid,
 | 
						|
                        &mConsolePrefDxeVendorDevicePath,
 | 
						|
                        NULL
 | 
						|
                        );
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    return Status;
 | 
						|
  }
 | 
						|
 | 
						|
  HiiHandle = HiiAddPackages (
 | 
						|
                &gConsolePrefFormSetGuid,
 | 
						|
                DriverHandle,
 | 
						|
                ConsolePrefDxeStrings,
 | 
						|
                ConsolePrefHiiBin,
 | 
						|
                NULL
 | 
						|
                );
 | 
						|
 | 
						|
  if (HiiHandle == NULL) {
 | 
						|
    gBS->UninstallMultipleProtocolInterfaces (
 | 
						|
           DriverHandle,
 | 
						|
           &gEfiDevicePathProtocolGuid,
 | 
						|
           &mConsolePrefDxeVendorDevicePath,
 | 
						|
           NULL
 | 
						|
           );
 | 
						|
    return EFI_OUT_OF_RESOURCES;
 | 
						|
  }
 | 
						|
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
STATIC
 | 
						|
VOID
 | 
						|
RemoveDtStdoutPath (
 | 
						|
  VOID
 | 
						|
  )
 | 
						|
{
 | 
						|
  VOID        *Dtb;
 | 
						|
  INT32       Node;
 | 
						|
  INT32       Error;
 | 
						|
  EFI_STATUS  Status;
 | 
						|
 | 
						|
  Status = EfiGetSystemConfigurationTable (&gFdtTableGuid, &Dtb);
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    DEBUG ((
 | 
						|
      DEBUG_INFO,
 | 
						|
      "%a: could not retrieve DT blob - %r\n",
 | 
						|
      __func__,
 | 
						|
      Status
 | 
						|
      ));
 | 
						|
    return;
 | 
						|
  }
 | 
						|
 | 
						|
  Node = fdt_path_offset (Dtb, "/chosen");
 | 
						|
  if (Node < 0) {
 | 
						|
    return;
 | 
						|
  }
 | 
						|
 | 
						|
  Error = fdt_delprop (Dtb, Node, "stdout-path");
 | 
						|
  if (Error) {
 | 
						|
    DEBUG ((
 | 
						|
      DEBUG_INFO,
 | 
						|
      "%a: Failed to delete 'stdout-path' property: %a\n",
 | 
						|
      __func__,
 | 
						|
      fdt_strerror (Error)
 | 
						|
      ));
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
STATIC
 | 
						|
VOID
 | 
						|
RemoveSpcrTable (
 | 
						|
  VOID
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_ACPI_SDT_PROTOCOL    *Sdt;
 | 
						|
  EFI_ACPI_TABLE_PROTOCOL  *AcpiTable;
 | 
						|
  EFI_STATUS               Status;
 | 
						|
  UINTN                    TableIndex;
 | 
						|
  EFI_ACPI_SDT_HEADER      *TableHeader;
 | 
						|
  EFI_ACPI_TABLE_VERSION   TableVersion;
 | 
						|
  UINTN                    TableKey;
 | 
						|
 | 
						|
  Status = gBS->LocateProtocol (
 | 
						|
                  &gEfiAcpiTableProtocolGuid,
 | 
						|
                  NULL,
 | 
						|
                  (VOID **)&AcpiTable
 | 
						|
                  );
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    return;
 | 
						|
  }
 | 
						|
 | 
						|
  Status = gBS->LocateProtocol (&gEfiAcpiSdtProtocolGuid, NULL, (VOID **)&Sdt);
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    return;
 | 
						|
  }
 | 
						|
 | 
						|
  TableIndex  = 0;
 | 
						|
  TableKey    = 0;
 | 
						|
  TableHeader = NULL;
 | 
						|
 | 
						|
  do {
 | 
						|
    Status = Sdt->GetAcpiTable (
 | 
						|
                    TableIndex++,
 | 
						|
                    &TableHeader,
 | 
						|
                    &TableVersion,
 | 
						|
                    &TableKey
 | 
						|
                    );
 | 
						|
    if (EFI_ERROR (Status)) {
 | 
						|
      break;
 | 
						|
    }
 | 
						|
 | 
						|
    if (TableHeader->Signature != SPCR_SIG) {
 | 
						|
      continue;
 | 
						|
    }
 | 
						|
 | 
						|
    Status = AcpiTable->UninstallAcpiTable (AcpiTable, TableKey);
 | 
						|
    if (EFI_ERROR (Status)) {
 | 
						|
      DEBUG ((
 | 
						|
        DEBUG_WARN,
 | 
						|
        "%a: failed to uninstall SPCR table - %r\n",
 | 
						|
        __func__,
 | 
						|
        Status
 | 
						|
        ));
 | 
						|
    }
 | 
						|
 | 
						|
    break;
 | 
						|
  } while (TRUE);
 | 
						|
}
 | 
						|
 | 
						|
STATIC
 | 
						|
VOID
 | 
						|
EFIAPI
 | 
						|
OnReadyToBoot (
 | 
						|
  IN EFI_EVENT  Event,
 | 
						|
  IN VOID       *Context
 | 
						|
  )
 | 
						|
{
 | 
						|
  CONSOLE_PREF_VARSTORE_DATA  ConsolePref;
 | 
						|
  UINTN                       BufferSize;
 | 
						|
  EFI_STATUS                  Status;
 | 
						|
  VOID                        *Gop;
 | 
						|
 | 
						|
  BufferSize = sizeof (ConsolePref);
 | 
						|
  Status     = gRT->GetVariable (
 | 
						|
                      CONSOLE_PREF_VARIABLE_NAME,
 | 
						|
                      &gConsolePrefFormSetGuid,
 | 
						|
                      NULL,
 | 
						|
                      &BufferSize,
 | 
						|
                      &ConsolePref
 | 
						|
                      );
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    DEBUG ((
 | 
						|
      DEBUG_ERROR,
 | 
						|
      "%a: variable '%s' could not be read - bailing!\n",
 | 
						|
      __func__,
 | 
						|
      CONSOLE_PREF_VARIABLE_NAME
 | 
						|
      ));
 | 
						|
    return;
 | 
						|
  }
 | 
						|
 | 
						|
  if (ConsolePref.Console == CONSOLE_PREF_SERIAL) {
 | 
						|
    DEBUG ((
 | 
						|
      DEBUG_INFO,
 | 
						|
      "%a: serial console preferred - doing nothing\n",
 | 
						|
      __func__
 | 
						|
      ));
 | 
						|
    return;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Check if any GOP instances exist: if so, disable stdout-path and SPCR
 | 
						|
  //
 | 
						|
  Status = gBS->LocateProtocol (&gEfiGraphicsOutputProtocolGuid, NULL, &Gop);
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    DEBUG ((
 | 
						|
      DEBUG_INFO,
 | 
						|
      "%a: no GOP instances found - doing nothing (%r)\n",
 | 
						|
      __func__,
 | 
						|
      Status
 | 
						|
      ));
 | 
						|
    return;
 | 
						|
  }
 | 
						|
 | 
						|
  RemoveDtStdoutPath ();
 | 
						|
  RemoveSpcrTable ();
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  The entry point for ConsolePrefDxe driver.
 | 
						|
 | 
						|
  @param[in] ImageHandle     The image handle of the driver.
 | 
						|
  @param[in] SystemTable     The system table.
 | 
						|
 | 
						|
  @retval EFI_ALREADY_STARTED     The driver already exists in system.
 | 
						|
  @retval EFI_OUT_OF_RESOURCES    Fail to execute entry point due to lack of
 | 
						|
                                  resources.
 | 
						|
  @retval EFI_SUCCESS             All the related protocols are installed on
 | 
						|
                                  the driver.
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
ConsolePrefDxeEntryPoint (
 | 
						|
  IN EFI_HANDLE        ImageHandle,
 | 
						|
  IN EFI_SYSTEM_TABLE  *SystemTable
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS                  Status;
 | 
						|
  CONSOLE_PREF_VARSTORE_DATA  ConsolePref;
 | 
						|
  UINTN                       BufferSize;
 | 
						|
 | 
						|
  //
 | 
						|
  // Get the current console preference from the ConsolePref variable.
 | 
						|
  //
 | 
						|
  BufferSize = sizeof (ConsolePref);
 | 
						|
  Status     = gRT->GetVariable (
 | 
						|
                      CONSOLE_PREF_VARIABLE_NAME,
 | 
						|
                      &gConsolePrefFormSetGuid,
 | 
						|
                      NULL,
 | 
						|
                      &BufferSize,
 | 
						|
                      &ConsolePref
 | 
						|
                      );
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    DEBUG ((
 | 
						|
      DEBUG_INFO,
 | 
						|
      "%a: no console preference found, defaulting to graphical\n",
 | 
						|
      __func__
 | 
						|
      ));
 | 
						|
    ConsolePref.Console = CONSOLE_PREF_GRAPHICAL;
 | 
						|
  }
 | 
						|
 | 
						|
  if (!EFI_ERROR (Status) &&
 | 
						|
      (ConsolePref.Console != CONSOLE_PREF_GRAPHICAL) &&
 | 
						|
      (ConsolePref.Console != CONSOLE_PREF_SERIAL))
 | 
						|
  {
 | 
						|
    DEBUG ((
 | 
						|
      DEBUG_WARN,
 | 
						|
      "%a: invalid value for %s, defaulting to graphical\n",
 | 
						|
      __func__,
 | 
						|
      CONSOLE_PREF_VARIABLE_NAME
 | 
						|
      ));
 | 
						|
    ConsolePref.Console = CONSOLE_PREF_GRAPHICAL;
 | 
						|
    Status              = EFI_INVALID_PARAMETER; // trigger setvar below
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Write the newly selected value back to the variable store.
 | 
						|
  //
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    ZeroMem (&ConsolePref.Reserved, sizeof (ConsolePref.Reserved));
 | 
						|
    Status = gRT->SetVariable (
 | 
						|
                    CONSOLE_PREF_VARIABLE_NAME,
 | 
						|
                    &gConsolePrefFormSetGuid,
 | 
						|
                    EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
 | 
						|
                    sizeof (ConsolePref),
 | 
						|
                    &ConsolePref
 | 
						|
                    );
 | 
						|
 | 
						|
    if (EFI_ERROR (Status)) {
 | 
						|
      DEBUG ((
 | 
						|
        DEBUG_ERROR,
 | 
						|
        "%a: gRT->SetVariable () failed - %r\n",
 | 
						|
        __func__,
 | 
						|
        Status
 | 
						|
        ));
 | 
						|
      return Status;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  Status = gBS->CreateEventEx (
 | 
						|
                  EVT_NOTIFY_SIGNAL,
 | 
						|
                  TPL_CALLBACK,
 | 
						|
                  OnReadyToBoot,
 | 
						|
                  NULL,
 | 
						|
                  &gEfiEventReadyToBootGuid,
 | 
						|
                  &mReadyToBootEvent
 | 
						|
                  );
 | 
						|
  ASSERT_EFI_ERROR (Status);
 | 
						|
 | 
						|
  return InstallHiiPages ();
 | 
						|
}
 |