mirror of
https://github.com/acidanthera/OpenCorePkg.git
synced 2025-12-08 19:25:01 +00:00
193 lines
4.7 KiB
C
193 lines
4.7 KiB
C
/** @file
|
|
Boot entry protocol implementation of Reset NVRAM boot picker entry.
|
|
|
|
Copyright (c) 2022, Mike Beaton. All rights reserved.<BR>
|
|
SPDX-License-Identifier: BSD-3-Clause
|
|
**/
|
|
|
|
#include <Guid/AppleVariable.h>
|
|
|
|
#include <Uefi.h>
|
|
#include <Library/BaseLib.h>
|
|
#include <Library/OcDeviceMiscLib.h>
|
|
#include <Library/UefiBootServicesTableLib.h>
|
|
#include <Library/UefiRuntimeServicesTableLib.h>
|
|
|
|
#include <Protocol/OcBootEntry.h>
|
|
|
|
#define OC_MENU_RESET_NVRAM_ID "reset_nvram"
|
|
#define OC_MENU_RESET_NVRAM_ENTRY "Reset NVRAM"
|
|
|
|
STATIC BOOLEAN mUseApple = FALSE;
|
|
STATIC BOOLEAN mPreserveBoot = FALSE;
|
|
|
|
STATIC
|
|
VOID
|
|
WaitForChime (
|
|
IN OUT OC_PICKER_CONTEXT *Context
|
|
)
|
|
{
|
|
//
|
|
// Allow chime to finish, if playing.
|
|
//
|
|
if (Context->OcAudio != NULL) {
|
|
Context->OcAudio->StopPlayback (Context->OcAudio, TRUE);
|
|
}
|
|
}
|
|
|
|
STATIC
|
|
EFI_STATUS
|
|
SystemActionResetNvram (
|
|
IN OUT OC_PICKER_CONTEXT *PickerContext
|
|
)
|
|
{
|
|
UINT8 ResetNVRam = 1;
|
|
|
|
WaitForChime (PickerContext);
|
|
|
|
if (!mUseApple) {
|
|
return OcResetNvram (mPreserveBoot);
|
|
}
|
|
|
|
//
|
|
// Any size, any value for this variable will cause a reset on supported firmware.
|
|
//
|
|
gRT->SetVariable (
|
|
APPLE_RESET_NVRAM_VARIABLE_NAME,
|
|
&gAppleBootVariableGuid,
|
|
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
|
|
sizeof (ResetNVRam),
|
|
&ResetNVRam
|
|
);
|
|
|
|
DirectResetCold ();
|
|
|
|
return EFI_DEVICE_ERROR;
|
|
}
|
|
|
|
STATIC OC_PICKER_ENTRY mResetNvramBootEntries[1] = {
|
|
{
|
|
.Id = OC_MENU_RESET_NVRAM_ID,
|
|
.Name = OC_MENU_RESET_NVRAM_ENTRY,
|
|
.Path = NULL,
|
|
.Arguments = NULL,
|
|
.Flavour = OC_FLAVOUR_RESET_NVRAM,
|
|
.Auxiliary = TRUE,
|
|
.Tool = FALSE,
|
|
.TextMode = FALSE,
|
|
.RealPath = FALSE,
|
|
.SystemAction = SystemActionResetNvram,
|
|
.AudioBasePath = OC_VOICE_OVER_AUDIO_FILE_RESET_NVRAM,
|
|
.AudioBaseType = OC_VOICE_OVER_AUDIO_BASE_TYPE_OPEN_CORE
|
|
}
|
|
};
|
|
|
|
STATIC
|
|
EFI_STATUS
|
|
EFIAPI
|
|
ResetNvramGetBootEntries (
|
|
IN OUT OC_PICKER_CONTEXT *PickerContext,
|
|
IN CONST EFI_HANDLE Device OPTIONAL,
|
|
OUT OC_PICKER_ENTRY **Entries,
|
|
OUT UINTN *NumEntries
|
|
)
|
|
{
|
|
//
|
|
// Custom entries only.
|
|
//
|
|
if (Device != NULL) {
|
|
return EFI_NOT_FOUND;
|
|
}
|
|
|
|
DEBUG ((DEBUG_INFO, "BEP: Reset NVRAM entry, preserve boot %u, apple %u\n", mPreserveBoot, mUseApple));
|
|
|
|
*Entries = mResetNvramBootEntries;
|
|
*NumEntries = ARRAY_SIZE (mResetNvramBootEntries);
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
STATIC
|
|
CHAR8 *
|
|
EFIAPI
|
|
ResetNvramCheckHotKeys (
|
|
IN OUT OC_PICKER_CONTEXT *Context,
|
|
IN UINTN NumKeys,
|
|
IN APPLE_MODIFIER_MAP Modifiers,
|
|
IN APPLE_KEY_CODE *Keys
|
|
)
|
|
{
|
|
BOOLEAN HasCommand;
|
|
BOOLEAN HasOption;
|
|
BOOLEAN HasKeyP;
|
|
BOOLEAN HasKeyR;
|
|
|
|
HasCommand = (Modifiers & (APPLE_MODIFIER_LEFT_COMMAND | APPLE_MODIFIER_RIGHT_COMMAND)) != 0;
|
|
HasOption = (Modifiers & (APPLE_MODIFIER_LEFT_OPTION | APPLE_MODIFIER_RIGHT_OPTION)) != 0;
|
|
HasKeyP = OcKeyMapHasKey (Keys, NumKeys, AppleHidUsbKbUsageKeyP);
|
|
HasKeyR = OcKeyMapHasKey (Keys, NumKeys, AppleHidUsbKbUsageKeyR);
|
|
|
|
if (HasOption && HasCommand && HasKeyP && HasKeyR) {
|
|
DEBUG ((DEBUG_INFO, "BEP: CMD+OPT+P+R causes NVRAM reset\n"));
|
|
return OC_MENU_RESET_NVRAM_ID;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
STATIC
|
|
OC_BOOT_ENTRY_PROTOCOL
|
|
mResetNvramBootEntryProtocol = {
|
|
OC_BOOT_ENTRY_PROTOCOL_REVISION,
|
|
ResetNvramGetBootEntries,
|
|
NULL,
|
|
ResetNvramCheckHotKeys
|
|
};
|
|
|
|
EFI_STATUS
|
|
EFIAPI
|
|
UefiMain (
|
|
IN EFI_HANDLE ImageHandle,
|
|
IN EFI_SYSTEM_TABLE *SystemTable
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;
|
|
OC_FLEX_ARRAY *ParsedLoadOptions;
|
|
|
|
Status = gBS->HandleProtocol (
|
|
ImageHandle,
|
|
&gEfiLoadedImageProtocolGuid,
|
|
(VOID **)&LoadedImage
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
Status = OcParseLoadOptions (LoadedImage, &ParsedLoadOptions);
|
|
if (!EFI_ERROR (Status)) {
|
|
mPreserveBoot = OcHasParsedVar (ParsedLoadOptions, L"--preserve-boot", TRUE);
|
|
mUseApple = OcHasParsedVar (ParsedLoadOptions, L"--apple", TRUE);
|
|
|
|
OcFlexArrayFree (&ParsedLoadOptions);
|
|
} else {
|
|
ASSERT (ParsedLoadOptions == NULL);
|
|
|
|
if (Status != EFI_NOT_FOUND) {
|
|
return Status;
|
|
}
|
|
}
|
|
|
|
if (mUseApple && mPreserveBoot) {
|
|
DEBUG ((DEBUG_WARN, "BEP: ResetNvram %s is ignored due to %s!\n", L"--preserve-boot", L"--apple"));
|
|
}
|
|
|
|
Status = gBS->InstallMultipleProtocolInterfaces (
|
|
&ImageHandle,
|
|
&gOcBootEntryProtocolGuid,
|
|
&mResetNvramBootEntryProtocol,
|
|
NULL
|
|
);
|
|
return Status;
|
|
}
|