/** @file
|
|
Copyright (c) 2018, Linaro, Ltd. All rights reserved.
|
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
|
**/
|
|
#include <Uefi.h>
|
#include <Library/BaseLib.h>
|
#include <Library/BaseMemoryLib.h>
|
#include <Library/DebugLib.h>
|
#include <Library/DevicePathLib.h>
|
#include <Library/HiiLib.h>
|
#include <Library/UefiBootServicesTableLib.h>
|
#include <Library/UefiLib.h>
|
#include <Library/UefiRuntimeServicesTableLib.h>
|
#include <Protocol/AcpiTable.h>
|
#include <Protocol/LsConnector.h>
|
#include <Protocol/Mezzanine.h>
|
|
#include "LsConnectorDxe.h"
|
|
extern UINT8 LsConnectorHiiBin[];
|
extern UINT8 LsConnectorDxeStrings[];
|
|
typedef struct {
|
VENDOR_DEVICE_PATH VendorDevicePath;
|
EFI_DEVICE_PATH_PROTOCOL End;
|
} HII_VENDOR_DEVICE_PATH;
|
|
STATIC HII_VENDOR_DEVICE_PATH m96BoardsDxeVendorDevicePath = {
|
{
|
{
|
HARDWARE_DEVICE_PATH,
|
HW_VENDOR_DP,
|
{
|
(UINT8) (sizeof (VENDOR_DEVICE_PATH)),
|
(UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)
|
}
|
},
|
NINETY_SIX_BOARDS_FORMSET_GUID
|
},
|
{
|
END_DEVICE_PATH_TYPE,
|
END_ENTIRE_DEVICE_PATH_SUBTYPE,
|
{
|
(UINT8) (END_DEVICE_PATH_LENGTH),
|
(UINT8) ((END_DEVICE_PATH_LENGTH) >> 8)
|
}
|
}
|
};
|
|
STATIC LS_CONNECTOR_PROTOCOL mLsConnector;
|
STATIC EFI_EVENT EndOfDxeEvent;
|
|
STATIC
|
EFI_STATUS
|
InstallHiiPages (
|
VOID
|
)
|
{
|
EFI_STATUS Status;
|
EFI_HII_HANDLE HiiHandle;
|
EFI_HANDLE DriverHandle;
|
|
DriverHandle = NULL;
|
Status = gBS->InstallMultipleProtocolInterfaces (&DriverHandle,
|
&gEfiDevicePathProtocolGuid,
|
&m96BoardsDxeVendorDevicePath,
|
NULL);
|
if (EFI_ERROR (Status)) {
|
return Status;
|
}
|
|
HiiHandle = HiiAddPackages (&g96BoardsFormsetGuid,
|
DriverHandle,
|
LsConnectorDxeStrings,
|
LsConnectorHiiBin,
|
NULL);
|
|
if (HiiHandle == NULL) {
|
gBS->UninstallMultipleProtocolInterfaces (DriverHandle,
|
&gEfiDevicePathProtocolGuid,
|
&m96BoardsDxeVendorDevicePath,
|
NULL);
|
return EFI_OUT_OF_RESOURCES;
|
}
|
return EFI_SUCCESS;
|
}
|
|
STATIC
|
VOID
|
EFIAPI
|
PublishOsDescription (
|
EFI_EVENT Event,
|
VOID *Context
|
)
|
{
|
VOID *Dtb;
|
MEZZANINE_PROTOCOL *Mezzanine;
|
EFI_STATUS Status;
|
EFI_ACPI_TABLE_PROTOCOL *AcpiProtocol;
|
|
Status = gBS->LocateProtocol (&g96BoardsMezzanineProtocolGuid, NULL,
|
(VOID **)&Mezzanine);
|
if (EFI_ERROR (Status)) {
|
DEBUG ((DEBUG_INFO, "%a: no mezzanine driver active\n", __FUNCTION__));
|
return;
|
}
|
|
Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL,
|
(VOID **)&AcpiProtocol);
|
if (!EFI_ERROR (Status)) {
|
Status = Mezzanine->InstallSsdtTable (Mezzanine, AcpiProtocol);
|
if (EFI_ERROR (Status)) {
|
DEBUG ((DEBUG_WARN, "%a: failed to install SSDT table - %r\n",
|
__FUNCTION__, Status));
|
}
|
return;
|
}
|
|
//
|
// Find the DTB in the configuration table array. If it isn't there, just
|
// bail without an error: the system may be able to proceed even without
|
// ACPI or DT description, so it isn't up to us to complain about this.
|
//
|
Status = EfiGetSystemConfigurationTable (&gFdtTableGuid, &Dtb);
|
if (Status == EFI_NOT_FOUND) {
|
return;
|
}
|
ASSERT_EFI_ERROR (Status);
|
|
Status = Mezzanine->ApplyDeviceTreeOverlay (Mezzanine, Dtb);
|
if (EFI_ERROR (Status)) {
|
DEBUG ((DEBUG_WARN, "%a: failed to apply DT overlay - %r\n", __FUNCTION__,
|
Status));
|
}
|
}
|
|
/**
|
The entry point for 96BoardsDxe 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_SUCCES All the related protocols are installed on
|
the driver.
|
|
**/
|
EFI_STATUS
|
EFIAPI
|
EntryPoint (
|
IN EFI_HANDLE ImageHandle,
|
IN EFI_SYSTEM_TABLE *SystemTable
|
)
|
{
|
EFI_STATUS Status;
|
NINETY_SIX_BOARDS_CONFIG_DATA ConfigData;
|
UINTN BufferSize;
|
|
//
|
// Get the current config settings from the EFI variable.
|
//
|
BufferSize = sizeof (ConfigData);
|
Status = gRT->GetVariable (NINETY_SIX_BOARDS_CONFIG_VARIABLE_NAME,
|
&g96BoardsFormsetGuid, NULL, &BufferSize, &ConfigData);
|
if (EFI_ERROR (Status)) {
|
DEBUG ((DEBUG_INFO, "%a: no config data found\n", __FUNCTION__));
|
ConfigData.MezzanineType = MEZZANINE_NONE;
|
}
|
|
if (!EFI_ERROR (Status) &&
|
ConfigData.MezzanineType >= MEZZANINE_MAX) {
|
DEBUG ((DEBUG_WARN,
|
"%a: invalid value for %s, defaulting to MEZZANINE_NONE\n",
|
__FUNCTION__, NINETY_SIX_BOARDS_CONFIG_VARIABLE_NAME));
|
ConfigData.MezzanineType = MEZZANINE_NONE;
|
Status = EFI_INVALID_PARAMETER; // trigger setvar below
|
}
|
|
//
|
// Write the newly selected value back to the variable store.
|
//
|
if (EFI_ERROR (Status)) {
|
ZeroMem (&ConfigData.Reserved, sizeof (ConfigData.Reserved));
|
Status = gRT->SetVariable (NINETY_SIX_BOARDS_CONFIG_VARIABLE_NAME,
|
&g96BoardsFormsetGuid,
|
EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
|
sizeof (ConfigData), &ConfigData);
|
|
if (EFI_ERROR (Status)) {
|
DEBUG ((DEBUG_ERROR, "%a: gRT->SetVariable () failed - %r\n",
|
__FUNCTION__, Status));
|
return Status;
|
}
|
}
|
|
switch (ConfigData.MezzanineType) {
|
case MEZZANINE_SECURE96:
|
mLsConnector.MezzanineType = MezzanineSecure96;
|
break;
|
default:
|
mLsConnector.MezzanineType = MezzanineUnknown;
|
}
|
|
Status = gBS->InstallProtocolInterface (&ImageHandle,
|
&g96BoardsLsConnectorProtocolGuid,
|
EFI_NATIVE_INTERFACE,
|
&mLsConnector);
|
if (EFI_ERROR (Status)) {
|
return Status;
|
}
|
|
Status = gBS->CreateEventEx (
|
EVT_NOTIFY_SIGNAL,
|
TPL_NOTIFY,
|
PublishOsDescription,
|
NULL,
|
&gEfiEndOfDxeEventGroupGuid,
|
&EndOfDxeEvent);
|
ASSERT_EFI_ERROR (Status);
|
|
return InstallHiiPages ();
|
}
|