Standarized code styles (clang-format)

This commit is contained in:
Gustave Monce 2021-12-03 17:28:30 +01:00 committed by BigfootACA
parent ebe85dc0f2
commit aee5d4edfa
40 changed files with 4756 additions and 5205 deletions

17
.clang-format Normal file
View File

@ -0,0 +1,17 @@
Language: Cpp
BreakBeforeBraces: Stroustrup
PointerAlignment: Right
IndentWidth: 2
AccessModifierOffset: 0
ColumnLimit: 80
NamespaceIndentation: All
AlignTrailingComments: true
AllowAllParametersOfDeclarationOnNextLine: true
AlwaysBreakTemplateDeclarations: true
AlignAfterOpenBracket: AlwaysBreak
UseTab: Never
IncludeBlocks: Preserve
AlignConsecutiveDeclarations: true
AlignConsecutiveAssignments: true
SpacesInParentheses: false
SpaceBeforeParens: ControlStatements

View File

@ -16,27 +16,26 @@
* along with this program. If not, see <https://www.gnu.org/licenses/ * along with this program. If not, see <https://www.gnu.org/licenses/
*/ */
#include <Library/UefiApplicationEntryPoint.h>
#include <Library/BootSlotLib.h> #include <Library/BootSlotLib.h>
#include <Library/UefiApplicationEntryPoint.h>
EFI_STATUS EFI_STATUS
EFIAPI EFIAPI
SwitchSlotsAppEntryPoint ( SwitchSlotsAppEntryPoint(
IN EFI_HANDLE ImageHandle, IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable)
IN EFI_SYSTEM_TABLE *SystemTable
)
{ {
MemCardType Type = CheckRootDeviceType(); MemCardType Type = CheckRootDeviceType();
if (Type == UNKNOWN) { if (Type == UNKNOWN) {
PrintAndWaitAnyKey(SystemTable, L"Unknown device storage. Press any key to exit.\n"); PrintAndWaitAnyKey(
SystemTable, L"Unknown device storage. Press any key to exit.\n");
return EFI_UNSUPPORTED; return EFI_UNSUPPORTED;
} }
EFI_STATUS Status = EnumeratePartitions(); EFI_STATUS Status = EnumeratePartitions();
if (EFI_ERROR (Status)) { if (EFI_ERROR(Status)) {
Print (L"Could not enumerate partitions. Code %d\n", Status); Print(L"Could not enumerate partitions. Code %d\n", Status);
WaitAnyKey(SystemTable); WaitAnyKey(SystemTable);
return Status; return Status;
} }
@ -44,39 +43,46 @@ SwitchSlotsAppEntryPoint (
UpdatePartitionEntries(); UpdatePartitionEntries();
/*Check for multislot boot support*/ /*Check for multislot boot support*/
BOOLEAN MultiSlotSupported = PartitionHasMultiSlot ((CONST CHAR16 *)L"boot"); BOOLEAN MultiSlotSupported = PartitionHasMultiSlot((CONST CHAR16 *)L"boot");
if (!MultiSlotSupported) { if (!MultiSlotSupported) {
PrintAndWaitAnyKey(SystemTable, L"A/B slots aren't supported on this device. Press any key to exit.\n"); PrintAndWaitAnyKey(
SystemTable,
L"A/B slots aren't supported on this device. Press any key to exit.\n");
return EFI_UNSUPPORTED; return EFI_UNSUPPORTED;
} }
Slot CurrentSlot = GetCurrentSlotSuffix(); Slot CurrentSlot = GetCurrentSlotSuffix();
if (IsSuffixEmpty(&CurrentSlot)) { if (IsSuffixEmpty(&CurrentSlot)) {
PrintAndWaitAnyKey(SystemTable, L"Current active slot not found, try to boot Android first. Press any key to exit.\n"); PrintAndWaitAnyKey(
SystemTable, L"Current active slot not found, try to boot Android "
L"first. Press any key to exit.\n");
return EFI_NOT_READY; return EFI_NOT_READY;
} }
Slot *NewSlot = NULL; Slot *NewSlot = NULL;
Slot Slots[] = {{L"_a"}, {L"_b"}}; Slot Slots[] = {{L"_a"}, {L"_b"}};
if (StrnCmp (CurrentSlot.Suffix, Slots[0].Suffix, StrLen (Slots[0].Suffix)) == 0) { if (StrnCmp(CurrentSlot.Suffix, Slots[0].Suffix, StrLen(Slots[0].Suffix)) ==
0) {
NewSlot = &Slots[1]; NewSlot = &Slots[1];
} else { }
else {
NewSlot = &Slots[0]; NewSlot = &Slots[0];
} }
//Print (L"Current active slot suffix is: %s, next slot suffix is: %s\n", &CurrentSlot.Suffix, &NewSlot->Suffix); // Print (L"Current active slot suffix is: %s, next slot suffix is: %s\n",
// &CurrentSlot.Suffix, &NewSlot->Suffix);
Status = SetActiveSlot(NewSlot, TRUE, FALSE); Status = SetActiveSlot(NewSlot, TRUE, FALSE);
if (EFI_ERROR(Status)) { if (EFI_ERROR(Status)) {
Print (L"Could not update active slot. Code %d\n", Status); Print(L"Could not update active slot. Code %d\n", Status);
WaitAnyKey(SystemTable); WaitAnyKey(SystemTable);
return Status; return Status;
} }
//Print (L"Current active slot has been updated successfully! Press any key to reboot.\n"); // Print (L"Current active slot has been updated successfully! Press any key
//WaitAnyKey(SystemTable); // to reboot.\n"); WaitAnyKey(SystemTable);
gRT->ResetSystem (EfiResetWarm, EFI_SUCCESS, 0, NULL); gRT->ResetSystem(EfiResetWarm, EFI_SUCCESS, 0, NULL);
CpuDeadLoop (); CpuDeadLoop();
return EFI_SUCCESS; return EFI_SUCCESS;
} }

View File

@ -16,35 +16,35 @@
* along with this program. If not, see <https://www.gnu.org/licenses/ * along with this program. If not, see <https://www.gnu.org/licenses/
*/ */
#include <Uefi.h>
#include <Library/UefiLib.h>
#include <Library/BootSlotLib.h> #include <Library/BootSlotLib.h>
#include <Library/UefiLib.h>
#include <Uefi.h>
EFI_STATUS EFI_STATUS
EFIAPI EFIAPI
BootSlotMain( BootSlotMain(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable)
IN EFI_HANDLE ImageHandle, {
IN EFI_SYSTEM_TABLE *SystemTable
) {
MemCardType Type = CheckRootDeviceType(); MemCardType Type = CheckRootDeviceType();
if (Type == UNKNOWN) { if (Type == UNKNOWN) {
DEBUG ((EFI_D_ERROR, "Device storage is not supported \n")); DEBUG((EFI_D_ERROR, "Device storage is not supported \n"));
return EFI_SUCCESS; return EFI_SUCCESS;
} }
EFI_STATUS Status = EnumeratePartitions(); EFI_STATUS Status = EnumeratePartitions();
if (EFI_ERROR (Status)) { if (EFI_ERROR(Status)) {
DEBUG ((EFI_D_ERROR, "Could not enumerate partitions. Code %d\n", Status)); DEBUG((EFI_D_ERROR, "Could not enumerate partitions. Code %d\n", Status));
return Status; return Status;
} }
UpdatePartitionEntries(); UpdatePartitionEntries();
/*Check for multislot boot support*/ /*Check for multislot boot support*/
BOOLEAN MultiSlotSupported = PartitionHasMultiSlot ((CONST CHAR16 *)L"boot"); BOOLEAN MultiSlotSupported = PartitionHasMultiSlot((CONST CHAR16 *)L"boot");
if (!MultiSlotSupported) { if (!MultiSlotSupported) {
DEBUG ((EFI_D_ERROR, "A/B slots aren't supported on this device. Press any key to exit.\n")); DEBUG((
EFI_D_ERROR,
"A/B slots aren't supported on this device. Press any key to exit.\n"));
return EFI_SUCCESS; return EFI_SUCCESS;
} }
@ -52,22 +52,24 @@ BootSlotMain(
Slot CurrentSlot = GetCurrentSlotSuffix(); Slot CurrentSlot = GetCurrentSlotSuffix();
if (IsSuffixEmpty(&CurrentSlot)) { if (IsSuffixEmpty(&CurrentSlot)) {
CurrentSlot = Slots[0]; // Set A as active if there is no slot available (shouldn't happen though) CurrentSlot = Slots[0]; // Set A as active if there is no slot available
// (shouldn't happen though)
} }
// Clear all unbootable bits if exists // Clear all unbootable bits if exists
for (UINTN SlotIndex = 0; SlotIndex < ARRAY_SIZE (Slots); SlotIndex++) { for (UINTN SlotIndex = 0; SlotIndex < ARRAY_SIZE(Slots); SlotIndex++) {
Slot *SlotEntry = &Slots[SlotIndex]; Slot *SlotEntry = &Slots[SlotIndex];
if (!IsSlotBootable(SlotEntry)) { if (!IsSlotBootable(SlotEntry)) {
ClearUnbootable(SlotEntry); ClearUnbootable(SlotEntry);
} }
} }
// Set current slot as active again just refresh its attributes + mark it successful // Set current slot as active again just refresh its attributes + mark it
// successful
Status = SetActiveSlot(&CurrentSlot, FALSE, TRUE); Status = SetActiveSlot(&CurrentSlot, FALSE, TRUE);
if (EFI_ERROR(Status)) { if (EFI_ERROR(Status)) {
DEBUG ((EFI_D_ERROR, "Could not update active slot. Code %d\n", Status)); DEBUG((EFI_D_ERROR, "Could not update active slot. Code %d\n", Status));
return Status; return Status;
} }

View File

@ -1,8 +1,8 @@
#include <PiDxe.h>
#include <Protocol/KeypadDevice.h>
#include <Library/DebugLib.h> #include <Library/DebugLib.h>
#include <Library/KeypadDeviceImplLib.h> #include <Library/KeypadDeviceImplLib.h>
#include <Library/UefiBootServicesTableLib.h> #include <Library/UefiBootServicesTableLib.h>
#include <PiDxe.h>
#include <Protocol/KeypadDevice.h>
typedef struct { typedef struct {
VENDOR_DEVICE_PATH Keypad; VENDOR_DEVICE_PATH Keypad;
@ -21,12 +21,9 @@ KEYPAD_DEVICE_PATH mInternalDevicePath = {
}, },
EFI_CALLER_ID_GUID, EFI_CALLER_ID_GUID,
}, },
{ {END_DEVICE_PATH_TYPE,
END_DEVICE_PATH_TYPE,
END_ENTIRE_DEVICE_PATH_SUBTYPE, END_ENTIRE_DEVICE_PATH_SUBTYPE,
{ sizeof (EFI_DEVICE_PATH_PROTOCOL), 0 } {sizeof(EFI_DEVICE_PATH_PROTOCOL), 0}}};
}
};
STATIC KEYPAD_DEVICE_PROTOCOL mInternalKeypadDevice = { STATIC KEYPAD_DEVICE_PROTOCOL mInternalKeypadDevice = {
KeypadDeviceImplReset, KeypadDeviceImplReset,
@ -35,21 +32,14 @@ STATIC KEYPAD_DEVICE_PROTOCOL mInternalKeypadDevice = {
EFI_STATUS EFI_STATUS
EFIAPI EFIAPI
KeypadDeviceDxeInitialize ( KeypadDeviceDxeInitialize(
IN EFI_HANDLE ImageHandle, IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable)
IN EFI_SYSTEM_TABLE *SystemTable
)
{ {
EFI_STATUS Status; EFI_STATUS Status;
Status = gBS->InstallMultipleProtocolInterfaces( Status = gBS->InstallMultipleProtocolInterfaces(
&ImageHandle, &ImageHandle, &gEFIDroidKeypadDeviceProtocolGuid, &mInternalKeypadDevice,
&gEFIDroidKeypadDeviceProtocolGuid, &gEfiDevicePathProtocolGuid, &mInternalDevicePath, NULL);
&mInternalKeypadDevice,
&gEfiDevicePathProtocolGuid,
&mInternalDevicePath,
NULL
);
ASSERT_EFI_ERROR(Status); ASSERT_EFI_ERROR(Status);
return Status; return Status;

View File

@ -3,9 +3,9 @@
Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR> Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License are licensed and made available under the terms and conditions of the BSD
which accompanies this distribution. The full text of the license may be found at License which accompanies this distribution. The full text of the license may
http://opensource.org/licenses/bsd-license.php be found at http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
@ -58,12 +58,9 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/ **/
EFI_STATUS EFI_STATUS
EFIAPI EFIAPI
KeypadComponentNameGetDriverName ( KeypadComponentNameGetDriverName(
IN EFI_COMPONENT_NAME_PROTOCOL *This, IN EFI_COMPONENT_NAME_PROTOCOL *This, IN CHAR8 *Language,
IN CHAR8 *Language, OUT CHAR16 **DriverName);
OUT CHAR16 **DriverName
);
/** /**
Retrieves a Unicode string that is the user readable name of the controller Retrieves a Unicode string that is the user readable name of the controller
@ -135,44 +132,30 @@ KeypadComponentNameGetDriverName (
**/ **/
EFI_STATUS EFI_STATUS
EFIAPI EFIAPI
KeypadComponentNameGetControllerName ( KeypadComponentNameGetControllerName(
IN EFI_COMPONENT_NAME_PROTOCOL *This, IN EFI_COMPONENT_NAME_PROTOCOL *This, IN EFI_HANDLE ControllerHandle,
IN EFI_HANDLE ControllerHandle, IN EFI_HANDLE ChildHandle OPTIONAL, IN CHAR8 *Language,
IN EFI_HANDLE ChildHandle OPTIONAL, OUT CHAR16 **ControllerName);
IN CHAR8 *Language,
OUT CHAR16 **ControllerName
);
// //
// EFI Component Name Protocol // EFI Component Name Protocol
// //
GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME_PROTOCOL gKeypadComponentName = { GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME_PROTOCOL gKeypadComponentName =
KeypadComponentNameGetDriverName, {KeypadComponentNameGetDriverName, KeypadComponentNameGetControllerName,
KeypadComponentNameGetControllerName, "eng"};
"eng"
};
// //
// EFI Component Name 2 Protocol // EFI Component Name 2 Protocol
// //
GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL gKeypadComponentName2 = { GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL
(EFI_COMPONENT_NAME2_GET_DRIVER_NAME) KeypadComponentNameGetDriverName, gKeypadComponentName2 = {
(EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) KeypadComponentNameGetControllerName, (EFI_COMPONENT_NAME2_GET_DRIVER_NAME)KeypadComponentNameGetDriverName,
"en" (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME)
}; KeypadComponentNameGetControllerName,
"en"};
GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE
GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mKeypadDriverNameTable[] = { mKeypadDriverNameTable[] = {{"eng;en", L"Keypad Driver"}, {NULL, NULL}};
{
"eng;en",
L"Keypad Driver"
},
{
NULL,
NULL
}
};
/** /**
Retrieves a Unicode string that is the user readable name of the driver. Retrieves a Unicode string that is the user readable name of the driver.
@ -215,19 +198,13 @@ GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mKeypadDriverNameTable[]
**/ **/
EFI_STATUS EFI_STATUS
EFIAPI EFIAPI
KeypadComponentNameGetDriverName ( KeypadComponentNameGetDriverName(
IN EFI_COMPONENT_NAME_PROTOCOL *This, IN EFI_COMPONENT_NAME_PROTOCOL *This, IN CHAR8 *Language,
IN CHAR8 *Language, OUT CHAR16 **DriverName)
OUT CHAR16 **DriverName
)
{ {
return LookupUnicodeString2 ( return LookupUnicodeString2(
Language, Language, This->SupportedLanguages, mKeypadDriverNameTable, DriverName,
This->SupportedLanguages, (BOOLEAN)(This == &gKeypadComponentName));
mKeypadDriverNameTable,
DriverName,
(BOOLEAN)(This == &gKeypadComponentName)
);
} }
/** /**
@ -300,17 +277,14 @@ KeypadComponentNameGetDriverName (
**/ **/
EFI_STATUS EFI_STATUS
EFIAPI EFIAPI
KeypadComponentNameGetControllerName ( KeypadComponentNameGetControllerName(
IN EFI_COMPONENT_NAME_PROTOCOL *This, IN EFI_COMPONENT_NAME_PROTOCOL *This, IN EFI_HANDLE ControllerHandle,
IN EFI_HANDLE ControllerHandle, IN EFI_HANDLE ChildHandle OPTIONAL, IN CHAR8 *Language,
IN EFI_HANDLE ChildHandle OPTIONAL, OUT CHAR16 **ControllerName)
IN CHAR8 *Language,
OUT CHAR16 **ControllerName
)
{ {
EFI_STATUS Status; EFI_STATUS Status;
EFI_SIMPLE_TEXT_INPUT_PROTOCOL *ConIn; EFI_SIMPLE_TEXT_INPUT_PROTOCOL *ConIn;
KEYPAD_CONSOLE_IN_DEV *ConsoleIn; KEYPAD_CONSOLE_IN_DEV * ConsoleIn;
// //
// This is a device driver, so ChildHandle must be NULL. // This is a device driver, so ChildHandle must be NULL.
// //
@ -321,32 +295,26 @@ KeypadComponentNameGetControllerName (
// //
// Check Controller's handle // Check Controller's handle
// //
Status = EfiTestManagedDevice (ControllerHandle, gKeypadControllerDriver.DriverBindingHandle, &gEFIDroidKeypadDeviceProtocolGuid); Status = EfiTestManagedDevice(
if (EFI_ERROR (Status)) { ControllerHandle, gKeypadControllerDriver.DriverBindingHandle,
&gEFIDroidKeypadDeviceProtocolGuid);
if (EFI_ERROR(Status)) {
return Status; return Status;
} }
// //
// Get the device context // Get the device context
// //
Status = gBS->OpenProtocol ( Status = gBS->OpenProtocol(
ControllerHandle, ControllerHandle, &gEfiSimpleTextInProtocolGuid, (VOID **)&ConIn,
&gEfiSimpleTextInProtocolGuid, gKeypadControllerDriver.DriverBindingHandle, ControllerHandle,
(VOID **) &ConIn, EFI_OPEN_PROTOCOL_GET_PROTOCOL);
gKeypadControllerDriver.DriverBindingHandle, if (EFI_ERROR(Status)) {
ControllerHandle,
EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
if (EFI_ERROR (Status)) {
return Status; return Status;
} }
ConsoleIn = KEYPAD_CONSOLE_IN_DEV_FROM_THIS (ConIn); ConsoleIn = KEYPAD_CONSOLE_IN_DEV_FROM_THIS(ConIn);
return LookupUnicodeString2 ( return LookupUnicodeString2(
Language, Language, This->SupportedLanguages, ConsoleIn->ControllerNameTable,
This->SupportedLanguages, ControllerName, (BOOLEAN)(This == &gKeypadComponentName));
ConsoleIn->ControllerNameTable,
ControllerName,
(BOOLEAN)(This == &gKeypadComponentName)
);
} }

View File

@ -5,9 +5,9 @@
Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR> Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License are licensed and made available under the terms and conditions of the BSD
which accompanies this distribution. The full text of the license may be found at License which accompanies this distribution. The full text of the license may
http://opensource.org/licenses/bsd-license.php be found at http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
@ -32,11 +32,9 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/ **/
EFI_STATUS EFI_STATUS
EFIAPI EFIAPI
KeypadControllerDriverSupported ( KeypadControllerDriverSupported(
IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE Controller,
IN EFI_HANDLE Controller, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath);
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
);
/** /**
Create KEYPAD_CONSOLE_IN_DEV instance on controller. Create KEYPAD_CONSOLE_IN_DEV instance on controller.
@ -49,11 +47,9 @@ KeypadControllerDriverSupported (
**/ **/
EFI_STATUS EFI_STATUS
EFIAPI EFIAPI
KeypadControllerDriverStart ( KeypadControllerDriverStart(
IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE Controller,
IN EFI_HANDLE Controller, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath);
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
);
/** /**
Stop this driver on ControllerHandle. Support stopping any child handles Stop this driver on ControllerHandle. Support stopping any child handles
@ -71,12 +67,9 @@ KeypadControllerDriverStart (
**/ **/
EFI_STATUS EFI_STATUS
EFIAPI EFIAPI
KeypadControllerDriverStop ( KeypadControllerDriverStop(
IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE Controller,
IN EFI_HANDLE Controller, IN UINTN NumberOfChildren, IN EFI_HANDLE *ChildHandleBuffer);
IN UINTN NumberOfChildren,
IN EFI_HANDLE *ChildHandleBuffer
);
/** /**
Free the waiting key notify list. Free the waiting key notify list.
@ -87,9 +80,7 @@ KeypadControllerDriverStop (
@retval EFI_SUCCESS Sucess to free NotifyList @retval EFI_SUCCESS Sucess to free NotifyList
**/ **/
EFI_STATUS EFI_STATUS
KbdFreeNotifyList ( KbdFreeNotifyList(IN OUT LIST_ENTRY *ListHead);
IN OUT LIST_ENTRY *ListHead
);
// //
// DriverBinding Protocol Instance // DriverBinding Protocol Instance
@ -100,8 +91,7 @@ EFI_DRIVER_BINDING_PROTOCOL gKeypadControllerDriver = {
KeypadControllerDriverStop, KeypadControllerDriverStop,
0xa, 0xa,
NULL, NULL,
NULL NULL};
};
/** /**
Test controller is a keypad Controller. Test controller is a keypad Controller.
@ -115,11 +105,9 @@ EFI_DRIVER_BINDING_PROTOCOL gKeypadControllerDriver = {
**/ **/
EFI_STATUS EFI_STATUS
EFIAPI EFIAPI
KeypadControllerDriverSupported ( KeypadControllerDriverSupported(
IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE Controller,
IN EFI_HANDLE Controller, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath)
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
)
{ {
EFI_STATUS Status; EFI_STATUS Status;
KEYPAD_DEVICE_PROTOCOL *KeypadDevice; KEYPAD_DEVICE_PROTOCOL *KeypadDevice;
@ -127,77 +115,65 @@ KeypadControllerDriverSupported (
// //
// Open the IO Abstraction(s) needed to perform the supported test // Open the IO Abstraction(s) needed to perform the supported test
// //
Status = gBS->OpenProtocol ( Status = gBS->OpenProtocol(
Controller, Controller, &gEFIDroidKeypadDeviceProtocolGuid, (VOID **)&KeypadDevice,
&gEFIDroidKeypadDeviceProtocolGuid, This->DriverBindingHandle, Controller, EFI_OPEN_PROTOCOL_BY_DRIVER);
(VOID **) &KeypadDevice, if (EFI_ERROR(Status)) {
This->DriverBindingHandle,
Controller,
EFI_OPEN_PROTOCOL_BY_DRIVER
);
if (EFI_ERROR (Status)) {
return Status; return Status;
} }
// //
// Close the I/O Abstraction(s) used to perform the supported test // Close the I/O Abstraction(s) used to perform the supported test
// //
gBS->CloseProtocol ( gBS->CloseProtocol(
Controller, Controller, &gEFIDroidKeypadDeviceProtocolGuid, This->DriverBindingHandle,
&gEFIDroidKeypadDeviceProtocolGuid, Controller);
This->DriverBindingHandle,
Controller
);
return Status; return Status;
} }
STATIC STATIC
VOID VOID EFIAPI
EFIAPI KeypadReturnApiPushEfikeyBufTail(KEYPAD_RETURN_API *This, EFI_KEY_DATA *KeyData)
KeypadReturnApiPushEfikeyBufTail (
KEYPAD_RETURN_API *This,
EFI_KEY_DATA *KeyData
)
{ {
KEYPAD_CONSOLE_IN_DEV *ConsoleIn; KEYPAD_CONSOLE_IN_DEV * ConsoleIn;
LIST_ENTRY *Link; LIST_ENTRY * Link;
KEYPAD_CONSOLE_IN_EX_NOTIFY *CurrentNotify; KEYPAD_CONSOLE_IN_EX_NOTIFY *CurrentNotify;
ConsoleIn = KEYPAD_CONSOLE_IN_DEV_FROM_KEYPAD_RETURN_API (This); ConsoleIn = KEYPAD_CONSOLE_IN_DEV_FROM_KEYPAD_RETURN_API(This);
// //
// If the key can not be converted then just return. // If the key can not be converted then just return.
// //
if (KeyData->Key.ScanCode == SCAN_NULL && KeyData->Key.UnicodeChar == CHAR_NULL) { if (KeyData->Key.ScanCode == SCAN_NULL &&
KeyData->Key.UnicodeChar == CHAR_NULL) {
if (!ConsoleIn->IsSupportPartialKey) { if (!ConsoleIn->IsSupportPartialKey) {
return; return;
} }
} }
// //
// Signal KeyNotify process event if this key pressed matches any key registered. // Signal KeyNotify process event if this key pressed matches any key
// registered.
// //
for (Link = GetFirstNode (&ConsoleIn->NotifyList); !IsNull (&ConsoleIn->NotifyList, Link); Link = GetNextNode (&ConsoleIn->NotifyList, Link)) { for (Link = GetFirstNode(&ConsoleIn->NotifyList);
CurrentNotify = CR ( !IsNull(&ConsoleIn->NotifyList, Link);
Link, Link = GetNextNode(&ConsoleIn->NotifyList, Link)) {
KEYPAD_CONSOLE_IN_EX_NOTIFY, CurrentNotify =
NotifyEntry, CR(Link, KEYPAD_CONSOLE_IN_EX_NOTIFY, NotifyEntry,
KEYPAD_CONSOLE_IN_EX_NOTIFY_SIGNATURE KEYPAD_CONSOLE_IN_EX_NOTIFY_SIGNATURE);
); if (IsKeyRegistered(&CurrentNotify->KeyData, KeyData)) {
if (IsKeyRegistered (&CurrentNotify->KeyData, KeyData)) {
// //
// The key notification function needs to run at TPL_CALLBACK // The key notification function needs to run at TPL_CALLBACK
// while current TPL is TPL_NOTIFY. It will be invoked in // while current TPL is TPL_NOTIFY. It will be invoked in
// KeyNotifyProcessHandler() which runs at TPL_CALLBACK. // KeyNotifyProcessHandler() which runs at TPL_CALLBACK.
// //
PushEfikeyBufTail (&ConsoleIn->EfiKeyQueueForNotify, KeyData); PushEfikeyBufTail(&ConsoleIn->EfiKeyQueueForNotify, KeyData);
gBS->SignalEvent (ConsoleIn->KeyNotifyProcessEvent); gBS->SignalEvent(ConsoleIn->KeyNotifyProcessEvent);
} }
} }
PushEfikeyBufTail (&ConsoleIn->EfiKeyQueue, KeyData); PushEfikeyBufTail(&ConsoleIn->EfiKeyQueue, KeyData);
} }
/** /**
@ -211,34 +187,27 @@ KeypadReturnApiPushEfikeyBufTail (
**/ **/
EFI_STATUS EFI_STATUS
EFIAPI EFIAPI
KeypadControllerDriverStart ( KeypadControllerDriverStart(
IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE Controller,
IN EFI_HANDLE Controller, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath)
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
)
{ {
EFI_STATUS Status; EFI_STATUS Status;
KEYPAD_DEVICE_PROTOCOL *KeypadDevice; KEYPAD_DEVICE_PROTOCOL *KeypadDevice;
KEYPAD_CONSOLE_IN_DEV *ConsoleIn; KEYPAD_CONSOLE_IN_DEV * ConsoleIn;
// //
// Get the ISA I/O Protocol on Controller's handle // Get the ISA I/O Protocol on Controller's handle
// //
Status = gBS->OpenProtocol ( Status = gBS->OpenProtocol(
Controller, Controller, &gEFIDroidKeypadDeviceProtocolGuid, (VOID **)&KeypadDevice,
&gEFIDroidKeypadDeviceProtocolGuid, This->DriverBindingHandle, Controller, EFI_OPEN_PROTOCOL_BY_DRIVER);
(VOID **) &KeypadDevice, if (EFI_ERROR(Status)) {
This->DriverBindingHandle,
Controller,
EFI_OPEN_PROTOCOL_BY_DRIVER
);
if (EFI_ERROR (Status)) {
return Status; return Status;
} }
// //
// Allocate private data // Allocate private data
// //
ConsoleIn = AllocateZeroPool (sizeof (KEYPAD_CONSOLE_IN_DEV)); ConsoleIn = AllocateZeroPool(sizeof(KEYPAD_CONSOLE_IN_DEV));
if (ConsoleIn == NULL) { if (ConsoleIn == NULL) {
Status = EFI_OUT_OF_RESOURCES; Status = EFI_OUT_OF_RESOURCES;
goto ErrorExit; goto ErrorExit;
@ -251,7 +220,8 @@ KeypadControllerDriverStart (
(ConsoleIn->ConIn).Reset = KeypadEfiReset; (ConsoleIn->ConIn).Reset = KeypadEfiReset;
(ConsoleIn->ConIn).ReadKeyStroke = KeypadReadKeyStroke; (ConsoleIn->ConIn).ReadKeyStroke = KeypadReadKeyStroke;
ConsoleIn->KeypadDevice = KeypadDevice; ConsoleIn->KeypadDevice = KeypadDevice;
ConsoleIn->KeypadReturnApi.PushEfikeyBufTail = KeypadReturnApiPushEfikeyBufTail; ConsoleIn->KeypadReturnApi.PushEfikeyBufTail =
KeypadReturnApiPushEfikeyBufTail;
ConsoleIn->Last = (UINT64)-1; ConsoleIn->Last = (UINT64)-1;
ConsoleIn->ConInEx.Reset = KeypadEfiResetEx; ConsoleIn->ConInEx.Reset = KeypadEfiResetEx;
@ -260,75 +230,56 @@ KeypadControllerDriverStart (
ConsoleIn->ConInEx.RegisterKeyNotify = KeypadRegisterKeyNotify; ConsoleIn->ConInEx.RegisterKeyNotify = KeypadRegisterKeyNotify;
ConsoleIn->ConInEx.UnregisterKeyNotify = KeypadUnregisterKeyNotify; ConsoleIn->ConInEx.UnregisterKeyNotify = KeypadUnregisterKeyNotify;
InitializeListHead (&ConsoleIn->NotifyList); InitializeListHead(&ConsoleIn->NotifyList);
// //
// Fix for random hangs in System waiting for the Key if no KBC is present in BIOS. // Fix for random hangs in System waiting for the Key if no KBC is present in
// When KBC decode (IO port 0x60/0x64 decode) is not enabled, // BIOS. When KBC decode (IO port 0x60/0x64 decode) is not enabled, KeypadRead
// KeypadRead will read back as 0xFF and return status is EFI_SUCCESS. // will read back as 0xFF and return status is EFI_SUCCESS. So instead we read
// So instead we read status register to detect after read if KBC decode is enabled. // status register to detect after read if KBC decode is enabled.
// //
// //
// Setup the WaitForKey event // Setup the WaitForKey event
// //
Status = gBS->CreateEvent ( Status = gBS->CreateEvent(
EVT_NOTIFY_WAIT, EVT_NOTIFY_WAIT, TPL_NOTIFY, KeypadWaitForKey, ConsoleIn,
TPL_NOTIFY, &((ConsoleIn->ConIn).WaitForKey));
KeypadWaitForKey, if (EFI_ERROR(Status)) {
ConsoleIn,
&((ConsoleIn->ConIn).WaitForKey)
);
if (EFI_ERROR (Status)) {
Status = EFI_OUT_OF_RESOURCES; Status = EFI_OUT_OF_RESOURCES;
goto ErrorExit; goto ErrorExit;
} }
// //
// Setup the WaitForKeyEx event // Setup the WaitForKeyEx event
// //
Status = gBS->CreateEvent ( Status = gBS->CreateEvent(
EVT_NOTIFY_WAIT, EVT_NOTIFY_WAIT, TPL_NOTIFY, KeypadWaitForKeyEx, ConsoleIn,
TPL_NOTIFY, &(ConsoleIn->ConInEx.WaitForKeyEx));
KeypadWaitForKeyEx, if (EFI_ERROR(Status)) {
ConsoleIn,
&(ConsoleIn->ConInEx.WaitForKeyEx)
);
if (EFI_ERROR (Status)) {
Status = EFI_OUT_OF_RESOURCES; Status = EFI_OUT_OF_RESOURCES;
goto ErrorExit; goto ErrorExit;
} }
// Setup a periodic timer, used for reading keystrokes at a fixed interval // Setup a periodic timer, used for reading keystrokes at a fixed interval
// //
Status = gBS->CreateEvent ( Status = gBS->CreateEvent(
EVT_TIMER | EVT_NOTIFY_SIGNAL, EVT_TIMER | EVT_NOTIFY_SIGNAL, TPL_NOTIFY, KeypadTimerHandler, ConsoleIn,
TPL_NOTIFY, &ConsoleIn->TimerEvent);
KeypadTimerHandler, if (EFI_ERROR(Status)) {
ConsoleIn,
&ConsoleIn->TimerEvent
);
if (EFI_ERROR (Status)) {
Status = EFI_OUT_OF_RESOURCES; Status = EFI_OUT_OF_RESOURCES;
goto ErrorExit; goto ErrorExit;
} }
Status = gBS->SetTimer ( Status = gBS->SetTimer(
ConsoleIn->TimerEvent, ConsoleIn->TimerEvent, TimerPeriodic, KEYPAD_TIMER_INTERVAL);
TimerPeriodic, if (EFI_ERROR(Status)) {
KEYPAD_TIMER_INTERVAL
);
if (EFI_ERROR (Status)) {
Status = EFI_OUT_OF_RESOURCES; Status = EFI_OUT_OF_RESOURCES;
goto ErrorExit; goto ErrorExit;
} }
Status = gBS->CreateEvent ( Status = gBS->CreateEvent(
EVT_NOTIFY_SIGNAL, EVT_NOTIFY_SIGNAL, TPL_CALLBACK, KeyNotifyProcessHandler, ConsoleIn,
TPL_CALLBACK, &ConsoleIn->KeyNotifyProcessEvent);
KeyNotifyProcessHandler, if (EFI_ERROR(Status)) {
ConsoleIn,
&ConsoleIn->KeyNotifyProcessEvent
);
if (EFI_ERROR (Status)) {
Status = EFI_OUT_OF_RESOURCES; Status = EFI_OUT_OF_RESOURCES;
goto ErrorExit; goto ErrorExit;
} }
@ -336,41 +287,27 @@ KeypadControllerDriverStart (
// //
// Reset the keypad device // Reset the keypad device
// //
Status = ConsoleIn->ConInEx.Reset (&ConsoleIn->ConInEx, FALSE); Status = ConsoleIn->ConInEx.Reset(&ConsoleIn->ConInEx, FALSE);
if (EFI_ERROR (Status)) { if (EFI_ERROR(Status)) {
Status = EFI_DEVICE_ERROR; Status = EFI_DEVICE_ERROR;
goto ErrorExit; goto ErrorExit;
} }
ConsoleIn->ControllerNameTable = NULL; ConsoleIn->ControllerNameTable = NULL;
AddUnicodeString2 ( AddUnicodeString2(
"eng", "eng", gKeypadComponentName.SupportedLanguages,
gKeypadComponentName.SupportedLanguages, &ConsoleIn->ControllerNameTable, L"Keypad Device", TRUE);
&ConsoleIn->ControllerNameTable, AddUnicodeString2(
L"Keypad Device", "en", gKeypadComponentName2.SupportedLanguages,
TRUE &ConsoleIn->ControllerNameTable, L"Keypad Device", FALSE);
);
AddUnicodeString2 (
"en",
gKeypadComponentName2.SupportedLanguages,
&ConsoleIn->ControllerNameTable,
L"Keypad Device",
FALSE
);
// //
// Install protocol interfaces for the keypad device. // Install protocol interfaces for the keypad device.
// //
Status = gBS->InstallMultipleProtocolInterfaces ( Status = gBS->InstallMultipleProtocolInterfaces(
&Controller, &Controller, &gEfiSimpleTextInProtocolGuid, &ConsoleIn->ConIn,
&gEfiSimpleTextInProtocolGuid, &gEfiSimpleTextInputExProtocolGuid, &ConsoleIn->ConInEx, NULL);
&ConsoleIn->ConIn, if (EFI_ERROR(Status)) {
&gEfiSimpleTextInputExProtocolGuid,
&ConsoleIn->ConInEx,
NULL
);
if (EFI_ERROR (Status)) {
goto ErrorExit; goto ErrorExit;
} }
@ -378,33 +315,30 @@ KeypadControllerDriverStart (
ErrorExit: ErrorExit:
if ((ConsoleIn != NULL) && (ConsoleIn->ConIn.WaitForKey != NULL)) { if ((ConsoleIn != NULL) && (ConsoleIn->ConIn.WaitForKey != NULL)) {
gBS->CloseEvent (ConsoleIn->ConIn.WaitForKey); gBS->CloseEvent(ConsoleIn->ConIn.WaitForKey);
} }
if ((ConsoleIn != NULL) && (ConsoleIn->TimerEvent != NULL)) { if ((ConsoleIn != NULL) && (ConsoleIn->TimerEvent != NULL)) {
gBS->CloseEvent (ConsoleIn->TimerEvent); gBS->CloseEvent(ConsoleIn->TimerEvent);
} }
if ((ConsoleIn != NULL) && (ConsoleIn->ConInEx.WaitForKeyEx != NULL)) { if ((ConsoleIn != NULL) && (ConsoleIn->ConInEx.WaitForKeyEx != NULL)) {
gBS->CloseEvent (ConsoleIn->ConInEx.WaitForKeyEx); gBS->CloseEvent(ConsoleIn->ConInEx.WaitForKeyEx);
} }
if ((ConsoleIn != NULL) && (ConsoleIn->KeyNotifyProcessEvent != NULL)) { if ((ConsoleIn != NULL) && (ConsoleIn->KeyNotifyProcessEvent != NULL)) {
gBS->CloseEvent (ConsoleIn->KeyNotifyProcessEvent); gBS->CloseEvent(ConsoleIn->KeyNotifyProcessEvent);
} }
KbdFreeNotifyList (&ConsoleIn->NotifyList); KbdFreeNotifyList(&ConsoleIn->NotifyList);
if ((ConsoleIn != NULL) && (ConsoleIn->ControllerNameTable != NULL)) { if ((ConsoleIn != NULL) && (ConsoleIn->ControllerNameTable != NULL)) {
FreeUnicodeStringTable (ConsoleIn->ControllerNameTable); FreeUnicodeStringTable(ConsoleIn->ControllerNameTable);
} }
if (ConsoleIn != NULL) { if (ConsoleIn != NULL) {
gBS->FreePool (ConsoleIn); gBS->FreePool(ConsoleIn);
} }
gBS->CloseProtocol ( gBS->CloseProtocol(
Controller, Controller, &gEFIDroidKeypadDeviceProtocolGuid, This->DriverBindingHandle,
&gEFIDroidKeypadDeviceProtocolGuid, Controller);
This->DriverBindingHandle,
Controller
);
return Status; return Status;
} }
@ -425,90 +359,69 @@ ErrorExit:
**/ **/
EFI_STATUS EFI_STATUS
EFIAPI EFIAPI
KeypadControllerDriverStop ( KeypadControllerDriverStop(
IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE Controller,
IN EFI_HANDLE Controller, IN UINTN NumberOfChildren, IN EFI_HANDLE *ChildHandleBuffer)
IN UINTN NumberOfChildren,
IN EFI_HANDLE *ChildHandleBuffer
)
{ {
EFI_STATUS Status; EFI_STATUS Status;
EFI_SIMPLE_TEXT_INPUT_PROTOCOL *ConIn; EFI_SIMPLE_TEXT_INPUT_PROTOCOL *ConIn;
KEYPAD_CONSOLE_IN_DEV *ConsoleIn; KEYPAD_CONSOLE_IN_DEV * ConsoleIn;
// //
// Disable Keypad // Disable Keypad
// //
Status = gBS->OpenProtocol ( Status = gBS->OpenProtocol(
Controller, Controller, &gEfiSimpleTextInProtocolGuid, (VOID **)&ConIn,
&gEfiSimpleTextInProtocolGuid, This->DriverBindingHandle, Controller, EFI_OPEN_PROTOCOL_GET_PROTOCOL);
(VOID **) &ConIn, if (EFI_ERROR(Status)) {
This->DriverBindingHandle,
Controller,
EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
if (EFI_ERROR (Status)) {
return Status; return Status;
} }
Status = gBS->OpenProtocol ( Status = gBS->OpenProtocol(
Controller, Controller, &gEfiSimpleTextInputExProtocolGuid, NULL,
&gEfiSimpleTextInputExProtocolGuid, This->DriverBindingHandle, Controller, EFI_OPEN_PROTOCOL_TEST_PROTOCOL);
NULL, if (EFI_ERROR(Status)) {
This->DriverBindingHandle,
Controller,
EFI_OPEN_PROTOCOL_TEST_PROTOCOL
);
if (EFI_ERROR (Status)) {
return Status; return Status;
} }
ConsoleIn = KEYPAD_CONSOLE_IN_DEV_FROM_THIS (ConIn); ConsoleIn = KEYPAD_CONSOLE_IN_DEV_FROM_THIS(ConIn);
if (ConsoleIn->TimerEvent != NULL) { if (ConsoleIn->TimerEvent != NULL) {
gBS->CloseEvent (ConsoleIn->TimerEvent); gBS->CloseEvent(ConsoleIn->TimerEvent);
ConsoleIn->TimerEvent = NULL; ConsoleIn->TimerEvent = NULL;
} }
// //
// Uninstall the SimpleTextIn and SimpleTextInEx protocols // Uninstall the SimpleTextIn and SimpleTextInEx protocols
// //
Status = gBS->UninstallMultipleProtocolInterfaces ( Status = gBS->UninstallMultipleProtocolInterfaces(
Controller, Controller, &gEfiSimpleTextInProtocolGuid, &ConsoleIn->ConIn,
&gEfiSimpleTextInProtocolGuid, &gEfiSimpleTextInputExProtocolGuid, &ConsoleIn->ConInEx, NULL);
&ConsoleIn->ConIn, if (EFI_ERROR(Status)) {
&gEfiSimpleTextInputExProtocolGuid,
&ConsoleIn->ConInEx,
NULL
);
if (EFI_ERROR (Status)) {
return Status; return Status;
} }
gBS->CloseProtocol ( gBS->CloseProtocol(
Controller, Controller, &gEFIDroidKeypadDeviceProtocolGuid, This->DriverBindingHandle,
&gEFIDroidKeypadDeviceProtocolGuid, Controller);
This->DriverBindingHandle,
Controller
);
// //
// Free other resources // Free other resources
// //
if ((ConsoleIn->ConIn).WaitForKey != NULL) { if ((ConsoleIn->ConIn).WaitForKey != NULL) {
gBS->CloseEvent ((ConsoleIn->ConIn).WaitForKey); gBS->CloseEvent((ConsoleIn->ConIn).WaitForKey);
(ConsoleIn->ConIn).WaitForKey = NULL; (ConsoleIn->ConIn).WaitForKey = NULL;
} }
if (ConsoleIn->ConInEx.WaitForKeyEx != NULL) { if (ConsoleIn->ConInEx.WaitForKeyEx != NULL) {
gBS->CloseEvent (ConsoleIn->ConInEx.WaitForKeyEx); gBS->CloseEvent(ConsoleIn->ConInEx.WaitForKeyEx);
ConsoleIn->ConInEx.WaitForKeyEx = NULL; ConsoleIn->ConInEx.WaitForKeyEx = NULL;
} }
if (ConsoleIn->KeyNotifyProcessEvent != NULL) { if (ConsoleIn->KeyNotifyProcessEvent != NULL) {
gBS->CloseEvent (ConsoleIn->KeyNotifyProcessEvent); gBS->CloseEvent(ConsoleIn->KeyNotifyProcessEvent);
ConsoleIn->KeyNotifyProcessEvent = NULL; ConsoleIn->KeyNotifyProcessEvent = NULL;
} }
KbdFreeNotifyList (&ConsoleIn->NotifyList); KbdFreeNotifyList(&ConsoleIn->NotifyList);
FreeUnicodeStringTable (ConsoleIn->ControllerNameTable); FreeUnicodeStringTable(ConsoleIn->ControllerNameTable);
gBS->FreePool (ConsoleIn); gBS->FreePool(ConsoleIn);
return EFI_SUCCESS; return EFI_SUCCESS;
} }
@ -522,24 +435,19 @@ KeypadControllerDriverStop (
@retval EFI_SUCCESS Sucess to free NotifyList @retval EFI_SUCCESS Sucess to free NotifyList
**/ **/
EFI_STATUS EFI_STATUS
KbdFreeNotifyList ( KbdFreeNotifyList(IN OUT LIST_ENTRY *ListHead)
IN OUT LIST_ENTRY *ListHead
)
{ {
KEYPAD_CONSOLE_IN_EX_NOTIFY *NotifyNode; KEYPAD_CONSOLE_IN_EX_NOTIFY *NotifyNode;
if (ListHead == NULL) { if (ListHead == NULL) {
return EFI_INVALID_PARAMETER; return EFI_INVALID_PARAMETER;
} }
while (!IsListEmpty (ListHead)) { while (!IsListEmpty(ListHead)) {
NotifyNode = CR ( NotifyNode =
ListHead->ForwardLink, CR(ListHead->ForwardLink, KEYPAD_CONSOLE_IN_EX_NOTIFY, NotifyEntry,
KEYPAD_CONSOLE_IN_EX_NOTIFY, KEYPAD_CONSOLE_IN_EX_NOTIFY_SIGNATURE);
NotifyEntry, RemoveEntryList(ListHead->ForwardLink);
KEYPAD_CONSOLE_IN_EX_NOTIFY_SIGNATURE gBS->FreePool(NotifyNode);
);
RemoveEntryList (ListHead->ForwardLink);
gBS->FreePool (NotifyNode);
} }
return EFI_SUCCESS; return EFI_SUCCESS;
@ -557,27 +465,17 @@ KbdFreeNotifyList (
**/ **/
EFI_STATUS EFI_STATUS
EFIAPI EFIAPI
InitializeKeypad( InitializeKeypad(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable)
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{ {
EFI_STATUS Status; EFI_STATUS Status;
// //
// Install driver model protocol(s). // Install driver model protocol(s).
// //
Status = EfiLibInstallDriverBindingComponentName2 ( Status = EfiLibInstallDriverBindingComponentName2(
ImageHandle, ImageHandle, SystemTable, &gKeypadControllerDriver, ImageHandle,
SystemTable, &gKeypadComponentName, &gKeypadComponentName2);
&gKeypadControllerDriver, ASSERT_EFI_ERROR(Status);
ImageHandle,
&gKeypadComponentName,
&gKeypadComponentName2
);
ASSERT_EFI_ERROR (Status);
return Status; return Status;
} }

View File

@ -3,9 +3,9 @@
Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR> Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License are licensed and made available under the terms and conditions of the BSD
which accompanies this distribution. The full text of the license may be found at License which accompanies this distribution. The full text of the license may
http://opensource.org/licenses/bsd-license.php be found at http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
@ -17,21 +17,21 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include <Uefi.h> #include <Uefi.h>
#include <Protocol/KeypadDevice.h>
#include <Protocol/SimpleTextIn.h> #include <Protocol/SimpleTextIn.h>
#include <Protocol/SimpleTextInEx.h> #include <Protocol/SimpleTextInEx.h>
#include <Protocol/KeypadDevice.h>
#include <Library/IoLib.h>
#include <Library/UefiDriverEntryPoint.h>
#include <Library/UefiLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/DebugLib.h>
#include <Library/UefiRuntimeServicesTableLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/BaseLib.h> #include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h> #include <Library/BaseMemoryLib.h>
#include <Library/TimerLib.h> #include <Library/DebugLib.h>
#include <Library/IoLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/PcdLib.h> #include <Library/PcdLib.h>
#include <Library/TimerLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiDriverEntryPoint.h>
#include <Library/UefiLib.h>
#include <Library/UefiRuntimeServicesTableLib.h>
// //
// Global Variables // Global Variables
@ -43,8 +43,8 @@ extern EFI_COMPONENT_NAME2_PROTOCOL gKeypadComponentName2;
// //
// Driver Private Data // Driver Private Data
// //
#define KEYPAD_CONSOLE_IN_DEV_SIGNATURE SIGNATURE_32 ('k', 'k', 'e', 'y') #define KEYPAD_CONSOLE_IN_DEV_SIGNATURE SIGNATURE_32('k', 'k', 'e', 'y')
#define KEYPAD_CONSOLE_IN_EX_NOTIFY_SIGNATURE SIGNATURE_32 ('k', 'c', 'e', 'n') #define KEYPAD_CONSOLE_IN_EX_NOTIFY_SIGNATURE SIGNATURE_32('k', 'c', 'e', 'n')
typedef struct _KEYPAD_CONSOLE_IN_EX_NOTIFY { typedef struct _KEYPAD_CONSOLE_IN_EX_NOTIFY {
UINTN Signature; UINTN Signature;
@ -111,14 +111,12 @@ typedef struct {
EFI_EVENT KeyNotifyProcessEvent; EFI_EVENT KeyNotifyProcessEvent;
} KEYPAD_CONSOLE_IN_DEV; } KEYPAD_CONSOLE_IN_DEV;
#define KEYPAD_CONSOLE_IN_DEV_FROM_KEYPAD_RETURN_API(a) CR (a, KEYPAD_CONSOLE_IN_DEV, KeypadReturnApi, KEYPAD_CONSOLE_IN_DEV_SIGNATURE) #define KEYPAD_CONSOLE_IN_DEV_FROM_KEYPAD_RETURN_API(a) \
#define KEYPAD_CONSOLE_IN_DEV_FROM_THIS(a) CR (a, KEYPAD_CONSOLE_IN_DEV, ConIn, KEYPAD_CONSOLE_IN_DEV_SIGNATURE) CR(a, KEYPAD_CONSOLE_IN_DEV, KeypadReturnApi, KEYPAD_CONSOLE_IN_DEV_SIGNATURE)
#define KEYPAD_CONSOLE_IN_DEV_FROM_THIS(a) \
CR(a, KEYPAD_CONSOLE_IN_DEV, ConIn, KEYPAD_CONSOLE_IN_DEV_SIGNATURE)
#define TEXT_INPUT_EX_KEYPAD_CONSOLE_IN_DEV_FROM_THIS(a) \ #define TEXT_INPUT_EX_KEYPAD_CONSOLE_IN_DEV_FROM_THIS(a) \
CR (a, \ CR(a, KEYPAD_CONSOLE_IN_DEV, ConInEx, KEYPAD_CONSOLE_IN_DEV_SIGNATURE)
KEYPAD_CONSOLE_IN_DEV, \
ConInEx, \
KEYPAD_CONSOLE_IN_DEV_SIGNATURE \
)
#define TABLE_END 0x0 #define TABLE_END 0x0
@ -128,7 +126,8 @@ typedef struct {
// Driver entry point // Driver entry point
// //
/** /**
The user Entry Point for module KeypadDxe. The user code starts with this function. The user Entry Point for module KeypadDxe. The user code starts with this
function.
@param[in] ImageHandle The firmware allocated handle for the EFI image. @param[in] ImageHandle The firmware allocated handle for the EFI image.
@param[in] SystemTable A pointer to the EFI System Table. @param[in] SystemTable A pointer to the EFI System Table.
@ -139,10 +138,8 @@ typedef struct {
**/ **/
EFI_STATUS EFI_STATUS
EFIAPI EFIAPI
InstallKeypadDriver ( InstallKeypadDriver(
IN EFI_HANDLE ImageHandle, IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable);
IN EFI_SYSTEM_TABLE *SystemTable
);
// //
// Other functions that are used among .c files // Other functions that are used among .c files
@ -154,12 +151,7 @@ InstallKeypadDriver (
@param Event Indicates the event that invoke this function. @param Event Indicates the event that invoke this function.
@param Context Indicates the calling context. @param Context Indicates the calling context.
**/ **/
VOID VOID EFIAPI KeyNotifyProcessHandler(IN EFI_EVENT Event, IN VOID *Context);
EFIAPI
KeyNotifyProcessHandler (
IN EFI_EVENT Event,
IN VOID *Context
);
/** /**
Perform 8042 controller and keypad Initialization. Perform 8042 controller and keypad Initialization.
@ -173,10 +165,8 @@ KeyNotifyProcessHandler (
@retval EFI_SUCCESS Success to init keypad @retval EFI_SUCCESS Success to init keypad
**/ **/
EFI_STATUS EFI_STATUS
InitKeypad ( InitKeypad(
IN OUT KEYPAD_CONSOLE_IN_DEV *ConsoleIn, IN OUT KEYPAD_CONSOLE_IN_DEV *ConsoleIn, IN BOOLEAN ExtendedVerification);
IN BOOLEAN ExtendedVerification
);
/** /**
Timer event handler: read a series of scancodes from 8042 Timer event handler: read a series of scancodes from 8042
@ -189,12 +179,7 @@ InitKeypad (
@param Context - A KEYPAD_CONSOLE_IN_DEV pointer @param Context - A KEYPAD_CONSOLE_IN_DEV pointer
**/ **/
VOID VOID EFIAPI KeypadTimerHandler(IN EFI_EVENT Event, IN VOID *Context);
EFIAPI
KeypadTimerHandler (
IN EFI_EVENT Event,
IN VOID *Context
);
/** /**
logic reset keypad logic reset keypad
@ -203,16 +188,14 @@ KeypadTimerHandler (
@param This Pointer to instance of EFI_SIMPLE_TEXT_INPUT_PROTOCOL @param This Pointer to instance of EFI_SIMPLE_TEXT_INPUT_PROTOCOL
@param ExtendedVerification Indicate that the driver may perform a more @param ExtendedVerification Indicate that the driver may perform a more
exhaustive verification operation of the device during exhaustive verification operation of the device
reset, now this par is ignored in this driver during reset, now this par is ignored in this driver
**/ **/
EFI_STATUS EFI_STATUS
EFIAPI EFIAPI
KeypadEfiReset ( KeypadEfiReset(
IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This, IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This, IN BOOLEAN ExtendedVerification);
IN BOOLEAN ExtendedVerification
);
/** /**
Implement SIMPLE_TEXT_IN.ReadKeyStroke(). Implement SIMPLE_TEXT_IN.ReadKeyStroke().
@ -225,10 +208,8 @@ KeypadEfiReset (
**/ **/
EFI_STATUS EFI_STATUS
EFIAPI EFIAPI
KeypadReadKeyStroke ( KeypadReadKeyStroke(
IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This, IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This, OUT EFI_INPUT_KEY *Key);
OUT EFI_INPUT_KEY *Key
);
/** /**
Event notification function for SIMPLE_TEXT_IN.WaitForKey event Event notification function for SIMPLE_TEXT_IN.WaitForKey event
@ -238,27 +219,17 @@ KeypadReadKeyStroke (
@param Context waitting context @param Context waitting context
**/ **/
VOID VOID EFIAPI KeypadWaitForKey(IN EFI_EVENT Event, IN VOID *Context);
EFIAPI
KeypadWaitForKey (
IN EFI_EVENT Event,
IN VOID *Context
);
/** /**
Event notification function for SIMPLE_TEXT_INPUT_EX_PROTOCOL.WaitForKeyEx event Event notification function for SIMPLE_TEXT_INPUT_EX_PROTOCOL.WaitForKeyEx
Signal the event if there is key available event Signal the event if there is key available
@param Event event object @param Event event object
@param Context waiting context @param Context waiting context
**/ **/
VOID VOID EFIAPI KeypadWaitForKeyEx(IN EFI_EVENT Event, IN VOID *Context);
EFIAPI
KeypadWaitForKeyEx (
IN EFI_EVENT Event,
IN VOID *Context
);
// //
// Simple Text Input Ex protocol function prototypes // Simple Text Input Ex protocol function prototypes
@ -271,16 +242,15 @@ KeypadWaitForKeyEx (
@param ExtendedVerification - Driver may perform diagnostics on reset. @param ExtendedVerification - Driver may perform diagnostics on reset.
@retval EFI_SUCCESS - The device was reset. @retval EFI_SUCCESS - The device was reset.
@retval EFI_DEVICE_ERROR - The device is not functioning properly and could @retval EFI_DEVICE_ERROR - The device is not functioning properly and
not be reset. could not be reset.
**/ **/
EFI_STATUS EFI_STATUS
EFIAPI EFIAPI
KeypadEfiResetEx ( KeypadEfiResetEx(
IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This, IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
IN BOOLEAN ExtendedVerification IN BOOLEAN ExtendedVerification);
);
/** /**
Reads the next keystroke from the input device. The WaitForKey Event can Reads the next keystroke from the input device. The WaitForKey Event can
@ -288,22 +258,20 @@ KeypadEfiResetEx (
@param This - Protocol instance pointer. @param This - Protocol instance pointer.
@param KeyData - A pointer to a buffer that is filled in with the keystroke @param KeyData - A pointer to a buffer that is filled in with the
state data for the key that was pressed. keystroke state data for the key that was pressed.
@retval EFI_SUCCESS - The keystroke information was returned. @retval EFI_SUCCESS - The keystroke information was returned.
@retval EFI_NOT_READY - There was no keystroke data availiable. @retval EFI_NOT_READY - There was no keystroke data availiable.
@retval EFI_DEVICE_ERROR - The keystroke information was not returned due to @retval EFI_DEVICE_ERROR - The keystroke information was not returned
hardware errors. due to hardware errors.
@retval EFI_INVALID_PARAMETER - KeyData is NULL. @retval EFI_INVALID_PARAMETER - KeyData is NULL.
**/ **/
EFI_STATUS EFI_STATUS
EFIAPI EFIAPI
KeypadReadKeyStrokeEx ( KeypadReadKeyStrokeEx(
IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This, IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This, OUT EFI_KEY_DATA *KeyData);
OUT EFI_KEY_DATA *KeyData
);
/** /**
Set certain state for the input device. Set certain state for the input device.
@ -313,61 +281,64 @@ KeypadReadKeyStrokeEx (
state for the input device. state for the input device.
@retval EFI_SUCCESS - The device state was set successfully. @retval EFI_SUCCESS - The device state was set successfully.
@retval EFI_DEVICE_ERROR - The device is not functioning correctly and could @retval EFI_DEVICE_ERROR - The device is not functioning correctly and
not have the setting adjusted. could not have the setting adjusted.
@retval EFI_UNSUPPORTED - The device does not have the ability to set its state. @retval EFI_UNSUPPORTED - The device does not have the ability to set
its state.
@retval EFI_INVALID_PARAMETER - KeyToggleState is NULL. @retval EFI_INVALID_PARAMETER - KeyToggleState is NULL.
**/ **/
EFI_STATUS EFI_STATUS
EFIAPI EFIAPI
KeypadSetState ( KeypadSetState(
IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This, IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
IN EFI_KEY_TOGGLE_STATE *KeyToggleState IN EFI_KEY_TOGGLE_STATE *KeyToggleState);
);
/** /**
Register a notification function for a particular keystroke for the input device. Register a notification function for a particular keystroke for the input
device.
@param This - Protocol instance pointer. @param This - Protocol instance pointer.
@param KeyData - A pointer to a buffer that is filled in with the keystroke @param KeyData - A pointer to a buffer that is filled in
information data for the key that was pressed. with the keystroke information data for the key that was pressed.
@param KeyNotificationFunction - Points to the function to be called when the key @param KeyNotificationFunction - Points to the function to be called when
sequence is typed specified by KeyData. the key sequence is typed specified by KeyData.
@param NotifyHandle - Points to the unique handle assigned to the registered notification. @param NotifyHandle - Points to the unique handle assigned to the
registered notification.
@retval EFI_SUCCESS - The notification function was registered successfully. @retval EFI_SUCCESS - The notification function was registered
@retval EFI_OUT_OF_RESOURCES - Unable to allocate resources for necesssary data structures. successfully.
@retval EFI_OUT_OF_RESOURCES - Unable to allocate resources for
necesssary data structures.
@retval EFI_INVALID_PARAMETER - KeyData or NotifyHandle is NULL. @retval EFI_INVALID_PARAMETER - KeyData or NotifyHandle is NULL.
**/ **/
EFI_STATUS EFI_STATUS
EFIAPI EFIAPI
KeypadRegisterKeyNotify ( KeypadRegisterKeyNotify(
IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This, IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This, IN EFI_KEY_DATA *KeyData,
IN EFI_KEY_DATA *KeyData,
IN EFI_KEY_NOTIFY_FUNCTION KeyNotificationFunction, IN EFI_KEY_NOTIFY_FUNCTION KeyNotificationFunction,
OUT VOID **NotifyHandle OUT VOID **NotifyHandle);
);
/** /**
Remove a registered notification function from a particular keystroke. Remove a registered notification function from a particular keystroke.
@param This - Protocol instance pointer. @param This - Protocol instance pointer.
@param NotificationHandle - The handle of the notification function being unregistered. @param NotificationHandle - The handle of the notification function
being unregistered.
@retval EFI_SUCCESS - The notification function was unregistered successfully. @retval EFI_SUCCESS - The notification function was unregistered
successfully.
@retval EFI_INVALID_PARAMETER - The NotificationHandle is invalid. @retval EFI_INVALID_PARAMETER - The NotificationHandle is invalid.
@retval EFI_NOT_FOUND - Can not find the matching entry in database. @retval EFI_NOT_FOUND - Can not find the matching entry in
database.
**/ **/
EFI_STATUS EFI_STATUS
EFIAPI EFIAPI
KeypadUnregisterKeyNotify ( KeypadUnregisterKeyNotify(
IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This, IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This, IN VOID *NotificationHandle);
IN VOID *NotificationHandle
);
/** /**
Push one key data to the EFI key buffer. Push one key data to the EFI key buffer.
@ -375,28 +346,21 @@ KeypadUnregisterKeyNotify (
@param Queue Pointer to instance of EFI_KEY_QUEUE. @param Queue Pointer to instance of EFI_KEY_QUEUE.
@param KeyData The key data to push. @param KeyData The key data to push.
**/ **/
VOID VOID PushEfikeyBufTail(IN EFI_KEY_QUEUE *Queue, IN EFI_KEY_DATA *KeyData);
PushEfikeyBufTail (
IN EFI_KEY_QUEUE *Queue,
IN EFI_KEY_DATA *KeyData
);
/** /**
Judge whether is a registed key Judge whether is a registed key
@param RegsiteredData A pointer to a buffer that is filled in with the keystroke @param RegsiteredData A pointer to a buffer that is filled in with the
state data for the key that was registered. keystroke state data for the key that was registered.
@param InputData A pointer to a buffer that is filled in with the keystroke @param InputData A pointer to a buffer that is filled in with the
state data for the key that was pressed. keystroke state data for the key that was pressed.
@retval TRUE Key be pressed matches a registered key. @retval TRUE Key be pressed matches a registered key.
@retval FLASE Match failed. @retval FLASE Match failed.
**/ **/
BOOLEAN BOOLEAN
IsKeyRegistered ( IsKeyRegistered(IN EFI_KEY_DATA *RegsiteredData, IN EFI_KEY_DATA *InputData);
IN EFI_KEY_DATA *RegsiteredData,
IN EFI_KEY_DATA *InputData
);
#endif #endif

View File

@ -3,9 +3,9 @@
Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR> Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License are licensed and made available under the terms and conditions of the BSD
which accompanies this distribution. The full text of the license may be found at License which accompanies this distribution. The full text of the license may
http://opensource.org/licenses/bsd-license.php be found at http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
@ -21,11 +21,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
@param ErrMsg Unicode string of error message @param ErrMsg Unicode string of error message
**/ **/
VOID VOID KeypadError(IN KEYPAD_CONSOLE_IN_DEV *ConsoleIn, IN CHAR16 *ErrMsg)
KeypadError (
IN KEYPAD_CONSOLE_IN_DEV *ConsoleIn,
IN CHAR16 *ErrMsg
)
{ {
ConsoleIn->KeypadErr = TRUE; ConsoleIn->KeypadErr = TRUE;
} }
@ -41,42 +37,39 @@ KeypadError (
@param Context A KEYPAD_CONSOLE_IN_DEV pointer @param Context A KEYPAD_CONSOLE_IN_DEV pointer
**/ **/
VOID VOID EFIAPI KeypadTimerHandler(IN EFI_EVENT Event, IN VOID *Context)
EFIAPI
KeypadTimerHandler (
IN EFI_EVENT Event,
IN VOID *Context
)
{ {
EFI_TPL OldTpl; EFI_TPL OldTpl;
KEYPAD_CONSOLE_IN_DEV *ConsoleIn; KEYPAD_CONSOLE_IN_DEV *ConsoleIn;
ConsoleIn = (KEYPAD_CONSOLE_IN_DEV *) Context; ConsoleIn = (KEYPAD_CONSOLE_IN_DEV *)Context;
// //
// Enter critical section // Enter critical section
// //
OldTpl = gBS->RaiseTPL (TPL_NOTIFY); OldTpl = gBS->RaiseTPL(TPL_NOTIFY);
if (((KEYPAD_CONSOLE_IN_DEV *) Context)->KeypadErr) { if (((KEYPAD_CONSOLE_IN_DEV *)Context)->KeypadErr) {
// //
// Leave critical section and return // Leave critical section and return
// //
gBS->RestoreTPL (OldTpl); gBS->RestoreTPL(OldTpl);
return ; return;
} }
UINT64 CurrentCounterValue = GetPerformanceCounter(); UINT64 CurrentCounterValue = GetPerformanceCounter();
UINT64 DeltaCounter = CurrentCounterValue - ConsoleIn->Last; UINT64 DeltaCounter = CurrentCounterValue - ConsoleIn->Last;
ConsoleIn->Last = CurrentCounterValue; ConsoleIn->Last = CurrentCounterValue;
ConsoleIn->KeypadDevice->GetKeys(ConsoleIn->KeypadDevice, &ConsoleIn->KeypadReturnApi, GetTimeInNanoSecond(DeltaCounter)); ConsoleIn->KeypadDevice->GetKeys(
ConsoleIn->KeypadDevice, &ConsoleIn->KeypadReturnApi,
GetTimeInNanoSecond(DeltaCounter));
// //
// Leave critical section and return // Leave critical section and return
// //
gBS->RestoreTPL (OldTpl); gBS->RestoreTPL(OldTpl);
} }
/** /**
@ -91,10 +84,8 @@ KeypadTimerHandler (
@retval EFI_SUCCESS Success to init keypad @retval EFI_SUCCESS Success to init keypad
**/ **/
EFI_STATUS EFI_STATUS
InitKeypad ( InitKeypad(
IN OUT KEYPAD_CONSOLE_IN_DEV *ConsoleIn, IN OUT KEYPAD_CONSOLE_IN_DEV *ConsoleIn, IN BOOLEAN ExtendedVerification)
IN BOOLEAN ExtendedVerification
)
{ {
EFI_STATUS Status; EFI_STATUS Status;
@ -129,10 +120,10 @@ InitKeypad (
ConsoleIn->IsSupportPartialKey = FALSE; ConsoleIn->IsSupportPartialKey = FALSE;
if (!EFI_ERROR (Status)) { if (!EFI_ERROR(Status)) {
return EFI_SUCCESS; return EFI_SUCCESS;
} else { }
else {
return EFI_DEVICE_ERROR; return EFI_DEVICE_ERROR;
} }
} }

View File

@ -4,16 +4,15 @@
Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR> Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License are licensed and made available under the terms and conditions of the BSD
which accompanies this distribution. The full text of the license may be found at License which accompanies this distribution. The full text of the license may
http://opensource.org/licenses/bsd-license.php be found at http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/ **/
#include "Keypad.h" #include "Keypad.h"
/** /**
@ -25,11 +24,9 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
@retval FALSE The EFI key buffer isn't empty. @retval FALSE The EFI key buffer isn't empty.
**/ **/
BOOLEAN BOOLEAN
IsEfikeyBufEmpty ( IsEfikeyBufEmpty(IN EFI_KEY_QUEUE *Queue)
IN EFI_KEY_QUEUE *Queue
)
{ {
return (BOOLEAN) (Queue->Head == Queue->Tail); return (BOOLEAN)(Queue->Head == Queue->Tail);
} }
/** /**
@ -42,19 +39,16 @@ IsEfikeyBufEmpty (
@retval EFI_NOT_READY There is no key data available. @retval EFI_NOT_READY There is no key data available.
**/ **/
EFI_STATUS EFI_STATUS
PopEfikeyBufHead ( PopEfikeyBufHead(IN EFI_KEY_QUEUE *Queue, OUT EFI_KEY_DATA *KeyData OPTIONAL)
IN EFI_KEY_QUEUE *Queue,
OUT EFI_KEY_DATA *KeyData OPTIONAL
)
{ {
if (IsEfikeyBufEmpty (Queue)) { if (IsEfikeyBufEmpty(Queue)) {
return EFI_NOT_READY; return EFI_NOT_READY;
} }
// //
// Retrieve and remove the values // Retrieve and remove the values
// //
if (KeyData != NULL) { if (KeyData != NULL) {
CopyMem (KeyData, &Queue->Buffer[Queue->Head], sizeof (EFI_KEY_DATA)); CopyMem(KeyData, &Queue->Buffer[Queue->Head], sizeof(EFI_KEY_DATA));
} }
Queue->Head = (Queue->Head + 1) % KEYPAD_EFI_KEY_MAX_COUNT; Queue->Head = (Queue->Head + 1) % KEYPAD_EFI_KEY_MAX_COUNT;
return EFI_SUCCESS; return EFI_SUCCESS;
@ -66,42 +60,35 @@ PopEfikeyBufHead (
@param Queue Pointer to instance of EFI_KEY_QUEUE. @param Queue Pointer to instance of EFI_KEY_QUEUE.
@param KeyData The key data to push. @param KeyData The key data to push.
**/ **/
VOID VOID PushEfikeyBufTail(IN EFI_KEY_QUEUE *Queue, IN EFI_KEY_DATA *KeyData)
PushEfikeyBufTail (
IN EFI_KEY_QUEUE *Queue,
IN EFI_KEY_DATA *KeyData
)
{ {
if ((Queue->Tail + 1) % KEYPAD_EFI_KEY_MAX_COUNT == Queue->Head) { if ((Queue->Tail + 1) % KEYPAD_EFI_KEY_MAX_COUNT == Queue->Head) {
// //
// If Queue is full, pop the one from head. // If Queue is full, pop the one from head.
// //
PopEfikeyBufHead (Queue, NULL); PopEfikeyBufHead(Queue, NULL);
} }
CopyMem (&Queue->Buffer[Queue->Tail], KeyData, sizeof (EFI_KEY_DATA)); CopyMem(&Queue->Buffer[Queue->Tail], KeyData, sizeof(EFI_KEY_DATA));
Queue->Tail = (Queue->Tail + 1) % KEYPAD_EFI_KEY_MAX_COUNT; Queue->Tail = (Queue->Tail + 1) % KEYPAD_EFI_KEY_MAX_COUNT;
} }
/** /**
Judge whether is a registed key Judge whether is a registed key
@param RegsiteredData A pointer to a buffer that is filled in with the keystroke @param RegsiteredData A pointer to a buffer that is filled in with the
state data for the key that was registered. keystroke state data for the key that was registered.
@param InputData A pointer to a buffer that is filled in with the keystroke @param InputData A pointer to a buffer that is filled in with the
state data for the key that was pressed. keystroke state data for the key that was pressed.
@retval TRUE Key be pressed matches a registered key. @retval TRUE Key be pressed matches a registered key.
@retval FLASE Match failed. @retval FLASE Match failed.
**/ **/
BOOLEAN BOOLEAN
IsKeyRegistered ( IsKeyRegistered(IN EFI_KEY_DATA *RegsiteredData, IN EFI_KEY_DATA *InputData)
IN EFI_KEY_DATA *RegsiteredData,
IN EFI_KEY_DATA *InputData
)
{ {
ASSERT (RegsiteredData != NULL && InputData != NULL); ASSERT(RegsiteredData != NULL && InputData != NULL);
if ((RegsiteredData->Key.ScanCode != InputData->Key.ScanCode) || if ((RegsiteredData->Key.ScanCode != InputData->Key.ScanCode) ||
(RegsiteredData->Key.UnicodeChar != InputData->Key.UnicodeChar)) { (RegsiteredData->Key.UnicodeChar != InputData->Key.UnicodeChar)) {
@ -109,19 +96,21 @@ IsKeyRegistered (
} }
// //
// Assume KeyShiftState/KeyToggleState = 0 in Registered key data means these state could be ignored. // Assume KeyShiftState/KeyToggleState = 0 in Registered key data means these
// state could be ignored.
// //
if (RegsiteredData->KeyState.KeyShiftState != 0 && if (RegsiteredData->KeyState.KeyShiftState != 0 &&
RegsiteredData->KeyState.KeyShiftState != InputData->KeyState.KeyShiftState) { RegsiteredData->KeyState.KeyShiftState !=
InputData->KeyState.KeyShiftState) {
return FALSE; return FALSE;
} }
if (RegsiteredData->KeyState.KeyToggleState != 0 && if (RegsiteredData->KeyState.KeyToggleState != 0 &&
RegsiteredData->KeyState.KeyToggleState != InputData->KeyState.KeyToggleState) { RegsiteredData->KeyState.KeyToggleState !=
InputData->KeyState.KeyToggleState) {
return FALSE; return FALSE;
} }
return TRUE; return TRUE;
} }
/** /**
@ -129,22 +118,20 @@ IsKeyRegistered (
be used to test for existance of a keystroke via WaitForEvent () call. be used to test for existance of a keystroke via WaitForEvent () call.
@param ConsoleInDev Keypad private structure @param ConsoleInDev Keypad private structure
@param KeyData A pointer to a buffer that is filled in with the keystroke @param KeyData A pointer to a buffer that is filled in with
state data for the key that was pressed. the keystroke state data for the key that was pressed.
@retval EFI_SUCCESS The keystroke information was returned. @retval EFI_SUCCESS The keystroke information was returned.
@retval EFI_NOT_READY There was no keystroke data availiable. @retval EFI_NOT_READY There was no keystroke data availiable.
@retval EFI_DEVICE_ERROR The keystroke information was not returned due to @retval EFI_DEVICE_ERROR The keystroke information was not returned
hardware errors. due to hardware errors.
@retval EFI_INVALID_PARAMETER KeyData is NULL. @retval EFI_INVALID_PARAMETER KeyData is NULL.
**/ **/
EFI_STATUS EFI_STATUS
KeypadReadKeyStrokeWorker ( KeypadReadKeyStrokeWorker(
IN KEYPAD_CONSOLE_IN_DEV *ConsoleInDev, IN KEYPAD_CONSOLE_IN_DEV *ConsoleInDev, OUT EFI_KEY_DATA *KeyData)
OUT EFI_KEY_DATA *KeyData
)
{ {
EFI_STATUS Status; EFI_STATUS Status;
@ -157,41 +144,42 @@ KeypadReadKeyStrokeWorker (
// //
// Enter critical section // Enter critical section
// //
OldTpl = gBS->RaiseTPL (TPL_NOTIFY); OldTpl = gBS->RaiseTPL(TPL_NOTIFY);
KeypadTimerHandler (NULL, ConsoleInDev); KeypadTimerHandler(NULL, ConsoleInDev);
if (ConsoleInDev->KeypadErr) { if (ConsoleInDev->KeypadErr) {
Status = EFI_DEVICE_ERROR; Status = EFI_DEVICE_ERROR;
} else { }
Status = PopEfikeyBufHead (&ConsoleInDev->EfiKeyQueue, KeyData); else {
Status = PopEfikeyBufHead(&ConsoleInDev->EfiKeyQueue, KeyData);
} }
gBS->RestoreTPL (OldTpl); gBS->RestoreTPL(OldTpl);
return Status; return Status;
} }
/** /**
Perform 8042 controller and keypad initialization which implement SIMPLE_TEXT_IN.Reset() Perform 8042 controller and keypad initialization which implement
SIMPLE_TEXT_IN.Reset()
@param This Pointer to instance of EFI_SIMPLE_TEXT_INPUT_PROTOCOL @param This Pointer to instance of
EFI_SIMPLE_TEXT_INPUT_PROTOCOL
@param ExtendedVerification Indicate that the driver may perform a more @param ExtendedVerification Indicate that the driver may perform a more
exhaustive verification operation of the device during exhaustive verification operation of the device
reset, now this par is ignored in this driver during reset, now this par is ignored in this driver
**/ **/
EFI_STATUS EFI_STATUS
EFIAPI EFIAPI
KeypadEfiReset ( KeypadEfiReset(
IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This, IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This, IN BOOLEAN ExtendedVerification)
IN BOOLEAN ExtendedVerification
)
{ {
EFI_STATUS Status; EFI_STATUS Status;
KEYPAD_CONSOLE_IN_DEV *ConsoleIn; KEYPAD_CONSOLE_IN_DEV *ConsoleIn;
EFI_TPL OldTpl; EFI_TPL OldTpl;
ConsoleIn = KEYPAD_CONSOLE_IN_DEV_FROM_THIS (This); ConsoleIn = KEYPAD_CONSOLE_IN_DEV_FROM_THIS(This);
if (ConsoleIn->KeypadErr) { if (ConsoleIn->KeypadErr) {
return EFI_DEVICE_ERROR; return EFI_DEVICE_ERROR;
} }
@ -199,30 +187,31 @@ KeypadEfiReset (
// //
// Enter critical section // Enter critical section
// //
OldTpl = gBS->RaiseTPL (TPL_NOTIFY); OldTpl = gBS->RaiseTPL(TPL_NOTIFY);
// //
// Call InitKeypad to initialize the keypad // Call InitKeypad to initialize the keypad
// //
Status = InitKeypad (ConsoleIn, ExtendedVerification); Status = InitKeypad(ConsoleIn, ExtendedVerification);
if (EFI_ERROR (Status)) { if (EFI_ERROR(Status)) {
// //
// Leave critical section and return // Leave critical section and return
// //
gBS->RestoreTPL (OldTpl); gBS->RestoreTPL(OldTpl);
return EFI_DEVICE_ERROR; return EFI_DEVICE_ERROR;
} }
// //
// Leave critical section and return // Leave critical section and return
// //
gBS->RestoreTPL (OldTpl); gBS->RestoreTPL(OldTpl);
return EFI_SUCCESS; return EFI_SUCCESS;
} }
/** /**
Retrieve key values for driver user which implement SIMPLE_TEXT_IN.ReadKeyStroke(). Retrieve key values for driver user which implement
SIMPLE_TEXT_IN.ReadKeyStroke().
@param This Pointer to instance of EFI_SIMPLE_TEXT_INPUT_PROTOCOL @param This Pointer to instance of EFI_SIMPLE_TEXT_INPUT_PROTOCOL
@param Key The output buffer for key value @param Key The output buffer for key value
@ -231,16 +220,14 @@ KeypadEfiReset (
**/ **/
EFI_STATUS EFI_STATUS
EFIAPI EFIAPI
KeypadReadKeyStroke ( KeypadReadKeyStroke(
IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This, IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This, OUT EFI_INPUT_KEY *Key)
OUT EFI_INPUT_KEY *Key
)
{ {
EFI_STATUS Status; EFI_STATUS Status;
KEYPAD_CONSOLE_IN_DEV *ConsoleIn; KEYPAD_CONSOLE_IN_DEV *ConsoleIn;
EFI_KEY_DATA KeyData; EFI_KEY_DATA KeyData;
ConsoleIn = KEYPAD_CONSOLE_IN_DEV_FROM_THIS (This); ConsoleIn = KEYPAD_CONSOLE_IN_DEV_FROM_THIS(This);
// //
// Considering if the partial keystroke is enabled, there maybe a partial // Considering if the partial keystroke is enabled, there maybe a partial
@ -251,29 +238,33 @@ KeypadReadKeyStroke (
// //
// If there is no pending key, then return. // If there is no pending key, then return.
// //
Status = KeypadReadKeyStrokeWorker (ConsoleIn, &KeyData); Status = KeypadReadKeyStrokeWorker(ConsoleIn, &KeyData);
if (EFI_ERROR (Status)) { if (EFI_ERROR(Status)) {
return Status; return Status;
} }
// //
// If it is partial keystroke, skip it. // If it is partial keystroke, skip it.
// //
if (KeyData.Key.ScanCode == SCAN_NULL && KeyData.Key.UnicodeChar == CHAR_NULL) { if (KeyData.Key.ScanCode == SCAN_NULL &&
KeyData.Key.UnicodeChar == CHAR_NULL) {
continue; continue;
} }
// //
// Translate the CTRL-Alpha characters to their corresponding control value // Translate the CTRL-Alpha characters to their corresponding control value
// (ctrl-a = 0x0001 through ctrl-Z = 0x001A) // (ctrl-a = 0x0001 through ctrl-Z = 0x001A)
// //
if ((KeyData.KeyState.KeyShiftState & (EFI_LEFT_CONTROL_PRESSED | EFI_RIGHT_CONTROL_PRESSED)) != 0) { if ((KeyData.KeyState.KeyShiftState &
(EFI_LEFT_CONTROL_PRESSED | EFI_RIGHT_CONTROL_PRESSED)) != 0) {
if (KeyData.Key.UnicodeChar >= L'a' && KeyData.Key.UnicodeChar <= L'z') { if (KeyData.Key.UnicodeChar >= L'a' && KeyData.Key.UnicodeChar <= L'z') {
KeyData.Key.UnicodeChar = (CHAR16) (KeyData.Key.UnicodeChar - L'a' + 1); KeyData.Key.UnicodeChar = (CHAR16)(KeyData.Key.UnicodeChar - L'a' + 1);
} else if (KeyData.Key.UnicodeChar >= L'A' && KeyData.Key.UnicodeChar <= L'Z') { }
KeyData.Key.UnicodeChar = (CHAR16) (KeyData.Key.UnicodeChar - L'A' + 1); else if (
KeyData.Key.UnicodeChar >= L'A' && KeyData.Key.UnicodeChar <= L'Z') {
KeyData.Key.UnicodeChar = (CHAR16)(KeyData.Key.UnicodeChar - L'A' + 1);
} }
} }
CopyMem (Key, &KeyData.Key, sizeof (EFI_INPUT_KEY)); CopyMem(Key, &KeyData.Key, sizeof(EFI_INPUT_KEY));
return EFI_SUCCESS; return EFI_SUCCESS;
} }
} }
@ -286,25 +277,20 @@ KeypadReadKeyStroke (
@param Context waitting context @param Context waitting context
**/ **/
VOID VOID EFIAPI KeypadWaitForKey(IN EFI_EVENT Event, IN VOID *Context)
EFIAPI
KeypadWaitForKey (
IN EFI_EVENT Event,
IN VOID *Context
)
{ {
EFI_TPL OldTpl; EFI_TPL OldTpl;
KEYPAD_CONSOLE_IN_DEV *ConsoleIn; KEYPAD_CONSOLE_IN_DEV *ConsoleIn;
EFI_KEY_DATA KeyData; EFI_KEY_DATA KeyData;
ConsoleIn = (KEYPAD_CONSOLE_IN_DEV *) Context; ConsoleIn = (KEYPAD_CONSOLE_IN_DEV *)Context;
// //
// Enter critical section // Enter critical section
// //
OldTpl = gBS->RaiseTPL (TPL_NOTIFY); OldTpl = gBS->RaiseTPL(TPL_NOTIFY);
KeypadTimerHandler (NULL, ConsoleIn); KeypadTimerHandler(NULL, ConsoleIn);
if (!ConsoleIn->KeypadErr) { if (!ConsoleIn->KeypadErr) {
// //
@ -313,46 +299,41 @@ KeypadWaitForKey (
// keystroke in the queue, so here skip the partial keystroke and get the // keystroke in the queue, so here skip the partial keystroke and get the
// next key from the queue // next key from the queue
// //
while (!IsEfikeyBufEmpty (&ConsoleIn->EfiKeyQueue)) { while (!IsEfikeyBufEmpty(&ConsoleIn->EfiKeyQueue)) {
CopyMem ( CopyMem(
&KeyData, &KeyData,
&(ConsoleIn->EfiKeyQueue.Buffer[ConsoleIn->EfiKeyQueue.Head]), &(ConsoleIn->EfiKeyQueue.Buffer[ConsoleIn->EfiKeyQueue.Head]),
sizeof (EFI_KEY_DATA) sizeof(EFI_KEY_DATA));
); if (KeyData.Key.ScanCode == SCAN_NULL &&
if (KeyData.Key.ScanCode == SCAN_NULL && KeyData.Key.UnicodeChar == CHAR_NULL) { KeyData.Key.UnicodeChar == CHAR_NULL) {
PopEfikeyBufHead (&ConsoleIn->EfiKeyQueue, &KeyData); PopEfikeyBufHead(&ConsoleIn->EfiKeyQueue, &KeyData);
continue; continue;
} }
// //
// if there is pending value key, signal the event. // if there is pending value key, signal the event.
// //
gBS->SignalEvent (Event); gBS->SignalEvent(Event);
break; break;
} }
} }
// //
// Leave critical section and return // Leave critical section and return
// //
gBS->RestoreTPL (OldTpl); gBS->RestoreTPL(OldTpl);
} }
/** /**
Event notification function for SIMPLE_TEXT_INPUT_EX_PROTOCOL.WaitForKeyEx event Event notification function for SIMPLE_TEXT_INPUT_EX_PROTOCOL.WaitForKeyEx
Signal the event if there is key available event Signal the event if there is key available
@param Event event object @param Event event object
@param Context waiting context @param Context waiting context
**/ **/
VOID VOID EFIAPI KeypadWaitForKeyEx(IN EFI_EVENT Event, IN VOID *Context)
EFIAPI
KeypadWaitForKeyEx (
IN EFI_EVENT Event,
IN VOID *Context
)
{ {
KeypadWaitForKey (Event, Context); KeypadWaitForKey(Event, Context);
} }
/** /**
@ -362,26 +343,21 @@ KeypadWaitForKeyEx (
@param ExtendedVerification Driver may perform diagnostics on reset. @param ExtendedVerification Driver may perform diagnostics on reset.
@retval EFI_SUCCESS The device was reset. @retval EFI_SUCCESS The device was reset.
@retval EFI_DEVICE_ERROR The device is not functioning properly and could @retval EFI_DEVICE_ERROR The device is not functioning properly and
not be reset. could not be reset.
**/ **/
EFI_STATUS EFI_STATUS
EFIAPI EFIAPI
KeypadEfiResetEx ( KeypadEfiResetEx(
IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This, IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This, IN BOOLEAN ExtendedVerification)
IN BOOLEAN ExtendedVerification
)
{ {
KEYPAD_CONSOLE_IN_DEV *ConsoleInDev; KEYPAD_CONSOLE_IN_DEV *ConsoleInDev;
ConsoleInDev = TEXT_INPUT_EX_KEYPAD_CONSOLE_IN_DEV_FROM_THIS (This); ConsoleInDev = TEXT_INPUT_EX_KEYPAD_CONSOLE_IN_DEV_FROM_THIS(This);
return ConsoleInDev->ConIn.Reset ( return ConsoleInDev->ConIn.Reset(&ConsoleInDev->ConIn, ExtendedVerification);
&ConsoleInDev->ConIn,
ExtendedVerification
);
} }
/** /**
@ -390,22 +366,20 @@ KeypadEfiResetEx (
@param This Protocol instance pointer. @param This Protocol instance pointer.
@param KeyData A pointer to a buffer that is filled in with the keystroke @param KeyData A pointer to a buffer that is filled in with the
state data for the key that was pressed. keystroke state data for the key that was pressed.
@retval EFI_SUCCESS The keystroke information was returned. @retval EFI_SUCCESS The keystroke information was returned.
@retval EFI_NOT_READY There was no keystroke data availiable. @retval EFI_NOT_READY There was no keystroke data availiable.
@retval EFI_DEVICE_ERROR The keystroke information was not returned due to @retval EFI_DEVICE_ERROR The keystroke information was not returned due
hardware errors. to hardware errors.
@retval EFI_INVALID_PARAMETER KeyData is NULL. @retval EFI_INVALID_PARAMETER KeyData is NULL.
**/ **/
EFI_STATUS EFI_STATUS
EFIAPI EFIAPI
KeypadReadKeyStrokeEx ( KeypadReadKeyStrokeEx(
IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This, IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This, OUT EFI_KEY_DATA *KeyData)
OUT EFI_KEY_DATA *KeyData
)
{ {
KEYPAD_CONSOLE_IN_DEV *ConsoleInDev; KEYPAD_CONSOLE_IN_DEV *ConsoleInDev;
@ -414,8 +388,8 @@ KeypadReadKeyStrokeEx (
return EFI_INVALID_PARAMETER; return EFI_INVALID_PARAMETER;
} }
ConsoleInDev = TEXT_INPUT_EX_KEYPAD_CONSOLE_IN_DEV_FROM_THIS (This); ConsoleInDev = TEXT_INPUT_EX_KEYPAD_CONSOLE_IN_DEV_FROM_THIS(This);
return KeypadReadKeyStrokeWorker (ConsoleInDev, KeyData); return KeypadReadKeyStrokeWorker(ConsoleInDev, KeyData);
} }
/** /**
@ -426,18 +400,18 @@ KeypadReadKeyStrokeEx (
state for the input device. state for the input device.
@retval EFI_SUCCESS The device state was set successfully. @retval EFI_SUCCESS The device state was set successfully.
@retval EFI_DEVICE_ERROR The device is not functioning correctly and could @retval EFI_DEVICE_ERROR The device is not functioning correctly and
not have the setting adjusted. could not have the setting adjusted.
@retval EFI_UNSUPPORTED The device does not have the ability to set its state. @retval EFI_UNSUPPORTED The device does not have the ability to set its
state.
@retval EFI_INVALID_PARAMETER KeyToggleState is NULL. @retval EFI_INVALID_PARAMETER KeyToggleState is NULL.
**/ **/
EFI_STATUS EFI_STATUS
EFIAPI EFIAPI
KeypadSetState ( KeypadSetState(
IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This, IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
IN EFI_KEY_TOGGLE_STATE *KeyToggleState IN EFI_KEY_TOGGLE_STATE *KeyToggleState)
)
{ {
EFI_STATUS Status; EFI_STATUS Status;
@ -448,12 +422,12 @@ KeypadSetState (
return EFI_INVALID_PARAMETER; return EFI_INVALID_PARAMETER;
} }
ConsoleInDev = TEXT_INPUT_EX_KEYPAD_CONSOLE_IN_DEV_FROM_THIS (This); ConsoleInDev = TEXT_INPUT_EX_KEYPAD_CONSOLE_IN_DEV_FROM_THIS(This);
// //
// Enter critical section // Enter critical section
// //
OldTpl = gBS->RaiseTPL (TPL_NOTIFY); OldTpl = gBS->RaiseTPL(TPL_NOTIFY);
if (ConsoleInDev->KeypadErr) { if (ConsoleInDev->KeypadErr) {
Status = EFI_DEVICE_ERROR; Status = EFI_DEVICE_ERROR;
@ -490,65 +464,66 @@ Exit:
// //
// Leave critical section and return // Leave critical section and return
// //
gBS->RestoreTPL (OldTpl); gBS->RestoreTPL(OldTpl);
return Status; return Status;
} }
/** /**
Register a notification function for a particular keystroke for the input device. Register a notification function for a particular keystroke for the input
device.
@param This Protocol instance pointer. @param This Protocol instance pointer.
@param KeyData A pointer to a buffer that is filled in with the keystroke @param KeyData A pointer to a buffer that is filled in
information data for the key that was pressed. with the keystroke information data for the key that was pressed.
@param KeyNotificationFunction Points to the function to be called when the key @param KeyNotificationFunction Points to the function to be called when
sequence is typed specified by KeyData. the key sequence is typed specified by KeyData.
@param NotifyHandle Points to the unique handle assigned to the registered notification. @param NotifyHandle Points to the unique handle assigned to
the registered notification.
@retval EFI_SUCCESS The notification function was registered successfully. @retval EFI_SUCCESS The notification function was registered
@retval EFI_OUT_OF_RESOURCES Unable to allocate resources for necesssary data structures. successfully.
@retval EFI_INVALID_PARAMETER KeyData or NotifyHandle or KeyNotificationFunction is NULL. @retval EFI_OUT_OF_RESOURCES Unable to allocate resources for
necesssary data structures.
@retval EFI_INVALID_PARAMETER KeyData or NotifyHandle or
KeyNotificationFunction is NULL.
**/ **/
EFI_STATUS EFI_STATUS
EFIAPI EFIAPI
KeypadRegisterKeyNotify ( KeypadRegisterKeyNotify(
IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This, IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This, IN EFI_KEY_DATA *KeyData,
IN EFI_KEY_DATA *KeyData, IN EFI_KEY_NOTIFY_FUNCTION KeyNotificationFunction, OUT VOID **NotifyHandle)
IN EFI_KEY_NOTIFY_FUNCTION KeyNotificationFunction,
OUT VOID **NotifyHandle
)
{ {
EFI_STATUS Status; EFI_STATUS Status;
KEYPAD_CONSOLE_IN_DEV *ConsoleInDev; KEYPAD_CONSOLE_IN_DEV * ConsoleInDev;
EFI_TPL OldTpl; EFI_TPL OldTpl;
LIST_ENTRY *Link; LIST_ENTRY * Link;
KEYPAD_CONSOLE_IN_EX_NOTIFY *CurrentNotify; KEYPAD_CONSOLE_IN_EX_NOTIFY *CurrentNotify;
KEYPAD_CONSOLE_IN_EX_NOTIFY *NewNotify; KEYPAD_CONSOLE_IN_EX_NOTIFY *NewNotify;
if (KeyData == NULL || NotifyHandle == NULL || KeyNotificationFunction == NULL) { if (KeyData == NULL || NotifyHandle == NULL ||
KeyNotificationFunction == NULL) {
return EFI_INVALID_PARAMETER; return EFI_INVALID_PARAMETER;
} }
ConsoleInDev = TEXT_INPUT_EX_KEYPAD_CONSOLE_IN_DEV_FROM_THIS (This); ConsoleInDev = TEXT_INPUT_EX_KEYPAD_CONSOLE_IN_DEV_FROM_THIS(This);
// //
// Enter critical section // Enter critical section
// //
OldTpl = gBS->RaiseTPL (TPL_NOTIFY); OldTpl = gBS->RaiseTPL(TPL_NOTIFY);
// //
// Return EFI_SUCCESS if the (KeyData, NotificationFunction) is already registered. // Return EFI_SUCCESS if the (KeyData, NotificationFunction) is already
// registered.
// //
for (Link = ConsoleInDev->NotifyList.ForwardLink; Link != &ConsoleInDev->NotifyList; Link = Link->ForwardLink) { for (Link = ConsoleInDev->NotifyList.ForwardLink;
CurrentNotify = CR ( Link != &ConsoleInDev->NotifyList; Link = Link->ForwardLink) {
Link, CurrentNotify =
KEYPAD_CONSOLE_IN_EX_NOTIFY, CR(Link, KEYPAD_CONSOLE_IN_EX_NOTIFY, NotifyEntry,
NotifyEntry, KEYPAD_CONSOLE_IN_EX_NOTIFY_SIGNATURE);
KEYPAD_CONSOLE_IN_EX_NOTIFY_SIGNATURE if (IsKeyRegistered(&CurrentNotify->KeyData, KeyData)) {
);
if (IsKeyRegistered (&CurrentNotify->KeyData, KeyData)) {
if (CurrentNotify->KeyNotificationFn == KeyNotificationFunction) { if (CurrentNotify->KeyNotificationFn == KeyNotificationFunction) {
*NotifyHandle = CurrentNotify; *NotifyHandle = CurrentNotify;
Status = EFI_SUCCESS; Status = EFI_SUCCESS;
@ -560,7 +535,8 @@ KeypadRegisterKeyNotify (
// //
// Allocate resource to save the notification function // Allocate resource to save the notification function
// //
NewNotify = (KEYPAD_CONSOLE_IN_EX_NOTIFY *) AllocateZeroPool (sizeof (KEYPAD_CONSOLE_IN_EX_NOTIFY)); NewNotify = (KEYPAD_CONSOLE_IN_EX_NOTIFY *)AllocateZeroPool(
sizeof(KEYPAD_CONSOLE_IN_EX_NOTIFY));
if (NewNotify == NULL) { if (NewNotify == NULL) {
Status = EFI_OUT_OF_RESOURCES; Status = EFI_OUT_OF_RESOURCES;
goto Exit; goto Exit;
@ -568,8 +544,8 @@ KeypadRegisterKeyNotify (
NewNotify->Signature = KEYPAD_CONSOLE_IN_EX_NOTIFY_SIGNATURE; NewNotify->Signature = KEYPAD_CONSOLE_IN_EX_NOTIFY_SIGNATURE;
NewNotify->KeyNotificationFn = KeyNotificationFunction; NewNotify->KeyNotificationFn = KeyNotificationFunction;
CopyMem (&NewNotify->KeyData, KeyData, sizeof (EFI_KEY_DATA)); CopyMem(&NewNotify->KeyData, KeyData, sizeof(EFI_KEY_DATA));
InsertTailList (&ConsoleInDev->NotifyList, &NewNotify->NotifyEntry); InsertTailList(&ConsoleInDev->NotifyList, &NewNotify->NotifyEntry);
*NotifyHandle = NewNotify; *NotifyHandle = NewNotify;
Status = EFI_SUCCESS; Status = EFI_SUCCESS;
@ -578,60 +554,57 @@ Exit:
// //
// Leave critical section and return // Leave critical section and return
// //
gBS->RestoreTPL (OldTpl); gBS->RestoreTPL(OldTpl);
return Status; return Status;
} }
/** /**
Remove a registered notification function from a particular keystroke. Remove a registered notification function from a particular keystroke.
@param This Protocol instance pointer. @param This Protocol instance pointer.
@param NotificationHandle The handle of the notification function being unregistered. @param NotificationHandle The handle of the notification function
being unregistered.
@retval EFI_SUCCESS The notification function was unregistered successfully. @retval EFI_SUCCESS The notification function was unregistered
successfully.
@retval EFI_INVALID_PARAMETER The NotificationHandle is invalid. @retval EFI_INVALID_PARAMETER The NotificationHandle is invalid.
**/ **/
EFI_STATUS EFI_STATUS
EFIAPI EFIAPI
KeypadUnregisterKeyNotify ( KeypadUnregisterKeyNotify(
IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This, IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This, IN VOID *NotificationHandle)
IN VOID *NotificationHandle
)
{ {
EFI_STATUS Status; EFI_STATUS Status;
KEYPAD_CONSOLE_IN_DEV *ConsoleInDev; KEYPAD_CONSOLE_IN_DEV * ConsoleInDev;
EFI_TPL OldTpl; EFI_TPL OldTpl;
LIST_ENTRY *Link; LIST_ENTRY * Link;
KEYPAD_CONSOLE_IN_EX_NOTIFY *CurrentNotify; KEYPAD_CONSOLE_IN_EX_NOTIFY *CurrentNotify;
if (NotificationHandle == NULL) { if (NotificationHandle == NULL) {
return EFI_INVALID_PARAMETER; return EFI_INVALID_PARAMETER;
} }
ConsoleInDev = TEXT_INPUT_EX_KEYPAD_CONSOLE_IN_DEV_FROM_THIS (This); ConsoleInDev = TEXT_INPUT_EX_KEYPAD_CONSOLE_IN_DEV_FROM_THIS(This);
// //
// Enter critical section // Enter critical section
// //
OldTpl = gBS->RaiseTPL (TPL_NOTIFY); OldTpl = gBS->RaiseTPL(TPL_NOTIFY);
for (Link = ConsoleInDev->NotifyList.ForwardLink; Link != &ConsoleInDev->NotifyList; Link = Link->ForwardLink) { for (Link = ConsoleInDev->NotifyList.ForwardLink;
CurrentNotify = CR ( Link != &ConsoleInDev->NotifyList; Link = Link->ForwardLink) {
Link, CurrentNotify =
KEYPAD_CONSOLE_IN_EX_NOTIFY, CR(Link, KEYPAD_CONSOLE_IN_EX_NOTIFY, NotifyEntry,
NotifyEntry, KEYPAD_CONSOLE_IN_EX_NOTIFY_SIGNATURE);
KEYPAD_CONSOLE_IN_EX_NOTIFY_SIGNATURE
);
if (CurrentNotify == NotificationHandle) { if (CurrentNotify == NotificationHandle) {
// //
// Remove the notification function from NotifyList and free resources // Remove the notification function from NotifyList and free resources
// //
RemoveEntryList (&CurrentNotify->NotifyEntry); RemoveEntryList(&CurrentNotify->NotifyEntry);
gBS->FreePool (CurrentNotify); gBS->FreePool(CurrentNotify);
Status = EFI_SUCCESS; Status = EFI_SUCCESS;
goto Exit; goto Exit;
} }
@ -645,7 +618,7 @@ Exit:
// //
// Leave critical section and return // Leave critical section and return
// //
gBS->RestoreTPL (OldTpl); gBS->RestoreTPL(OldTpl);
return Status; return Status;
} }
@ -655,22 +628,17 @@ Exit:
@param Event Indicates the event that invoke this function. @param Event Indicates the event that invoke this function.
@param Context Indicates the calling context. @param Context Indicates the calling context.
**/ **/
VOID VOID EFIAPI KeyNotifyProcessHandler(IN EFI_EVENT Event, IN VOID *Context)
EFIAPI
KeyNotifyProcessHandler (
IN EFI_EVENT Event,
IN VOID *Context
)
{ {
EFI_STATUS Status; EFI_STATUS Status;
KEYPAD_CONSOLE_IN_DEV *ConsoleIn; KEYPAD_CONSOLE_IN_DEV * ConsoleIn;
EFI_KEY_DATA KeyData; EFI_KEY_DATA KeyData;
LIST_ENTRY *Link; LIST_ENTRY * Link;
LIST_ENTRY *NotifyList; LIST_ENTRY * NotifyList;
KEYPAD_CONSOLE_IN_EX_NOTIFY *CurrentNotify; KEYPAD_CONSOLE_IN_EX_NOTIFY *CurrentNotify;
EFI_TPL OldTpl; EFI_TPL OldTpl;
ConsoleIn = (KEYPAD_CONSOLE_IN_DEV *) Context; ConsoleIn = (KEYPAD_CONSOLE_IN_DEV *)Context;
// //
// Invoke notification functions. // Invoke notification functions.
@ -680,21 +648,23 @@ KeyNotifyProcessHandler (
// //
// Enter critical section // Enter critical section
// //
OldTpl = gBS->RaiseTPL (TPL_NOTIFY); OldTpl = gBS->RaiseTPL(TPL_NOTIFY);
Status = PopEfikeyBufHead (&ConsoleIn->EfiKeyQueueForNotify, &KeyData); Status = PopEfikeyBufHead(&ConsoleIn->EfiKeyQueueForNotify, &KeyData);
// //
// Leave critical section // Leave critical section
// //
gBS->RestoreTPL (OldTpl); gBS->RestoreTPL(OldTpl);
if (EFI_ERROR (Status)) { if (EFI_ERROR(Status)) {
break; break;
} }
for (Link = GetFirstNode (NotifyList); !IsNull (NotifyList, Link); Link = GetNextNode (NotifyList, Link)) { for (Link = GetFirstNode(NotifyList); !IsNull(NotifyList, Link);
CurrentNotify = CR (Link, KEYPAD_CONSOLE_IN_EX_NOTIFY, NotifyEntry, KEYPAD_CONSOLE_IN_EX_NOTIFY_SIGNATURE); Link = GetNextNode(NotifyList, Link)) {
if (IsKeyRegistered (&CurrentNotify->KeyData, &KeyData)) { CurrentNotify =
CurrentNotify->KeyNotificationFn (&KeyData); CR(Link, KEYPAD_CONSOLE_IN_EX_NOTIFY, NotifyEntry,
KEYPAD_CONSOLE_IN_EX_NOTIFY_SIGNATURE);
if (IsKeyRegistered(&CurrentNotify->KeyData, &KeyData)) {
CurrentNotify->KeyNotificationFn(&KeyData);
} }
} }
} }
} }

View File

@ -20,9 +20,10 @@
#include "crc32.h" #include "crc32.h"
#include <Library/UefiLib.h> #include <Library/UefiLib.h>
EFI_STATUS FixGptCRC32(EFI_BLOCK_IO_PROTOCOL *mBlockIoProtocol, EFI_STATUS FixGptCRC32(
EFI_DISK_IO_PROTOCOL *mDiskIoProtocol, EFI_BLOCK_IO_PROTOCOL *mBlockIoProtocol,
EFI_SYSTEM_TABLE *mSystemTable){ EFI_DISK_IO_PROTOCOL *mDiskIoProtocol, EFI_SYSTEM_TABLE *mSystemTable)
{
EFI_STATUS status; EFI_STATUS status;
UINT32 mMediaId; UINT32 mMediaId;
UINT32 mBlockSize; UINT32 mBlockSize;
@ -33,28 +34,26 @@ EFI_STATUS FixGptCRC32(EFI_BLOCK_IO_PROTOCOL *mBlockIoProtocol,
unsigned char *bufGptHeader; unsigned char *bufGptHeader;
unsigned char *bufGptEntry; unsigned char *bufGptEntry;
// try to allocate pool for bufGptEntry // try to allocate pool for bufGptEntry
status = mSystemTable->BootServices->AllocatePool(EfiBootServicesCode, GPT_ENTRY_COUNT * mBlockSize, (VOID**)&bufGptEntry); status = mSystemTable->BootServices->AllocatePool(
EfiBootServicesCode, GPT_ENTRY_COUNT * mBlockSize, (VOID **)&bufGptEntry);
if (EFI_ERROR(status)) { if (EFI_ERROR(status)) {
return status; return status;
} }
// read gpt entry list // read gpt entry list
status = mDiskIoProtocol->ReadDisk(mDiskIoProtocol, status = mDiskIoProtocol->ReadDisk(
mMediaId, mDiskIoProtocol, mMediaId, 2 * mBlockSize, GPT_ENTRY_COUNT * mBlockSize,
2 * mBlockSize,
GPT_ENTRY_COUNT * mBlockSize,
bufGptEntry); bufGptEntry);
if (EFI_ERROR(status)) if (EFI_ERROR(status))
return status; return status;
// get gpt entry crc32 value // get gpt entry crc32 value
get_result_array(calculate_crc32(bufGptEntry, GPT_ENTRY_COUNT * mBlockSize), crc32_entry); get_result_array(
calculate_crc32(bufGptEntry, GPT_ENTRY_COUNT * mBlockSize), crc32_entry);
// write gpt entry crc32 value to disk // write gpt entry crc32 value to disk
status = mDiskIoProtocol->WriteDisk(mDiskIoProtocol, status = mDiskIoProtocol->WriteDisk(
mMediaId, mDiskIoProtocol, mMediaId, mBlockSize + GPT_ENTRY_CRC32_LBA1_OFFSET,
mBlockSize + GPT_ENTRY_CRC32_LBA1_OFFSET, GPT_CRC32_LEN, crc32_entry);
GPT_CRC32_LEN,
crc32_entry);
if (EFI_ERROR(status)) if (EFI_ERROR(status))
return status; return status;
// try to release bufGptEntry // try to release bufGptEntry
@ -63,27 +62,25 @@ EFI_STATUS FixGptCRC32(EFI_BLOCK_IO_PROTOCOL *mBlockIoProtocol,
return status; return status;
} }
// try to allocate pool for bufGptHeader // try to allocate pool for bufGptHeader
status = mSystemTable->BootServices->AllocatePool(EfiBootServicesCode, GPT_HEADER_SIZE, (VOID**)&bufGptHeader); status = mSystemTable->BootServices->AllocatePool(
EfiBootServicesCode, GPT_HEADER_SIZE, (VOID **)&bufGptHeader);
// get gpt header // get gpt header
status = mDiskIoProtocol->ReadDisk(mDiskIoProtocol, status = mDiskIoProtocol->ReadDisk(
mMediaId, mDiskIoProtocol, mMediaId, mBlockSize, GPT_HEADER_SIZE, bufGptHeader);
mBlockSize,
GPT_HEADER_SIZE,
bufGptHeader);
if (EFI_ERROR(status)) if (EFI_ERROR(status))
return status; return status;
// set previous crc32 value to 0x00 // set previous crc32 value to 0x00
for (int i = GPT_HEADER_CRC32_LBA1_OFFSET; i < GPT_HEADER_CRC32_LBA1_OFFSET + GPT_CRC32_LEN; i++) { for (int i = GPT_HEADER_CRC32_LBA1_OFFSET;
i < GPT_HEADER_CRC32_LBA1_OFFSET + GPT_CRC32_LEN; i++) {
bufGptHeader[i] = 0x00; bufGptHeader[i] = 0x00;
} }
// get gpt header crc32 value // get gpt header crc32 value
get_result_array(calculate_crc32(bufGptHeader, GPT_HEADER_SIZE), crc32_header); get_result_array(
calculate_crc32(bufGptHeader, GPT_HEADER_SIZE), crc32_header);
// write gpt header crc32 value to disk // write gpt header crc32 value to disk
status = mDiskIoProtocol->WriteDisk(mDiskIoProtocol, status = mDiskIoProtocol->WriteDisk(
mMediaId, mDiskIoProtocol, mMediaId, mBlockSize + GPT_HEADER_CRC32_LBA1_OFFSET,
mBlockSize + GPT_HEADER_CRC32_LBA1_OFFSET, GPT_CRC32_LEN, crc32_header);
GPT_CRC32_LEN,
crc32_header);
if (EFI_ERROR(status)) if (EFI_ERROR(status))
return status; return status;
// try to release bufGptHeader // try to release bufGptHeader
@ -95,8 +92,8 @@ EFI_STATUS FixGptCRC32(EFI_BLOCK_IO_PROTOCOL *mBlockIoProtocol,
} }
/* /*
* A8h reflected is 15h, i.e. 10101000 <--> 00010101 * A8h reflected is 15h, i.e. 10101000 <--> 00010101
*/ */
int reflect(int data, int len) int reflect(int data, int len)
{ {
int ref = 0; int ref = 0;
@ -112,8 +109,8 @@ int reflect(int data, int len)
} }
/* /*
* Function to calculate the CRC32 * Function to calculate the CRC32
*/ */
unsigned int calculate_crc32(unsigned char *buffer, int len) unsigned int calculate_crc32(unsigned char *buffer, int len)
{ {
int byte_length = 8; /*length of unit (i.e. byte) */ int byte_length = 8; /*length of unit (i.e. byte) */
@ -146,13 +143,12 @@ unsigned int calculate_crc32(unsigned char *buffer, int len)
} }
// Convert Function // Convert Function
//unsigned char** convert(unsigned int reflected_regs, int *size) // unsigned char** convert(unsigned int reflected_regs, int *size)
void get_result_array(unsigned int reflected_regs, unsigned char * res) void get_result_array(unsigned int reflected_regs, unsigned char *res)
{ {
for (int i = 0; i < 4; i++) { for (int i = 0; i < 4; i++) {
res[i] = reflected_regs & 0xff; res[i] = reflected_regs & 0xff;
reflected_regs >>= 8; reflected_regs >>= 8;
} }
} }

View File

@ -32,8 +32,9 @@
int reflect(int, int); int reflect(int, int);
unsigned int calculate_crc32(unsigned char*, int); unsigned int calculate_crc32(unsigned char *, int);
void get_result_array(unsigned int, unsigned char*); void get_result_array(unsigned int, unsigned char *);
EFI_STATUS FixGptCRC32(EFI_BLOCK_IO_PROTOCOL*, EFI_DISK_IO_PROTOCOL*, EFI_SYSTEM_TABLE*); EFI_STATUS FixGptCRC32(
EFI_BLOCK_IO_PROTOCOL *, EFI_DISK_IO_PROTOCOL *, EFI_SYSTEM_TABLE *);

View File

@ -16,22 +16,22 @@
* along with this program. If not, see <https://www.gnu.org/licenses/ * along with this program. If not, see <https://www.gnu.org/licenses/
*/ */
#include <Uefi.h>
#include <Library/UefiLib.h>
#include <Protocol/DiskIo.h>
#include <Protocol/BlockIo.h>
#include "slot.h" #include "slot.h"
#include "crc32.h" #include "crc32.h"
#include <Library/UefiLib.h>
#include <Protocol/BlockIo.h>
#include <Protocol/DiskIo.h>
#include <Uefi.h>
void WaitAnyKey(EFI_SYSTEM_TABLE *mSystemTable); void WaitAnyKey(EFI_SYSTEM_TABLE *mSystemTable);
EFI_STATUS EFIAPI SlotMain(IN EFI_HANDLE ImageHandle, EFI_STATUS EFIAPI
IN EFI_SYSTEM_TABLE *SystemTable) SlotMain(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable)
{ {
EFI_STATUS status; EFI_STATUS status;
EFI_HANDLE *controllerHandles = NULL; EFI_HANDLE * controllerHandles = NULL;
UINTN handleIndex, numHandles; UINTN handleIndex, numHandles;
EFI_DISK_IO_PROTOCOL *mDiskIoProtocol = NULL; EFI_DISK_IO_PROTOCOL * mDiskIoProtocol = NULL;
EFI_BLOCK_IO_PROTOCOL *mBlockIoProtocol = NULL; EFI_BLOCK_IO_PROTOCOL *mBlockIoProtocol = NULL;
UINT32 mMediaId; UINT32 mMediaId;
UINT32 mBlockSize; UINT32 mBlockSize;
@ -39,46 +39,42 @@ EFI_STATUS EFIAPI SlotMain(IN EFI_HANDLE ImageHandle,
unsigned char currentSlotA[OP6T_SLOT_FLAG_SIZE]; unsigned char currentSlotA[OP6T_SLOT_FLAG_SIZE];
unsigned char currentSlotB[OP6T_SLOT_FLAG_SIZE]; unsigned char currentSlotB[OP6T_SLOT_FLAG_SIZE];
// list all Handles that installed DiskIoProtocol // list all Handles that installed DiskIoProtocol
status = SystemTable->BootServices->LocateHandleBuffer(ByProtocol, status = SystemTable->BootServices->LocateHandleBuffer(
&gEfiDiskIoProtocolGuid, ByProtocol, &gEfiDiskIoProtocolGuid, NULL, &numHandles,
NULL,
&numHandles,
&controllerHandles); &controllerHandles);
if (EFI_ERROR(status)) { if (EFI_ERROR(status)) {
//WaitAnyKey(SystemTable); // WaitAnyKey(SystemTable);
return status; return status;
} }
// ergodic the handles // ergodic the handles
for (handleIndex = 0; handleIndex < numHandles; handleIndex++) { for (handleIndex = 0; handleIndex < numHandles; handleIndex++) {
// open DiskIoProtocol on target handle // open DiskIoProtocol on target handle
status = SystemTable->BootServices->HandleProtocol( status = SystemTable->BootServices->HandleProtocol(
controllerHandles[handleIndex], controllerHandles[handleIndex], &gEfiDiskIoProtocolGuid,
&gEfiDiskIoProtocolGuid, (VOID **)&mDiskIoProtocol);
(VOID**)&mDiskIoProtocol);
unsigned char slotNameBuffer[OP6T_SLOT_BOOT_BUFFER_LEN]; unsigned char slotNameBuffer[OP6T_SLOT_BOOT_BUFFER_LEN];
if (EFI_ERROR(status)) if (EFI_ERROR(status))
continue; continue;
// open BlockIoProtocol on target handle // open BlockIoProtocol on target handle
status = SystemTable->BootServices->HandleProtocol( status = SystemTable->BootServices->HandleProtocol(
controllerHandles[handleIndex], controllerHandles[handleIndex], &gEfiBlockIoProtocolGuid,
&gEfiBlockIoProtocolGuid, (VOID **)&mBlockIoProtocol);
(VOID**)&mBlockIoProtocol);
if (EFI_ERROR(status)) { if (EFI_ERROR(status)) {
continue; continue;
} else { }
else {
// filter disk device by LogicalPartition // filter disk device by LogicalPartition
if (mBlockIoProtocol->Media->LogicalPartition) if (mBlockIoProtocol->Media->LogicalPartition)
continue; continue;
SystemTable->ConOut->OutputString(SystemTable->ConOut, L"The media is disk.\n"); SystemTable->ConOut->OutputString(
SystemTable->ConOut, L"The media is disk.\n");
mMediaId = mBlockIoProtocol->Media->MediaId; mMediaId = mBlockIoProtocol->Media->MediaId;
mBlockSize = mBlockIoProtocol->Media->BlockSize; mBlockSize = mBlockIoProtocol->Media->BlockSize;
// read buffers from disk // read buffers from disk
status = mDiskIoProtocol->ReadDisk( status = mDiskIoProtocol->ReadDisk(
mDiskIoProtocol, mDiskIoProtocol, mMediaId,
mMediaId,
2 * mBlockSize + OP6T_SLOT_A_BOOT_BUFFER_LBA2_OFFSET, 2 * mBlockSize + OP6T_SLOT_A_BOOT_BUFFER_LBA2_OFFSET,
OP6T_SLOT_BOOT_BUFFER_LEN, OP6T_SLOT_BOOT_BUFFER_LEN, slotNameBuffer);
slotNameBuffer);
if (EFI_ERROR(status)) if (EFI_ERROR(status))
continue; continue;
// filter disk device by the name of boot partition // filter disk device by the name of boot partition
@ -91,23 +87,20 @@ EFI_STATUS EFIAPI SlotMain(IN EFI_HANDLE ImageHandle,
} }
if (i == 1) if (i == 1)
continue; continue;
SystemTable->ConOut->OutputString(SystemTable->ConOut, L"The name of target partition is matched.\n"); SystemTable->ConOut->OutputString(
SystemTable->ConOut, L"The name of target partition is matched.\n");
// read flag of slot A // read flag of slot A
status = mDiskIoProtocol->ReadDisk( status = mDiskIoProtocol->ReadDisk(
mDiskIoProtocol, mDiskIoProtocol, mMediaId,
mMediaId,
2 * mBlockSize + OP6T_SLOT_A_BOOT_FLAG_LBA2_OFFSET, 2 * mBlockSize + OP6T_SLOT_A_BOOT_FLAG_LBA2_OFFSET,
OP6T_SLOT_FLAG_SIZE, OP6T_SLOT_FLAG_SIZE, currentSlotA);
currentSlotA);
if (EFI_ERROR(status)) if (EFI_ERROR(status))
return status; return status;
// read flag of slot B // read flag of slot B
status = mDiskIoProtocol->ReadDisk( status = mDiskIoProtocol->ReadDisk(
mDiskIoProtocol, mDiskIoProtocol, mMediaId,
mMediaId,
3 * mBlockSize + OP6T_SLOT_B_BOOT_FLAG_LBA3_OFFSET, 3 * mBlockSize + OP6T_SLOT_B_BOOT_FLAG_LBA3_OFFSET,
OP6T_SLOT_FLAG_SIZE, OP6T_SLOT_FLAG_SIZE, currentSlotB);
currentSlotB);
if (EFI_ERROR(status)) if (EFI_ERROR(status))
return status; return status;
@ -125,44 +118,45 @@ EFI_STATUS EFIAPI SlotMain(IN EFI_HANDLE ImageHandle,
else else
flag_offset = 2 * mBlockSize + OP6T_SLOT_A_BOOT_FLAG_LBA2_OFFSET; flag_offset = 2 * mBlockSize + OP6T_SLOT_A_BOOT_FLAG_LBA2_OFFSET;
// write flag into disk // write flag into disk
unsigned char f[1] = {OP6T_SLOT_FLAG_ACTIVE}; unsigned char f[1] = {OP6T_SLOT_FLAG_ACTIVE};
status = mDiskIoProtocol->WriteDisk( status = mDiskIoProtocol->WriteDisk(
mDiskIoProtocol, mDiskIoProtocol, mMediaId, flag_offset, OP6T_SLOT_FLAG_SIZE, f);
mMediaId,
flag_offset,
OP6T_SLOT_FLAG_SIZE,
f);
if (EFI_ERROR(status)) { if (EFI_ERROR(status)) {
SystemTable->ConOut->OutputString(SystemTable->ConOut, L"Failed to write flag into disk.\n"); SystemTable->ConOut->OutputString(
SystemTable->ConOut, L"Failed to write flag into disk.\n");
continue; continue;
} else { }
SystemTable->ConOut->OutputString(SystemTable->ConOut, L"Succeed to write flag into disk.\n"); else {
SystemTable->ConOut->OutputString(
SystemTable->ConOut, L"Succeed to write flag into disk.\n");
break; break;
} }
} }
} }
//try to fix gpt crc32 // try to fix gpt crc32
if (mBlockIoProtocol != NULL) { if (mBlockIoProtocol != NULL) {
status = (FixGptCRC32(mBlockIoProtocol, mDiskIoProtocol, SystemTable)); status = (FixGptCRC32(mBlockIoProtocol, mDiskIoProtocol, SystemTable));
if (EFI_ERROR(status)) if (EFI_ERROR(status))
SystemTable->ConOut->OutputString(SystemTable->ConOut, L"Failed to fix CRC32 value.\n"); SystemTable->ConOut->OutputString(
SystemTable->ConOut, L"Failed to fix CRC32 value.\n");
else else
SystemTable->ConOut->OutputString(SystemTable->ConOut, L"Succeed to fix CRC32 value.\n"); SystemTable->ConOut->OutputString(
SystemTable->ConOut, L"Succeed to fix CRC32 value.\n");
} }
// release memory // release memory
if (controllerHandles != NULL) if (controllerHandles != NULL)
SystemTable->BootServices->FreePool(controllerHandles); SystemTable->BootServices->FreePool(controllerHandles);
//WaitAnyKey(SystemTable); // WaitAnyKey(SystemTable);
return EFI_SUCCESS; return EFI_SUCCESS;
} }
void WaitAnyKey(EFI_SYSTEM_TABLE *mSystemTable) { void WaitAnyKey(EFI_SYSTEM_TABLE *mSystemTable)
{
UINTN index = 0; UINTN index = 0;
EFI_INPUT_KEY Key; EFI_INPUT_KEY Key;
mSystemTable->BootServices->WaitForEvent(1, &mSystemTable->ConIn->WaitForKey, &index); mSystemTable->BootServices->WaitForEvent(
1, &mSystemTable->ConIn->WaitForKey, &index);
mSystemTable->ConIn->ReadKeyStroke(mSystemTable->ConIn, &Key); mSystemTable->ConIn->ReadKeyStroke(mSystemTable->ConIn, &Key);
} }

View File

@ -17,8 +17,8 @@
*/ */
/* /*
* Flags of OP6T slots * Flags of OP6T slots
*/ */
const unsigned char OP6T_SLOT_FLAG_ACTIVE = 0x6F; const unsigned char OP6T_SLOT_FLAG_ACTIVE = 0x6F;
@ -36,38 +36,41 @@ const unsigned char OP6T_SLOT_FLAG_BOOTABLE_6 = 0x2F;
const unsigned OP6T_SLOT_FLAG_BOOTABLE_7 = 0x37; const unsigned OP6T_SLOT_FLAG_BOOTABLE_7 = 0x37;
const unsigned OP6T_SLOT_FLAG_BOOTABLE = 0x37; /* defaultly set bootable the same as bootable_7 */ const unsigned OP6T_SLOT_FLAG_BOOTABLE =
0x37; /* defaultly set bootable the same as bootable_7 */
const unsigned OP6T_SLOT_FLAG_UNBOOTABLE = 0xBA; const unsigned OP6T_SLOT_FLAG_UNBOOTABLE = 0xBA;
// const unsigned OP6T_SLOT_FLAG_SUCCESSFUL = 0xFF; /* OP6T_SLOT_FLAG_SUCCESSFUL maybe uncorrect in this file */ // const unsigned OP6T_SLOT_FLAG_SUCCESSFUL = 0xFF; /* OP6T_SLOT_FLAG_SUCCESSFUL
// maybe uncorrect in this file */
#define OP6T_SLOT_FLAG_SIZE 1 #define OP6T_SLOT_FLAG_SIZE 1
/* /*
* Flag's offset on disk * Flag's offset on disk
* The offset may very from device to device * The offset may very from device to device
* Make sure the offset is correct before using it * Make sure the offset is correct before using it
*/ */
#define OP6T_SLOT_A_BOOT_FLAG_LBA2_OFFSET 0x536 #define OP6T_SLOT_A_BOOT_FLAG_LBA2_OFFSET 0x536
#define OP6T_SLOT_B_BOOT_FLAG_LBA3_OFFSET 0x336 #define OP6T_SLOT_B_BOOT_FLAG_LBA3_OFFSET 0x336
/* /*
* Boot partitions name and their offsets * Boot partitions name and their offsets
* Find the right device by comparaing the partition name on the offset * Find the right device by comparaing the partition name on the offset
*/ */
const unsigned char OP6T_SLOT_A_BOOT_BUFFER[] = {0x62, 0x00, 0x6F, 0x00, 0x6F, const unsigned char OP6T_SLOT_A_BOOT_BUFFER[] = {
0x00, 0x74, 0x00, 0x5F, 0x00, 0x61}; /* ACSII: b.o.o.t._.a */ 0x62, 0x00, 0x6F, 0x00, 0x6F, 0x00,
0x74, 0x00, 0x5F, 0x00, 0x61}; /* ACSII: b.o.o.t._.a */
const unsigned char OP6T_SLOT_B_BOOT_BUFFER[] = {0x62, 0x00, 0x6F, 0x00, 0x6F, const unsigned char OP6T_SLOT_B_BOOT_BUFFER[] = {
0x00, 0x74, 0x00, 0x5F, 0x00, 0x62}; /* ACSII: b.o.o.t._.b */ 0x62, 0x00, 0x6F, 0x00, 0x6F, 0x00,
0x74, 0x00, 0x5F, 0x00, 0x62}; /* ACSII: b.o.o.t._.b */
#define OP6T_SLOT_BOOT_BUFFER_LEN 11 #define OP6T_SLOT_BOOT_BUFFER_LEN 11
#define OP6T_SLOT_A_BOOT_BUFFER_LBA2_OFFSET 0x538 #define OP6T_SLOT_A_BOOT_BUFFER_LBA2_OFFSET 0x538
#define OP6T_SLOT_B_BOOT_BUFFER_LBA3_OFFSET 0x338 #define OP6T_SLOT_B_BOOT_BUFFER_LBA3_OFFSET 0x338

File diff suppressed because it is too large Load Diff

View File

@ -1,17 +1,17 @@
/* SimpleFbDxe: Simple FrameBuffer */ /* SimpleFbDxe: Simple FrameBuffer */
#include <PiDxe.h>
#include <Uefi.h>
#include <Library/UefiLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/DebugLib.h>
#include <Library/PcdLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/DxeServicesTableLib.h>
#include <Protocol/GraphicsOutput.h>
#include <Library/BaseLib.h> #include <Library/BaseLib.h>
#include <Library/FrameBufferBltLib.h> #include <Library/BaseMemoryLib.h>
#include <Library/CacheMaintenanceLib.h> #include <Library/CacheMaintenanceLib.h>
#include <Library/DebugLib.h>
#include <Library/DxeServicesTableLib.h>
#include <Library/FrameBufferBltLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/PcdLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiLib.h>
#include <PiDxe.h>
#include <Protocol/GraphicsOutput.h>
#include <Uefi.h>
/// Defines /// Defines
/* /*
@ -42,28 +42,17 @@ typedef struct {
EFI_DEVICE_PATH EndDevicePath; EFI_DEVICE_PATH EndDevicePath;
} DISPLAY_DEVICE_PATH; } DISPLAY_DEVICE_PATH;
DISPLAY_DEVICE_PATH mDisplayDevicePath = DISPLAY_DEVICE_PATH mDisplayDevicePath = {
{ {{HARDWARE_DEVICE_PATH,
{
{
HARDWARE_DEVICE_PATH,
HW_VENDOR_DP, HW_VENDOR_DP,
{ {
(UINT8)(sizeof(VENDOR_DEVICE_PATH)), (UINT8)(sizeof(VENDOR_DEVICE_PATH)),
(UINT8)((sizeof(VENDOR_DEVICE_PATH)) >> 8), (UINT8)((sizeof(VENDOR_DEVICE_PATH)) >> 8),
} }},
}, EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID},
EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID {END_DEVICE_PATH_TYPE,
},
{
END_DEVICE_PATH_TYPE,
END_ENTIRE_DEVICE_PATH_SUBTYPE, END_ENTIRE_DEVICE_PATH_SUBTYPE,
{ {sizeof(EFI_DEVICE_PATH_PROTOCOL), 0}}};
sizeof(EFI_DEVICE_PATH_PROTOCOL),
0
}
}
};
/// Declares /// Declares
@ -73,63 +62,40 @@ STATIC UINTN mFrameBufferBltLibConfigureSize;
STATIC STATIC
EFI_STATUS EFI_STATUS
EFIAPI EFIAPI
DisplayQueryMode DisplayQueryMode(
( IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This, IN UINT32 ModeNumber,
IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This, OUT UINTN *SizeOfInfo, OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION **Info);
IN UINT32 ModeNumber,
OUT UINTN *SizeOfInfo,
OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION **Info
);
STATIC STATIC
EFI_STATUS EFI_STATUS
EFIAPI EFIAPI
DisplaySetMode DisplaySetMode(IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This, IN UINT32 ModeNumber);
(
IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This,
IN UINT32 ModeNumber
);
STATIC STATIC
EFI_STATUS EFI_STATUS
EFIAPI EFIAPI
DisplayBlt DisplayBlt(
(
IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This, IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This,
IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer, OPTIONAL IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL * BltBuffer,
IN EFI_GRAPHICS_OUTPUT_BLT_OPERATION BltOperation, OPTIONAL IN EFI_GRAPHICS_OUTPUT_BLT_OPERATION BltOperation,
IN UINTN SourceX, IN UINTN SourceX, IN UINTN SourceY, IN UINTN DestinationX,
IN UINTN SourceY, IN UINTN DestinationY, IN UINTN Width, IN UINTN Height,
IN UINTN DestinationX, IN UINTN Delta OPTIONAL);
IN UINTN DestinationY,
IN UINTN Width,
IN UINTN Height,
IN UINTN Delta OPTIONAL
);
STATIC EFI_GRAPHICS_OUTPUT_PROTOCOL mDisplay = { STATIC EFI_GRAPHICS_OUTPUT_PROTOCOL mDisplay = {
DisplayQueryMode, DisplayQueryMode, DisplaySetMode, DisplayBlt, NULL};
DisplaySetMode,
DisplayBlt,
NULL
};
STATIC STATIC
EFI_STATUS EFI_STATUS
EFIAPI EFIAPI
DisplayQueryMode DisplayQueryMode(
( IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This, IN UINT32 ModeNumber,
IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This, OUT UINTN *SizeOfInfo, OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION **Info)
IN UINT32 ModeNumber,
OUT UINTN *SizeOfInfo,
OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION **Info
)
{ {
EFI_STATUS Status; EFI_STATUS Status;
Status = gBS->AllocatePool( Status = gBS->AllocatePool(
EfiBootServicesData, EfiBootServicesData, sizeof(EFI_GRAPHICS_OUTPUT_MODE_INFORMATION),
sizeof(EFI_GRAPHICS_OUTPUT_MODE_INFORMATION), (VOID **)Info);
(VOID **) Info);
ASSERT_EFI_ERROR(Status); ASSERT_EFI_ERROR(Status);
@ -146,11 +112,7 @@ DisplayQueryMode
STATIC STATIC
EFI_STATUS EFI_STATUS
EFIAPI EFIAPI
DisplaySetMode DisplaySetMode(IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This, IN UINT32 ModeNumber)
(
IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This,
IN UINT32 ModeNumber
)
{ {
return EFI_SUCCESS; return EFI_SUCCESS;
} }
@ -158,97 +120,82 @@ DisplaySetMode
STATIC STATIC
EFI_STATUS EFI_STATUS
EFIAPI EFIAPI
DisplayBlt DisplayBlt(
(
IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This, IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This,
IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer, OPTIONAL IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL * BltBuffer,
IN EFI_GRAPHICS_OUTPUT_BLT_OPERATION BltOperation, OPTIONAL IN EFI_GRAPHICS_OUTPUT_BLT_OPERATION BltOperation,
IN UINTN SourceX, IN UINTN SourceX, IN UINTN SourceY, IN UINTN DestinationX,
IN UINTN SourceY, IN UINTN DestinationY, IN UINTN Width, IN UINTN Height,
IN UINTN DestinationX, IN UINTN Delta OPTIONAL)
IN UINTN DestinationY,
IN UINTN Width,
IN UINTN Height,
IN UINTN Delta OPTIONAL
)
{ {
RETURN_STATUS Status; RETURN_STATUS Status;
EFI_TPL Tpl; EFI_TPL Tpl;
// //
// We have to raise to TPL_NOTIFY, so we make an atomic write to the frame buffer. // We have to raise to TPL_NOTIFY, so we make an atomic write to the frame
// We would not want a timer based event (Cursor, ...) to come in while we are // buffer. We would not want a timer based event (Cursor, ...) to come in
// doing this operation. // while we are doing this operation.
// //
Tpl = gBS->RaiseTPL (TPL_NOTIFY); Tpl = gBS->RaiseTPL(TPL_NOTIFY);
Status = FrameBufferBlt ( Status = FrameBufferBlt(
mFrameBufferBltLibConfigure, mFrameBufferBltLibConfigure, BltBuffer, BltOperation, SourceX, SourceY,
BltBuffer, DestinationX, DestinationY, Width, Height, Delta);
BltOperation, gBS->RestoreTPL(Tpl);
SourceX, SourceY,
DestinationX, DestinationY, Width, Height,
Delta
);
gBS->RestoreTPL (Tpl);
// zhuowei: hack: flush the cache manually since my memory maps are still broken // zhuowei: hack: flush the cache manually since my memory maps are still
WriteBackInvalidateDataCacheRange((void*)mDisplay.Mode->FrameBufferBase, // broken
mDisplay.Mode->FrameBufferSize); WriteBackInvalidateDataCacheRange(
(void *)mDisplay.Mode->FrameBufferBase, mDisplay.Mode->FrameBufferSize);
// zhuowei: end hack // zhuowei: end hack
return RETURN_ERROR (Status) ? EFI_INVALID_PARAMETER : EFI_SUCCESS; return RETURN_ERROR(Status) ? EFI_INVALID_PARAMETER : EFI_SUCCESS;
} }
EFI_STATUS EFI_STATUS
EFIAPI EFIAPI
SimpleFbDxeInitialize SimpleFbDxeInitialize(
( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable)
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{ {
EFI_STATUS Status = EFI_SUCCESS; EFI_STATUS Status = EFI_SUCCESS;
EFI_HANDLE hUEFIDisplayHandle = NULL; EFI_HANDLE hUEFIDisplayHandle = NULL;
/* Retrieve simple frame buffer from pre-SEC bootloader */ /* Retrieve simple frame buffer from pre-SEC bootloader */
DEBUG((EFI_D_ERROR, "SimpleFbDxe: Retrieve MIPI FrameBuffer parameters from PCD\n")); DEBUG(
(EFI_D_ERROR,
"SimpleFbDxe: Retrieve MIPI FrameBuffer parameters from PCD\n"));
UINT32 MipiFrameBufferAddr = FixedPcdGet32(PcdMipiFrameBufferAddress); UINT32 MipiFrameBufferAddr = FixedPcdGet32(PcdMipiFrameBufferAddress);
UINT32 MipiFrameBufferWidth = FixedPcdGet32(PcdMipiFrameBufferWidth); UINT32 MipiFrameBufferWidth = FixedPcdGet32(PcdMipiFrameBufferWidth);
UINT32 MipiFrameBufferHeight = FixedPcdGet32(PcdMipiFrameBufferHeight); UINT32 MipiFrameBufferHeight = FixedPcdGet32(PcdMipiFrameBufferHeight);
/* Sanity check */ /* Sanity check */
if (MipiFrameBufferAddr == 0 || MipiFrameBufferWidth == 0 || MipiFrameBufferHeight == 0) if (MipiFrameBufferAddr == 0 || MipiFrameBufferWidth == 0 ||
{ MipiFrameBufferHeight == 0) {
DEBUG((EFI_D_ERROR, "SimpleFbDxe: Invalid FrameBuffer parameters\n")); DEBUG((EFI_D_ERROR, "SimpleFbDxe: Invalid FrameBuffer parameters\n"));
return EFI_DEVICE_ERROR; return EFI_DEVICE_ERROR;
} }
/* Prepare struct */ /* Prepare struct */
if (mDisplay.Mode == NULL) if (mDisplay.Mode == NULL) {
{
Status = gBS->AllocatePool( Status = gBS->AllocatePool(
EfiBootServicesData, EfiBootServicesData, sizeof(EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE),
sizeof(EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE), (VOID **)&mDisplay.Mode);
(VOID **) &mDisplay.Mode
);
ASSERT_EFI_ERROR(Status); ASSERT_EFI_ERROR(Status);
if (EFI_ERROR(Status)) return Status; if (EFI_ERROR(Status))
return Status;
ZeroMem(mDisplay.Mode, sizeof(EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE)); ZeroMem(mDisplay.Mode, sizeof(EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE));
} }
if (mDisplay.Mode->Info == NULL) if (mDisplay.Mode->Info == NULL) {
{
Status = gBS->AllocatePool( Status = gBS->AllocatePool(
EfiBootServicesData, EfiBootServicesData, sizeof(EFI_GRAPHICS_OUTPUT_MODE_INFORMATION),
sizeof(EFI_GRAPHICS_OUTPUT_MODE_INFORMATION), (VOID **)&mDisplay.Mode->Info);
(VOID **) &mDisplay.Mode->Info
);
ASSERT_EFI_ERROR(Status); ASSERT_EFI_ERROR(Status);
if (EFI_ERROR(Status)) return Status; if (EFI_ERROR(Status))
return Status;
ZeroMem(mDisplay.Mode->Info, sizeof(EFI_GRAPHICS_OUTPUT_MODE_INFORMATION)); ZeroMem(mDisplay.Mode->Info, sizeof(EFI_GRAPHICS_OUTPUT_MODE_INFORMATION));
} }
@ -275,43 +222,34 @@ SimpleFbDxeInitialize
// //
// Create the FrameBufferBltLib configuration. // Create the FrameBufferBltLib configuration.
// //
Status = FrameBufferBltConfigure ( Status = FrameBufferBltConfigure(
(VOID *) (UINTN) mDisplay.Mode->FrameBufferBase, (VOID *)(UINTN)mDisplay.Mode->FrameBufferBase, mDisplay.Mode->Info,
mDisplay.Mode->Info, mFrameBufferBltLibConfigure, &mFrameBufferBltLibConfigureSize);
mFrameBufferBltLibConfigure,
&mFrameBufferBltLibConfigureSize
);
if (Status == RETURN_BUFFER_TOO_SMALL) { if (Status == RETURN_BUFFER_TOO_SMALL) {
mFrameBufferBltLibConfigure = AllocatePool (mFrameBufferBltLibConfigureSize); mFrameBufferBltLibConfigure = AllocatePool(mFrameBufferBltLibConfigureSize);
if (mFrameBufferBltLibConfigure != NULL) { if (mFrameBufferBltLibConfigure != NULL) {
Status = FrameBufferBltConfigure ( Status = FrameBufferBltConfigure(
(VOID *) (UINTN) mDisplay.Mode->FrameBufferBase, (VOID *)(UINTN)mDisplay.Mode->FrameBufferBase, mDisplay.Mode->Info,
mDisplay.Mode->Info, mFrameBufferBltLibConfigure, &mFrameBufferBltLibConfigureSize);
mFrameBufferBltLibConfigure,
&mFrameBufferBltLibConfigureSize
);
} }
} }
ASSERT_EFI_ERROR (Status); ASSERT_EFI_ERROR(Status);
// zhuowei: clear the screen to black // zhuowei: clear the screen to black
// UEFI standard requires this, since text is white - see OvmfPkg/QemuVideoDxe/Gop.c // UEFI standard requires this, since text is white - see
ZeroMem((void*)FrameBufferAddress, FrameBufferSize); // OvmfPkg/QemuVideoDxe/Gop.c
ZeroMem((void *)FrameBufferAddress, FrameBufferSize);
// hack: clear cache // hack: clear cache
WriteBackInvalidateDataCacheRange((void*)FrameBufferAddress, FrameBufferSize); WriteBackInvalidateDataCacheRange(
(void *)FrameBufferAddress, FrameBufferSize);
// zhuowei: end // zhuowei: end
/* Register handle */ /* Register handle */
Status = gBS->InstallMultipleProtocolInterfaces( Status = gBS->InstallMultipleProtocolInterfaces(
&hUEFIDisplayHandle, &hUEFIDisplayHandle, &gEfiDevicePathProtocolGuid, &mDisplayDevicePath,
&gEfiDevicePathProtocolGuid, &gEfiGraphicsOutputProtocolGuid, &mDisplay, NULL);
&mDisplayDevicePath,
&gEfiGraphicsOutputProtocolGuid,
&mDisplay,
NULL);
ASSERT_EFI_ERROR (Status); ASSERT_EFI_ERROR(Status);
return Status; return Status;
} }

File diff suppressed because it is too large Load Diff

View File

@ -1,16 +1,17 @@
/** @file /** @file
* *
* Copyright (c) 2018, Linaro Ltd. All rights reserved. * Copyright (c) 2018, Linaro Ltd. All rights reserved.
* *
* This program and the accompanying materials * This program and the accompanying materials
* are licensed and made available under the terms and conditions of the BSD License * are licensed and made available under the terms and conditions of the BSD
* which accompanies this distribution. The full text of the license may be found at *License which accompanies this distribution. The full text of the license may
* http://opensource.org/licenses/bsd-license.php *be found at http://opensource.org/licenses/bsd-license.php
* *
* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, * THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. * WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR
* *IMPLIED.
**/ *
**/
#include <Guid/EventGroup.h> #include <Guid/EventGroup.h>
@ -38,15 +39,11 @@
EFI_CPU_ARCH_PROTOCOL *gCpu; EFI_CPU_ARCH_PROTOCOL *gCpu;
VOID VOID InitPeripherals(IN VOID)
InitPeripherals (
IN VOID
)
{ {
//Lock the QcomWdogTimer in a cage on certain devices // Lock the QcomWdogTimer in a cage on certain devices
MmioWrite32(0x17980008,0x000000); MmioWrite32(0x17980008, 0x000000);
DEBUG ((EFI_D_WARN, "\n \v The Dog has been locked in a cage :)\v")); DEBUG((EFI_D_WARN, "\n \v The Dog has been locked in a cage :)\v"));
} }
/** /**
@ -64,28 +61,19 @@ InitPeripherals (
@param[in] Context NULL @param[in] Context NULL
**/ **/
STATIC STATIC
VOID VOID OnEndOfDxe(IN EFI_EVENT Event, IN VOID *Context) {}
OnEndOfDxe (
IN EFI_EVENT Event,
IN VOID *Context
)
{
}
EFI_STATUS EFI_STATUS
EFIAPI EFIAPI
sdm845EntryPoint ( sdm845EntryPoint(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable)
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{ {
EFI_STATUS Status; EFI_STATUS Status;
EFI_EVENT EndOfDxeEvent; EFI_EVENT EndOfDxeEvent;
Status = gBS->LocateProtocol (&gEfiCpuArchProtocolGuid, NULL, (VOID **)&gCpu); Status = gBS->LocateProtocol(&gEfiCpuArchProtocolGuid, NULL, (VOID **)&gCpu);
ASSERT_EFI_ERROR(Status); ASSERT_EFI_ERROR(Status);
InitPeripherals (); InitPeripherals();
// //
// Create an event belonging to the "gEfiEndOfDxeEventGroupGuid" group. // Create an event belonging to the "gEfiEndOfDxeEventGroupGuid" group.
@ -94,13 +82,8 @@ sdm845EntryPoint (
// same group is signalled to inform about the end of the DXE phase. // same group is signalled to inform about the end of the DXE phase.
// Install the INSTALL_FDT_PROTOCOL protocol. // Install the INSTALL_FDT_PROTOCOL protocol.
// //
Status = gBS->CreateEventEx ( Status = gBS->CreateEventEx(
EVT_NOTIFY_SIGNAL, EVT_NOTIFY_SIGNAL, TPL_CALLBACK, OnEndOfDxe, NULL,
TPL_CALLBACK, &gEfiEndOfDxeEventGroupGuid, &EndOfDxeEvent);
OnEndOfDxe,
NULL,
&gEfiEndOfDxeEventGroupGuid,
&EndOfDxeEvent
);
return Status; return Status;
} }

View File

@ -1,16 +1,17 @@
/** @file /** @file
* *
* Copyright (c) 2013-2017, ARM Limited. All rights reserved. * Copyright (c) 2013-2017, ARM Limited. All rights reserved.
* *
* This program and the accompanying materials * This program and the accompanying materials
* are licensed and made available under the terms and conditions of the BSD License * are licensed and made available under the terms and conditions of the BSD
* which accompanies this distribution. The full text of the license may be found at *License which accompanies this distribution. The full text of the license may
* http://opensource.org/licenses/bsd-license.php *be found at http://opensource.org/licenses/bsd-license.php
* *
* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, * THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. * WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR
* *IMPLIED.
**/ *
**/
#ifndef __ARM_JUNO_H__ #ifndef __ARM_JUNO_H__
#define __ARM_JUNO_H__ #define __ARM_JUNO_H__
@ -26,20 +27,23 @@
// //
// ACPI table information used to initialize tables. // ACPI table information used to initialize tables.
// //
#define EFI_ACPI_ARM_OEM_ID 'A','R','M','L','T','D' // OEMID 6 bytes long #define EFI_ACPI_ARM_OEM_ID 'A', 'R', 'M', 'L', 'T', 'D' // OEMID 6 bytes long
#define EFI_ACPI_ARM_OEM_TABLE_ID SIGNATURE_64('A','R','M','-','J','U','N','O') // OEM table id 8 bytes long #define EFI_ACPI_ARM_OEM_TABLE_ID \
SIGNATURE_64( \
'A', 'R', 'M', '-', 'J', 'U', 'N', 'O') // OEM table id 8 bytes long
#define EFI_ACPI_ARM_OEM_REVISION 0x20140727 #define EFI_ACPI_ARM_OEM_REVISION 0x20140727
#define EFI_ACPI_ARM_CREATOR_ID SIGNATURE_32('A','R','M',' ') #define EFI_ACPI_ARM_CREATOR_ID SIGNATURE_32('A', 'R', 'M', ' ')
#define EFI_ACPI_ARM_CREATOR_REVISION 0x00000099 #define EFI_ACPI_ARM_CREATOR_REVISION 0x00000099
// A macro to initialise the common header part of EFI ACPI tables as defined by // A macro to initialise the common header part of EFI ACPI tables as defined by
// EFI_ACPI_DESCRIPTION_HEADER structure. // EFI_ACPI_DESCRIPTION_HEADER structure.
#define ARM_ACPI_HEADER(Signature, Type, Revision) { \ #define ARM_ACPI_HEADER(Signature, Type, Revision) \
{ \
Signature, /* UINT32 Signature */ \ Signature, /* UINT32 Signature */ \
sizeof (Type), /* UINT32 Length */ \ sizeof(Type), /* UINT32 Length */ \
Revision, /* UINT8 Revision */ \ Revision, /* UINT8 Revision */ \
0, /* UINT8 Checksum */ \ 0, /* UINT8 Checksum */ \
{ EFI_ACPI_ARM_OEM_ID }, /* UINT8 OemId[6] */ \ {EFI_ACPI_ARM_OEM_ID}, /* UINT8 OemId[6] */ \
EFI_ACPI_ARM_OEM_TABLE_ID, /* UINT64 OemTableId */ \ EFI_ACPI_ARM_OEM_TABLE_ID, /* UINT64 OemTableId */ \
EFI_ACPI_ARM_OEM_REVISION, /* UINT32 OemRevision */ \ EFI_ACPI_ARM_OEM_REVISION, /* UINT32 OemRevision */ \
EFI_ACPI_ARM_CREATOR_ID, /* UINT32 CreatorId */ \ EFI_ACPI_ARM_CREATOR_ID, /* UINT32 CreatorId */ \

View File

@ -39,8 +39,7 @@ static ARM_MEMORY_REGION_DESCRIPTOR_EX gDeviceMemoryDescriptorEx[] = {
/* HLOS1 */ /* HLOS1 */
{0x81AC0000, 0x03C40000, EFI_RESOURCE_SYSTEM_MEMORY, {0x81AC0000, 0x03C40000, EFI_RESOURCE_SYSTEM_MEMORY,
SYSTEM_MEMORY_RESOURCE_ATTR_CAPABILITIES, SYSTEM_MEMORY_RESOURCE_ATTR_CAPABILITIES,
ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK, AddMem, ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK, AddMem, EfiBootServicesData},
EfiBootServicesData},
/* MPSS_EFS */ /* MPSS_EFS */
{0x85D00000, 0x00200000, EFI_RESOURCE_SYSTEM_MEMORY, {0x85D00000, 0x00200000, EFI_RESOURCE_SYSTEM_MEMORY,
SYSTEM_MEMORY_RESOURCE_ATTR_CAPABILITIES, SYSTEM_MEMORY_RESOURCE_ATTR_CAPABILITIES,
@ -168,7 +167,7 @@ static ARM_MEMORY_REGION_DESCRIPTOR_EX gDeviceMemoryDescriptorEx[] = {
{0xA0000000, 0xE0000000, EFI_RESOURCE_SYSTEM_MEMORY, {0xA0000000, 0xE0000000, EFI_RESOURCE_SYSTEM_MEMORY,
SYSTEM_MEMORY_RESOURCE_ATTR_CAPABILITIES, SYSTEM_MEMORY_RESOURCE_ATTR_CAPABILITIES,
ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK, AddMem, EfiConventionalMemory}, ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK, AddMem, EfiConventionalMemory},
{0x180000000,0xFC8A0000, EFI_RESOURCE_SYSTEM_MEMORY, {0x180000000, 0xFC8A0000, EFI_RESOURCE_SYSTEM_MEMORY,
SYSTEM_MEMORY_RESOURCE_ATTR_CAPABILITIES, SYSTEM_MEMORY_RESOURCE_ATTR_CAPABILITIES,
ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK, AddMem, EfiConventionalMemory}, ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK, AddMem, EfiConventionalMemory},
#else #else

View File

@ -24,7 +24,7 @@
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifndef __BSL_BLOCK_UTILS_H__ #ifndef __BSL_BLOCK_UTILS_H__
#define __BSL_BLOCK_UTILS_H__ #define __BSL_BLOCK_UTILS_H__
@ -97,14 +97,13 @@ typedef struct {
typedef struct { typedef struct {
EFI_GUID *RootDeviceType; /* GUID Selecting the root device type */ EFI_GUID *RootDeviceType; /* GUID Selecting the root device type */
EFI_GUID *PartitionType; /* Partition Type to match */ EFI_GUID *PartitionType; /* Partition Type to match */
CHAR8 *VolumeName; /* Mounted filesystem volume name to match */ CHAR8 * VolumeName; /* Mounted filesystem volume name to match */
CHAR16 *PartitionLabel; /* Partition label to match */ CHAR16 * PartitionLabel; /* Partition label to match */
} PartiSelectFilter; } PartiSelectFilter;
EFI_STATUS EFI_STATUS
EFIAPI EFIAPI
GetPartitionEntry (IN EFI_HANDLE Handle, GetPartitionEntry(IN EFI_HANDLE Handle, OUT EFI_PARTITION_ENTRY **PartEntry);
OUT EFI_PARTITION_ENTRY **PartEntry);
/** /**
Returns a list of BlkIo handles based on required criteria Returns a list of BlkIo handles based on required criteria
@ -122,9 +121,8 @@ GetPartitionEntry (IN EFI_HANDLE Handle,
*/ */
EFI_STATUS EFI_STATUS
EFIAPI EFIAPI
GetBlkIOHandles (IN UINT32 SelectionAttrib, GetBlkIOHandles(
IN PartiSelectFilter *FilterData, IN UINT32 SelectionAttrib, IN PartiSelectFilter *FilterData,
OUT HandleInfo *HandleInfoPtr, OUT HandleInfo *HandleInfoPtr, IN OUT UINT32 *MaxBlkIopCnt);
IN OUT UINT32 *MaxBlkIopCnt);
#endif #endif

View File

@ -163,7 +163,8 @@ table in the respective position mentioned below.
do { \ do { \
Status = (code); \ Status = (code); \
if (Status != EFI_SUCCESS) { \ if (Status != EFI_SUCCESS) { \
DEBUG ((EFI_D_ERROR, "Err: line:%d %a() status: %r\n", __LINE__, \ DEBUG( \
(EFI_D_ERROR, "Err: line:%d %a() status: %r\n", __LINE__, \
__FUNCTION__, Status)); \ __FUNCTION__, Status)); \
return Status; \ return Status; \
} \ } \
@ -179,10 +180,10 @@ typedef struct {
CHAR16 Suffix[MAX_SLOT_SUFFIX_SZ]; CHAR16 Suffix[MAX_SLOT_SUFFIX_SZ];
} Slot; } Slot;
Slot GetCurrentSlotSuffix (); Slot GetCurrentSlotSuffix();
UINT32 GetMaxLuns (); UINT32 GetMaxLuns();
VOID GetPartitionCount (UINT32 *Val); VOID GetPartitionCount(UINT32 *Val);
VOID SetMultiSlotBootVal (BOOLEAN Val); VOID SetMultiSlotBootVal(BOOLEAN Val);
struct PartitionEntry { struct PartitionEntry {
EFI_PARTITION_ENTRY PartEntry; EFI_PARTITION_ENTRY PartEntry;
@ -195,15 +196,16 @@ struct BootPartsLinkedList {
struct BootPartsLinkedList *Next; struct BootPartsLinkedList *Next;
}; };
INT32 GetPartitionIndex (CHAR16 *PartitionName); INT32 GetPartitionIndex(CHAR16 *PartitionName);
BOOLEAN PartitionHasMultiSlot (CONST CHAR16 *Pname); BOOLEAN PartitionHasMultiSlot(CONST CHAR16 *Pname);
EFI_STATUS EnumeratePartitions (VOID); EFI_STATUS EnumeratePartitions(VOID);
VOID UpdatePartitionEntries (VOID); VOID UpdatePartitionEntries(VOID);
VOID UpdatePartitionAttributes (UINT32 UpdateType); VOID UpdatePartitionAttributes(UINT32 UpdateType);
BOOLEAN IsSuffixEmpty (Slot *CheckSlot); BOOLEAN IsSuffixEmpty(Slot *CheckSlot);
EFI_STATUS SetActiveSlot (Slot *NewSlot, BOOLEAN ResetSuccessBit, BOOLEAN SetSuccessBit); EFI_STATUS
BOOLEAN IsSlotBootable (Slot *CheckSlot); SetActiveSlot(Slot *NewSlot, BOOLEAN ResetSuccessBit, BOOLEAN SetSuccessBit);
EFI_STATUS ClearUnbootable (Slot *CheckSlot); BOOLEAN IsSlotBootable(Slot *CheckSlot);
UINT64 GetPartitionSize (EFI_BLOCK_IO_PROTOCOL *BlockIo); EFI_STATUS ClearUnbootable(Slot *CheckSlot);
UINT64 GetPartitionSize(EFI_BLOCK_IO_PROTOCOL *BlockIo);
#endif #endif

View File

@ -1,4 +1,5 @@
/* Copyright (c) 2015-2018, 2020-2021, The Linux Foundation. All rights reserved. /* Copyright (c) 2015-2018, 2020-2021, The Linux Foundation. All rights
* reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are * modification, are permitted provided that the following conditions are
@ -24,18 +25,18 @@
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifndef __BSL_BOARD_H__ #ifndef __BSL_BOARD_H__
#define __BSL_BOARD_H__ #define __BSL_BOARD_H__
#include <Uefi.h> #include <Library/BootSlotLib/EFICardInfo.h>
#include <Library/PrintLib.h>
#include <Library/DebugLib.h> #include <Library/DebugLib.h>
#include <Library/MemoryAllocationLib.h> #include <Library/MemoryAllocationLib.h>
#include <Library/PrintLib.h>
#include <Library/UefiBootServicesTableLib.h> #include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiLib.h> #include <Library/UefiLib.h>
#include <Library/BootSlotLib/EFICardInfo.h> #include <Uefi.h>
#define HANDLE_MAX_INFO_LIST 128 #define HANDLE_MAX_INFO_LIST 128
@ -45,11 +46,9 @@ typedef enum {
UNKNOWN, UNKNOWN,
} MemCardType; } MemCardType;
VOID VOID GetRootDeviceType(CHAR8 *StrDeviceType, UINT32 Len);
GetRootDeviceType (CHAR8 *StrDeviceType, UINT32 Len); MemCardType CheckRootDeviceType(VOID);
MemCardType
CheckRootDeviceType (VOID);
EFI_STATUS EFI_STATUS
UfsGetSetBootLun (UINT32 *UfsBootlun, BOOLEAN IsGet); UfsGetSetBootLun(UINT32 *UfsBootlun, BOOLEAN IsGet);
#endif #endif

View File

@ -32,10 +32,6 @@ void ResetFb(void);
UINTN UINTN
EFIAPI EFIAPI
SerialPortWriteCritical SerialPortWriteCritical(IN UINT8 *Buffer, IN UINTN NumberOfBytes);
(
IN UINT8 *Buffer,
IN UINTN NumberOfBytes
);
#endif #endif

View File

@ -35,102 +35,38 @@
#define SCALE_FACTOR 2 #define SCALE_FACTOR 2
unsigned font5x12[] = { unsigned font5x12[] = {
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x08421080, 0x00020084, 0x00052940, 0x00000000,
0x08421080, 0x00020084, 0x15f52800, 0x0000295f, 0x1c52f880, 0x00023e94, 0x08855640, 0x0004d542,
0x00052940, 0x00000000, 0x04528800, 0x000b2725, 0x00021080, 0x00000000, 0x04211088, 0x00821042,
0x15f52800, 0x0000295f, 0x10841082, 0x00221108, 0x09575480, 0x00000000, 0x3e420000, 0x00000084,
0x1c52f880, 0x00023e94, 0x00000000, 0x00223000, 0x3e000000, 0x00000000, 0x00000000, 0x00471000,
0x08855640, 0x0004d542, 0x08844200, 0x00008442, 0x2318a880, 0x00022a31, 0x08429880, 0x000f9084,
0x04528800, 0x000b2725, 0x1108c5c0, 0x000f8444, 0x1c4443e0, 0x00074610, 0x14a62100, 0x000423e9,
0x00021080, 0x00000000, 0x26d087e0, 0x00074610, 0x1e10c5c0, 0x00074631, 0x088443e0, 0x00010844,
0x04211088, 0x00821042, 0x1d18c5c0, 0x00074631, 0x3d18c5c0, 0x00074610, 0x08e20000, 0x00471000,
0x10841082, 0x00221108, 0x08e20000, 0x00223000, 0x02222200, 0x00082082, 0x01f00000, 0x000003e0,
0x09575480, 0x00000000, 0x20820820, 0x00008888, 0x1108c5c0, 0x00020084, 0x2b98c5c0, 0x000f05b5,
0x3e420000, 0x00000084, 0x2318a880, 0x0008c63f, 0x1d2949e0, 0x0007ca52, 0x0210c5c0, 0x00074421,
0x00000000, 0x00223000, 0x252949e0, 0x0007ca52, 0x1e1087e0, 0x000f8421, 0x1e1087e0, 0x00008421,
0x3e000000, 0x00000000, 0x0210c5c0, 0x00074639, 0x3f18c620, 0x0008c631, 0x084211c0, 0x00071084,
0x00000000, 0x00471000, 0x10842380, 0x00032508, 0x0654c620, 0x0008c525, 0x02108420, 0x000f8421,
0x08844200, 0x00008442, 0x2b5dc620, 0x0008c631, 0x2b59ce20, 0x0008c739, 0x2318c5c0, 0x00074631,
0x2318a880, 0x00022a31, 0x1f18c5e0, 0x00008421, 0x2318c5c0, 0x01075631, 0x1f18c5e0, 0x0008c525,
0x08429880, 0x000f9084, 0x1c10c5c0, 0x00074610, 0x084213e0, 0x00021084, 0x2318c620, 0x00074631,
0x1108c5c0, 0x000f8444, 0x1518c620, 0x0002114a, 0x2b18c620, 0x000556b5, 0x08a54620, 0x0008c54a,
0x1c4443e0, 0x00074610, 0x08a54620, 0x00021084, 0x088443e0, 0x000f8442, 0x0421084e, 0x00e10842,
0x14a62100, 0x000423e9, 0x08210420, 0x00084108, 0x1084210e, 0x00e42108, 0x0008a880, 0x00000000,
0x26d087e0, 0x00074610, 0x00000000, 0x01f00000, 0x00000104, 0x00000000, 0x20e00000, 0x000b663e,
0x1e10c5c0, 0x00074631, 0x22f08420, 0x0007c631, 0x22e00000, 0x00074421, 0x23e84200, 0x000f4631,
0x088443e0, 0x00010844, 0x22e00000, 0x0007443f, 0x1e214980, 0x00010842, 0x22e00000, 0x1d187a31,
0x1d18c5c0, 0x00074631, 0x26d08420, 0x0008c631, 0x08601000, 0x00071084, 0x10c02000, 0x0c94a108,
0x3d18c5c0, 0x00074610, 0x0a908420, 0x0008a4a3, 0x084210c0, 0x00071084, 0x2ab00000, 0x0008d6b5,
0x08e20000, 0x00471000, 0x26d00000, 0x0008c631, 0x22e00000, 0x00074631, 0x22f00000, 0x0210be31,
0x08e20000, 0x00223000, 0x23e00000, 0x21087a31, 0x26d00000, 0x00008421, 0x22e00000, 0x00074506,
0x02222200, 0x00082082, 0x04f10800, 0x00064842, 0x23100000, 0x000b6631, 0x23100000, 0x00022951,
0x01f00000, 0x000003e0, 0x23100000, 0x000556b5, 0x15100000, 0x0008a884, 0x23100000, 0x1d185b31,
0x20820820, 0x00008888, 0x11f00000, 0x000f8444, 0x06421098, 0x01821084, 0x08421080, 0x00021084,
0x1108c5c0, 0x00020084, 0x30421083, 0x00321084, 0x0004d640, 0x00000000, 0x00000000, 0x00000000,
0x2b98c5c0, 0x000f05b5,
0x2318a880, 0x0008c63f,
0x1d2949e0, 0x0007ca52,
0x0210c5c0, 0x00074421,
0x252949e0, 0x0007ca52,
0x1e1087e0, 0x000f8421,
0x1e1087e0, 0x00008421,
0x0210c5c0, 0x00074639,
0x3f18c620, 0x0008c631,
0x084211c0, 0x00071084,
0x10842380, 0x00032508,
0x0654c620, 0x0008c525,
0x02108420, 0x000f8421,
0x2b5dc620, 0x0008c631,
0x2b59ce20, 0x0008c739,
0x2318c5c0, 0x00074631,
0x1f18c5e0, 0x00008421,
0x2318c5c0, 0x01075631,
0x1f18c5e0, 0x0008c525,
0x1c10c5c0, 0x00074610,
0x084213e0, 0x00021084,
0x2318c620, 0x00074631,
0x1518c620, 0x0002114a,
0x2b18c620, 0x000556b5,
0x08a54620, 0x0008c54a,
0x08a54620, 0x00021084,
0x088443e0, 0x000f8442,
0x0421084e, 0x00e10842,
0x08210420, 0x00084108,
0x1084210e, 0x00e42108,
0x0008a880, 0x00000000,
0x00000000, 0x01f00000,
0x00000104, 0x00000000,
0x20e00000, 0x000b663e,
0x22f08420, 0x0007c631,
0x22e00000, 0x00074421,
0x23e84200, 0x000f4631,
0x22e00000, 0x0007443f,
0x1e214980, 0x00010842,
0x22e00000, 0x1d187a31,
0x26d08420, 0x0008c631,
0x08601000, 0x00071084,
0x10c02000, 0x0c94a108,
0x0a908420, 0x0008a4a3,
0x084210c0, 0x00071084,
0x2ab00000, 0x0008d6b5,
0x26d00000, 0x0008c631,
0x22e00000, 0x00074631,
0x22f00000, 0x0210be31,
0x23e00000, 0x21087a31,
0x26d00000, 0x00008421,
0x22e00000, 0x00074506,
0x04f10800, 0x00064842,
0x23100000, 0x000b6631,
0x23100000, 0x00022951,
0x23100000, 0x000556b5,
0x15100000, 0x0008a884,
0x23100000, 0x1d185b31,
0x11f00000, 0x000f8444,
0x06421098, 0x01821084,
0x08421080, 0x00021084,
0x30421083, 0x00321084,
0x0004d640, 0x00000000,
0x00000000, 0x00000000,
}; };
#endif #endif

View File

@ -1,32 +1,30 @@
/** @file /** @file
* File managing the MMU for ARMv8 architecture * File managing the MMU for ARMv8 architecture
* *
* Copyright (c) 2011-2014, ARM Limited. All rights reserved. * Copyright (c) 2011-2014, ARM Limited. All rights reserved.
* Copyright (c) 2016, Linaro Limited. All rights reserved. * Copyright (c) 2016, Linaro Limited. All rights reserved.
* Copyright (c) 2017, Intel Corporation. All rights reserved.<BR> * Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
* *
* SPDX-License-Identifier: BSD-2-Clause-Patent * SPDX-License-Identifier: BSD-2-Clause-Patent
* *
**/ **/
#include <Uefi.h>
#include <Chipset/AArch64.h> #include <Chipset/AArch64.h>
#include <Library/BaseMemoryLib.h>
#include <Library/CacheMaintenanceLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/ArmLib.h> #include <Library/ArmLib.h>
#include <Library/ArmMmuLib.h> #include <Library/ArmMmuLib.h>
#include <Library/BaseLib.h> #include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/CacheMaintenanceLib.h>
#include <Library/DebugLib.h> #include <Library/DebugLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Uefi.h>
// We use this index definition to define an invalid block entry // We use this index definition to define an invalid block entry
#define TT_ATTR_INDX_INVALID ((UINT32)~0) #define TT_ATTR_INDX_INVALID ((UINT32)~0)
STATIC STATIC
UINT64 UINT64
ArmMemoryAttributeToPageAttribute ( ArmMemoryAttributeToPageAttribute(IN ARM_MEMORY_REGION_ATTRIBUTES Attributes)
IN ARM_MEMORY_REGION_ATTRIBUTES Attributes
)
{ {
switch (Attributes) { switch (Attributes) {
case ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK_NONSHAREABLE: case ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK_NONSHAREABLE:
@ -50,7 +48,7 @@ ArmMemoryAttributeToPageAttribute (
ASSERT(0); ASSERT(0);
case ARM_MEMORY_REGION_ATTRIBUTE_DEVICE: case ARM_MEMORY_REGION_ATTRIBUTE_DEVICE:
case ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_DEVICE: case ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_DEVICE:
if (ArmReadCurrentEL () == AARCH64_EL2) if (ArmReadCurrentEL() == AARCH64_EL2)
return TT_ATTR_INDX_DEVICE_MEMORY | TT_XN_MASK; return TT_ATTR_INDX_DEVICE_MEMORY | TT_XN_MASK;
else else
return TT_ATTR_INDX_DEVICE_MEMORY | TT_UXN_MASK | TT_PXN_MASK; return TT_ATTR_INDX_DEVICE_MEMORY | TT_UXN_MASK | TT_PXN_MASK;
@ -58,9 +56,7 @@ ArmMemoryAttributeToPageAttribute (
} }
UINT64 UINT64
PageAttributeToGcdAttribute ( PageAttributeToGcdAttribute(IN UINT64 PageAttributes)
IN UINT64 PageAttributes
)
{ {
UINT64 GcdAttributes; UINT64 GcdAttributes;
@ -78,21 +74,25 @@ PageAttributeToGcdAttribute (
GcdAttributes = EFI_MEMORY_WB; GcdAttributes = EFI_MEMORY_WB;
break; break;
default: default:
DEBUG ((EFI_D_ERROR, "PageAttributeToGcdAttribute: PageAttributes:0x%lX not supported.\n", PageAttributes)); DEBUG(
ASSERT (0); (EFI_D_ERROR,
"PageAttributeToGcdAttribute: PageAttributes:0x%lX not supported.\n",
PageAttributes));
ASSERT(0);
// The Global Coherency Domain (GCD) value is defined as a bit set. // The Global Coherency Domain (GCD) value is defined as a bit set.
// Returning 0 means no attribute has been set. // Returning 0 means no attribute has been set.
GcdAttributes = 0; GcdAttributes = 0;
} }
// Determine protection attributes // Determine protection attributes
if (((PageAttributes & TT_AP_MASK) == TT_AP_NO_RO) || ((PageAttributes & TT_AP_MASK) == TT_AP_RO_RO)) { if (((PageAttributes & TT_AP_MASK) == TT_AP_NO_RO) ||
((PageAttributes & TT_AP_MASK) == TT_AP_RO_RO)) {
// Read only cases map to write-protect // Read only cases map to write-protect
GcdAttributes |= EFI_MEMORY_RO; GcdAttributes |= EFI_MEMORY_RO;
} }
// Process eXecute Never attribute // Process eXecute Never attribute
if ((PageAttributes & (TT_PXN_MASK | TT_UXN_MASK)) != 0 ) { if ((PageAttributes & (TT_PXN_MASK | TT_UXN_MASK)) != 0) {
GcdAttributes |= EFI_MEMORY_XP; GcdAttributes |= EFI_MEMORY_XP;
} }
@ -102,12 +102,8 @@ PageAttributeToGcdAttribute (
#define MIN_T0SZ 16 #define MIN_T0SZ 16
#define BITS_PER_LEVEL 9 #define BITS_PER_LEVEL 9
VOID VOID GetRootTranslationTableInfo(
GetRootTranslationTableInfo ( IN UINTN T0SZ, OUT UINTN *TableLevel, OUT UINTN *TableEntryCount)
IN UINTN T0SZ,
OUT UINTN *TableLevel,
OUT UINTN *TableEntryCount
)
{ {
// Get the level of the root table // Get the level of the root table
if (TableLevel) { if (TableLevel) {
@ -115,7 +111,8 @@ GetRootTranslationTableInfo (
} }
if (TableEntryCount) { if (TableEntryCount) {
*TableEntryCount = 1UL << (BITS_PER_LEVEL - (T0SZ - MIN_T0SZ) % BITS_PER_LEVEL); *TableEntryCount =
1UL << (BITS_PER_LEVEL - (T0SZ - MIN_T0SZ) % BITS_PER_LEVEL);
} }
} }
@ -137,17 +134,13 @@ ReplaceLiveEntry (
*/ */
STATIC STATIC
VOID VOID LookupAddresstoRootTable(
LookupAddresstoRootTable ( IN UINT64 MaxAddress, OUT UINTN *T0SZ, OUT UINTN *TableEntryCount)
IN UINT64 MaxAddress,
OUT UINTN *T0SZ,
OUT UINTN *TableEntryCount
)
{ {
UINTN TopBit; UINTN TopBit;
// Check the parameters are not NULL // Check the parameters are not NULL
ASSERT ((T0SZ != NULL) && (TableEntryCount != NULL)); ASSERT((T0SZ != NULL) && (TableEntryCount != NULL));
// Look for the highest bit set in MaxAddress // Look for the highest bit set in MaxAddress
for (TopBit = 63; TopBit != 0; TopBit--) { for (TopBit = 63; TopBit != 0; TopBit--) {
@ -157,24 +150,19 @@ LookupAddresstoRootTable (
break; break;
} }
} }
ASSERT (TopBit != 0); ASSERT(TopBit != 0);
// Calculate T0SZ from the top bit of the MaxAddress // Calculate T0SZ from the top bit of the MaxAddress
*T0SZ = 64 - TopBit; *T0SZ = 64 - TopBit;
// Get the Table info from T0SZ // Get the Table info from T0SZ
GetRootTranslationTableInfo (*T0SZ, NULL, TableEntryCount); GetRootTranslationTableInfo(*T0SZ, NULL, TableEntryCount);
} }
STATIC STATIC
UINT64* UINT64 *GetBlockEntryListFromAddress(
GetBlockEntryListFromAddress ( IN UINT64 *RootTable, IN UINT64 RegionStart, OUT UINTN *TableLevel,
IN UINT64 *RootTable, IN OUT UINT64 *BlockEntrySize, OUT UINT64 **LastBlockEntry)
IN UINT64 RegionStart,
OUT UINTN *TableLevel,
IN OUT UINT64 *BlockEntrySize,
OUT UINT64 **LastBlockEntry
)
{ {
UINTN RootTableLevel; UINTN RootTableLevel;
UINTN RootTableEntryCount; UINTN RootTableEntryCount;
@ -195,65 +183,72 @@ GetBlockEntryListFromAddress (
// Ensure the parameters are valid // Ensure the parameters are valid
if (!(TableLevel && BlockEntrySize && LastBlockEntry)) { if (!(TableLevel && BlockEntrySize && LastBlockEntry)) {
ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER); ASSERT_EFI_ERROR(EFI_INVALID_PARAMETER);
return NULL; return NULL;
} }
// Ensure the Region is aligned on 4KB boundary // Ensure the Region is aligned on 4KB boundary
if ((RegionStart & (SIZE_4KB - 1)) != 0) { if ((RegionStart & (SIZE_4KB - 1)) != 0) {
ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER); ASSERT_EFI_ERROR(EFI_INVALID_PARAMETER);
return NULL; return NULL;
} }
// Ensure the required size is aligned on 4KB boundary and not 0 // Ensure the required size is aligned on 4KB boundary and not 0
if ((*BlockEntrySize & (SIZE_4KB - 1)) != 0 || *BlockEntrySize == 0) { if ((*BlockEntrySize & (SIZE_4KB - 1)) != 0 || *BlockEntrySize == 0) {
ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER); ASSERT_EFI_ERROR(EFI_INVALID_PARAMETER);
return NULL; return NULL;
} }
T0SZ = ArmGetTCR () & TCR_T0SZ_MASK; T0SZ = ArmGetTCR() & TCR_T0SZ_MASK;
// Get the Table info from T0SZ // Get the Table info from T0SZ
GetRootTranslationTableInfo (T0SZ, &RootTableLevel, &RootTableEntryCount); GetRootTranslationTableInfo(T0SZ, &RootTableLevel, &RootTableEntryCount);
// If the start address is 0x0 then we use the size of the region to identify the alignment // If the start address is 0x0 then we use the size of the region to identify
// the alignment
if (RegionStart == 0) { if (RegionStart == 0) {
// Identify the highest possible alignment for the Region Size // Identify the highest possible alignment for the Region Size
BaseAddressAlignment = LowBitSet64 (*BlockEntrySize); BaseAddressAlignment = LowBitSet64(*BlockEntrySize);
} else { }
else {
// Identify the highest possible alignment for the Base Address // Identify the highest possible alignment for the Base Address
BaseAddressAlignment = LowBitSet64 (RegionStart); BaseAddressAlignment = LowBitSet64(RegionStart);
} }
// Identify the Page Level the RegionStart must belong to. Note that PageLevel // Identify the Page Level the RegionStart must belong to. Note that PageLevel
// should be at least 1 since block translations are not supported at level 0 // should be at least 1 since block translations are not supported at level 0
PageLevel = MAX (3 - ((BaseAddressAlignment - 12) / 9), 1); PageLevel = MAX(3 - ((BaseAddressAlignment - 12) / 9), 1);
// If the required size is smaller than the current block size then we need to go to the page below. // If the required size is smaller than the current block size then we need to
// The PageLevel was calculated on the Base Address alignment but did not take in account the alignment // go to the page below. The PageLevel was calculated on the Base Address
// of the allocation size // alignment but did not take in account the alignment of the allocation size
while (*BlockEntrySize < TT_BLOCK_ENTRY_SIZE_AT_LEVEL (PageLevel)) { while (*BlockEntrySize < TT_BLOCK_ENTRY_SIZE_AT_LEVEL(PageLevel)) {
// It does not fit so we need to go a page level above // It does not fit so we need to go a page level above
PageLevel++; PageLevel++;
} }
// //
// Get the Table Descriptor for the corresponding PageLevel. We need to decompose RegionStart to get appropriate entries // Get the Table Descriptor for the corresponding PageLevel. We need to
// decompose RegionStart to get appropriate entries
// //
TranslationTable = RootTable; TranslationTable = RootTable;
for (IndexLevel = RootTableLevel; IndexLevel <= PageLevel; IndexLevel++) { for (IndexLevel = RootTableLevel; IndexLevel <= PageLevel; IndexLevel++) {
BlockEntry = (UINT64*)TT_GET_ENTRY_FOR_ADDRESS (TranslationTable, IndexLevel, RegionStart); BlockEntry = (UINT64 *)TT_GET_ENTRY_FOR_ADDRESS(
TranslationTable, IndexLevel, RegionStart);
if ((IndexLevel != 3) && ((*BlockEntry & TT_TYPE_MASK) == TT_TYPE_TABLE_ENTRY)) { if ((IndexLevel != 3) &&
((*BlockEntry & TT_TYPE_MASK) == TT_TYPE_TABLE_ENTRY)) {
// Go to the next table // Go to the next table
TranslationTable = (UINT64*)(*BlockEntry & TT_ADDRESS_MASK_DESCRIPTION_TABLE); TranslationTable =
(UINT64 *)(*BlockEntry & TT_ADDRESS_MASK_DESCRIPTION_TABLE);
// If we are at the last level then update the last level to next level // If we are at the last level then update the last level to next level
if (IndexLevel == PageLevel) { if (IndexLevel == PageLevel) {
// Enter the next level // Enter the next level
PageLevel++; PageLevel++;
} }
} else if ((*BlockEntry & TT_TYPE_MASK) == TT_TYPE_BLOCK_ENTRY) { }
else if ((*BlockEntry & TT_TYPE_MASK) == TT_TYPE_BLOCK_ENTRY) {
// If we are not at the last level then we need to split this BlockEntry // If we are not at the last level then we need to split this BlockEntry
if (IndexLevel != PageLevel) { if (IndexLevel != PageLevel) {
// Retrieve the attributes from the block entry // Retrieve the attributes from the block entry
@ -267,19 +262,22 @@ GetBlockEntryListFromAddress (
// Get the address corresponding at this entry // Get the address corresponding at this entry
BlockEntryAddress = RegionStart; BlockEntryAddress = RegionStart;
BlockEntryAddress = BlockEntryAddress >> TT_ADDRESS_OFFSET_AT_LEVEL(IndexLevel); BlockEntryAddress =
BlockEntryAddress >> TT_ADDRESS_OFFSET_AT_LEVEL(IndexLevel);
// Shift back to right to set zero before the effective address // Shift back to right to set zero before the effective address
BlockEntryAddress = BlockEntryAddress << TT_ADDRESS_OFFSET_AT_LEVEL(IndexLevel); BlockEntryAddress = BlockEntryAddress
<< TT_ADDRESS_OFFSET_AT_LEVEL(IndexLevel);
// Set the correct entry type for the next page level // Set the correct entry type for the next page level
if ((IndexLevel + 1) == 3) { if ((IndexLevel + 1) == 3) {
Attributes |= TT_TYPE_BLOCK_ENTRY_LEVEL3; Attributes |= TT_TYPE_BLOCK_ENTRY_LEVEL3;
} else { }
else {
Attributes |= TT_TYPE_BLOCK_ENTRY; Attributes |= TT_TYPE_BLOCK_ENTRY;
} }
// Create a new translation table // Create a new translation table
TranslationTable = AllocatePages (1); TranslationTable = AllocatePages(1);
if (TranslationTable == NULL) { if (TranslationTable == NULL) {
return NULL; return NULL;
} }
@ -287,29 +285,38 @@ GetBlockEntryListFromAddress (
// Populate the newly created lower level table // Populate the newly created lower level table
SubTableBlockEntry = TranslationTable; SubTableBlockEntry = TranslationTable;
for (Index = 0; Index < TT_ENTRY_COUNT; Index++) { for (Index = 0; Index < TT_ENTRY_COUNT; Index++) {
*SubTableBlockEntry = Attributes | (BlockEntryAddress + (Index << TT_ADDRESS_OFFSET_AT_LEVEL(IndexLevel + 1))); *SubTableBlockEntry =
Attributes |
(BlockEntryAddress +
(Index << TT_ADDRESS_OFFSET_AT_LEVEL(IndexLevel + 1)));
SubTableBlockEntry++; SubTableBlockEntry++;
} }
// Fill the BlockEntry with the new TranslationTable // Fill the BlockEntry with the new TranslationTable
*BlockEntry = ((UINTN)TranslationTable & TT_ADDRESS_MASK_DESCRIPTION_TABLE) | TableAttributes | TT_TYPE_TABLE_ENTRY; *BlockEntry =
((UINTN)TranslationTable & TT_ADDRESS_MASK_DESCRIPTION_TABLE) |
TableAttributes | TT_TYPE_TABLE_ENTRY;
} }
} else { }
else {
if (IndexLevel != PageLevel) { if (IndexLevel != PageLevel) {
// //
// Case when we have an Invalid Entry and we are at a page level above of the one targetted. // Case when we have an Invalid Entry and we are at a page level above
// of the one targetted.
// //
// Create a new translation table // Create a new translation table
TranslationTable = AllocatePages (1); TranslationTable = AllocatePages(1);
if (TranslationTable == NULL) { if (TranslationTable == NULL) {
return NULL; return NULL;
} }
ZeroMem (TranslationTable, TT_ENTRY_COUNT * sizeof(UINT64)); ZeroMem(TranslationTable, TT_ENTRY_COUNT * sizeof(UINT64));
// Fill the new BlockEntry with the TranslationTable // Fill the new BlockEntry with the TranslationTable
*BlockEntry = ((UINTN)TranslationTable & TT_ADDRESS_MASK_DESCRIPTION_TABLE) | TT_TYPE_TABLE_ENTRY; *BlockEntry =
((UINTN)TranslationTable & TT_ADDRESS_MASK_DESCRIPTION_TABLE) |
TT_TYPE_TABLE_ENTRY;
} }
} }
} }
@ -317,12 +324,15 @@ GetBlockEntryListFromAddress (
// Expose the found PageLevel to the caller // Expose the found PageLevel to the caller
*TableLevel = PageLevel; *TableLevel = PageLevel;
// Now, we have the Table Level we can get the Block Size associated to this table // Now, we have the Table Level we can get the Block Size associated to this
*BlockEntrySize = TT_BLOCK_ENTRY_SIZE_AT_LEVEL (PageLevel); // table
*BlockEntrySize = TT_BLOCK_ENTRY_SIZE_AT_LEVEL(PageLevel);
// The last block of the root table depends on the number of entry in this table, // The last block of the root table depends on the number of entry in this
// otherwise it is always the (TT_ENTRY_COUNT - 1)th entry in the table. // table, otherwise it is always the (TT_ENTRY_COUNT - 1)th entry in the
*LastBlockEntry = TT_LAST_BLOCK_ADDRESS(TranslationTable, // table.
*LastBlockEntry = TT_LAST_BLOCK_ADDRESS(
TranslationTable,
(PageLevel == RootTableLevel) ? RootTableEntryCount : TT_ENTRY_COUNT); (PageLevel == RootTableLevel) ? RootTableEntryCount : TT_ENTRY_COUNT);
return BlockEntry; return BlockEntry;
@ -330,13 +340,9 @@ GetBlockEntryListFromAddress (
STATIC STATIC
EFI_STATUS EFI_STATUS
UpdateRegionMapping ( UpdateRegionMapping(
IN UINT64 *RootTable, IN UINT64 *RootTable, IN UINT64 RegionStart, IN UINT64 RegionLength,
IN UINT64 RegionStart, IN UINT64 Attributes, IN UINT64 BlockEntryMask)
IN UINT64 RegionLength,
IN UINT64 Attributes,
IN UINT64 BlockEntryMask
)
{ {
UINT32 Type; UINT32 Type;
UINT64 *BlockEntry; UINT64 *BlockEntry;
@ -346,32 +352,37 @@ UpdateRegionMapping (
// Ensure the Length is aligned on 4KB boundary // Ensure the Length is aligned on 4KB boundary
if ((RegionLength == 0) || ((RegionLength & (SIZE_4KB - 1)) != 0)) { if ((RegionLength == 0) || ((RegionLength & (SIZE_4KB - 1)) != 0)) {
ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER); ASSERT_EFI_ERROR(EFI_INVALID_PARAMETER);
return EFI_INVALID_PARAMETER; return EFI_INVALID_PARAMETER;
} }
do { do {
// Get the first Block Entry that matches the Virtual Address and also the information on the Table Descriptor // Get the first Block Entry that matches the Virtual Address and also the
// such as the size of the Block Entry and the address of the last BlockEntry of the Table Descriptor // information on the Table Descriptor such as the size of the Block Entry
// and the address of the last BlockEntry of the Table Descriptor
BlockEntrySize = RegionLength; BlockEntrySize = RegionLength;
BlockEntry = GetBlockEntryListFromAddress (RootTable, RegionStart, &TableLevel, &BlockEntrySize, &LastBlockEntry); BlockEntry = GetBlockEntryListFromAddress(
RootTable, RegionStart, &TableLevel, &BlockEntrySize, &LastBlockEntry);
if (BlockEntry == NULL) { if (BlockEntry == NULL) {
// GetBlockEntryListFromAddress() return NULL when it fails to allocate new pages from the Translation Tables // GetBlockEntryListFromAddress() return NULL when it fails to allocate
// new pages from the Translation Tables
return EFI_OUT_OF_RESOURCES; return EFI_OUT_OF_RESOURCES;
} }
if (TableLevel != 3) { if (TableLevel != 3) {
Type = TT_TYPE_BLOCK_ENTRY; Type = TT_TYPE_BLOCK_ENTRY;
} else { }
else {
Type = TT_TYPE_BLOCK_ENTRY_LEVEL3; Type = TT_TYPE_BLOCK_ENTRY_LEVEL3;
} }
do { do {
// Fill the Block Entry with attribute and output block address // Fill the Block Entry with attribute and output block address
*BlockEntry &= BlockEntryMask; *BlockEntry &= BlockEntryMask;
*BlockEntry |= (RegionStart & TT_ADDRESS_MASK_BLOCK_ENTRY) | Attributes | Type; *BlockEntry |=
(RegionStart & TT_ADDRESS_MASK_BLOCK_ENTRY) | Attributes | Type;
ArmUpdateTranslationTableEntry (BlockEntry, (VOID *)RegionStart); ArmUpdateTranslationTableEntry(BlockEntry, (VOID *)RegionStart);
// Go to the next BlockEntry // Go to the next BlockEntry
RegionStart += BlockEntrySize; RegionStart += BlockEntrySize;
@ -384,7 +395,8 @@ UpdateRegionMapping (
(*BlockEntry & TT_TYPE_MASK) == TT_TYPE_TABLE_ENTRY) { (*BlockEntry & TT_TYPE_MASK) == TT_TYPE_TABLE_ENTRY) {
break; break;
} }
} while ((RegionLength >= BlockEntrySize) && (BlockEntry <= LastBlockEntry)); } while ((RegionLength >= BlockEntrySize) &&
(BlockEntry <= LastBlockEntry));
} while (RegionLength != 0); } while (RegionLength != 0);
return EFI_SUCCESS; return EFI_SUCCESS;
@ -392,25 +404,17 @@ UpdateRegionMapping (
STATIC STATIC
EFI_STATUS EFI_STATUS
FillTranslationTable ( FillTranslationTable(
IN UINT64 *RootTable, IN UINT64 *RootTable, IN ARM_MEMORY_REGION_DESCRIPTOR *MemoryRegion)
IN ARM_MEMORY_REGION_DESCRIPTOR *MemoryRegion
)
{ {
return UpdateRegionMapping ( return UpdateRegionMapping(
RootTable, RootTable, MemoryRegion->VirtualBase, MemoryRegion->Length,
MemoryRegion->VirtualBase, ArmMemoryAttributeToPageAttribute(MemoryRegion->Attributes) | TT_AF, 0);
MemoryRegion->Length,
ArmMemoryAttributeToPageAttribute (MemoryRegion->Attributes) | TT_AF,
0
);
} }
STATIC STATIC
UINT64 UINT64
GcdAttributeToPageAttribute ( GcdAttributeToPageAttribute(IN UINT64 GcdAttributes)
IN UINT64 GcdAttributes
)
{ {
UINT64 PageAttributes; UINT64 PageAttributes;
@ -434,9 +438,10 @@ GcdAttributeToPageAttribute (
if ((GcdAttributes & EFI_MEMORY_XP) != 0 || if ((GcdAttributes & EFI_MEMORY_XP) != 0 ||
(GcdAttributes & EFI_MEMORY_CACHETYPE_MASK) == EFI_MEMORY_UC) { (GcdAttributes & EFI_MEMORY_CACHETYPE_MASK) == EFI_MEMORY_UC) {
if (ArmReadCurrentEL () == AARCH64_EL2) { if (ArmReadCurrentEL() == AARCH64_EL2) {
PageAttributes |= TT_XN_MASK; PageAttributes |= TT_XN_MASK;
} else { }
else {
PageAttributes |= TT_UXN_MASK | TT_PXN_MASK; PageAttributes |= TT_UXN_MASK | TT_PXN_MASK;
} }
} }
@ -449,18 +454,15 @@ GcdAttributeToPageAttribute (
} }
EFI_STATUS EFI_STATUS
ArmSetMemoryAttributes ( ArmSetMemoryAttributes(
IN EFI_PHYSICAL_ADDRESS BaseAddress, IN EFI_PHYSICAL_ADDRESS BaseAddress, IN UINT64 Length, IN UINT64 Attributes)
IN UINT64 Length,
IN UINT64 Attributes
)
{ {
EFI_STATUS Status; EFI_STATUS Status;
UINT64 *TranslationTable; UINT64 * TranslationTable;
UINT64 PageAttributes; UINT64 PageAttributes;
UINT64 PageAttributeMask; UINT64 PageAttributeMask;
PageAttributes = GcdAttributeToPageAttribute (Attributes); PageAttributes = GcdAttributeToPageAttribute(Attributes);
PageAttributeMask = 0; PageAttributeMask = 0;
if ((Attributes & EFI_MEMORY_CACHETYPE_MASK) == 0) { if ((Attributes & EFI_MEMORY_CACHETYPE_MASK) == 0) {
@ -469,19 +471,15 @@ ArmSetMemoryAttributes (
// permissions only. // permissions only.
// //
PageAttributes &= TT_AP_MASK | TT_UXN_MASK | TT_PXN_MASK; PageAttributes &= TT_AP_MASK | TT_UXN_MASK | TT_PXN_MASK;
PageAttributeMask = ~(TT_ADDRESS_MASK_BLOCK_ENTRY | TT_AP_MASK | PageAttributeMask =
TT_PXN_MASK | TT_XN_MASK); ~(TT_ADDRESS_MASK_BLOCK_ENTRY | TT_AP_MASK | TT_PXN_MASK | TT_XN_MASK);
} }
TranslationTable = ArmGetTTBR0BaseAddress (); TranslationTable = ArmGetTTBR0BaseAddress();
Status = UpdateRegionMapping ( Status = UpdateRegionMapping(
TranslationTable, TranslationTable, BaseAddress, Length, PageAttributes, PageAttributeMask);
BaseAddress, if (EFI_ERROR(Status)) {
Length,
PageAttributes,
PageAttributeMask);
if (EFI_ERROR (Status)) {
return Status; return Status;
} }
@ -490,20 +488,18 @@ ArmSetMemoryAttributes (
STATIC STATIC
EFI_STATUS EFI_STATUS
SetMemoryRegionAttribute ( SetMemoryRegionAttribute(
IN EFI_PHYSICAL_ADDRESS BaseAddress, IN EFI_PHYSICAL_ADDRESS BaseAddress, IN UINT64 Length, IN UINT64 Attributes,
IN UINT64 Length, IN UINT64 BlockEntryMask)
IN UINT64 Attributes,
IN UINT64 BlockEntryMask
)
{ {
EFI_STATUS Status; EFI_STATUS Status;
UINT64 *RootTable; UINT64 * RootTable;
RootTable = ArmGetTTBR0BaseAddress (); RootTable = ArmGetTTBR0BaseAddress();
Status = UpdateRegionMapping (RootTable, BaseAddress, Length, Attributes, BlockEntryMask); Status = UpdateRegionMapping(
if (EFI_ERROR (Status)) { RootTable, BaseAddress, Length, Attributes, BlockEntryMask);
if (EFI_ERROR(Status)) {
return Status; return Status;
} }
@ -511,79 +507,58 @@ SetMemoryRegionAttribute (
} }
EFI_STATUS EFI_STATUS
ArmSetMemoryRegionNoExec ( ArmSetMemoryRegionNoExec(IN EFI_PHYSICAL_ADDRESS BaseAddress, IN UINT64 Length)
IN EFI_PHYSICAL_ADDRESS BaseAddress,
IN UINT64 Length
)
{ {
UINT64 Val; UINT64 Val;
if (ArmReadCurrentEL () == AARCH64_EL1) { if (ArmReadCurrentEL() == AARCH64_EL1) {
Val = TT_PXN_MASK | TT_UXN_MASK; Val = TT_PXN_MASK | TT_UXN_MASK;
} else { }
else {
Val = TT_XN_MASK; Val = TT_XN_MASK;
} }
return SetMemoryRegionAttribute ( return SetMemoryRegionAttribute(
BaseAddress, BaseAddress, Length, Val, ~TT_ADDRESS_MASK_BLOCK_ENTRY);
Length,
Val,
~TT_ADDRESS_MASK_BLOCK_ENTRY);
} }
EFI_STATUS EFI_STATUS
ArmClearMemoryRegionNoExec ( ArmClearMemoryRegionNoExec(
IN EFI_PHYSICAL_ADDRESS BaseAddress, IN EFI_PHYSICAL_ADDRESS BaseAddress, IN UINT64 Length)
IN UINT64 Length
)
{ {
UINT64 Mask; UINT64 Mask;
// XN maps to UXN in the EL1&0 translation regime // XN maps to UXN in the EL1&0 translation regime
Mask = ~(TT_ADDRESS_MASK_BLOCK_ENTRY | TT_PXN_MASK | TT_XN_MASK); Mask = ~(TT_ADDRESS_MASK_BLOCK_ENTRY | TT_PXN_MASK | TT_XN_MASK);
return SetMemoryRegionAttribute ( return SetMemoryRegionAttribute(BaseAddress, Length, 0, Mask);
BaseAddress,
Length,
0,
Mask);
} }
EFI_STATUS EFI_STATUS
ArmSetMemoryRegionReadOnly ( ArmSetMemoryRegionReadOnly(
IN EFI_PHYSICAL_ADDRESS BaseAddress, IN EFI_PHYSICAL_ADDRESS BaseAddress, IN UINT64 Length)
IN UINT64 Length
)
{ {
return SetMemoryRegionAttribute ( return SetMemoryRegionAttribute(
BaseAddress, BaseAddress, Length, TT_AP_RO_RO, ~TT_ADDRESS_MASK_BLOCK_ENTRY);
Length,
TT_AP_RO_RO,
~TT_ADDRESS_MASK_BLOCK_ENTRY);
} }
EFI_STATUS EFI_STATUS
ArmClearMemoryRegionReadOnly ( ArmClearMemoryRegionReadOnly(
IN EFI_PHYSICAL_ADDRESS BaseAddress, IN EFI_PHYSICAL_ADDRESS BaseAddress, IN UINT64 Length)
IN UINT64 Length
)
{ {
return SetMemoryRegionAttribute ( return SetMemoryRegionAttribute(
BaseAddress, BaseAddress, Length, TT_AP_RW_RW,
Length,
TT_AP_RW_RW,
~(TT_ADDRESS_MASK_BLOCK_ENTRY | TT_AP_MASK)); ~(TT_ADDRESS_MASK_BLOCK_ENTRY | TT_AP_MASK));
} }
EFI_STATUS EFI_STATUS
EFIAPI EFIAPI
ArmConfigureMmu ( ArmConfigureMmu(
IN ARM_MEMORY_REGION_DESCRIPTOR *MemoryTable, IN ARM_MEMORY_REGION_DESCRIPTOR *MemoryTable,
OUT VOID **TranslationTableBase OPTIONAL, OUT VOID **TranslationTableBase OPTIONAL,
OUT UINTN *TranslationTableSize OPTIONAL OUT UINTN *TranslationTableSize OPTIONAL)
)
{ {
VOID* TranslationTable; VOID * TranslationTable;
UINT32 TranslationTableAttribute; UINT32 TranslationTableAttribute;
UINT64 MaxAddress; UINT64 MaxAddress;
UINTN T0SZ; UINTN T0SZ;
@ -591,8 +566,8 @@ ArmConfigureMmu (
UINT64 TCR; UINT64 TCR;
EFI_STATUS Status; EFI_STATUS Status;
if(MemoryTable == NULL) { if (MemoryTable == NULL) {
ASSERT (MemoryTable != NULL); ASSERT(MemoryTable != NULL);
return EFI_INVALID_PARAMETER; return EFI_INVALID_PARAMETER;
} }
@ -603,63 +578,86 @@ ArmConfigureMmu (
// into account the architectural limitations that result from UEFI's // into account the architectural limitations that result from UEFI's
// use of 4 KB pages. // use of 4 KB pages.
// //
MaxAddress = MIN (LShiftU64 (1ULL, ArmGetPhysicalAddressBits ()) - 1, MaxAddress =
MAX_ALLOC_ADDRESS); MIN(LShiftU64(1ULL, ArmGetPhysicalAddressBits()) - 1, MAX_ALLOC_ADDRESS);
// Lookup the Table Level to get the information // Lookup the Table Level to get the information
LookupAddresstoRootTable (MaxAddress, &T0SZ, &RootTableEntryCount); LookupAddresstoRootTable(MaxAddress, &T0SZ, &RootTableEntryCount);
// //
// Set TCR that allows us to retrieve T0SZ in the subsequent functions // Set TCR that allows us to retrieve T0SZ in the subsequent functions
// //
// Ideally we will be running at EL2, but should support EL1 as well. // Ideally we will be running at EL2, but should support EL1 as well.
// UEFI should not run at EL3. // UEFI should not run at EL3.
if (ArmReadCurrentEL () == AARCH64_EL2) { if (ArmReadCurrentEL() == AARCH64_EL2) {
//Note: Bits 23 and 31 are reserved(RES1) bits in TCR_EL2 // Note: Bits 23 and 31 are reserved(RES1) bits in TCR_EL2
TCR = T0SZ | (1UL << 31) | (1UL << 23) | TCR_TG0_4KB; TCR = T0SZ | (1UL << 31) | (1UL << 23) | TCR_TG0_4KB;
// Set the Physical Address Size using MaxAddress // Set the Physical Address Size using MaxAddress
if (MaxAddress < SIZE_4GB) { if (MaxAddress < SIZE_4GB) {
TCR |= TCR_PS_4GB; TCR |= TCR_PS_4GB;
} else if (MaxAddress < SIZE_64GB) { }
else if (MaxAddress < SIZE_64GB) {
TCR |= TCR_PS_64GB; TCR |= TCR_PS_64GB;
} else if (MaxAddress < SIZE_1TB) { }
else if (MaxAddress < SIZE_1TB) {
TCR |= TCR_PS_1TB; TCR |= TCR_PS_1TB;
} else if (MaxAddress < SIZE_4TB) { }
else if (MaxAddress < SIZE_4TB) {
TCR |= TCR_PS_4TB; TCR |= TCR_PS_4TB;
} else if (MaxAddress < SIZE_16TB) { }
else if (MaxAddress < SIZE_16TB) {
TCR |= TCR_PS_16TB; TCR |= TCR_PS_16TB;
} else if (MaxAddress < SIZE_256TB) { }
else if (MaxAddress < SIZE_256TB) {
TCR |= TCR_PS_256TB; TCR |= TCR_PS_256TB;
} else { }
DEBUG ((EFI_D_ERROR, "ArmConfigureMmu: The MaxAddress 0x%lX is not supported by this MMU configuration.\n", MaxAddress)); else {
ASSERT (0); // Bigger than 48-bit memory space are not supported DEBUG(
(EFI_D_ERROR,
"ArmConfigureMmu: The MaxAddress 0x%lX is not supported by this MMU "
"configuration.\n",
MaxAddress));
ASSERT(0); // Bigger than 48-bit memory space are not supported
return EFI_UNSUPPORTED; return EFI_UNSUPPORTED;
} }
} else if (ArmReadCurrentEL () == AARCH64_EL1) { }
// Due to Cortex-A57 erratum #822227 we must set TG1[1] == 1, regardless of EPD1. else if (ArmReadCurrentEL() == AARCH64_EL1) {
// Due to Cortex-A57 erratum #822227 we must set TG1[1] == 1, regardless of
// EPD1.
TCR = T0SZ | TCR_TG0_4KB | TCR_TG1_4KB | TCR_EPD1; TCR = T0SZ | TCR_TG0_4KB | TCR_TG1_4KB | TCR_EPD1;
// Set the Physical Address Size using MaxAddress // Set the Physical Address Size using MaxAddress
if (MaxAddress < SIZE_4GB) { if (MaxAddress < SIZE_4GB) {
TCR |= TCR_IPS_4GB; TCR |= TCR_IPS_4GB;
} else if (MaxAddress < SIZE_64GB) { }
else if (MaxAddress < SIZE_64GB) {
TCR |= TCR_IPS_64GB; TCR |= TCR_IPS_64GB;
} else if (MaxAddress < SIZE_1TB) { }
else if (MaxAddress < SIZE_1TB) {
TCR |= TCR_IPS_1TB; TCR |= TCR_IPS_1TB;
} else if (MaxAddress < SIZE_4TB) { }
else if (MaxAddress < SIZE_4TB) {
TCR |= TCR_IPS_4TB; TCR |= TCR_IPS_4TB;
} else if (MaxAddress < SIZE_16TB) { }
else if (MaxAddress < SIZE_16TB) {
TCR |= TCR_IPS_16TB; TCR |= TCR_IPS_16TB;
} else if (MaxAddress < SIZE_256TB) { }
else if (MaxAddress < SIZE_256TB) {
TCR |= TCR_IPS_256TB; TCR |= TCR_IPS_256TB;
} else { }
DEBUG ((EFI_D_ERROR, "ArmConfigureMmu: The MaxAddress 0x%lX is not supported by this MMU configuration.\n", MaxAddress)); else {
ASSERT (0); // Bigger than 48-bit memory space are not supported DEBUG(
(EFI_D_ERROR,
"ArmConfigureMmu: The MaxAddress 0x%lX is not supported by this MMU "
"configuration.\n",
MaxAddress));
ASSERT(0); // Bigger than 48-bit memory space are not supported
return EFI_UNSUPPORTED; return EFI_UNSUPPORTED;
} }
} else { }
ASSERT (0); // UEFI is only expected to run at EL2 and EL1, not EL3. else {
ASSERT(0); // UEFI is only expected to run at EL2 and EL1, not EL3.
return EFI_UNSUPPORTED; return EFI_UNSUPPORTED;
} }
@ -672,22 +670,22 @@ ArmConfigureMmu (
// assert below that that matches the attributes we use for CPU accesses to // assert below that that matches the attributes we use for CPU accesses to
// the region. // the region.
// //
TCR |= TCR_SH_INNER_SHAREABLE | TCR |= TCR_SH_INNER_SHAREABLE | TCR_RGN_OUTER_WRITE_BACK_ALLOC |
TCR_RGN_OUTER_WRITE_BACK_ALLOC |
TCR_RGN_INNER_WRITE_BACK_ALLOC; TCR_RGN_INNER_WRITE_BACK_ALLOC;
// Set TCR // Set TCR
ArmSetTCR (TCR); ArmSetTCR(TCR);
// Allocate pages for translation table // Allocate pages for translation table
TranslationTable = AllocatePages (1); TranslationTable = AllocatePages(1);
if (TranslationTable == NULL) { if (TranslationTable == NULL) {
return EFI_OUT_OF_RESOURCES; return EFI_OUT_OF_RESOURCES;
} }
// We set TTBR0 just after allocating the table to retrieve its location from the subsequent // We set TTBR0 just after allocating the table to retrieve its location from
// functions without needing to pass this value across the functions. The MMU is only enabled // the subsequent functions without needing to pass this value across the
// after the translation tables are populated. // functions. The MMU is only enabled after the translation tables are
ArmSetTTBR0 (TranslationTable); // populated.
ArmSetTTBR0(TranslationTable);
if (TranslationTableBase != NULL) { if (TranslationTableBase != NULL) {
*TranslationTableBase = TranslationTable; *TranslationTableBase = TranslationTable;
@ -697,67 +695,76 @@ ArmConfigureMmu (
*TranslationTableSize = RootTableEntryCount * sizeof(UINT64); *TranslationTableSize = RootTableEntryCount * sizeof(UINT64);
} }
ZeroMem (TranslationTable, RootTableEntryCount * sizeof(UINT64)); ZeroMem(TranslationTable, RootTableEntryCount * sizeof(UINT64));
// Disable MMU and caches. ArmDisableMmu() also invalidates the TLBs // Disable MMU and caches. ArmDisableMmu() also invalidates the TLBs
ArmDisableMmu (); ArmDisableMmu();
ArmDisableDataCache (); ArmDisableDataCache();
ArmDisableInstructionCache (); ArmDisableInstructionCache();
// Make sure nothing sneaked into the cache // Make sure nothing sneaked into the cache
ArmCleanInvalidateDataCache (); ArmCleanInvalidateDataCache();
ArmInvalidateInstructionCache (); ArmInvalidateInstructionCache();
TranslationTableAttribute = TT_ATTR_INDX_INVALID; TranslationTableAttribute = TT_ATTR_INDX_INVALID;
UINTN idx = 0; UINTN idx = 0;
while (MemoryTable->Length != 0) { while (MemoryTable->Length != 0) {
if ((MemoryTable->Length & (SIZE_4KB - 1)) != 0) { if ((MemoryTable->Length & (SIZE_4KB - 1)) != 0) {
DEBUG ((DEBUG_ERROR, "bruh: %d\n", idx)); DEBUG((DEBUG_ERROR, "bruh: %d\n", idx));
} }
DEBUG_CODE_BEGIN (); DEBUG_CODE_BEGIN();
// Find the memory attribute for the Translation Table // Find the memory attribute for the Translation Table
if ((UINTN)TranslationTable >= MemoryTable->PhysicalBase && if ((UINTN)TranslationTable >= MemoryTable->PhysicalBase &&
(UINTN)TranslationTable + EFI_PAGE_SIZE <= MemoryTable->PhysicalBase + (UINTN)TranslationTable + EFI_PAGE_SIZE <=
MemoryTable->Length) { MemoryTable->PhysicalBase + MemoryTable->Length) {
TranslationTableAttribute = MemoryTable->Attributes; TranslationTableAttribute = MemoryTable->Attributes;
} }
DEBUG_CODE_END (); DEBUG_CODE_END();
Status = FillTranslationTable (TranslationTable, MemoryTable); Status = FillTranslationTable(TranslationTable, MemoryTable);
if (EFI_ERROR (Status)) { if (EFI_ERROR(Status)) {
goto FREE_TRANSLATION_TABLE; goto FREE_TRANSLATION_TABLE;
} }
MemoryTable++; MemoryTable++;
idx++; idx++;
} }
ASSERT (TranslationTableAttribute == ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK || ASSERT(
TranslationTableAttribute == ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_WRITE_BACK); TranslationTableAttribute == ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK ||
TranslationTableAttribute ==
ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_WRITE_BACK);
ArmSetMAIR (MAIR_ATTR(TT_ATTR_INDX_DEVICE_MEMORY, MAIR_ATTR_DEVICE_MEMORY) | // mapped to EFI_MEMORY_UC ArmSetMAIR(
MAIR_ATTR(TT_ATTR_INDX_MEMORY_NON_CACHEABLE, MAIR_ATTR_NORMAL_MEMORY_NON_CACHEABLE) | // mapped to EFI_MEMORY_WC MAIR_ATTR(
MAIR_ATTR(TT_ATTR_INDX_MEMORY_WRITE_THROUGH, MAIR_ATTR_NORMAL_MEMORY_WRITE_THROUGH) | // mapped to EFI_MEMORY_WT TT_ATTR_INDX_DEVICE_MEMORY,
MAIR_ATTR(TT_ATTR_INDX_MEMORY_WRITE_BACK, MAIR_ATTR_NORMAL_MEMORY_WRITE_BACK)); // mapped to EFI_MEMORY_WB MAIR_ATTR_DEVICE_MEMORY) | // mapped to EFI_MEMORY_UC
MAIR_ATTR(
TT_ATTR_INDX_MEMORY_NON_CACHEABLE,
MAIR_ATTR_NORMAL_MEMORY_NON_CACHEABLE) | // mapped to EFI_MEMORY_WC
MAIR_ATTR(
TT_ATTR_INDX_MEMORY_WRITE_THROUGH,
MAIR_ATTR_NORMAL_MEMORY_WRITE_THROUGH) | // mapped to EFI_MEMORY_WT
MAIR_ATTR(
TT_ATTR_INDX_MEMORY_WRITE_BACK,
MAIR_ATTR_NORMAL_MEMORY_WRITE_BACK)); // mapped to EFI_MEMORY_WB
ArmDisableAlignmentCheck (); ArmDisableAlignmentCheck();
ArmEnableStackAlignmentCheck (); ArmEnableStackAlignmentCheck();
ArmEnableInstructionCache (); ArmEnableInstructionCache();
ArmEnableDataCache (); ArmEnableDataCache();
ArmEnableMmu (); ArmEnableMmu();
return EFI_SUCCESS; return EFI_SUCCESS;
FREE_TRANSLATION_TABLE: FREE_TRANSLATION_TABLE:
FreePages (TranslationTable, 1); FreePages(TranslationTable, 1);
return Status; return Status;
} }
RETURN_STATUS RETURN_STATUS
EFIAPI EFIAPI
ArmMmuBaseLibConstructor ( ArmMmuBaseLibConstructor(VOID)
VOID
)
{ {
extern UINT32 ArmReplaceLiveTranslationEntrySize; extern UINT32 ArmReplaceLiveTranslationEntrySize;
@ -765,8 +772,8 @@ ArmMmuBaseLibConstructor (
// The ArmReplaceLiveTranslationEntry () helper function may be invoked // The ArmReplaceLiveTranslationEntry () helper function may be invoked
// with the MMU off so we have to ensure that it gets cleaned to the PoC // with the MMU off so we have to ensure that it gets cleaned to the PoC
// //
WriteBackDataCacheRange (ArmReplaceLiveTranslationEntry, WriteBackDataCacheRange(
ArmReplaceLiveTranslationEntrySize); ArmReplaceLiveTranslationEntry, ArmReplaceLiveTranslationEntrySize);
return RETURN_SUCCESS; return RETURN_SUCCESS;
} }

View File

@ -15,20 +15,18 @@
EFI_STATUS EFI_STATUS
EFIAPI EFIAPI
ArmMmuPeiLibConstructor ( ArmMmuPeiLibConstructor(
IN EFI_PEI_FILE_HANDLE FileHandle, IN EFI_PEI_FILE_HANDLE FileHandle, IN CONST EFI_PEI_SERVICES **PeiServices)
IN CONST EFI_PEI_SERVICES **PeiServices
)
{ {
extern UINT32 ArmReplaceLiveTranslationEntrySize; extern UINT32 ArmReplaceLiveTranslationEntrySize;
EFI_FV_FILE_INFO FileInfo; EFI_FV_FILE_INFO FileInfo;
EFI_STATUS Status; EFI_STATUS Status;
ASSERT (FileHandle != NULL); ASSERT(FileHandle != NULL);
Status = (*PeiServices)->FfsGetFileInfo (FileHandle, &FileInfo); Status = (*PeiServices)->FfsGetFileInfo(FileHandle, &FileInfo);
ASSERT_EFI_ERROR (Status); ASSERT_EFI_ERROR(Status);
// //
// Some platforms do not cope very well with cache maintenance being // Some platforms do not cope very well with cache maintenance being
@ -39,16 +37,20 @@ ArmMmuPeiLibConstructor (
// //
if ((UINTN)FileInfo.Buffer <= (UINTN)ArmReplaceLiveTranslationEntry && if ((UINTN)FileInfo.Buffer <= (UINTN)ArmReplaceLiveTranslationEntry &&
((UINTN)FileInfo.Buffer + FileInfo.BufferSize >= ((UINTN)FileInfo.Buffer + FileInfo.BufferSize >=
(UINTN)ArmReplaceLiveTranslationEntry + ArmReplaceLiveTranslationEntrySize)) { (UINTN)ArmReplaceLiveTranslationEntry +
DEBUG ((EFI_D_INFO, "ArmMmuLib: skipping cache maintenance on XIP PEIM\n")); ArmReplaceLiveTranslationEntrySize)) {
} else { DEBUG((EFI_D_INFO, "ArmMmuLib: skipping cache maintenance on XIP PEIM\n"));
DEBUG ((EFI_D_INFO, "ArmMmuLib: performing cache maintenance on shadowed PEIM\n")); }
else {
DEBUG(
(EFI_D_INFO,
"ArmMmuLib: performing cache maintenance on shadowed PEIM\n"));
// //
// The ArmReplaceLiveTranslationEntry () helper function may be invoked // The ArmReplaceLiveTranslationEntry () helper function may be invoked
// with the MMU off so we have to ensure that it gets cleaned to the PoC // with the MMU off so we have to ensure that it gets cleaned to the PoC
// //
WriteBackDataCacheRange (ArmReplaceLiveTranslationEntry, WriteBackDataCacheRange(
ArmReplaceLiveTranslationEntrySize); ArmReplaceLiveTranslationEntry, ArmReplaceLiveTranslationEntrySize);
} }
return RETURN_SUCCESS; return RETURN_SUCCESS;

View File

@ -1,21 +1,21 @@
/** @file /** @file
* File managing the MMU for ARMv7 architecture * File managing the MMU for ARMv7 architecture
* *
* Copyright (c) 2011-2016, ARM Limited. All rights reserved. * Copyright (c) 2011-2016, ARM Limited. All rights reserved.
* *
* SPDX-License-Identifier: BSD-2-Clause-Patent * SPDX-License-Identifier: BSD-2-Clause-Patent
* *
**/ **/
#include <Uefi.h>
#include <Chipset/ArmV7.h> #include <Chipset/ArmV7.h>
#include <Library/BaseMemoryLib.h>
#include <Library/CacheMaintenanceLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/ArmLib.h> #include <Library/ArmLib.h>
#include <Library/BaseLib.h> #include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/CacheMaintenanceLib.h>
#include <Library/DebugLib.h> #include <Library/DebugLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/PcdLib.h> #include <Library/PcdLib.h>
#include <Uefi.h>
#define ID_MMFR0_SHARELVL_SHIFT 12 #define ID_MMFR0_SHARELVL_SHIFT 12
#define ID_MMFR0_SHARELVL_MASK 0xf #define ID_MMFR0_SHARELVL_MASK 0xf
@ -33,53 +33,44 @@
#define __EFI_MEMORY_RWX 0 // no restrictions #define __EFI_MEMORY_RWX 0 // no restrictions
#define CACHE_ATTRIBUTE_MASK (EFI_MEMORY_UC | \ #define CACHE_ATTRIBUTE_MASK \
EFI_MEMORY_WC | \ (EFI_MEMORY_UC | EFI_MEMORY_WC | EFI_MEMORY_WT | EFI_MEMORY_WB | \
EFI_MEMORY_WT | \ EFI_MEMORY_UCE | EFI_MEMORY_WP)
EFI_MEMORY_WB | \
EFI_MEMORY_UCE | \
EFI_MEMORY_WP)
UINTN UINTN
EFIAPI EFIAPI
ArmReadIdMmfr0 ( ArmReadIdMmfr0(VOID);
VOID
);
BOOLEAN BOOLEAN
EFIAPI EFIAPI
ArmHasMpExtensions ( ArmHasMpExtensions(VOID);
VOID
);
UINT32 UINT32
ConvertSectionAttributesToPageAttributes ( ConvertSectionAttributesToPageAttributes(
IN UINT32 SectionAttributes, IN UINT32 SectionAttributes, IN BOOLEAN IsLargePage)
IN BOOLEAN IsLargePage
)
{ {
UINT32 PageAttributes; UINT32 PageAttributes;
PageAttributes = 0; PageAttributes = 0;
PageAttributes |= TT_DESCRIPTOR_CONVERT_TO_PAGE_CACHE_POLICY (SectionAttributes, IsLargePage); PageAttributes |= TT_DESCRIPTOR_CONVERT_TO_PAGE_CACHE_POLICY(
PageAttributes |= TT_DESCRIPTOR_CONVERT_TO_PAGE_AP (SectionAttributes); SectionAttributes, IsLargePage);
PageAttributes |= TT_DESCRIPTOR_CONVERT_TO_PAGE_XN (SectionAttributes, IsLargePage); PageAttributes |= TT_DESCRIPTOR_CONVERT_TO_PAGE_AP(SectionAttributes);
PageAttributes |= TT_DESCRIPTOR_CONVERT_TO_PAGE_NG (SectionAttributes); PageAttributes |=
PageAttributes |= TT_DESCRIPTOR_CONVERT_TO_PAGE_S (SectionAttributes); TT_DESCRIPTOR_CONVERT_TO_PAGE_XN(SectionAttributes, IsLargePage);
PageAttributes |= TT_DESCRIPTOR_CONVERT_TO_PAGE_NG(SectionAttributes);
PageAttributes |= TT_DESCRIPTOR_CONVERT_TO_PAGE_S(SectionAttributes);
return PageAttributes; return PageAttributes;
} }
STATIC STATIC
BOOLEAN BOOLEAN
PreferNonshareableMemory ( PreferNonshareableMemory(VOID)
VOID
)
{ {
UINTN Mmfr; UINTN Mmfr;
UINTN Val; UINTN Val;
if (FeaturePcdGet (PcdNormalMemoryNonshareableOverride)) { if (FeaturePcdGet(PcdNormalMemoryNonshareableOverride)) {
return TRUE; return TRUE;
} }
@ -88,7 +79,7 @@ PreferNonshareableMemory (
// by default to map normal memory) is implemented with hardware coherency // by default to map normal memory) is implemented with hardware coherency
// support. Otherwise, revert to mapping as non-shareable. // support. Otherwise, revert to mapping as non-shareable.
// //
Mmfr = ArmReadIdMmfr0 (); Mmfr = ArmReadIdMmfr0();
switch ((Mmfr >> ID_MMFR0_SHARELVL_SHIFT) & ID_MMFR0_SHARELVL_MASK) { switch ((Mmfr >> ID_MMFR0_SHARELVL_SHIFT) & ID_MMFR0_SHARELVL_MASK) {
case ID_MMFR0_SHARELVL_ONE: case ID_MMFR0_SHARELVL_ONE:
// one level of shareability // one level of shareability
@ -100,22 +91,18 @@ PreferNonshareableMemory (
break; break;
default: default:
// unexpected value -> shareable is the safe option // unexpected value -> shareable is the safe option
ASSERT (FALSE); ASSERT(FALSE);
return FALSE; return FALSE;
} }
return Val != ID_MMFR0_SHR_IMP_HW_COHERENT; return Val != ID_MMFR0_SHR_IMP_HW_COHERENT;
} }
STATIC STATIC
VOID VOID PopulateLevel2PageTable(
PopulateLevel2PageTable ( IN UINT32 *SectionEntry, IN UINT32 PhysicalBase, IN UINT32 RemainLength,
IN UINT32 *SectionEntry, IN ARM_MEMORY_REGION_ATTRIBUTES Attributes)
IN UINT32 PhysicalBase,
IN UINT32 RemainLength,
IN ARM_MEMORY_REGION_ATTRIBUTES Attributes
)
{ {
UINT32* PageEntry; UINT32 *PageEntry;
UINT32 Pages; UINT32 Pages;
UINT32 Index; UINT32 Index;
UINT32 PageAttributes; UINT32 PageAttributes;
@ -151,73 +138,91 @@ PopulateLevel2PageTable (
break; break;
} }
if (PreferNonshareableMemory ()) { if (PreferNonshareableMemory()) {
PageAttributes &= ~TT_DESCRIPTOR_PAGE_S_SHARED; PageAttributes &= ~TT_DESCRIPTOR_PAGE_S_SHARED;
} }
// Check if the Section Entry has already been populated. Otherwise attach a // Check if the Section Entry has already been populated. Otherwise attach a
// Level 2 Translation Table to it // Level 2 Translation Table to it
if (*SectionEntry != 0) { if (*SectionEntry != 0) {
// The entry must be a page table. Otherwise it exists an overlapping in the memory map // The entry must be a page table. Otherwise it exists an overlapping in the
// memory map
if (TT_DESCRIPTOR_SECTION_TYPE_IS_PAGE_TABLE(*SectionEntry)) { if (TT_DESCRIPTOR_SECTION_TYPE_IS_PAGE_TABLE(*SectionEntry)) {
TranslationTable = *SectionEntry & TT_DESCRIPTOR_SECTION_PAGETABLE_ADDRESS_MASK; TranslationTable =
} else if ((*SectionEntry & TT_DESCRIPTOR_SECTION_TYPE_MASK) == TT_DESCRIPTOR_SECTION_TYPE_SECTION) { *SectionEntry & TT_DESCRIPTOR_SECTION_PAGETABLE_ADDRESS_MASK;
}
else if (
(*SectionEntry & TT_DESCRIPTOR_SECTION_TYPE_MASK) ==
TT_DESCRIPTOR_SECTION_TYPE_SECTION) {
// Case where a virtual memory map descriptor overlapped a section entry // Case where a virtual memory map descriptor overlapped a section entry
// Allocate a Level2 Page Table for this Section // Allocate a Level2 Page Table for this Section
TranslationTable = (UINTN)AllocatePages(EFI_SIZE_TO_PAGES(TRANSLATION_TABLE_PAGE_SIZE + TRANSLATION_TABLE_PAGE_ALIGNMENT)); TranslationTable = (UINTN)AllocatePages(EFI_SIZE_TO_PAGES(
TranslationTable = ((UINTN)TranslationTable + TRANSLATION_TABLE_PAGE_ALIGNMENT_MASK) & ~TRANSLATION_TABLE_PAGE_ALIGNMENT_MASK; TRANSLATION_TABLE_PAGE_SIZE + TRANSLATION_TABLE_PAGE_ALIGNMENT));
TranslationTable =
((UINTN)TranslationTable + TRANSLATION_TABLE_PAGE_ALIGNMENT_MASK) &
~TRANSLATION_TABLE_PAGE_ALIGNMENT_MASK;
// Translate the Section Descriptor into Page Descriptor // Translate the Section Descriptor into Page Descriptor
SectionDescriptor = TT_DESCRIPTOR_PAGE_TYPE_PAGE | ConvertSectionAttributesToPageAttributes (*SectionEntry, FALSE); SectionDescriptor =
TT_DESCRIPTOR_PAGE_TYPE_PAGE |
ConvertSectionAttributesToPageAttributes(*SectionEntry, FALSE);
BaseSectionAddress = TT_DESCRIPTOR_SECTION_BASE_ADDRESS(*SectionEntry); BaseSectionAddress = TT_DESCRIPTOR_SECTION_BASE_ADDRESS(*SectionEntry);
// Populate the new Level2 Page Table for the section // Populate the new Level2 Page Table for the section
PageEntry = (UINT32*)TranslationTable; PageEntry = (UINT32 *)TranslationTable;
for (Index = 0; Index < TRANSLATION_TABLE_PAGE_COUNT; Index++) { for (Index = 0; Index < TRANSLATION_TABLE_PAGE_COUNT; Index++) {
PageEntry[Index] = TT_DESCRIPTOR_PAGE_BASE_ADDRESS(BaseSectionAddress + (Index << 12)) | SectionDescriptor; PageEntry[Index] = TT_DESCRIPTOR_PAGE_BASE_ADDRESS(
BaseSectionAddress + (Index << 12)) |
SectionDescriptor;
} }
// Overwrite the section entry to point to the new Level2 Translation Table // Overwrite the section entry to point to the new Level2 Translation
*SectionEntry = (TranslationTable & TT_DESCRIPTOR_SECTION_PAGETABLE_ADDRESS_MASK) | // Table
*SectionEntry =
(TranslationTable & TT_DESCRIPTOR_SECTION_PAGETABLE_ADDRESS_MASK) |
(IS_ARM_MEMORY_REGION_ATTRIBUTES_SECURE(Attributes) ? (1 << 3) : 0) | (IS_ARM_MEMORY_REGION_ATTRIBUTES_SECURE(Attributes) ? (1 << 3) : 0) |
TT_DESCRIPTOR_SECTION_TYPE_PAGE_TABLE; TT_DESCRIPTOR_SECTION_TYPE_PAGE_TABLE;
} else { }
else {
// We do not support the other section type (16MB Section) // We do not support the other section type (16MB Section)
ASSERT(0); ASSERT(0);
return; return;
} }
} else { }
TranslationTable = (UINTN)AllocatePages(EFI_SIZE_TO_PAGES(TRANSLATION_TABLE_PAGE_SIZE + TRANSLATION_TABLE_PAGE_ALIGNMENT)); else {
TranslationTable = ((UINTN)TranslationTable + TRANSLATION_TABLE_PAGE_ALIGNMENT_MASK) & ~TRANSLATION_TABLE_PAGE_ALIGNMENT_MASK; TranslationTable = (UINTN)AllocatePages(EFI_SIZE_TO_PAGES(
TRANSLATION_TABLE_PAGE_SIZE + TRANSLATION_TABLE_PAGE_ALIGNMENT));
TranslationTable =
((UINTN)TranslationTable + TRANSLATION_TABLE_PAGE_ALIGNMENT_MASK) &
~TRANSLATION_TABLE_PAGE_ALIGNMENT_MASK;
ZeroMem ((VOID *)TranslationTable, TRANSLATION_TABLE_PAGE_SIZE); ZeroMem((VOID *)TranslationTable, TRANSLATION_TABLE_PAGE_SIZE);
*SectionEntry = (TranslationTable & TT_DESCRIPTOR_SECTION_PAGETABLE_ADDRESS_MASK) | *SectionEntry =
(TranslationTable & TT_DESCRIPTOR_SECTION_PAGETABLE_ADDRESS_MASK) |
(IS_ARM_MEMORY_REGION_ATTRIBUTES_SECURE(Attributes) ? (1 << 3) : 0) | (IS_ARM_MEMORY_REGION_ATTRIBUTES_SECURE(Attributes) ? (1 << 3) : 0) |
TT_DESCRIPTOR_SECTION_TYPE_PAGE_TABLE; TT_DESCRIPTOR_SECTION_TYPE_PAGE_TABLE;
} }
FirstPageOffset = (PhysicalBase & TT_DESCRIPTOR_PAGE_INDEX_MASK) >> TT_DESCRIPTOR_PAGE_BASE_SHIFT; FirstPageOffset = (PhysicalBase & TT_DESCRIPTOR_PAGE_INDEX_MASK) >>
TT_DESCRIPTOR_PAGE_BASE_SHIFT;
PageEntry = (UINT32 *)TranslationTable + FirstPageOffset; PageEntry = (UINT32 *)TranslationTable + FirstPageOffset;
Pages = RemainLength / TT_DESCRIPTOR_PAGE_SIZE; Pages = RemainLength / TT_DESCRIPTOR_PAGE_SIZE;
ASSERT (FirstPageOffset + Pages <= TRANSLATION_TABLE_PAGE_COUNT); ASSERT(FirstPageOffset + Pages <= TRANSLATION_TABLE_PAGE_COUNT);
for (Index = 0; Index < Pages; Index++) { for (Index = 0; Index < Pages; Index++) {
*PageEntry++ = TT_DESCRIPTOR_PAGE_BASE_ADDRESS(PhysicalBase) | PageAttributes; *PageEntry++ =
TT_DESCRIPTOR_PAGE_BASE_ADDRESS(PhysicalBase) | PageAttributes;
PhysicalBase += TT_DESCRIPTOR_PAGE_SIZE; PhysicalBase += TT_DESCRIPTOR_PAGE_SIZE;
} }
} }
STATIC STATIC
VOID VOID FillTranslationTable(
FillTranslationTable ( IN UINT32 *TranslationTable, IN ARM_MEMORY_REGION_DESCRIPTOR *MemoryRegion)
IN UINT32 *TranslationTable,
IN ARM_MEMORY_REGION_DESCRIPTOR *MemoryRegion
)
{ {
UINT32 *SectionEntry; UINT32 *SectionEntry;
UINT32 Attributes; UINT32 Attributes;
@ -272,29 +277,34 @@ FillTranslationTable (
break; break;
} }
if (PreferNonshareableMemory ()) { if (PreferNonshareableMemory()) {
Attributes &= ~TT_DESCRIPTOR_SECTION_S_SHARED; Attributes &= ~TT_DESCRIPTOR_SECTION_S_SHARED;
} }
// Get the first section entry for this mapping // Get the first section entry for this mapping
SectionEntry = TRANSLATION_TABLE_ENTRY_FOR_VIRTUAL_ADDRESS(TranslationTable, MemoryRegion->VirtualBase); SectionEntry = TRANSLATION_TABLE_ENTRY_FOR_VIRTUAL_ADDRESS(
TranslationTable, MemoryRegion->VirtualBase);
while (RemainLength != 0) { while (RemainLength != 0) {
if (PhysicalBase % TT_DESCRIPTOR_SECTION_SIZE == 0 && if (PhysicalBase % TT_DESCRIPTOR_SECTION_SIZE == 0 &&
RemainLength >= TT_DESCRIPTOR_SECTION_SIZE) { RemainLength >= TT_DESCRIPTOR_SECTION_SIZE) {
// Case: Physical address aligned on the Section Size (1MB) && the length // Case: Physical address aligned on the Section Size (1MB) && the length
// is greater than the Section Size // is greater than the Section Size
*SectionEntry++ = TT_DESCRIPTOR_SECTION_BASE_ADDRESS(PhysicalBase) | Attributes; *SectionEntry++ =
TT_DESCRIPTOR_SECTION_BASE_ADDRESS(PhysicalBase) | Attributes;
PhysicalBase += TT_DESCRIPTOR_SECTION_SIZE; PhysicalBase += TT_DESCRIPTOR_SECTION_SIZE;
RemainLength -= TT_DESCRIPTOR_SECTION_SIZE; RemainLength -= TT_DESCRIPTOR_SECTION_SIZE;
} else { }
PageMapLength = MIN (RemainLength, TT_DESCRIPTOR_SECTION_SIZE - else {
PageMapLength =
MIN(RemainLength, TT_DESCRIPTOR_SECTION_SIZE -
(PhysicalBase % TT_DESCRIPTOR_SECTION_SIZE)); (PhysicalBase % TT_DESCRIPTOR_SECTION_SIZE));
// Case: Physical address aligned on the Section Size (1MB) && the length // Case: Physical address aligned on the Section Size (1MB) && the length
// does not fill a section // does not fill a section
// Case: Physical address NOT aligned on the Section Size (1MB) // Case: Physical address NOT aligned on the Section Size (1MB)
PopulateLevel2PageTable (SectionEntry++, PhysicalBase, PageMapLength, PopulateLevel2PageTable(
SectionEntry++, PhysicalBase, PageMapLength,
MemoryRegion->Attributes); MemoryRegion->Attributes);
// If it is the last entry // If it is the last entry
@ -310,22 +320,24 @@ FillTranslationTable (
RETURN_STATUS RETURN_STATUS
EFIAPI EFIAPI
ArmConfigureMmu ( ArmConfigureMmu(
IN ARM_MEMORY_REGION_DESCRIPTOR *MemoryTable, IN ARM_MEMORY_REGION_DESCRIPTOR *MemoryTable,
OUT VOID **TranslationTableBase OPTIONAL, OUT VOID **TranslationTableBase OPTIONAL,
OUT UINTN *TranslationTableSize OPTIONAL OUT UINTN *TranslationTableSize OPTIONAL)
)
{ {
VOID* TranslationTable; VOID * TranslationTable;
ARM_MEMORY_REGION_ATTRIBUTES TranslationTableAttribute; ARM_MEMORY_REGION_ATTRIBUTES TranslationTableAttribute;
UINT32 TTBRAttributes; UINT32 TTBRAttributes;
// Allocate pages for translation table. // Allocate pages for translation table.
TranslationTable = AllocatePages (EFI_SIZE_TO_PAGES (TRANSLATION_TABLE_SECTION_SIZE + TRANSLATION_TABLE_SECTION_ALIGNMENT)); TranslationTable = AllocatePages(EFI_SIZE_TO_PAGES(
TRANSLATION_TABLE_SECTION_SIZE + TRANSLATION_TABLE_SECTION_ALIGNMENT));
if (TranslationTable == NULL) { if (TranslationTable == NULL) {
return RETURN_OUT_OF_RESOURCES; return RETURN_OUT_OF_RESOURCES;
} }
TranslationTable = (VOID*)(((UINTN)TranslationTable + TRANSLATION_TABLE_SECTION_ALIGNMENT_MASK) & ~TRANSLATION_TABLE_SECTION_ALIGNMENT_MASK); TranslationTable =
(VOID
*)(((UINTN)TranslationTable + TRANSLATION_TABLE_SECTION_ALIGNMENT_MASK) & ~TRANSLATION_TABLE_SECTION_ALIGNMENT_MASK);
if (TranslationTableBase != NULL) { if (TranslationTableBase != NULL) {
*TranslationTableBase = TranslationTable; *TranslationTableBase = TranslationTable;
@ -335,60 +347,69 @@ ArmConfigureMmu (
*TranslationTableSize = TRANSLATION_TABLE_SECTION_SIZE; *TranslationTableSize = TRANSLATION_TABLE_SECTION_SIZE;
} }
ZeroMem (TranslationTable, TRANSLATION_TABLE_SECTION_SIZE); ZeroMem(TranslationTable, TRANSLATION_TABLE_SECTION_SIZE);
// By default, mark the translation table as belonging to a uncached region // By default, mark the translation table as belonging to a uncached region
TranslationTableAttribute = ARM_MEMORY_REGION_ATTRIBUTE_UNCACHED_UNBUFFERED; TranslationTableAttribute = ARM_MEMORY_REGION_ATTRIBUTE_UNCACHED_UNBUFFERED;
while (MemoryTable->Length != 0) { while (MemoryTable->Length != 0) {
// Find the memory attribute for the Translation Table // Find the memory attribute for the Translation Table
if (((UINTN)TranslationTable >= MemoryTable->PhysicalBase) && ((UINTN)TranslationTable <= MemoryTable->PhysicalBase - 1 + MemoryTable->Length)) { if (((UINTN)TranslationTable >= MemoryTable->PhysicalBase) &&
((UINTN)TranslationTable <=
MemoryTable->PhysicalBase - 1 + MemoryTable->Length)) {
TranslationTableAttribute = MemoryTable->Attributes; TranslationTableAttribute = MemoryTable->Attributes;
} }
FillTranslationTable (TranslationTable, MemoryTable); FillTranslationTable(TranslationTable, MemoryTable);
MemoryTable++; MemoryTable++;
} }
// Translate the Memory Attributes into Translation Table Register Attributes // Translate the Memory Attributes into Translation Table Register Attributes
if ((TranslationTableAttribute == ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK) || if ((TranslationTableAttribute == ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK) ||
(TranslationTableAttribute == ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_WRITE_BACK)) { (TranslationTableAttribute ==
TTBRAttributes = ArmHasMpExtensions () ? TTBR_MP_WRITE_BACK_ALLOC : TTBR_WRITE_BACK_ALLOC; ARM_MEMORY_REGION_ATTRIBUTE_NONSECURE_WRITE_BACK)) {
} else { TTBRAttributes =
ArmHasMpExtensions() ? TTBR_MP_WRITE_BACK_ALLOC : TTBR_WRITE_BACK_ALLOC;
}
else {
// Page tables must reside in memory mapped as write-back cacheable // Page tables must reside in memory mapped as write-back cacheable
ASSERT (0); ASSERT(0);
return RETURN_UNSUPPORTED; return RETURN_UNSUPPORTED;
} }
if (TTBRAttributes & TTBR_SHAREABLE) { if (TTBRAttributes & TTBR_SHAREABLE) {
if (PreferNonshareableMemory ()) { if (PreferNonshareableMemory()) {
TTBRAttributes ^= TTBR_SHAREABLE; TTBRAttributes ^= TTBR_SHAREABLE;
} else { }
else {
// //
// Unlike the S bit in the short descriptors, which implies inner shareable // Unlike the S bit in the short descriptors, which implies inner
// on an implementation that supports two levels, the meaning of the S bit // shareable on an implementation that supports two levels, the meaning of
// in the TTBR depends on the NOS bit, which defaults to Outer Shareable. // the S bit in the TTBR depends on the NOS bit, which defaults to Outer
// However, we should only set this bit after we have confirmed that the // Shareable. However, we should only set this bit after we have confirmed
// implementation supports multiple levels, or else the NOS bit is UNK/SBZP // that the implementation supports multiple levels, or else the NOS bit
// is UNK/SBZP
// //
if (((ArmReadIdMmfr0 () >> 12) & 0xf) != 0) { if (((ArmReadIdMmfr0() >> 12) & 0xf) != 0) {
TTBRAttributes |= TTBR_NOT_OUTER_SHAREABLE; TTBRAttributes |= TTBR_NOT_OUTER_SHAREABLE;
} }
} }
} }
ArmCleanInvalidateDataCache (); ArmCleanInvalidateDataCache();
ArmInvalidateInstructionCache (); ArmInvalidateInstructionCache();
ArmDisableDataCache (); ArmDisableDataCache();
ArmDisableInstructionCache(); ArmDisableInstructionCache();
// TLBs are also invalidated when calling ArmDisableMmu() // TLBs are also invalidated when calling ArmDisableMmu()
ArmDisableMmu (); ArmDisableMmu();
// Make sure nothing sneaked into the cache // Make sure nothing sneaked into the cache
ArmCleanInvalidateDataCache (); ArmCleanInvalidateDataCache();
ArmInvalidateInstructionCache (); ArmInvalidateInstructionCache();
ArmSetTTBR0 ((VOID *)(UINTN)(((UINTN)TranslationTable & ~TRANSLATION_TABLE_SECTION_ALIGNMENT_MASK) | (TTBRAttributes & 0x7F))); ArmSetTTBR0((
VOID
*)(UINTN)(((UINTN)TranslationTable & ~TRANSLATION_TABLE_SECTION_ALIGNMENT_MASK) | (TTBRAttributes & 0x7F)));
// //
// The TTBCR register value is undefined at reset in the Non-Secure world. // The TTBCR register value is undefined at reset in the Non-Secure world.
@ -399,24 +420,17 @@ ArmConfigureMmu (
// (0 is the default reset value in systems not implementing // (0 is the default reset value in systems not implementing
// the Security Extensions.) // the Security Extensions.)
// //
ArmSetTTBCR (0); ArmSetTTBCR(0);
ArmSetDomainAccessControl (DOMAIN_ACCESS_CONTROL_NONE(15) | ArmSetDomainAccessControl(
DOMAIN_ACCESS_CONTROL_NONE(14) | DOMAIN_ACCESS_CONTROL_NONE(15) | DOMAIN_ACCESS_CONTROL_NONE(14) |
DOMAIN_ACCESS_CONTROL_NONE(13) | DOMAIN_ACCESS_CONTROL_NONE(13) | DOMAIN_ACCESS_CONTROL_NONE(12) |
DOMAIN_ACCESS_CONTROL_NONE(12) | DOMAIN_ACCESS_CONTROL_NONE(11) | DOMAIN_ACCESS_CONTROL_NONE(10) |
DOMAIN_ACCESS_CONTROL_NONE(11) | DOMAIN_ACCESS_CONTROL_NONE(9) | DOMAIN_ACCESS_CONTROL_NONE(8) |
DOMAIN_ACCESS_CONTROL_NONE(10) | DOMAIN_ACCESS_CONTROL_NONE(7) | DOMAIN_ACCESS_CONTROL_NONE(6) |
DOMAIN_ACCESS_CONTROL_NONE( 9) | DOMAIN_ACCESS_CONTROL_NONE(5) | DOMAIN_ACCESS_CONTROL_NONE(4) |
DOMAIN_ACCESS_CONTROL_NONE( 8) | DOMAIN_ACCESS_CONTROL_NONE(3) | DOMAIN_ACCESS_CONTROL_NONE(2) |
DOMAIN_ACCESS_CONTROL_NONE( 7) | DOMAIN_ACCESS_CONTROL_NONE(1) | DOMAIN_ACCESS_CONTROL_CLIENT(0));
DOMAIN_ACCESS_CONTROL_NONE( 6) |
DOMAIN_ACCESS_CONTROL_NONE( 5) |
DOMAIN_ACCESS_CONTROL_NONE( 4) |
DOMAIN_ACCESS_CONTROL_NONE( 3) |
DOMAIN_ACCESS_CONTROL_NONE( 2) |
DOMAIN_ACCESS_CONTROL_NONE( 1) |
DOMAIN_ACCESS_CONTROL_CLIENT(0));
ArmEnableInstructionCache(); ArmEnableInstructionCache();
ArmEnableDataCache(); ArmEnableDataCache();
@ -426,9 +440,7 @@ ArmConfigureMmu (
STATIC STATIC
EFI_STATUS EFI_STATUS
ConvertSectionToPages ( ConvertSectionToPages(IN EFI_PHYSICAL_ADDRESS BaseAddress)
IN EFI_PHYSICAL_ADDRESS BaseAddress
)
{ {
UINT32 FirstLevelIdx; UINT32 FirstLevelIdx;
UINT32 SectionDescriptor; UINT32 SectionDescriptor;
@ -437,34 +449,44 @@ ConvertSectionToPages (
UINT32 Index; UINT32 Index;
volatile ARM_FIRST_LEVEL_DESCRIPTOR *FirstLevelTable; volatile ARM_FIRST_LEVEL_DESCRIPTOR *FirstLevelTable;
volatile ARM_PAGE_TABLE_ENTRY *PageTable; volatile ARM_PAGE_TABLE_ENTRY * PageTable;
DEBUG ((EFI_D_PAGE, "Converting section at 0x%x to pages\n", (UINTN)BaseAddress)); DEBUG((
EFI_D_PAGE, "Converting section at 0x%x to pages\n", (UINTN)BaseAddress));
// Obtain page table base // Obtain page table base
FirstLevelTable = (ARM_FIRST_LEVEL_DESCRIPTOR *)ArmGetTTBR0BaseAddress (); FirstLevelTable = (ARM_FIRST_LEVEL_DESCRIPTOR *)ArmGetTTBR0BaseAddress();
// Calculate index into first level translation table for start of modification // Calculate index into first level translation table for start of
FirstLevelIdx = TT_DESCRIPTOR_SECTION_BASE_ADDRESS(BaseAddress) >> TT_DESCRIPTOR_SECTION_BASE_SHIFT; // modification
ASSERT (FirstLevelIdx < TRANSLATION_TABLE_SECTION_COUNT); FirstLevelIdx = TT_DESCRIPTOR_SECTION_BASE_ADDRESS(BaseAddress) >>
TT_DESCRIPTOR_SECTION_BASE_SHIFT;
ASSERT(FirstLevelIdx < TRANSLATION_TABLE_SECTION_COUNT);
// Get section attributes and convert to page attributes // Get section attributes and convert to page attributes
SectionDescriptor = FirstLevelTable[FirstLevelIdx]; SectionDescriptor = FirstLevelTable[FirstLevelIdx];
PageDescriptor = TT_DESCRIPTOR_PAGE_TYPE_PAGE | ConvertSectionAttributesToPageAttributes (SectionDescriptor, FALSE); PageDescriptor =
TT_DESCRIPTOR_PAGE_TYPE_PAGE |
ConvertSectionAttributesToPageAttributes(SectionDescriptor, FALSE);
// Allocate a page table for the 4KB entries (we use up a full page even though we only need 1KB) // Allocate a page table for the 4KB entries (we use up a full page even
PageTable = (volatile ARM_PAGE_TABLE_ENTRY *)AllocatePages (1); // though we only need 1KB)
PageTable = (volatile ARM_PAGE_TABLE_ENTRY *)AllocatePages(1);
if (PageTable == NULL) { if (PageTable == NULL) {
return EFI_OUT_OF_RESOURCES; return EFI_OUT_OF_RESOURCES;
} }
// Write the page table entries out // Write the page table entries out
for (Index = 0; Index < TRANSLATION_TABLE_PAGE_COUNT; Index++) { for (Index = 0; Index < TRANSLATION_TABLE_PAGE_COUNT; Index++) {
PageTable[Index] = TT_DESCRIPTOR_PAGE_BASE_ADDRESS(BaseAddress + (Index << 12)) | PageDescriptor; PageTable[Index] =
TT_DESCRIPTOR_PAGE_BASE_ADDRESS(BaseAddress + (Index << 12)) |
PageDescriptor;
} }
// Formulate page table entry, Domain=0, NS=0 // Formulate page table entry, Domain=0, NS=0
PageTableDescriptor = (((UINTN)PageTable) & TT_DESCRIPTOR_SECTION_PAGETABLE_ADDRESS_MASK) | TT_DESCRIPTOR_SECTION_TYPE_PAGE_TABLE; PageTableDescriptor =
(((UINTN)PageTable) & TT_DESCRIPTOR_SECTION_PAGETABLE_ADDRESS_MASK) |
TT_DESCRIPTOR_SECTION_TYPE_PAGE_TABLE;
// Write the page table entry out, replacing section entry // Write the page table entry out, replacing section entry
FirstLevelTable[FirstLevelIdx] = PageTableDescriptor; FirstLevelTable[FirstLevelIdx] = PageTableDescriptor;
@ -474,12 +496,9 @@ ConvertSectionToPages (
STATIC STATIC
EFI_STATUS EFI_STATUS
UpdatePageEntries ( UpdatePageEntries(
IN EFI_PHYSICAL_ADDRESS BaseAddress, IN EFI_PHYSICAL_ADDRESS BaseAddress, IN UINT64 Length, IN UINT64 Attributes,
IN UINT64 Length, OUT BOOLEAN *FlushTlbs OPTIONAL)
IN UINT64 Attributes,
OUT BOOLEAN *FlushTlbs OPTIONAL
)
{ {
EFI_STATUS Status; EFI_STATUS Status;
UINT32 EntryValue; UINT32 EntryValue;
@ -492,19 +511,20 @@ UpdatePageEntries (
UINT32 PageTableIndex; UINT32 PageTableIndex;
UINT32 PageTableEntry; UINT32 PageTableEntry;
UINT32 CurrentPageTableEntry; UINT32 CurrentPageTableEntry;
VOID *Mva; VOID * Mva;
volatile ARM_FIRST_LEVEL_DESCRIPTOR *FirstLevelTable; volatile ARM_FIRST_LEVEL_DESCRIPTOR *FirstLevelTable;
volatile ARM_PAGE_TABLE_ENTRY *PageTable; volatile ARM_PAGE_TABLE_ENTRY * PageTable;
Status = EFI_SUCCESS; Status = EFI_SUCCESS;
// EntryMask: bitmask of values to change (1 = change this value, 0 = leave alone) // EntryMask: bitmask of values to change (1 = change this value, 0 = leave
// EntryValue: values at bit positions specified by EntryMask // alone) EntryValue: values at bit positions specified by EntryMask
EntryMask = TT_DESCRIPTOR_PAGE_TYPE_MASK | TT_DESCRIPTOR_PAGE_AP_MASK; EntryMask = TT_DESCRIPTOR_PAGE_TYPE_MASK | TT_DESCRIPTOR_PAGE_AP_MASK;
if (Attributes & EFI_MEMORY_XP) { if (Attributes & EFI_MEMORY_XP) {
EntryValue = TT_DESCRIPTOR_PAGE_TYPE_PAGE_XN; EntryValue = TT_DESCRIPTOR_PAGE_TYPE_PAGE_XN;
} else { }
else {
EntryValue = TT_DESCRIPTOR_PAGE_TYPE_PAGE; EntryValue = TT_DESCRIPTOR_PAGE_TYPE_PAGE;
} }
@ -517,54 +537,69 @@ UpdatePageEntries (
// modify cacheability attributes // modify cacheability attributes
EntryMask |= TT_DESCRIPTOR_PAGE_CACHE_POLICY_MASK; EntryMask |= TT_DESCRIPTOR_PAGE_CACHE_POLICY_MASK;
// map to strongly ordered // map to strongly ordered
EntryValue |= TT_DESCRIPTOR_PAGE_CACHE_POLICY_STRONGLY_ORDERED; // TEX[2:0] = 0, C=0, B=0 EntryValue |=
} else if (Attributes & EFI_MEMORY_WC) { TT_DESCRIPTOR_PAGE_CACHE_POLICY_STRONGLY_ORDERED; // TEX[2:0] = 0, C=0,
// B=0
}
else if (Attributes & EFI_MEMORY_WC) {
// modify cacheability attributes // modify cacheability attributes
EntryMask |= TT_DESCRIPTOR_PAGE_CACHE_POLICY_MASK; EntryMask |= TT_DESCRIPTOR_PAGE_CACHE_POLICY_MASK;
// map to normal non-cachable // map to normal non-cachable
EntryValue |= TT_DESCRIPTOR_PAGE_CACHE_POLICY_NON_CACHEABLE; // TEX [2:0]= 001 = 0x2, B=0, C=0 EntryValue |=
} else if (Attributes & EFI_MEMORY_WT) { TT_DESCRIPTOR_PAGE_CACHE_POLICY_NON_CACHEABLE; // TEX [2:0]= 001 = 0x2,
// B=0, C=0
}
else if (Attributes & EFI_MEMORY_WT) {
// modify cacheability attributes // modify cacheability attributes
EntryMask |= TT_DESCRIPTOR_PAGE_CACHE_POLICY_MASK; EntryMask |= TT_DESCRIPTOR_PAGE_CACHE_POLICY_MASK;
// write through with no-allocate // write through with no-allocate
EntryValue |= TT_DESCRIPTOR_PAGE_CACHE_POLICY_WRITE_THROUGH_NO_ALLOC; // TEX [2:0] = 0, C=1, B=0 EntryValue |=
} else if (Attributes & EFI_MEMORY_WB) { TT_DESCRIPTOR_PAGE_CACHE_POLICY_WRITE_THROUGH_NO_ALLOC; // TEX [2:0] =
// 0, C=1, B=0
}
else if (Attributes & EFI_MEMORY_WB) {
// modify cacheability attributes // modify cacheability attributes
EntryMask |= TT_DESCRIPTOR_PAGE_CACHE_POLICY_MASK; EntryMask |= TT_DESCRIPTOR_PAGE_CACHE_POLICY_MASK;
// write back (with allocate) // write back (with allocate)
EntryValue |= TT_DESCRIPTOR_PAGE_CACHE_POLICY_WRITE_BACK_ALLOC; // TEX [2:0] = 001, C=1, B=1 EntryValue |=
} else if (Attributes & CACHE_ATTRIBUTE_MASK) { TT_DESCRIPTOR_PAGE_CACHE_POLICY_WRITE_BACK_ALLOC; // TEX [2:0] = 001,
// C=1, B=1
}
else if (Attributes & CACHE_ATTRIBUTE_MASK) {
// catch unsupported memory type attributes // catch unsupported memory type attributes
ASSERT (FALSE); ASSERT(FALSE);
return EFI_UNSUPPORTED; return EFI_UNSUPPORTED;
} }
if (Attributes & EFI_MEMORY_RO) { if (Attributes & EFI_MEMORY_RO) {
EntryValue |= TT_DESCRIPTOR_PAGE_AP_RO_RO; EntryValue |= TT_DESCRIPTOR_PAGE_AP_RO_RO;
} else { }
else {
EntryValue |= TT_DESCRIPTOR_PAGE_AP_RW_RW; EntryValue |= TT_DESCRIPTOR_PAGE_AP_RW_RW;
} }
// Obtain page table base // Obtain page table base
FirstLevelTable = (ARM_FIRST_LEVEL_DESCRIPTOR *)ArmGetTTBR0BaseAddress (); FirstLevelTable = (ARM_FIRST_LEVEL_DESCRIPTOR *)ArmGetTTBR0BaseAddress();
// Calculate number of 4KB page table entries to change // Calculate number of 4KB page table entries to change
NumPageEntries = Length / TT_DESCRIPTOR_PAGE_SIZE; NumPageEntries = Length / TT_DESCRIPTOR_PAGE_SIZE;
// Iterate for the number of 4KB pages to change // Iterate for the number of 4KB pages to change
Offset = 0; Offset = 0;
for(p = 0; p < NumPageEntries; p++) { for (p = 0; p < NumPageEntries; p++) {
// Calculate index into first level translation table for page table value // Calculate index into first level translation table for page table value
FirstLevelIdx = TT_DESCRIPTOR_SECTION_BASE_ADDRESS(BaseAddress + Offset) >> TT_DESCRIPTOR_SECTION_BASE_SHIFT; FirstLevelIdx = TT_DESCRIPTOR_SECTION_BASE_ADDRESS(BaseAddress + Offset) >>
ASSERT (FirstLevelIdx < TRANSLATION_TABLE_SECTION_COUNT); TT_DESCRIPTOR_SECTION_BASE_SHIFT;
ASSERT(FirstLevelIdx < TRANSLATION_TABLE_SECTION_COUNT);
// Read the descriptor from the first level page table // Read the descriptor from the first level page table
Descriptor = FirstLevelTable[FirstLevelIdx]; Descriptor = FirstLevelTable[FirstLevelIdx];
// Does this descriptor need to be converted from section entry to 4K pages? // Does this descriptor need to be converted from section entry to 4K pages?
if (!TT_DESCRIPTOR_SECTION_TYPE_IS_PAGE_TABLE(Descriptor)) { if (!TT_DESCRIPTOR_SECTION_TYPE_IS_PAGE_TABLE(Descriptor)) {
Status = ConvertSectionToPages (FirstLevelIdx << TT_DESCRIPTOR_SECTION_BASE_SHIFT); Status = ConvertSectionToPages(
FirstLevelIdx << TT_DESCRIPTOR_SECTION_BASE_SHIFT);
if (EFI_ERROR(Status)) { if (EFI_ERROR(Status)) {
// Exit for loop // Exit for loop
break; break;
@ -578,11 +613,13 @@ UpdatePageEntries (
} }
// Obtain page table base address // Obtain page table base address
PageTable = (ARM_PAGE_TABLE_ENTRY *)TT_DESCRIPTOR_PAGE_BASE_ADDRESS(Descriptor); PageTable =
(ARM_PAGE_TABLE_ENTRY *)TT_DESCRIPTOR_PAGE_BASE_ADDRESS(Descriptor);
// Calculate index into the page table // Calculate index into the page table
PageTableIndex = ((BaseAddress + Offset) & TT_DESCRIPTOR_PAGE_INDEX_MASK) >> TT_DESCRIPTOR_PAGE_BASE_SHIFT; PageTableIndex = ((BaseAddress + Offset) & TT_DESCRIPTOR_PAGE_INDEX_MASK) >>
ASSERT (PageTableIndex < TRANSLATION_TABLE_PAGE_COUNT); TT_DESCRIPTOR_PAGE_BASE_SHIFT;
ASSERT(PageTableIndex < TRANSLATION_TABLE_PAGE_COUNT);
// Get the entry // Get the entry
CurrentPageTableEntry = PageTable[PageTableIndex]; CurrentPageTableEntry = PageTable[PageTableIndex];
@ -594,11 +631,13 @@ UpdatePageEntries (
PageTableEntry |= EntryValue; PageTableEntry |= EntryValue;
if (CurrentPageTableEntry != PageTableEntry) { if (CurrentPageTableEntry != PageTableEntry) {
Mva = (VOID *)(UINTN)((((UINTN)FirstLevelIdx) << TT_DESCRIPTOR_SECTION_BASE_SHIFT) + (PageTableIndex << TT_DESCRIPTOR_PAGE_BASE_SHIFT)); Mva =
(VOID
*)(UINTN)((((UINTN)FirstLevelIdx) << TT_DESCRIPTOR_SECTION_BASE_SHIFT) + (PageTableIndex << TT_DESCRIPTOR_PAGE_BASE_SHIFT));
// Only need to update if we are changing the entry // Only need to update if we are changing the entry
PageTable[PageTableIndex] = PageTableEntry; PageTable[PageTableIndex] = PageTableEntry;
ArmUpdateTranslationTableEntry ((VOID *)&PageTable[PageTableIndex], Mva); ArmUpdateTranslationTableEntry((VOID *)&PageTable[PageTableIndex], Mva);
} }
Status = EFI_SUCCESS; Status = EFI_SUCCESS;
@ -611,11 +650,8 @@ UpdatePageEntries (
STATIC STATIC
EFI_STATUS EFI_STATUS
UpdateSectionEntries ( UpdateSectionEntries(
IN EFI_PHYSICAL_ADDRESS BaseAddress, IN EFI_PHYSICAL_ADDRESS BaseAddress, IN UINT64 Length, IN UINT64 Attributes)
IN UINT64 Length,
IN UINT64 Attributes
)
{ {
EFI_STATUS Status = EFI_SUCCESS; EFI_STATUS Status = EFI_SUCCESS;
UINT32 EntryMask; UINT32 EntryMask;
@ -625,11 +661,11 @@ UpdateSectionEntries (
UINT32 i; UINT32 i;
UINT32 CurrentDescriptor; UINT32 CurrentDescriptor;
UINT32 Descriptor; UINT32 Descriptor;
VOID *Mva; VOID * Mva;
volatile ARM_FIRST_LEVEL_DESCRIPTOR *FirstLevelTable; volatile ARM_FIRST_LEVEL_DESCRIPTOR *FirstLevelTable;
// EntryMask: bitmask of values to change (1 = change this value, 0 = leave alone) // EntryMask: bitmask of values to change (1 = change this value, 0 = leave
// EntryValue: values at bit positions specified by EntryMask // alone) EntryValue: values at bit positions specified by EntryMask
// Make sure we handle a section range that is unmapped // Make sure we handle a section range that is unmapped
EntryMask = TT_DESCRIPTOR_SECTION_TYPE_MASK | TT_DESCRIPTOR_SECTION_XN_MASK | EntryMask = TT_DESCRIPTOR_SECTION_TYPE_MASK | TT_DESCRIPTOR_SECTION_XN_MASK |
@ -645,31 +681,45 @@ UpdateSectionEntries (
// modify cacheability attributes // modify cacheability attributes
EntryMask |= TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK; EntryMask |= TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK;
// map to strongly ordered // map to strongly ordered
EntryValue |= TT_DESCRIPTOR_SECTION_CACHE_POLICY_STRONGLY_ORDERED; // TEX[2:0] = 0, C=0, B=0 EntryValue |=
} else if (Attributes & EFI_MEMORY_WC) { TT_DESCRIPTOR_SECTION_CACHE_POLICY_STRONGLY_ORDERED; // TEX[2:0] = 0,
// C=0, B=0
}
else if (Attributes & EFI_MEMORY_WC) {
// modify cacheability attributes // modify cacheability attributes
EntryMask |= TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK; EntryMask |= TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK;
// map to normal non-cachable // map to normal non-cachable
EntryValue |= TT_DESCRIPTOR_SECTION_CACHE_POLICY_NON_CACHEABLE; // TEX [2:0]= 001 = 0x2, B=0, C=0 EntryValue |=
} else if (Attributes & EFI_MEMORY_WT) { TT_DESCRIPTOR_SECTION_CACHE_POLICY_NON_CACHEABLE; // TEX [2:0]= 001 =
// 0x2, B=0, C=0
}
else if (Attributes & EFI_MEMORY_WT) {
// modify cacheability attributes // modify cacheability attributes
EntryMask |= TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK; EntryMask |= TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK;
// write through with no-allocate // write through with no-allocate
EntryValue |= TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_THROUGH_NO_ALLOC; // TEX [2:0] = 0, C=1, B=0 EntryValue |=
} else if (Attributes & EFI_MEMORY_WB) { TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_THROUGH_NO_ALLOC; // TEX [2:0]
// = 0, C=1,
// B=0
}
else if (Attributes & EFI_MEMORY_WB) {
// modify cacheability attributes // modify cacheability attributes
EntryMask |= TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK; EntryMask |= TT_DESCRIPTOR_SECTION_CACHE_POLICY_MASK;
// write back (with allocate) // write back (with allocate)
EntryValue |= TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_BACK_ALLOC; // TEX [2:0] = 001, C=1, B=1 EntryValue |=
} else if (Attributes & CACHE_ATTRIBUTE_MASK) { TT_DESCRIPTOR_SECTION_CACHE_POLICY_WRITE_BACK_ALLOC; // TEX [2:0] = 001,
// C=1, B=1
}
else if (Attributes & CACHE_ATTRIBUTE_MASK) {
// catch unsupported memory type attributes // catch unsupported memory type attributes
ASSERT (FALSE); ASSERT(FALSE);
return EFI_UNSUPPORTED; return EFI_UNSUPPORTED;
} }
if (Attributes & EFI_MEMORY_RO) { if (Attributes & EFI_MEMORY_RO) {
EntryValue |= TT_DESCRIPTOR_SECTION_AP_RO_RO; EntryValue |= TT_DESCRIPTOR_SECTION_AP_RO_RO;
} else { }
else {
EntryValue |= TT_DESCRIPTOR_SECTION_AP_RW_RW; EntryValue |= TT_DESCRIPTOR_SECTION_AP_RW_RW;
} }
@ -678,46 +728,52 @@ UpdateSectionEntries (
} }
// obtain page table base // obtain page table base
FirstLevelTable = (ARM_FIRST_LEVEL_DESCRIPTOR *)ArmGetTTBR0BaseAddress (); FirstLevelTable = (ARM_FIRST_LEVEL_DESCRIPTOR *)ArmGetTTBR0BaseAddress();
// calculate index into first level translation table for start of modification // calculate index into first level translation table for start of
FirstLevelIdx = TT_DESCRIPTOR_SECTION_BASE_ADDRESS(BaseAddress) >> TT_DESCRIPTOR_SECTION_BASE_SHIFT; // modification
ASSERT (FirstLevelIdx < TRANSLATION_TABLE_SECTION_COUNT); FirstLevelIdx = TT_DESCRIPTOR_SECTION_BASE_ADDRESS(BaseAddress) >>
TT_DESCRIPTOR_SECTION_BASE_SHIFT;
ASSERT(FirstLevelIdx < TRANSLATION_TABLE_SECTION_COUNT);
// calculate number of 1MB first level entries this applies to // calculate number of 1MB first level entries this applies to
NumSections = Length / TT_DESCRIPTOR_SECTION_SIZE; NumSections = Length / TT_DESCRIPTOR_SECTION_SIZE;
// iterate through each descriptor // iterate through each descriptor
for(i=0; i<NumSections; i++) { for (i = 0; i < NumSections; i++) {
CurrentDescriptor = FirstLevelTable[FirstLevelIdx + i]; CurrentDescriptor = FirstLevelTable[FirstLevelIdx + i];
// has this descriptor already been converted to pages? // has this descriptor already been converted to pages?
if (TT_DESCRIPTOR_SECTION_TYPE_IS_PAGE_TABLE(CurrentDescriptor)) { if (TT_DESCRIPTOR_SECTION_TYPE_IS_PAGE_TABLE(CurrentDescriptor)) {
// forward this 1MB range to page table function instead // forward this 1MB range to page table function instead
Status = UpdatePageEntries ( Status = UpdatePageEntries(
(FirstLevelIdx + i) << TT_DESCRIPTOR_SECTION_BASE_SHIFT, (FirstLevelIdx + i) << TT_DESCRIPTOR_SECTION_BASE_SHIFT,
TT_DESCRIPTOR_SECTION_SIZE, TT_DESCRIPTOR_SECTION_SIZE, Attributes, NULL);
Attributes, }
NULL); else {
} else {
// still a section entry // still a section entry
if (CurrentDescriptor != 0) { if (CurrentDescriptor != 0) {
// mask off appropriate fields // mask off appropriate fields
Descriptor = CurrentDescriptor & ~EntryMask; Descriptor = CurrentDescriptor & ~EntryMask;
} else { }
Descriptor = ((UINTN)FirstLevelIdx + i) << TT_DESCRIPTOR_SECTION_BASE_SHIFT; else {
Descriptor = ((UINTN)FirstLevelIdx + i)
<< TT_DESCRIPTOR_SECTION_BASE_SHIFT;
} }
// mask in new attributes and/or permissions // mask in new attributes and/or permissions
Descriptor |= EntryValue; Descriptor |= EntryValue;
if (CurrentDescriptor != Descriptor) { if (CurrentDescriptor != Descriptor) {
Mva = (VOID *)(UINTN)(((UINTN)FirstLevelIdx + i) << TT_DESCRIPTOR_SECTION_BASE_SHIFT); Mva =
(VOID
*)(UINTN)(((UINTN)FirstLevelIdx + i) << TT_DESCRIPTOR_SECTION_BASE_SHIFT);
// Only need to update if we are changing the descriptor // Only need to update if we are changing the descriptor
FirstLevelTable[FirstLevelIdx + i] = Descriptor; FirstLevelTable[FirstLevelIdx + i] = Descriptor;
ArmUpdateTranslationTableEntry ((VOID *)&FirstLevelTable[FirstLevelIdx + i], Mva); ArmUpdateTranslationTableEntry(
(VOID *)&FirstLevelTable[FirstLevelIdx + i], Mva);
} }
Status = EFI_SUCCESS; Status = EFI_SUCCESS;
@ -728,11 +784,8 @@ UpdateSectionEntries (
} }
EFI_STATUS EFI_STATUS
ArmSetMemoryAttributes ( ArmSetMemoryAttributes(
IN EFI_PHYSICAL_ADDRESS BaseAddress, IN EFI_PHYSICAL_ADDRESS BaseAddress, IN UINT64 Length, IN UINT64 Attributes)
IN UINT64 Length,
IN UINT64 Attributes
)
{ {
EFI_STATUS Status; EFI_STATUS Status;
UINT64 ChunkLength; UINT64 ChunkLength;
@ -742,7 +795,7 @@ ArmSetMemoryAttributes (
return EFI_UNSUPPORTED; return EFI_UNSUPPORTED;
} }
Length = MIN (Length, (UINT64)MAX_ADDRESS - BaseAddress + 1); Length = MIN(Length, (UINT64)MAX_ADDRESS - BaseAddress + 1);
if (Length == 0) { if (Length == 0) {
return EFI_SUCCESS; return EFI_SUCCESS;
} }
@ -754,14 +807,16 @@ ArmSetMemoryAttributes (
ChunkLength = Length - Length % TT_DESCRIPTOR_SECTION_SIZE; ChunkLength = Length - Length % TT_DESCRIPTOR_SECTION_SIZE;
DEBUG ((DEBUG_PAGE, DEBUG(
(DEBUG_PAGE,
"SetMemoryAttributes(): MMU section 0x%lx length 0x%lx to %lx\n", "SetMemoryAttributes(): MMU section 0x%lx length 0x%lx to %lx\n",
BaseAddress, ChunkLength, Attributes)); BaseAddress, ChunkLength, Attributes));
Status = UpdateSectionEntries (BaseAddress, ChunkLength, Attributes); Status = UpdateSectionEntries(BaseAddress, ChunkLength, Attributes);
FlushTlbs = TRUE; FlushTlbs = TRUE;
} else { }
else {
// //
// Process page by page until the next section boundary, but only if // Process page by page until the next section boundary, but only if
@ -773,15 +828,16 @@ ArmSetMemoryAttributes (
ChunkLength = Length; ChunkLength = Length;
} }
DEBUG ((DEBUG_PAGE, DEBUG(
(DEBUG_PAGE,
"SetMemoryAttributes(): MMU page 0x%lx length 0x%lx to %lx\n", "SetMemoryAttributes(): MMU page 0x%lx length 0x%lx to %lx\n",
BaseAddress, ChunkLength, Attributes)); BaseAddress, ChunkLength, Attributes));
Status = UpdatePageEntries (BaseAddress, ChunkLength, Attributes, Status =
&FlushTlbs); UpdatePageEntries(BaseAddress, ChunkLength, Attributes, &FlushTlbs);
} }
if (EFI_ERROR (Status)) { if (EFI_ERROR(Status)) {
break; break;
} }
@ -790,52 +846,38 @@ ArmSetMemoryAttributes (
} }
if (FlushTlbs) { if (FlushTlbs) {
ArmInvalidateTlb (); ArmInvalidateTlb();
} }
return Status; return Status;
} }
EFI_STATUS EFI_STATUS
ArmSetMemoryRegionNoExec ( ArmSetMemoryRegionNoExec(IN EFI_PHYSICAL_ADDRESS BaseAddress, IN UINT64 Length)
IN EFI_PHYSICAL_ADDRESS BaseAddress,
IN UINT64 Length
)
{ {
return ArmSetMemoryAttributes (BaseAddress, Length, EFI_MEMORY_XP); return ArmSetMemoryAttributes(BaseAddress, Length, EFI_MEMORY_XP);
} }
EFI_STATUS EFI_STATUS
ArmClearMemoryRegionNoExec ( ArmClearMemoryRegionNoExec(
IN EFI_PHYSICAL_ADDRESS BaseAddress, IN EFI_PHYSICAL_ADDRESS BaseAddress, IN UINT64 Length)
IN UINT64 Length
)
{ {
return ArmSetMemoryAttributes (BaseAddress, Length, __EFI_MEMORY_RWX); return ArmSetMemoryAttributes(BaseAddress, Length, __EFI_MEMORY_RWX);
} }
EFI_STATUS EFI_STATUS
ArmSetMemoryRegionReadOnly ( ArmSetMemoryRegionReadOnly(
IN EFI_PHYSICAL_ADDRESS BaseAddress, IN EFI_PHYSICAL_ADDRESS BaseAddress, IN UINT64 Length)
IN UINT64 Length
)
{ {
return ArmSetMemoryAttributes (BaseAddress, Length, EFI_MEMORY_RO); return ArmSetMemoryAttributes(BaseAddress, Length, EFI_MEMORY_RO);
} }
EFI_STATUS EFI_STATUS
ArmClearMemoryRegionReadOnly ( ArmClearMemoryRegionReadOnly(
IN EFI_PHYSICAL_ADDRESS BaseAddress, IN EFI_PHYSICAL_ADDRESS BaseAddress, IN UINT64 Length)
IN UINT64 Length
)
{ {
return ArmSetMemoryAttributes (BaseAddress, Length, __EFI_MEMORY_RWX); return ArmSetMemoryAttributes(BaseAddress, Length, __EFI_MEMORY_RWX);
} }
RETURN_STATUS RETURN_STATUS
EFIAPI EFIAPI
ArmMmuBaseLibConstructor ( ArmMmuBaseLibConstructor(VOID) { return RETURN_SUCCESS; }
VOID
)
{
return RETURN_SUCCESS;
}

View File

@ -24,7 +24,7 @@
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#include "AutoGen.h" #include "AutoGen.h"
#include <Library/BootSlotLib/BlockIoUtils.h> #include <Library/BootSlotLib/BlockIoUtils.h>
@ -42,20 +42,19 @@
BLK_IO_SEL_MATCH_ROOT_DEVICE) BLK_IO_SEL_MATCH_ROOT_DEVICE)
/* Returns 0 if the volume label matches otherwise non zero */ /* Returns 0 if the volume label matches otherwise non zero */
STATIC UINTN STATIC UINTN CompareVolumeLabel(
CompareVolumeLabel (IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL* Fs, IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *Fs, IN CHAR8 *ReqVolumeName)
IN CHAR8* ReqVolumeName)
{ {
INT32 CmpResult; INT32 CmpResult;
UINT32 j; UINT32 j;
UINT16 VolumeLabel[VOLUME_LABEL_SIZE]; UINT16 VolumeLabel[VOLUME_LABEL_SIZE];
EFI_FILE_PROTOCOL *FsVolume = NULL; EFI_FILE_PROTOCOL * FsVolume = NULL;
EFI_STATUS Status; EFI_STATUS Status;
UINTN Size; UINTN Size;
EFI_FILE_SYSTEM_INFO *FsInfo; EFI_FILE_SYSTEM_INFO *FsInfo;
// Get information about the volume // Get information about the volume
Status = Fs->OpenVolume (Fs, &FsVolume); Status = Fs->OpenVolume(Fs, &FsVolume);
if (Status != EFI_SUCCESS) { if (Status != EFI_SUCCESS) {
return 1; return 1;
@ -64,13 +63,13 @@ CompareVolumeLabel (IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL* Fs,
/* Get the Volume name */ /* Get the Volume name */
Size = 0; Size = 0;
FsInfo = NULL; FsInfo = NULL;
Status = FsVolume->GetInfo (FsVolume, &gEfiFileSystemInfoGuid, &Size, FsInfo); Status = FsVolume->GetInfo(FsVolume, &gEfiFileSystemInfoGuid, &Size, FsInfo);
if (Status == EFI_BUFFER_TOO_SMALL) { if (Status == EFI_BUFFER_TOO_SMALL) {
FsInfo = AllocateZeroPool (Size); FsInfo = AllocateZeroPool(Size);
Status = FsVolume->GetInfo (FsVolume, Status =
&gEfiFileSystemInfoGuid, &Size, FsInfo); FsVolume->GetInfo(FsVolume, &gEfiFileSystemInfoGuid, &Size, FsInfo);
if (Status != EFI_SUCCESS) { if (Status != EFI_SUCCESS) {
FreePool (FsInfo); FreePool(FsInfo);
return 1; return 1;
} }
} }
@ -83,8 +82,7 @@ CompareVolumeLabel (IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL* Fs,
for (j = 0; (j < VOLUME_LABEL_SIZE - 1) && ReqVolumeName[j]; ++j) { for (j = 0; (j < VOLUME_LABEL_SIZE - 1) && ReqVolumeName[j]; ++j) {
VolumeLabel[j] = ReqVolumeName[j]; VolumeLabel[j] = ReqVolumeName[j];
if ((VolumeLabel[j] >= 'a') && if ((VolumeLabel[j] >= 'a') && (VolumeLabel[j] <= 'z')) {
(VolumeLabel[j] <= 'z')) {
VolumeLabel[j] -= ('a' - 'A'); VolumeLabel[j] -= ('a' - 'A');
} }
} }
@ -95,27 +93,26 @@ CompareVolumeLabel (IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL* Fs,
/* Change any lower chars in volume name to upper /* Change any lower chars in volume name to upper
* (ideally this is not needed) */ * (ideally this is not needed) */
for (j = 0; (j < VOLUME_LABEL_SIZE - 1) && FsInfo->VolumeLabel[j]; ++j) { for (j = 0; (j < VOLUME_LABEL_SIZE - 1) && FsInfo->VolumeLabel[j]; ++j) {
if ((FsInfo->VolumeLabel[j] >= 'a') && if ((FsInfo->VolumeLabel[j] >= 'a') && (FsInfo->VolumeLabel[j] <= 'z')) {
(FsInfo->VolumeLabel[j] <= 'z')) {
FsInfo->VolumeLabel[j] -= ('a' - 'A'); FsInfo->VolumeLabel[j] -= ('a' - 'A');
} }
} }
CmpResult = StrnCmp (FsInfo->VolumeLabel, VolumeLabel, VOLUME_LABEL_SIZE); CmpResult = StrnCmp(FsInfo->VolumeLabel, VolumeLabel, VOLUME_LABEL_SIZE);
FreePool (FsInfo); FreePool(FsInfo);
FsVolume->Close (FsVolume); FsVolume->Close(FsVolume);
return CmpResult; return CmpResult;
} }
EFI_STATUS EFI_STATUS
EFIAPI EFIAPI
GetPartitionEntry (IN EFI_HANDLE Handle, GetPartitionEntry(IN EFI_HANDLE Handle, OUT EFI_PARTITION_ENTRY **PartEntry)
OUT EFI_PARTITION_ENTRY **PartEntry)
{ {
EFI_PARTITION_INFO_PROTOCOL *PartInfo; EFI_PARTITION_INFO_PROTOCOL *PartInfo;
EFI_STATUS Status = gBS->HandleProtocol (Handle, &gEfiPartitionInfoProtocolGuid, (VOID **)&PartInfo); EFI_STATUS Status = gBS->HandleProtocol(
Handle, &gEfiPartitionInfoProtocolGuid, (VOID **)&PartInfo);
if (!EFI_ERROR(Status)) { if (!EFI_ERROR(Status)) {
*PartEntry = &PartInfo->Info.Gpt; *PartEntry = &PartInfo->Info.Gpt;
} }
@ -139,24 +136,23 @@ On output, the number of handle structures returned.
*/ */
EFI_STATUS EFI_STATUS
EFIAPI EFIAPI
GetBlkIOHandles (IN UINT32 SelectionAttrib, GetBlkIOHandles(
IN PartiSelectFilter *FilterData, IN UINT32 SelectionAttrib, IN PartiSelectFilter *FilterData,
OUT HandleInfo *HandleInfoPtr, OUT HandleInfo *HandleInfoPtr, IN OUT UINT32 *MaxBlkIopCnt)
IN OUT UINT32* MaxBlkIopCnt)
{ {
EFI_BLOCK_IO_PROTOCOL *BlkIo; EFI_BLOCK_IO_PROTOCOL * BlkIo;
EFI_HANDLE *BlkIoHandles; EFI_HANDLE * BlkIoHandles;
UINTN BlkIoHandleCount; UINTN BlkIoHandleCount;
UINTN i; UINTN i;
UINTN DevicePathDepth; UINTN DevicePathDepth;
HARDDRIVE_DEVICE_PATH *Partition, *PartitionOut; HARDDRIVE_DEVICE_PATH * Partition, *PartitionOut;
EFI_STATUS Status; EFI_STATUS Status;
EFI_DEVICE_PATH_PROTOCOL *DevPathInst; EFI_DEVICE_PATH_PROTOCOL * DevPathInst;
EFI_DEVICE_PATH_PROTOCOL *TempDevicePath; EFI_DEVICE_PATH_PROTOCOL * TempDevicePath;
VENDOR_DEVICE_PATH *RootDevicePath; VENDOR_DEVICE_PATH * RootDevicePath;
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *Fs; EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *Fs;
UINT32 BlkIoCnt = 0; UINT32 BlkIoCnt = 0;
EFI_PARTITION_ENTRY *PartEntry; EFI_PARTITION_ENTRY * PartEntry;
if ((MaxBlkIopCnt == NULL) || (HandleInfoPtr == NULL)) if ((MaxBlkIopCnt == NULL) || (HandleInfoPtr == NULL))
return EFI_INVALID_PARAMETER; return EFI_INVALID_PARAMETER;
@ -176,32 +172,33 @@ GetBlkIOHandles (IN UINT32 SelectionAttrib,
* than BlkIo */ * than BlkIo */
if (SelectionAttrib & (BLK_IO_SEL_SELECT_MOUNTED_FILESYSTEM | if (SelectionAttrib & (BLK_IO_SEL_SELECT_MOUNTED_FILESYSTEM |
BLK_IO_SEL_SELECT_BY_VOLUME_NAME)) { BLK_IO_SEL_SELECT_BY_VOLUME_NAME)) {
Status = Status = gBS->LocateHandleBuffer(
gBS->LocateHandleBuffer (ByProtocol, &gEfiSimpleFileSystemProtocolGuid, ByProtocol, &gEfiSimpleFileSystemProtocolGuid, NULL, &BlkIoHandleCount,
NULL, &BlkIoHandleCount, &BlkIoHandles); &BlkIoHandles);
} else { }
Status = gBS->LocateHandleBuffer (ByProtocol, &gEfiBlockIoProtocolGuid, else {
NULL, &BlkIoHandleCount, &BlkIoHandles); Status = gBS->LocateHandleBuffer(
ByProtocol, &gEfiBlockIoProtocolGuid, NULL, &BlkIoHandleCount,
&BlkIoHandles);
} }
if (Status != EFI_SUCCESS) { if (Status != EFI_SUCCESS) {
DEBUG ( DEBUG((EFI_D_ERROR, "Unable to get Filesystem Handle buffer %r\n", Status));
(EFI_D_ERROR, "Unable to get Filesystem Handle buffer %r\n", Status));
return Status; return Status;
} }
/* Loop through to search for the ones we are interested in. */ /* Loop through to search for the ones we are interested in. */
for (i = 0; i < BlkIoHandleCount; i++) { for (i = 0; i < BlkIoHandleCount; i++) {
Status = gBS->HandleProtocol (BlkIoHandles[i], &gEfiBlockIoProtocolGuid, Status = gBS->HandleProtocol(
(VOID **)&BlkIo); BlkIoHandles[i], &gEfiBlockIoProtocolGuid, (VOID **)&BlkIo);
/* Fv volumes will not support Blk I/O protocol */ /* Fv volumes will not support Blk I/O protocol */
if (Status == EFI_UNSUPPORTED) { if (Status == EFI_UNSUPPORTED) {
continue; continue;
} }
if (Status != EFI_SUCCESS) { if (Status != EFI_SUCCESS) {
DEBUG ((EFI_D_ERROR, "Unable to get Filesystem Handle %r\n", Status)); DEBUG((EFI_D_ERROR, "Unable to get Filesystem Handle %r\n", Status));
return Status; return Status;
} }
@ -209,7 +206,8 @@ GetBlkIOHandles (IN UINT32 SelectionAttrib,
if (BlkIo->Media->RemovableMedia) { if (BlkIo->Media->RemovableMedia) {
if ((SelectionAttrib & BLK_IO_SEL_MEDIA_TYPE_REMOVABLE) == 0) if ((SelectionAttrib & BLK_IO_SEL_MEDIA_TYPE_REMOVABLE) == 0)
continue; continue;
} else { }
else {
if ((SelectionAttrib & BLK_IO_SEL_MEDIA_TYPE_NON_REMOVABLE) == 0) if ((SelectionAttrib & BLK_IO_SEL_MEDIA_TYPE_NON_REMOVABLE) == 0)
continue; continue;
} }
@ -219,12 +217,12 @@ GetBlkIOHandles (IN UINT32 SelectionAttrib,
/* Check if partition related criteria satisfies */ /* Check if partition related criteria satisfies */
if ((SelectionAttrib & FILTERS_NEEDING_DEVICEPATH) != 0) { if ((SelectionAttrib & FILTERS_NEEDING_DEVICEPATH) != 0) {
Status = gBS->HandleProtocol ( Status = gBS->HandleProtocol(
BlkIoHandles[i], &gEfiDevicePathProtocolGuid, (VOID **)&DevPathInst); BlkIoHandles[i], &gEfiDevicePathProtocolGuid, (VOID **)&DevPathInst);
/* If we didn't get the DevicePath Protocol then this handle /* If we didn't get the DevicePath Protocol then this handle
* cannot be used */ * cannot be used */
if (EFI_ERROR (Status)) if (EFI_ERROR(Status))
continue; continue;
DevicePathDepth = 0; DevicePathDepth = 0;
@ -245,18 +243,18 @@ GetBlkIOHandles (IN UINT32 SelectionAttrib,
RootDevicePath->Header.SubType != HW_VENDOR_DP || RootDevicePath->Header.SubType != HW_VENDOR_DP ||
(RootDevicePath->Header.Length[0] | (RootDevicePath->Header.Length[0] |
(RootDevicePath->Header.Length[1] << 8)) != (RootDevicePath->Header.Length[1] << 8)) !=
sizeof (VENDOR_DEVICE_PATH) || sizeof(VENDOR_DEVICE_PATH) ||
((FilterData->RootDeviceType != NULL) && ((FilterData->RootDeviceType != NULL) &&
(CompareGuid (FilterData->RootDeviceType, (CompareGuid(FilterData->RootDeviceType, &RootDevicePath->Guid) ==
&RootDevicePath->Guid) == FALSE))) FALSE)))
continue; continue;
} }
/* Locate the last Device Path Node */ /* Locate the last Device Path Node */
while (!IsDevicePathEnd (TempDevicePath)) { while (!IsDevicePathEnd(TempDevicePath)) {
DevicePathDepth++; DevicePathDepth++;
Partition = (HARDDRIVE_DEVICE_PATH *)TempDevicePath; Partition = (HARDDRIVE_DEVICE_PATH *)TempDevicePath;
TempDevicePath = NextDevicePathNode (TempDevicePath); TempDevicePath = NextDevicePathNode(TempDevicePath);
} }
/* If we need the handle for root device only and if this is representing /* If we need the handle for root device only and if this is representing
@ -270,7 +268,7 @@ GetBlkIOHandles (IN UINT32 SelectionAttrib,
if (Partition->Header.Type == MEDIA_DEVICE_PATH && if (Partition->Header.Type == MEDIA_DEVICE_PATH &&
Partition->Header.SubType == MEDIA_HARDDRIVE_DP && Partition->Header.SubType == MEDIA_HARDDRIVE_DP &&
(Partition->Header.Length[0] | (Partition->Header.Length[1] << 8)) == (Partition->Header.Length[0] | (Partition->Header.Length[1] << 8)) ==
sizeof (*Partition)) { sizeof(*Partition)) {
PartitionOut = Partition; PartitionOut = Partition;
if ((SelectionAttrib & BLK_IO_SEL_PARTITIONED_GPT) == 0) if ((SelectionAttrib & BLK_IO_SEL_PARTITIONED_GPT) == 0)
@ -285,20 +283,20 @@ GetBlkIOHandles (IN UINT32 SelectionAttrib,
if ((SelectionAttrib & BLK_IO_SEL_MATCH_PARTITION_TYPE_GUID) != 0) { if ((SelectionAttrib & BLK_IO_SEL_MATCH_PARTITION_TYPE_GUID) != 0) {
VOID *Interface; VOID *Interface;
if (!FilterData || if (!FilterData || FilterData->PartitionType == NULL) {
FilterData->PartitionType == NULL) {
return EFI_INVALID_PARAMETER; return EFI_INVALID_PARAMETER;
} }
Status = gBS->HandleProtocol (BlkIoHandles[i], Status = gBS->HandleProtocol(
FilterData->PartitionType, BlkIoHandles[i], FilterData->PartitionType, (VOID **)&Interface);
(VOID**)&Interface); if (EFI_ERROR(Status)) {
if (EFI_ERROR (Status)) {
Status = GetPartitionEntry(BlkIoHandles[i], &PartEntry); Status = GetPartitionEntry(BlkIoHandles[i], &PartEntry);
if (EFI_ERROR (Status)) { if (EFI_ERROR(Status)) {
continue; continue;
} }
if (CompareGuid (&PartEntry->PartitionTypeGUID, FilterData->PartitionType) == FALSE) { if (CompareGuid(
&PartEntry->PartitionTypeGUID, FilterData->PartitionType) ==
FALSE) {
continue; continue;
} }
} }
@ -312,18 +310,17 @@ GetBlkIOHandles (IN UINT32 SelectionAttrib,
/* Check if the Filesystem related criteria satisfies */ /* Check if the Filesystem related criteria satisfies */
if ((SelectionAttrib & BLK_IO_SEL_SELECT_MOUNTED_FILESYSTEM) != 0) { if ((SelectionAttrib & BLK_IO_SEL_SELECT_MOUNTED_FILESYSTEM) != 0) {
Status = gBS->HandleProtocol (BlkIoHandles[i], Status = gBS->HandleProtocol(
&gEfiSimpleFileSystemProtocolGuid, (VOID **)&Fs); BlkIoHandles[i], &gEfiSimpleFileSystemProtocolGuid, (VOID **)&Fs);
if (EFI_ERROR (Status)) { if (EFI_ERROR(Status)) {
continue; continue;
} }
if ((SelectionAttrib & BLK_IO_SEL_SELECT_BY_VOLUME_NAME) != 0) { if ((SelectionAttrib & BLK_IO_SEL_SELECT_BY_VOLUME_NAME) != 0) {
if (!FilterData || if (!FilterData || FilterData->VolumeName == NULL) {
FilterData->VolumeName == NULL) {
return EFI_INVALID_PARAMETER; return EFI_INVALID_PARAMETER;
} }
if (CompareVolumeLabel (Fs, FilterData->VolumeName) != 0) { if (CompareVolumeLabel(Fs, FilterData->VolumeName) != 0) {
continue; continue;
} }
} }
@ -334,9 +331,10 @@ GetBlkIOHandles (IN UINT32 SelectionAttrib,
Status = GetPartitionEntry(BlkIoHandles[i], &PartEntry); Status = GetPartitionEntry(BlkIoHandles[i], &PartEntry);
if (Status != EFI_SUCCESS) if (Status != EFI_SUCCESS)
continue; continue;
if (StrnCmp (PartEntry->PartitionName, FilterData->PartitionLabel, if (StrnCmp(
MAX (StrLen (PartEntry->PartitionName), PartEntry->PartitionName, FilterData->PartitionLabel,
StrLen (FilterData->PartitionLabel)))) MAX(StrLen(PartEntry->PartitionName),
StrLen(FilterData->PartitionLabel))))
continue; continue;
} }
/* We came here means, this handle satisfies all the conditions needed, /* We came here means, this handle satisfies all the conditions needed,
@ -353,7 +351,7 @@ GetBlkIOHandles (IN UINT32 SelectionAttrib,
/* Free the handle buffer */ /* Free the handle buffer */
if (BlkIoHandles != NULL) { if (BlkIoHandles != NULL) {
FreePool (BlkIoHandles); FreePool(BlkIoHandles);
BlkIoHandles = NULL; BlkIoHandles = NULL;
} }

View File

@ -19,14 +19,17 @@
#include <Library/BootSlotLib/EFIUtils.h> #include <Library/BootSlotLib/EFIUtils.h>
#include <Library/UefiLib.h> #include <Library/UefiLib.h>
void WaitAnyKey(EFI_SYSTEM_TABLE *mSystemTable) { void WaitAnyKey(EFI_SYSTEM_TABLE *mSystemTable)
{
UINTN index = 0; UINTN index = 0;
EFI_INPUT_KEY Key; EFI_INPUT_KEY Key;
mSystemTable->BootServices->WaitForEvent(1, &mSystemTable->ConIn->WaitForKey, &index); mSystemTable->BootServices->WaitForEvent(
1, &mSystemTable->ConIn->WaitForKey, &index);
mSystemTable->ConIn->ReadKeyStroke(mSystemTable->ConIn, &Key); mSystemTable->ConIn->ReadKeyStroke(mSystemTable->ConIn, &Key);
} }
void PrintAndWaitAnyKey(EFI_SYSTEM_TABLE *mSystemTable, CHAR16 *Message) { void PrintAndWaitAnyKey(EFI_SYSTEM_TABLE *mSystemTable, CHAR16 *Message)
{
Print(Message); Print(Message);
WaitAnyKey(mSystemTable); WaitAnyKey(mSystemTable);
} }

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,5 @@
/* Copyright (c) 2015-2018, 2020-2021, The Linux Foundation. All rights reserved. /* Copyright (c) 2015-2018, 2020-2021, The Linux Foundation. All rights
* reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are * modification, are permitted provided that the following conditions are
@ -24,15 +25,17 @@
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#include "AutoGen.h" #include "AutoGen.h"
#include <Library/BootSlotLib/StorageUtils.h>
#include <Library/BootSlotLib/BlockIoUtils.h> #include <Library/BootSlotLib/BlockIoUtils.h>
#include <Library/BootSlotLib/StorageUtils.h>
STATIC CONST CHAR8 *DeviceType[] = { STATIC CONST CHAR8 *DeviceType[] = {
[EMMC] = "EMMC", [UFS] = "UFS", [UNKNOWN] = "Unknown", [EMMC] = "EMMC",
[UFS] = "UFS",
[UNKNOWN] = "Unknown",
}; };
/** /**
@ -48,12 +51,12 @@ STATIC CONST CHAR8 *DeviceType[] = {
**/ **/
STATIC EFI_STATUS STATIC EFI_STATUS
GetDeviceHandleInfo (VOID *HndlInfo, UINT32 MaxHandles, MemCardType Type) GetDeviceHandleInfo(VOID *HndlInfo, UINT32 MaxHandles, MemCardType Type)
{ {
EFI_STATUS Status = EFI_INVALID_PARAMETER; EFI_STATUS Status = EFI_INVALID_PARAMETER;
UINT32 Attribs = 0; UINT32 Attribs = 0;
PartiSelectFilter HandleFilter; PartiSelectFilter HandleFilter;
HandleInfo *HandleInfoList = HndlInfo; HandleInfo * HandleInfoList = HndlInfo;
Attribs |= BLK_IO_SEL_MATCH_ROOT_DEVICE; Attribs |= BLK_IO_SEL_MATCH_ROOT_DEVICE;
HandleFilter.PartitionType = NULL; HandleFilter.PartitionType = NULL;
@ -67,15 +70,13 @@ GetDeviceHandleInfo (VOID *HndlInfo, UINT32 MaxHandles, MemCardType Type)
HandleFilter.RootDeviceType = &gEfiEmmcUserPartitionGuid; HandleFilter.RootDeviceType = &gEfiEmmcUserPartitionGuid;
break; break;
case UNKNOWN: case UNKNOWN:
DEBUG ((EFI_D_ERROR, "Device type unknown\n")); DEBUG((EFI_D_ERROR, "Device type unknown\n"));
return Status; return Status;
} }
Status = Status = GetBlkIOHandles(Attribs, &HandleFilter, HandleInfoList, &MaxHandles);
GetBlkIOHandles (Attribs, &HandleFilter, HandleInfoList, &MaxHandles); if (EFI_ERROR(Status) || MaxHandles == 0) {
if (EFI_ERROR (Status) || DEBUG((EFI_D_ERROR, "Get BlkIohandles failed\n"));
MaxHandles == 0) {
DEBUG ((EFI_D_ERROR, "Get BlkIohandles failed\n"));
return Status; return Status;
} }
return Status; return Status;
@ -85,16 +86,15 @@ GetDeviceHandleInfo (VOID *HndlInfo, UINT32 MaxHandles, MemCardType Type)
Return a device type Return a device type
@retval Device type : UNKNOWN | UFS | EMMC | NAND @retval Device type : UNKNOWN | UFS | EMMC | NAND
**/ **/
STATIC UINT32 STATIC UINT32 GetCompatibleRootDeviceType(VOID)
GetCompatibleRootDeviceType (VOID)
{ {
EFI_STATUS Status = EFI_INVALID_PARAMETER; EFI_STATUS Status = EFI_INVALID_PARAMETER;
HandleInfo HandleInfoList[HANDLE_MAX_INFO_LIST]; HandleInfo HandleInfoList[HANDLE_MAX_INFO_LIST];
UINT32 MaxHandles = ARRAY_SIZE (HandleInfoList); UINT32 MaxHandles = ARRAY_SIZE(HandleInfoList);
UINT32 Index; UINT32 Index;
for (Index = 0; Index < UNKNOWN; Index++) { for (Index = 0; Index < UNKNOWN; Index++) {
Status = GetDeviceHandleInfo (HandleInfoList, MaxHandles, Index); Status = GetDeviceHandleInfo(HandleInfoList, MaxHandles, Index);
if (Status == EFI_SUCCESS) { if (Status == EFI_SUCCESS) {
return Index; return Index;
} }
@ -108,8 +108,7 @@ GetCompatibleRootDeviceType (VOID)
@retval Device type : UNKNOWN | UFS | EMMC, default is UNKNOWN @retval Device type : UNKNOWN | UFS | EMMC, default is UNKNOWN
**/ **/
MemCardType MemCardType CheckRootDeviceType(VOID)
CheckRootDeviceType (VOID)
{ {
EFI_STATUS Status = EFI_INVALID_PARAMETER; EFI_STATUS Status = EFI_INVALID_PARAMETER;
STATIC MemCardType Type = UNKNOWN; STATIC MemCardType Type = UNKNOWN;
@ -117,22 +116,25 @@ CheckRootDeviceType (VOID)
EFI_MEM_CARDINFO_PROTOCOL *CardInfo; EFI_MEM_CARDINFO_PROTOCOL *CardInfo;
if (Type == UNKNOWN) { if (Type == UNKNOWN) {
Status = gBS->LocateProtocol (&gEfiMemCardInfoProtocolGuid, NULL, Status = gBS->LocateProtocol(
(VOID **)&CardInfo); &gEfiMemCardInfoProtocolGuid, NULL, (VOID **)&CardInfo);
if (!EFI_ERROR (Status)) { if (!EFI_ERROR(Status)) {
Status = CardInfo->GetCardInfo (CardInfo, &CardInfoData); Status = CardInfo->GetCardInfo(CardInfo, &CardInfoData);
if (!EFI_ERROR (Status)) { if (!EFI_ERROR(Status)) {
if (!AsciiStrnCmp ((CHAR8 *)CardInfoData.card_type, "UFS", if (!AsciiStrnCmp(
AsciiStrLen ("UFS"))) { (CHAR8 *)CardInfoData.card_type, "UFS", AsciiStrLen("UFS"))) {
Type = UFS; Type = UFS;
} else if (!AsciiStrnCmp ((CHAR8 *)CardInfoData.card_type, "EMMC", }
AsciiStrLen ("EMMC"))) { else if (!AsciiStrnCmp(
(CHAR8 *)CardInfoData.card_type, "EMMC",
AsciiStrLen("EMMC"))) {
Type = EMMC; Type = EMMC;
} else { }
Type = GetCompatibleRootDeviceType (); else {
Type = GetCompatibleRootDeviceType();
} }
} }
} }
@ -145,17 +147,16 @@ CheckRootDeviceType (VOID)
@param[out] StrDeviceType : Pointer to array of device type string. @param[out] StrDeviceType : Pointer to array of device type string.
@param[in] Len : The size of the device type string @param[in] Len : The size of the device type string
**/ **/
VOID VOID GetRootDeviceType(CHAR8 *StrDeviceType, UINT32 Len)
GetRootDeviceType (CHAR8 *StrDeviceType, UINT32 Len)
{ {
UINT32 Type; UINT32 Type;
Type = CheckRootDeviceType (); Type = CheckRootDeviceType();
AsciiSPrint (StrDeviceType, Len, "%a", DeviceType[Type]); AsciiSPrint(StrDeviceType, Len, "%a", DeviceType[Type]);
} }
EFI_STATUS EFI_STATUS
UfsGetSetBootLun (UINT32 *UfsBootlun, BOOLEAN IsGet) UfsGetSetBootLun(UINT32 *UfsBootlun, BOOLEAN IsGet)
{ {
EFI_STATUS Status = EFI_INVALID_PARAMETER; EFI_STATUS Status = EFI_INVALID_PARAMETER;
EFI_MEM_CARDINFO_PROTOCOL *CardInfo; EFI_MEM_CARDINFO_PROTOCOL *CardInfo;
@ -165,37 +166,38 @@ UfsGetSetBootLun (UINT32 *UfsBootlun, BOOLEAN IsGet)
PartiSelectFilter HandleFilter; PartiSelectFilter HandleFilter;
Attribs |= BLK_IO_SEL_MATCH_ROOT_DEVICE; Attribs |= BLK_IO_SEL_MATCH_ROOT_DEVICE;
MaxHandles = ARRAY_SIZE (HandleInfoList); MaxHandles = ARRAY_SIZE(HandleInfoList);
HandleFilter.PartitionType = NULL; HandleFilter.PartitionType = NULL;
HandleFilter.VolumeName = NULL; HandleFilter.VolumeName = NULL;
HandleFilter.RootDeviceType = &gEfiUfsLU0Guid; HandleFilter.RootDeviceType = &gEfiUfsLU0Guid;
Status = Status = GetBlkIOHandles(Attribs, &HandleFilter, HandleInfoList, &MaxHandles);
GetBlkIOHandles (Attribs, &HandleFilter, HandleInfoList, &MaxHandles); if (EFI_ERROR(Status))
if (EFI_ERROR (Status))
return EFI_NOT_FOUND; return EFI_NOT_FOUND;
Status = Status = gBS->HandleProtocol(
gBS->HandleProtocol (HandleInfoList[0].Handle, HandleInfoList[0].Handle, &gEfiMemCardInfoProtocolGuid,
&gEfiMemCardInfoProtocolGuid, (VOID **)&CardInfo); (VOID **)&CardInfo);
if (Status != EFI_SUCCESS) { if (Status != EFI_SUCCESS) {
DEBUG ((EFI_D_ERROR, "Error locating MemCardInfoProtocol:%x\n", Status)); DEBUG((EFI_D_ERROR, "Error locating MemCardInfoProtocol:%x\n", Status));
return Status; return Status;
} }
if (CardInfo->Revision < EFI_MEM_CARD_INFO_PROTOCOL_REVISION) { if (CardInfo->Revision < EFI_MEM_CARD_INFO_PROTOCOL_REVISION) {
DEBUG ((EFI_D_ERROR, "This API not supported in Revision =%u\n", DEBUG(
(EFI_D_ERROR, "This API not supported in Revision =%u\n",
CardInfo->Revision)); CardInfo->Revision));
return EFI_NOT_FOUND; return EFI_NOT_FOUND;
} }
if (IsGet == TRUE) { if (IsGet == TRUE) {
if (CardInfo->GetBootLU (CardInfo, UfsBootlun) == EFI_SUCCESS) if (CardInfo->GetBootLU(CardInfo, UfsBootlun) == EFI_SUCCESS)
DEBUG ((EFI_D_VERBOSE, "Get BootLun =%u\n", *UfsBootlun)); DEBUG((EFI_D_VERBOSE, "Get BootLun =%u\n", *UfsBootlun));
} else { }
if (CardInfo->SetBootLU (CardInfo, *UfsBootlun) == EFI_SUCCESS) else {
DEBUG ((EFI_D_VERBOSE, "SetBootLun =%u\n", *UfsBootlun)); if (CardInfo->SetBootLU(CardInfo, *UfsBootlun) == EFI_SUCCESS)
DEBUG((EFI_D_VERBOSE, "SetBootLun =%u\n", *UfsBootlun));
} }
return Status; return Status;
} }

View File

@ -5,8 +5,8 @@
#include <Library/HobLib.h> #include <Library/HobLib.h>
#include <Library/SerialPortLib.h> #include <Library/SerialPortLib.h>
#include <Resources/font5x12.h>
#include <Resources/FbColor.h> #include <Resources/FbColor.h>
#include <Resources/font5x12.h>
#include "FrameBufferSerialPortLib.h" #include "FrameBufferSerialPortLib.h"
@ -21,21 +21,11 @@ UINTN gHeight = FixedPcdGet32(PcdMipiFrameBufferHeight);
UINTN gBpp = FixedPcdGet32(PcdMipiFrameBufferPixelBpp); UINTN gBpp = FixedPcdGet32(PcdMipiFrameBufferPixelBpp);
// Module-used internal routine // Module-used internal routine
void FbConPutCharWithFactor void FbConPutCharWithFactor(char c, int type, unsigned scale_factor);
(
char c,
int type,
unsigned scale_factor
);
void FbConDrawglyph void FbConDrawglyph(
( char *pixels, unsigned stride, unsigned bpp, unsigned *glyph,
char *pixels, unsigned scale_factor);
unsigned stride,
unsigned bpp,
unsigned *glyph,
unsigned scale_factor
);
void FbConReset(void); void FbConReset(void);
void FbConScrollUp(void); void FbConScrollUp(void);
@ -43,15 +33,13 @@ void FbConFlush(void);
RETURN_STATUS RETURN_STATUS
EFIAPI EFIAPI
SerialPortInitialize SerialPortInitialize(VOID)
(
VOID
)
{ {
UINTN InterruptState = 0; UINTN InterruptState = 0;
// Prevent dup initialization // Prevent dup initialization
if (m_Initialized) return RETURN_SUCCESS; if (m_Initialized)
return RETURN_SUCCESS;
// Interrupt Disable // Interrupt Disable
InterruptState = ArmGetInterruptState(); InterruptState = ArmGetInterruptState();
@ -63,25 +51,23 @@ SerialPortInitialize
// Set flag // Set flag
m_Initialized = TRUE; m_Initialized = TRUE;
if (InterruptState) ArmEnableInterrupts(); if (InterruptState)
ArmEnableInterrupts();
return RETURN_SUCCESS; return RETURN_SUCCESS;
} }
void ResetFb(void) void ResetFb(void)
{ {
// Clear current screen. // Clear current screen.
char* Pixels = (void*)FixedPcdGet32(PcdMipiFrameBufferAddress); char *Pixels = (void *)FixedPcdGet32(PcdMipiFrameBufferAddress);
UINTN BgColor = FB_BGRA8888_BLACK; UINTN BgColor = FB_BGRA8888_BLACK;
// Set to black color. // Set to black color.
for (UINTN i = 0; i < gWidth; i++) for (UINTN i = 0; i < gWidth; i++) {
{ for (UINTN j = 0; j < gHeight; j++) {
for (UINTN j = 0; j < gHeight; j++)
{
BgColor = FB_BGRA8888_BLACK; BgColor = FB_BGRA8888_BLACK;
// Set pixel bit // Set pixel bit
for (UINTN p = 0; p < (gBpp / 8); p++) for (UINTN p = 0; p < (gBpp / 8); p++) {
{
*Pixels = (unsigned char)BgColor; *Pixels = (unsigned char)BgColor;
BgColor = BgColor >> 8; BgColor = BgColor >> 8;
Pixels++; Pixels++;
@ -105,112 +91,91 @@ void FbConReset(void)
m_Color.Background = FB_BGRA8888_BLACK; m_Color.Background = FB_BGRA8888_BLACK;
} }
void FbConPutCharWithFactor void FbConPutCharWithFactor(char c, int type, unsigned scale_factor)
(
char c,
int type,
unsigned scale_factor
)
{ {
char* Pixels; char *Pixels;
if (!m_Initialized) return; if (!m_Initialized)
return;
paint: paint:
if ((unsigned char)c > 127) return; if ((unsigned char)c > 127)
return;
if ((unsigned char)c < 32) if ((unsigned char)c < 32) {
{ if (c == '\n') {
if (c == '\n')
{
goto newline; goto newline;
} }
else if (c == '\r') else if (c == '\r') {
{
m_Position.x = 0; m_Position.x = 0;
return; return;
} }
else else {
{
return; return;
} }
} }
// Save some space // Save some space
if (m_Position.x == 0 && (unsigned char)c == ' ' && if (m_Position.x == 0 && (unsigned char)c == ' ' &&
type != FBCON_SUBTITLE_MSG && type != FBCON_SUBTITLE_MSG && type != FBCON_TITLE_MSG)
type != FBCON_TITLE_MSG)
return; return;
BOOLEAN intstate = ArmGetInterruptState(); BOOLEAN intstate = ArmGetInterruptState();
ArmDisableInterrupts(); ArmDisableInterrupts();
Pixels = (void*)FixedPcdGet32(PcdMipiFrameBufferAddress); Pixels = (void *)FixedPcdGet32(PcdMipiFrameBufferAddress);
Pixels += m_Position.y * ((gBpp / 8) * FONT_HEIGHT * gWidth); Pixels += m_Position.y * ((gBpp / 8) * FONT_HEIGHT * gWidth);
Pixels += m_Position.x * scale_factor * ((gBpp / 8) * (FONT_WIDTH + 1)); Pixels += m_Position.x * scale_factor * ((gBpp / 8) * (FONT_WIDTH + 1));
FbConDrawglyph( FbConDrawglyph(
Pixels, Pixels, gWidth, (gBpp / 8), font5x12 + (c - 32) * 2, scale_factor);
gWidth,
(gBpp / 8),
font5x12 + (c - 32) * 2,
scale_factor);
m_Position.x++; m_Position.x++;
if (m_Position.x >= (int)(m_MaxPosition.x / scale_factor)) goto newline; if (m_Position.x >= (int)(m_MaxPosition.x / scale_factor))
goto newline;
if (intstate) ArmEnableInterrupts(); if (intstate)
ArmEnableInterrupts();
return; return;
newline: newline:
m_Position.y += scale_factor; m_Position.y += scale_factor;
m_Position.x = 0; m_Position.x = 0;
if (m_Position.y >= m_MaxPosition.y - scale_factor) if (m_Position.y >= m_MaxPosition.y - scale_factor) {
{
ResetFb(); ResetFb();
FbConFlush(); FbConFlush();
m_Position.y = 0; m_Position.y = 0;
if (intstate) ArmEnableInterrupts(); if (intstate)
ArmEnableInterrupts();
goto paint; goto paint;
} }
else else {
{
FbConFlush(); FbConFlush();
if (intstate) ArmEnableInterrupts(); if (intstate)
ArmEnableInterrupts();
} }
} }
void FbConDrawglyph void FbConDrawglyph(
( char *pixels, unsigned stride, unsigned bpp, unsigned *glyph,
char *pixels, unsigned scale_factor)
unsigned stride,
unsigned bpp,
unsigned *glyph,
unsigned scale_factor
)
{ {
char *bg_pixels = pixels; char * bg_pixels = pixels;
unsigned x, y, i, j, k; unsigned x, y, i, j, k;
unsigned data, temp; unsigned data, temp;
unsigned int fg_color = m_Color.Foreground; unsigned int fg_color = m_Color.Foreground;
unsigned int bg_color = m_Color.Background; unsigned int bg_color = m_Color.Background;
stride -= FONT_WIDTH * scale_factor; stride -= FONT_WIDTH * scale_factor;
for (y = 0; y < FONT_HEIGHT / 2; ++y) for (y = 0; y < FONT_HEIGHT / 2; ++y) {
{ for (i = 0; i < scale_factor; i++) {
for (i = 0; i < scale_factor; i++) for (x = 0; x < FONT_WIDTH; ++x) {
{ for (j = 0; j < scale_factor; j++) {
for (x = 0; x < FONT_WIDTH; ++x)
{
for (j = 0; j < scale_factor; j++)
{
bg_color = m_Color.Background; bg_color = m_Color.Background;
for (k = 0; k < bpp; k++) for (k = 0; k < bpp; k++) {
{
*bg_pixels = (unsigned char)bg_color; *bg_pixels = (unsigned char)bg_color;
bg_color = bg_color >> 8; bg_color = bg_color >> 8;
bg_pixels++; bg_pixels++;
@ -221,17 +186,12 @@ void FbConDrawglyph
} }
} }
for (y = 0; y < FONT_HEIGHT / 2; ++y) for (y = 0; y < FONT_HEIGHT / 2; ++y) {
{ for (i = 0; i < scale_factor; i++) {
for (i = 0; i < scale_factor; i++) for (x = 0; x < FONT_WIDTH; ++x) {
{ for (j = 0; j < scale_factor; j++) {
for (x = 0; x < FONT_WIDTH; ++x)
{
for (j = 0; j < scale_factor; j++)
{
bg_color = m_Color.Background; bg_color = m_Color.Background;
for (k = 0; k < bpp; k++) for (k = 0; k < bpp; k++) {
{
*bg_pixels = (unsigned char)bg_color; *bg_pixels = (unsigned char)bg_color;
bg_color = bg_color >> 8; bg_color = bg_color >> 8;
bg_pixels++; bg_pixels++;
@ -243,31 +203,23 @@ void FbConDrawglyph
} }
data = glyph[0]; data = glyph[0];
for (y = 0; y < FONT_HEIGHT / 2; ++y) for (y = 0; y < FONT_HEIGHT / 2; ++y) {
{
temp = data; temp = data;
for (i = 0; i < scale_factor; i++) for (i = 0; i < scale_factor; i++) {
{
data = temp; data = temp;
for (x = 0; x < FONT_WIDTH; ++x) for (x = 0; x < FONT_WIDTH; ++x) {
{ if (data & 1) {
if (data & 1) for (j = 0; j < scale_factor; j++) {
{
for (j = 0; j < scale_factor; j++)
{
fg_color = m_Color.Foreground; fg_color = m_Color.Foreground;
for (k = 0; k < bpp; k++) for (k = 0; k < bpp; k++) {
{
*pixels = (unsigned char)fg_color; *pixels = (unsigned char)fg_color;
fg_color = fg_color >> 8; fg_color = fg_color >> 8;
pixels++; pixels++;
} }
} }
} }
else else {
{ for (j = 0; j < scale_factor; j++) {
for (j = 0; j < scale_factor; j++)
{
pixels = pixels + bpp; pixels = pixels + bpp;
} }
} }
@ -278,31 +230,23 @@ void FbConDrawglyph
} }
data = glyph[1]; data = glyph[1];
for (y = 0; y < FONT_HEIGHT / 2; ++y) for (y = 0; y < FONT_HEIGHT / 2; ++y) {
{
temp = data; temp = data;
for (i = 0; i < scale_factor; i++) for (i = 0; i < scale_factor; i++) {
{
data = temp; data = temp;
for (x = 0; x < FONT_WIDTH; ++x) for (x = 0; x < FONT_WIDTH; ++x) {
{ if (data & 1) {
if (data & 1) for (j = 0; j < scale_factor; j++) {
{
for (j = 0; j < scale_factor; j++)
{
fg_color = m_Color.Foreground; fg_color = m_Color.Foreground;
for (k = 0; k < bpp; k++) for (k = 0; k < bpp; k++) {
{
*pixels = (unsigned char)fg_color; *pixels = (unsigned char)fg_color;
fg_color = fg_color >> 8; fg_color = fg_color >> 8;
pixels++; pixels++;
} }
} }
} }
else else {
{ for (j = 0; j < scale_factor; j++) {
for (j = 0; j < scale_factor; j++)
{
pixels = pixels + bpp; pixels = pixels + bpp;
} }
} }
@ -316,18 +260,16 @@ void FbConDrawglyph
/* TODO: Take stride into account */ /* TODO: Take stride into account */
void FbConScrollUp(void) void FbConScrollUp(void)
{ {
unsigned short *dst = (void*)FixedPcdGet32(PcdMipiFrameBufferAddress); unsigned short *dst = (void *)FixedPcdGet32(PcdMipiFrameBufferAddress);
unsigned short *src = dst + (gWidth * FONT_HEIGHT); unsigned short *src = dst + (gWidth * FONT_HEIGHT);
unsigned count = gWidth * (gHeight - FONT_HEIGHT); unsigned count = gWidth * (gHeight - FONT_HEIGHT);
while (count--) while (count--) {
{
*dst++ = *src++; *dst++ = *src++;
} }
count = gWidth * FONT_HEIGHT; count = gWidth * FONT_HEIGHT;
while (count--) while (count--) {
{
*dst++ = m_Color.Background; *dst++ = m_Color.Background;
} }
@ -344,121 +286,78 @@ void FbConFlush(void)
bytes_per_bpp = (gBpp / 8); bytes_per_bpp = (gBpp / 8);
WriteBackInvalidateDataCacheRange( WriteBackInvalidateDataCacheRange(
(void*)FixedPcdGet32(PcdMipiFrameBufferAddress), (void *)FixedPcdGet32(PcdMipiFrameBufferAddress),
(total_x * total_y * bytes_per_bpp) (total_x * total_y * bytes_per_bpp));
);
} }
UINTN UINTN
EFIAPI EFIAPI
SerialPortWrite SerialPortWrite(IN UINT8 *Buffer, IN UINTN NumberOfBytes)
(
IN UINT8 *Buffer,
IN UINTN NumberOfBytes
)
{ {
UINT8* CONST Final = &Buffer[NumberOfBytes]; UINT8 *CONST Final = &Buffer[NumberOfBytes];
UINTN InterruptState = ArmGetInterruptState(); UINTN InterruptState = ArmGetInterruptState();
ArmDisableInterrupts(); ArmDisableInterrupts();
while (Buffer < Final) while (Buffer < Final) {
{
FbConPutCharWithFactor(*Buffer++, FBCON_COMMON_MSG, SCALE_FACTOR); FbConPutCharWithFactor(*Buffer++, FBCON_COMMON_MSG, SCALE_FACTOR);
} }
if (InterruptState) ArmEnableInterrupts(); if (InterruptState)
ArmEnableInterrupts();
return NumberOfBytes; return NumberOfBytes;
} }
UINTN UINTN
EFIAPI EFIAPI
SerialPortWriteCritical SerialPortWriteCritical(IN UINT8 *Buffer, IN UINTN NumberOfBytes)
(
IN UINT8 *Buffer,
IN UINTN NumberOfBytes
)
{ {
UINT8* CONST Final = &Buffer[NumberOfBytes]; UINT8 *CONST Final = &Buffer[NumberOfBytes];
UINTN CurrentForeground = m_Color.Foreground; UINTN CurrentForeground = m_Color.Foreground;
UINTN InterruptState = ArmGetInterruptState(); UINTN InterruptState = ArmGetInterruptState();
ArmDisableInterrupts(); ArmDisableInterrupts();
m_Color.Foreground = FB_BGRA8888_YELLOW; m_Color.Foreground = FB_BGRA8888_YELLOW;
while (Buffer < Final) while (Buffer < Final) {
{
FbConPutCharWithFactor(*Buffer++, FBCON_COMMON_MSG, SCALE_FACTOR); FbConPutCharWithFactor(*Buffer++, FBCON_COMMON_MSG, SCALE_FACTOR);
} }
m_Color.Foreground = CurrentForeground; m_Color.Foreground = CurrentForeground;
if (InterruptState) ArmEnableInterrupts(); if (InterruptState)
ArmEnableInterrupts();
return NumberOfBytes; return NumberOfBytes;
} }
UINTN UINTN
EFIAPI EFIAPI
SerialPortRead SerialPortRead(OUT UINT8 *Buffer, IN UINTN NumberOfBytes) { return 0; }
(
OUT UINT8 *Buffer,
IN UINTN NumberOfBytes
)
{
return 0;
}
BOOLEAN BOOLEAN
EFIAPI EFIAPI
SerialPortPoll SerialPortPoll(VOID) { return FALSE; }
(
VOID
)
{
return FALSE;
}
RETURN_STATUS RETURN_STATUS
EFIAPI EFIAPI
SerialPortSetControl SerialPortSetControl(IN UINT32 Control) { return RETURN_UNSUPPORTED; }
(
IN UINT32 Control RETURN_STATUS
) EFIAPI
SerialPortGetControl(OUT UINT32 *Control) { return RETURN_UNSUPPORTED; }
RETURN_STATUS
EFIAPI
SerialPortSetAttributes(
IN OUT UINT64 *BaudRate, IN OUT UINT32 *ReceiveFifoDepth,
IN OUT UINT32 *Timeout, IN OUT EFI_PARITY_TYPE *Parity,
IN OUT UINT8 *DataBits, IN OUT EFI_STOP_BITS_TYPE *StopBits)
{ {
return RETURN_UNSUPPORTED; return RETURN_UNSUPPORTED;
} }
RETURN_STATUS UINTN SerialPortFlush(VOID) { return 0; }
EFIAPI
SerialPortGetControl
(
OUT UINT32 *Control
)
{
return RETURN_UNSUPPORTED;
}
RETURN_STATUS VOID EnableSynchronousSerialPortIO(VOID)
EFIAPI
SerialPortSetAttributes
(
IN OUT UINT64 *BaudRate,
IN OUT UINT32 *ReceiveFifoDepth,
IN OUT UINT32 *Timeout,
IN OUT EFI_PARITY_TYPE *Parity,
IN OUT UINT8 *DataBits,
IN OUT EFI_STOP_BITS_TYPE *StopBits
)
{
return RETURN_UNSUPPORTED;
}
UINTN SerialPortFlush(VOID)
{
return 0;
}
VOID
EnableSynchronousSerialPortIO(VOID)
{ {
// Already synchronous // Already synchronous
} }

View File

@ -32,10 +32,6 @@ void ResetFb(void);
UINTN UINTN
EFIAPI EFIAPI
SerialPortWriteCritical SerialPortWriteCritical(IN UINT8 *Buffer, IN UINTN NumberOfBytes);
(
IN UINT8 *Buffer,
IN UINTN NumberOfBytes
);
#endif #endif

View File

@ -3,26 +3,26 @@
Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR> Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License are licensed and made available under the terms and conditions of the BSD
which accompanies this distribution. The full text of the license may be found at License which accompanies this distribution. The full text of the license may
http://opensource.org/licenses/bsd-license.php. be found at http://opensource.org/licenses/bsd-license.php.
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/ **/
#include <Base.h> #include <Base.h>
#include <Library/SerialPortLib.h>
#include <Library/CacheMaintenanceLib.h> #include <Library/CacheMaintenanceLib.h>
#include <Library/SerialPortLib.h>
/** /**
Initialize the serial device hardware. Initialize the serial device hardware.
If no initialization is required, then return RETURN_SUCCESS. If no initialization is required, then return RETURN_SUCCESS.
If the serial device was successfully initialized, then return RETURN_SUCCESS. If the serial device was successfully initialized, then return RETURN_SUCCESS.
If the serial device could not be initialized, then return RETURN_DEVICE_ERROR. If the serial device could not be initialized, then return
RETURN_DEVICE_ERROR.
@retval RETURN_SUCCESS The serial device was initialized. @retval RETURN_SUCCESS The serial device was initialized.
@retval RETURN_DEVICE_ERROR The serial device could not be initialized. @retval RETURN_DEVICE_ERROR The serial device could not be initialized.
@ -30,9 +30,7 @@
**/ **/
RETURN_STATUS RETURN_STATUS
EFIAPI EFIAPI
SerialPortInitialize ( SerialPortInitialize(VOID)
VOID
)
{ {
#if 0 #if 0
UINT8* base = (UINT8*)0xa1a10000ull; UINT8* base = (UINT8*)0xa1a10000ull;
@ -43,10 +41,11 @@ SerialPortInitialize (
return RETURN_SUCCESS; return RETURN_SUCCESS;
} }
static void mem_putchar(UINT8 c) { static void mem_putchar(UINT8 c)
{
static const UINTN size = 0x200000; static const UINTN size = 0x200000;
static UINTN offset = 0; static UINTN offset = 0;
UINT8* base = (UINT8*)0xa1a10000ull; UINT8 * base = (UINT8 *)0xa1a10000ull;
base[offset++] = c; base[offset++] = c;
if (offset >= size) { if (offset >= size) {
offset = 0; offset = 0;
@ -59,24 +58,22 @@ static void mem_putchar(UINT8 c) {
Writes NumberOfBytes data bytes from Buffer to the serial device. Writes NumberOfBytes data bytes from Buffer to the serial device.
The number of bytes actually written to the serial device is returned. The number of bytes actually written to the serial device is returned.
If the return value is less than NumberOfBytes, then the write operation failed. If the return value is less than NumberOfBytes, then the write operation
If Buffer is NULL, then ASSERT(). failed. If Buffer is NULL, then ASSERT(). If NumberOfBytes is zero, then return
If NumberOfBytes is zero, then return 0. 0.
@param Buffer The pointer to the data buffer to be written. @param Buffer The pointer to the data buffer to be written.
@param NumberOfBytes The number of bytes to written to the serial device. @param NumberOfBytes The number of bytes to written to the serial device.
@retval 0 NumberOfBytes is 0. @retval 0 NumberOfBytes is 0.
@retval >0 The number of bytes written to the serial device. @retval >0 The number of bytes written to the serial device.
If this value is less than NumberOfBytes, then the write operation failed. If this value is less than NumberOfBytes, then the
write operation failed.
**/ **/
UINTN UINTN
EFIAPI EFIAPI
SerialPortWrite ( SerialPortWrite(IN UINT8 *Buffer, IN UINTN NumberOfBytes)
IN UINT8 *Buffer,
IN UINTN NumberOfBytes
)
{ {
for (UINTN i = 0; i < NumberOfBytes; i++) { for (UINTN i = 0; i < NumberOfBytes; i++) {
mem_putchar(Buffer[i]); mem_putchar(Buffer[i]);
@ -84,17 +81,17 @@ SerialPortWrite (
return NumberOfBytes; return NumberOfBytes;
} }
/** /**
Read data from serial device and save the datas in buffer. Read data from serial device and save the datas in buffer.
Reads NumberOfBytes data bytes from a serial device into the buffer Reads NumberOfBytes data bytes from a serial device into the buffer
specified by Buffer. The number of bytes actually read is returned. specified by Buffer. The number of bytes actually read is returned.
If the return value is less than NumberOfBytes, then the rest operation failed. If the return value is less than NumberOfBytes, then the rest operation
If Buffer is NULL, then ASSERT(). failed. If Buffer is NULL, then ASSERT(). If NumberOfBytes is zero, then return
If NumberOfBytes is zero, then return 0. 0.
@param Buffer The pointer to the data buffer to store the data read from the serial device. @param Buffer The pointer to the data buffer to store the data read
from the serial device.
@param NumberOfBytes The number of bytes which will be read. @param NumberOfBytes The number of bytes which will be read.
@retval 0 Read data failed; No data is to be read. @retval 0 Read data failed; No data is to be read.
@ -103,116 +100,97 @@ SerialPortWrite (
**/ **/
UINTN UINTN
EFIAPI EFIAPI
SerialPortRead ( SerialPortRead(OUT UINT8 *Buffer, IN UINTN NumberOfBytes) { return 0; }
OUT UINT8 *Buffer,
IN UINTN NumberOfBytes
)
{
return 0;
}
/** /**
Polls a serial device to see if there is any data waiting to be read. Polls a serial device to see if there is any data waiting to be read.
Polls a serial device to see if there is any data waiting to be read. Polls a serial device to see if there is any data waiting to be read.
If there is data waiting to be read from the serial device, then TRUE is returned. If there is data waiting to be read from the serial device, then TRUE is
If there is no data waiting to be read from the serial device, then FALSE is returned. returned. If there is no data waiting to be read from the serial device, then
FALSE is returned.
@retval TRUE Data is waiting to be read from the serial device. @retval TRUE Data is waiting to be read from the serial device.
@retval FALSE There is no data waiting to be read from the serial device. @retval FALSE There is no data waiting to be read from the serial
device.
**/ **/
BOOLEAN BOOLEAN
EFIAPI EFIAPI
SerialPortPoll ( SerialPortPoll(VOID) { return FALSE; }
VOID
)
{
return FALSE;
}
/** /**
Sets the control bits on a serial device. Sets the control bits on a serial device.
@param Control Sets the bits of Control that are settable. @param Control Sets the bits of Control that are settable.
@retval RETURN_SUCCESS The new control bits were set on the serial device. @retval RETURN_SUCCESS The new control bits were set on the serial
@retval RETURN_UNSUPPORTED The serial device does not support this operation. device.
@retval RETURN_UNSUPPORTED The serial device does not support this
operation.
@retval RETURN_DEVICE_ERROR The serial device is not functioning correctly. @retval RETURN_DEVICE_ERROR The serial device is not functioning correctly.
**/ **/
RETURN_STATUS RETURN_STATUS
EFIAPI EFIAPI
SerialPortSetControl ( SerialPortSetControl(IN UINT32 Control) { return RETURN_UNSUPPORTED; }
IN UINT32 Control
)
{
return RETURN_UNSUPPORTED;
}
/** /**
Retrieve the status of the control bits on a serial device. Retrieve the status of the control bits on a serial device.
@param Control A pointer to return the current control signals from the serial device. @param Control A pointer to return the current control signals
from the serial device.
@retval RETURN_SUCCESS The control bits were read from the serial device. @retval RETURN_SUCCESS The control bits were read from the serial
@retval RETURN_UNSUPPORTED The serial device does not support this operation. device.
@retval RETURN_UNSUPPORTED The serial device does not support this
operation.
@retval RETURN_DEVICE_ERROR The serial device is not functioning correctly. @retval RETURN_DEVICE_ERROR The serial device is not functioning correctly.
**/ **/
RETURN_STATUS RETURN_STATUS
EFIAPI EFIAPI
SerialPortGetControl ( SerialPortGetControl(OUT UINT32 *Control) { return RETURN_UNSUPPORTED; }
OUT UINT32 *Control
)
{
return RETURN_UNSUPPORTED;
}
/** /**
Sets the baud rate, receive FIFO depth, transmit/receice time out, parity, Sets the baud rate, receive FIFO depth, transmit/receice time out, parity,
data bits, and stop bits on a serial device. data bits, and stop bits on a serial device.
@param BaudRate The requested baud rate. A BaudRate value of 0 will use the @param BaudRate The requested baud rate. A BaudRate value of 0 will
device's default interface speed. use the device's default interface speed. On output, the value actually set.
On output, the value actually set. @param ReveiveFifoDepth The requested depth of the FIFO on the receive side
@param ReveiveFifoDepth The requested depth of the FIFO on the receive side of the of the serial interface. A ReceiveFifoDepth value of 0 will use the device's
serial interface. A ReceiveFifoDepth value of 0 will use default FIFO depth. On output, the value actually set.
the device's default FIFO depth. @param Timeout The requested time out for a single character in
On output, the value actually set. microseconds. This timeout applies to both the transmit and receive side of the
@param Timeout The requested time out for a single character in microseconds. interface. A Timeout value of 0 will use the
This timeout applies to both the transmit and receive side of the device's default time out value. On output, the value actually set.
interface. A Timeout value of 0 will use the device's default time @param Parity The type of parity to use on this serial device. A
out value. Parity value of DefaultParity will use the device's default parity value. On
On output, the value actually set. output, the value actually set.
@param Parity The type of parity to use on this serial device. A Parity value of @param DataBits The number of data bits to use on the serial device.
DefaultParity will use the device's default parity value. A DataBits vaule of 0 will use the device's default data bit setting. On output,
On output, the value actually set. the value actually set.
@param DataBits The number of data bits to use on the serial device. A DataBits @param StopBits The number of stop bits to use on this serial
vaule of 0 will use the device's default data bit setting. device. A StopBits value of DefaultStopBits will use the device's default number
On output, the value actually set. of stop bits. On output, the value actually set.
@param StopBits The number of stop bits to use on this serial device. A StopBits
value of DefaultStopBits will use the device's default number of
stop bits.
On output, the value actually set.
@retval RETURN_SUCCESS The new attributes were set on the serial device. @retval RETURN_SUCCESS The new attributes were set on the serial
@retval RETURN_UNSUPPORTED The serial device does not support this operation. device.
@retval RETURN_INVALID_PARAMETER One or more of the attributes has an unsupported value. @retval RETURN_UNSUPPORTED The serial device does not support this
@retval RETURN_DEVICE_ERROR The serial device is not functioning correctly. operation.
@retval RETURN_INVALID_PARAMETER One or more of the attributes has an
unsupported value.
@retval RETURN_DEVICE_ERROR The serial device is not functioning
correctly.
**/ **/
RETURN_STATUS RETURN_STATUS
EFIAPI EFIAPI
SerialPortSetAttributes ( SerialPortSetAttributes(
IN OUT UINT64 *BaudRate, IN OUT UINT64 *BaudRate, IN OUT UINT32 *ReceiveFifoDepth,
IN OUT UINT32 *ReceiveFifoDepth, IN OUT UINT32 *Timeout, IN OUT EFI_PARITY_TYPE *Parity,
IN OUT UINT32 *Timeout, IN OUT UINT8 *DataBits, IN OUT EFI_STOP_BITS_TYPE *StopBits)
IN OUT EFI_PARITY_TYPE *Parity,
IN OUT UINT8 *DataBits,
IN OUT EFI_STOP_BITS_TYPE *StopBits
)
{ {
return RETURN_UNSUPPORTED; return RETURN_UNSUPPORTED;
} }

View File

@ -10,6 +10,9 @@
**/ **/
#include <Guid/EventGroup.h>
#include <Guid/SerialPortLibVendor.h>
#include <Guid/TtyTerm.h>
#include <IndustryStandard/Pci22.h> #include <IndustryStandard/Pci22.h>
#include <Library/BootLogoLib.h> #include <Library/BootLogoLib.h>
#include <Library/CapsuleLib.h> #include <Library/CapsuleLib.h>
@ -26,54 +29,48 @@
#include <Protocol/PciIo.h> #include <Protocol/PciIo.h>
#include <Protocol/PciRootBridgeIo.h> #include <Protocol/PciRootBridgeIo.h>
#include <Protocol/PlatformBootManager.h> #include <Protocol/PlatformBootManager.h>
#include <Guid/EventGroup.h>
#include <Guid/TtyTerm.h>
#include <Guid/SerialPortLibVendor.h>
#include "PlatformBm.h" #include "PlatformBm.h"
#define DP_NODE_LEN(Type) \
{ \
(UINT8)sizeof(Type), (UINT8)(sizeof(Type) >> 8) \
}
#pragma pack(1)
#define DP_NODE_LEN(Type) { (UINT8)sizeof (Type), (UINT8)(sizeof (Type) >> 8) }
#pragma pack (1)
typedef struct { typedef struct {
VENDOR_DEVICE_PATH SerialDxe; VENDOR_DEVICE_PATH SerialDxe;
UART_DEVICE_PATH Uart; UART_DEVICE_PATH Uart;
VENDOR_DEFINED_DEVICE_PATH TermType; VENDOR_DEFINED_DEVICE_PATH TermType;
EFI_DEVICE_PATH_PROTOCOL End; EFI_DEVICE_PATH_PROTOCOL End;
} PLATFORM_SERIAL_CONSOLE; } PLATFORM_SERIAL_CONSOLE;
#pragma pack () #pragma pack()
STATIC PLATFORM_SERIAL_CONSOLE mSerialConsole = { STATIC PLATFORM_SERIAL_CONSOLE mSerialConsole = {
// //
// VENDOR_DEVICE_PATH SerialDxe // VENDOR_DEVICE_PATH SerialDxe
// //
{ {{HARDWARE_DEVICE_PATH, HW_VENDOR_DP, DP_NODE_LEN(VENDOR_DEVICE_PATH)},
{ HARDWARE_DEVICE_PATH, HW_VENDOR_DP, DP_NODE_LEN (VENDOR_DEVICE_PATH) }, EDKII_SERIAL_PORT_LIB_VENDOR_GUID},
EDKII_SERIAL_PORT_LIB_VENDOR_GUID
},
// //
// UART_DEVICE_PATH Uart // UART_DEVICE_PATH Uart
// //
{ {
{ MESSAGING_DEVICE_PATH, MSG_UART_DP, DP_NODE_LEN (UART_DEVICE_PATH) }, {MESSAGING_DEVICE_PATH, MSG_UART_DP, DP_NODE_LEN(UART_DEVICE_PATH)},
0, // Reserved 0, // Reserved
FixedPcdGet64 (PcdUartDefaultBaudRate), // BaudRate FixedPcdGet64(PcdUartDefaultBaudRate), // BaudRate
FixedPcdGet8 (PcdUartDefaultDataBits), // DataBits FixedPcdGet8(PcdUartDefaultDataBits), // DataBits
FixedPcdGet8 (PcdUartDefaultParity), // Parity FixedPcdGet8(PcdUartDefaultParity), // Parity
FixedPcdGet8 (PcdUartDefaultStopBits) // StopBits FixedPcdGet8(PcdUartDefaultStopBits) // StopBits
}, },
// //
// VENDOR_DEFINED_DEVICE_PATH TermType // VENDOR_DEFINED_DEVICE_PATH TermType
// //
{ {
{ {MESSAGING_DEVICE_PATH, MSG_VENDOR_DP,
MESSAGING_DEVICE_PATH, MSG_VENDOR_DP, DP_NODE_LEN(VENDOR_DEFINED_DEVICE_PATH)}
DP_NODE_LEN (VENDOR_DEFINED_DEVICE_PATH)
}
// //
// Guid to be filled in dynamically // Guid to be filled in dynamically
// //
@ -82,29 +79,23 @@ STATIC PLATFORM_SERIAL_CONSOLE mSerialConsole = {
// //
// EFI_DEVICE_PATH_PROTOCOL End // EFI_DEVICE_PATH_PROTOCOL End
// //
{ {END_DEVICE_PATH_TYPE, END_ENTIRE_DEVICE_PATH_SUBTYPE,
END_DEVICE_PATH_TYPE, END_ENTIRE_DEVICE_PATH_SUBTYPE, DP_NODE_LEN(EFI_DEVICE_PATH_PROTOCOL)}};
DP_NODE_LEN (EFI_DEVICE_PATH_PROTOCOL)
}
};
#pragma pack(1)
#pragma pack (1)
typedef struct { typedef struct {
USB_CLASS_DEVICE_PATH Keyboard; USB_CLASS_DEVICE_PATH Keyboard;
EFI_DEVICE_PATH_PROTOCOL End; EFI_DEVICE_PATH_PROTOCOL End;
} PLATFORM_USB_KEYBOARD; } PLATFORM_USB_KEYBOARD;
#pragma pack () #pragma pack()
STATIC PLATFORM_USB_KEYBOARD mUsbKeyboard = { STATIC PLATFORM_USB_KEYBOARD mUsbKeyboard = {
// //
// USB_CLASS_DEVICE_PATH Keyboard // USB_CLASS_DEVICE_PATH Keyboard
// //
{ {
{ {MESSAGING_DEVICE_PATH, MSG_USB_CLASS_DP,
MESSAGING_DEVICE_PATH, MSG_USB_CLASS_DP, DP_NODE_LEN(USB_CLASS_DEVICE_PATH)},
DP_NODE_LEN (USB_CLASS_DEVICE_PATH)
},
0xFFFF, // VendorId: any 0xFFFF, // VendorId: any
0xFFFF, // ProductId: any 0xFFFF, // ProductId: any
3, // DeviceClass: HID 3, // DeviceClass: HID
@ -115,12 +106,8 @@ STATIC PLATFORM_USB_KEYBOARD mUsbKeyboard = {
// //
// EFI_DEVICE_PATH_PROTOCOL End // EFI_DEVICE_PATH_PROTOCOL End
// //
{ {END_DEVICE_PATH_TYPE, END_ENTIRE_DEVICE_PATH_SUBTYPE,
END_DEVICE_PATH_TYPE, END_ENTIRE_DEVICE_PATH_SUBTYPE, DP_NODE_LEN(EFI_DEVICE_PATH_PROTOCOL)}};
DP_NODE_LEN (EFI_DEVICE_PATH_PROTOCOL)
}
};
/** /**
Check if the handle satisfies a particular condition. Check if the handle satisfies a particular condition.
@ -133,13 +120,8 @@ STATIC PLATFORM_USB_KEYBOARD mUsbKeyboard = {
@retval FALSE Otherwise. This includes the case when the condition could not @retval FALSE Otherwise. This includes the case when the condition could not
be fully evaluated due to an error. be fully evaluated due to an error.
**/ **/
typedef typedef BOOLEAN(EFIAPI *FILTER_FUNCTION)(
BOOLEAN IN EFI_HANDLE Handle, IN CONST CHAR16 *ReportText);
(EFIAPI *FILTER_FUNCTION) (
IN EFI_HANDLE Handle,
IN CONST CHAR16 *ReportText
);
/** /**
Process a handle. Process a handle.
@ -148,12 +130,8 @@ BOOLEAN
@param[in] ReportText A caller-allocated string passed in for reporting @param[in] ReportText A caller-allocated string passed in for reporting
purposes. It must never be NULL. purposes. It must never be NULL.
**/ **/
typedef typedef VOID(EFIAPI *CALLBACK_FUNCTION)(
VOID IN EFI_HANDLE Handle, IN CONST CHAR16 *ReportText);
(EFIAPI *CALLBACK_FUNCTION) (
IN EFI_HANDLE Handle,
IN CONST CHAR16 *ReportText
);
/** /**
Locate all handles that carry the specified protocol, filter them with a Locate all handles that carry the specified protocol, filter them with a
@ -169,39 +147,35 @@ VOID
clears the filter. clears the filter.
**/ **/
STATIC STATIC
VOID VOID FilterAndProcess(
FilterAndProcess ( IN EFI_GUID *ProtocolGuid, IN FILTER_FUNCTION Filter OPTIONAL,
IN EFI_GUID *ProtocolGuid, IN CALLBACK_FUNCTION Process)
IN FILTER_FUNCTION Filter OPTIONAL,
IN CALLBACK_FUNCTION Process
)
{ {
EFI_STATUS Status; EFI_STATUS Status;
EFI_HANDLE *Handles; EFI_HANDLE *Handles;
UINTN NoHandles; UINTN NoHandles;
UINTN Idx; UINTN Idx;
Status = gBS->LocateHandleBuffer (ByProtocol, ProtocolGuid, Status = gBS->LocateHandleBuffer(
NULL /* SearchKey */, &NoHandles, &Handles); ByProtocol, ProtocolGuid, NULL /* SearchKey */, &NoHandles, &Handles);
if (EFI_ERROR (Status)) { if (EFI_ERROR(Status)) {
// //
// This is not an error, just an informative condition. // This is not an error, just an informative condition.
// //
DEBUG ((EFI_D_VERBOSE, "%a: %g: %r\n", __FUNCTION__, ProtocolGuid, DEBUG((EFI_D_VERBOSE, "%a: %g: %r\n", __FUNCTION__, ProtocolGuid, Status));
Status));
return; return;
} }
ASSERT (NoHandles > 0); ASSERT(NoHandles > 0);
for (Idx = 0; Idx < NoHandles; ++Idx) { for (Idx = 0; Idx < NoHandles; ++Idx) {
CHAR16 *DevicePathText; CHAR16 * DevicePathText;
STATIC CHAR16 Fallback[] = L"<device path unavailable>"; STATIC CHAR16 Fallback[] = L"<device path unavailable>";
// //
// The ConvertDevicePathToText() function handles NULL input transparently. // The ConvertDevicePathToText() function handles NULL input transparently.
// //
DevicePathText = ConvertDevicePathToText ( DevicePathText = ConvertDevicePathToText(
DevicePathFromHandle (Handles[Idx]), DevicePathFromHandle(Handles[Idx]),
FALSE, // DisplayOnly FALSE, // DisplayOnly
FALSE // AllowShortcuts FALSE // AllowShortcuts
); );
@ -209,220 +183,183 @@ FilterAndProcess (
DevicePathText = Fallback; DevicePathText = Fallback;
} }
if (Filter == NULL || Filter (Handles[Idx], DevicePathText)) { if (Filter == NULL || Filter(Handles[Idx], DevicePathText)) {
Process (Handles[Idx], DevicePathText); Process(Handles[Idx], DevicePathText);
} }
if (DevicePathText != Fallback) { if (DevicePathText != Fallback) {
FreePool (DevicePathText); FreePool(DevicePathText);
} }
} }
gBS->FreePool (Handles); gBS->FreePool(Handles);
} }
/** /**
This FILTER_FUNCTION checks if a handle corresponds to a PCI display device. This FILTER_FUNCTION checks if a handle corresponds to a PCI display device.
**/ **/
STATIC STATIC
BOOLEAN BOOLEAN
EFIAPI EFIAPI
IsPciDisplay ( IsPciDisplay(IN EFI_HANDLE Handle, IN CONST CHAR16 *ReportText)
IN EFI_HANDLE Handle,
IN CONST CHAR16 *ReportText
)
{ {
EFI_STATUS Status; EFI_STATUS Status;
EFI_PCI_IO_PROTOCOL *PciIo; EFI_PCI_IO_PROTOCOL *PciIo;
PCI_TYPE00 Pci; PCI_TYPE00 Pci;
Status = gBS->HandleProtocol (Handle, &gEfiPciIoProtocolGuid, Status = gBS->HandleProtocol(Handle, &gEfiPciIoProtocolGuid, (VOID **)&PciIo);
(VOID**)&PciIo); if (EFI_ERROR(Status)) {
if (EFI_ERROR (Status)) {
// //
// This is not an error worth reporting. // This is not an error worth reporting.
// //
return FALSE; return FALSE;
} }
Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint32, 0 /* Offset */, Status = PciIo->Pci.Read(
sizeof Pci / sizeof (UINT32), &Pci); PciIo, EfiPciIoWidthUint32, 0 /* Offset */, sizeof Pci / sizeof(UINT32),
if (EFI_ERROR (Status)) { &Pci);
DEBUG ((EFI_D_ERROR, "%a: %s: %r\n", __FUNCTION__, ReportText, Status)); if (EFI_ERROR(Status)) {
DEBUG((EFI_D_ERROR, "%a: %s: %r\n", __FUNCTION__, ReportText, Status));
return FALSE; return FALSE;
} }
return IS_PCI_DISPLAY (&Pci); return IS_PCI_DISPLAY(&Pci);
} }
/** /**
This CALLBACK_FUNCTION attempts to connect a handle non-recursively, asking This CALLBACK_FUNCTION attempts to connect a handle non-recursively, asking
the matching driver to produce all first-level child handles. the matching driver to produce all first-level child handles.
**/ **/
STATIC STATIC
VOID VOID EFIAPI Connect(IN EFI_HANDLE Handle, IN CONST CHAR16 *ReportText)
EFIAPI
Connect (
IN EFI_HANDLE Handle,
IN CONST CHAR16 *ReportText
)
{ {
EFI_STATUS Status; EFI_STATUS Status;
Status = gBS->ConnectController ( Status = gBS->ConnectController(
Handle, // ControllerHandle Handle, // ControllerHandle
NULL, // DriverImageHandle NULL, // DriverImageHandle
NULL, // RemainingDevicePath -- produce all children NULL, // RemainingDevicePath -- produce all children
FALSE // Recursive FALSE // Recursive
); );
DEBUG ((EFI_ERROR (Status) ? EFI_D_ERROR : EFI_D_VERBOSE, "%a: %s: %r\n", DEBUG(
(EFI_ERROR(Status) ? EFI_D_ERROR : EFI_D_VERBOSE, "%a: %s: %r\n",
__FUNCTION__, ReportText, Status)); __FUNCTION__, ReportText, Status));
} }
/** /**
This CALLBACK_FUNCTION retrieves the EFI_DEVICE_PATH_PROTOCOL from the This CALLBACK_FUNCTION retrieves the EFI_DEVICE_PATH_PROTOCOL from the
handle, and adds it to ConOut and ErrOut. handle, and adds it to ConOut and ErrOut.
**/ **/
STATIC STATIC
VOID VOID EFIAPI AddOutput(IN EFI_HANDLE Handle, IN CONST CHAR16 *ReportText)
EFIAPI
AddOutput (
IN EFI_HANDLE Handle,
IN CONST CHAR16 *ReportText
)
{ {
EFI_STATUS Status; EFI_STATUS Status;
EFI_DEVICE_PATH_PROTOCOL *DevicePath; EFI_DEVICE_PATH_PROTOCOL *DevicePath;
DevicePath = DevicePathFromHandle (Handle); DevicePath = DevicePathFromHandle(Handle);
if (DevicePath == NULL) { if (DevicePath == NULL) {
DEBUG ((EFI_D_ERROR, "%a: %s: handle %p: device path not found\n", DEBUG(
(EFI_D_ERROR, "%a: %s: handle %p: device path not found\n",
__FUNCTION__, ReportText, Handle)); __FUNCTION__, ReportText, Handle));
return; return;
} }
Status = EfiBootManagerUpdateConsoleVariable (ConOut, DevicePath, NULL); Status = EfiBootManagerUpdateConsoleVariable(ConOut, DevicePath, NULL);
if (EFI_ERROR (Status)) { if (EFI_ERROR(Status)) {
DEBUG ((EFI_D_ERROR, "%a: %s: adding to ConOut: %r\n", __FUNCTION__, DEBUG(
(EFI_D_ERROR, "%a: %s: adding to ConOut: %r\n", __FUNCTION__,
ReportText, Status)); ReportText, Status));
return; return;
} }
Status = EfiBootManagerUpdateConsoleVariable (ErrOut, DevicePath, NULL); Status = EfiBootManagerUpdateConsoleVariable(ErrOut, DevicePath, NULL);
if (EFI_ERROR (Status)) { if (EFI_ERROR(Status)) {
DEBUG ((EFI_D_ERROR, "%a: %s: adding to ErrOut: %r\n", __FUNCTION__, DEBUG(
(EFI_D_ERROR, "%a: %s: adding to ErrOut: %r\n", __FUNCTION__,
ReportText, Status)); ReportText, Status));
return; return;
} }
DEBUG ((EFI_D_VERBOSE, "%a: %s: added to ConOut and ErrOut\n", __FUNCTION__, DEBUG(
(EFI_D_VERBOSE, "%a: %s: added to ConOut and ErrOut\n", __FUNCTION__,
ReportText)); ReportText));
} }
STATIC STATIC
UINT16 UINT16
PlatformRegisterFvBootOption ( PlatformRegisterFvBootOption(
CONST EFI_GUID *FileGuid, CONST EFI_GUID *FileGuid, CHAR16 *Description, UINT32 Attributes)
CHAR16 *Description,
UINT32 Attributes
)
{ {
EFI_STATUS Status; EFI_STATUS Status;
INTN OptionIndex; INTN OptionIndex;
EFI_BOOT_MANAGER_LOAD_OPTION NewOption; EFI_BOOT_MANAGER_LOAD_OPTION NewOption;
EFI_BOOT_MANAGER_LOAD_OPTION *BootOptions; EFI_BOOT_MANAGER_LOAD_OPTION * BootOptions;
UINTN BootOptionCount; UINTN BootOptionCount;
MEDIA_FW_VOL_FILEPATH_DEVICE_PATH FileNode; MEDIA_FW_VOL_FILEPATH_DEVICE_PATH FileNode;
EFI_LOADED_IMAGE_PROTOCOL *LoadedImage; EFI_LOADED_IMAGE_PROTOCOL * LoadedImage;
EFI_DEVICE_PATH_PROTOCOL *DevicePath; EFI_DEVICE_PATH_PROTOCOL * DevicePath;
UINT16 OptionNumber; UINT16 OptionNumber;
Status = gBS->HandleProtocol ( Status = gBS->HandleProtocol(
gImageHandle, gImageHandle, &gEfiLoadedImageProtocolGuid, (VOID **)&LoadedImage);
&gEfiLoadedImageProtocolGuid, ASSERT_EFI_ERROR(Status);
(VOID **) &LoadedImage
);
ASSERT_EFI_ERROR (Status);
EfiInitializeFwVolDevicepathNode (&FileNode, FileGuid); EfiInitializeFwVolDevicepathNode(&FileNode, FileGuid);
DevicePath = DevicePathFromHandle (LoadedImage->DeviceHandle); DevicePath = DevicePathFromHandle(LoadedImage->DeviceHandle);
ASSERT (DevicePath != NULL); ASSERT(DevicePath != NULL);
DevicePath = AppendDevicePathNode ( DevicePath =
DevicePath, AppendDevicePathNode(DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&FileNode);
(EFI_DEVICE_PATH_PROTOCOL *) &FileNode ASSERT(DevicePath != NULL);
);
ASSERT (DevicePath != NULL);
Status = EfiBootManagerInitializeLoadOption ( Status = EfiBootManagerInitializeLoadOption(
&NewOption, &NewOption, LoadOptionNumberUnassigned, LoadOptionTypeBoot, Attributes,
LoadOptionNumberUnassigned, Description, DevicePath, NULL, 0);
LoadOptionTypeBoot, ASSERT_EFI_ERROR(Status);
Attributes, FreePool(DevicePath);
Description,
DevicePath,
NULL,
0
);
ASSERT_EFI_ERROR (Status);
FreePool (DevicePath);
BootOptions = EfiBootManagerGetLoadOptions ( BootOptions =
&BootOptionCount, LoadOptionTypeBoot EfiBootManagerGetLoadOptions(&BootOptionCount, LoadOptionTypeBoot);
);
OptionIndex = EfiBootManagerFindLoadOption ( OptionIndex =
&NewOption, BootOptions, BootOptionCount EfiBootManagerFindLoadOption(&NewOption, BootOptions, BootOptionCount);
);
if (OptionIndex == -1) { if (OptionIndex == -1) {
Status = EfiBootManagerAddLoadOptionVariable (&NewOption, MAX_UINTN); Status = EfiBootManagerAddLoadOptionVariable(&NewOption, MAX_UINTN);
ASSERT_EFI_ERROR (Status); ASSERT_EFI_ERROR(Status);
} }
OptionNumber = NewOption.OptionNumber; OptionNumber = NewOption.OptionNumber;
EfiBootManagerFreeLoadOption (&NewOption); EfiBootManagerFreeLoadOption(&NewOption);
EfiBootManagerFreeLoadOptions (BootOptions, BootOptionCount); EfiBootManagerFreeLoadOptions(BootOptions, BootOptionCount);
return OptionNumber; return OptionNumber;
} }
STATIC STATIC
VOID VOID GetPlatformOptions(VOID)
GetPlatformOptions (
VOID
)
{ {
EFI_STATUS Status; EFI_STATUS Status;
EFI_BOOT_MANAGER_LOAD_OPTION *CurrentBootOptions; EFI_BOOT_MANAGER_LOAD_OPTION * CurrentBootOptions;
EFI_BOOT_MANAGER_LOAD_OPTION *BootOptions; EFI_BOOT_MANAGER_LOAD_OPTION * BootOptions;
EFI_INPUT_KEY *BootKeys; EFI_INPUT_KEY * BootKeys;
PLATFORM_BOOT_MANAGER_PROTOCOL *PlatformBootManager; PLATFORM_BOOT_MANAGER_PROTOCOL *PlatformBootManager;
UINTN CurrentBootOptionCount; UINTN CurrentBootOptionCount;
UINTN Index; UINTN Index;
UINTN BootCount; UINTN BootCount;
Status = gBS->LocateProtocol (&gPlatformBootManagerProtocolGuid, NULL, Status = gBS->LocateProtocol(
(VOID **)&PlatformBootManager); &gPlatformBootManagerProtocolGuid, NULL, (VOID **)&PlatformBootManager);
if (EFI_ERROR (Status)) { if (EFI_ERROR(Status)) {
return; return;
} }
Status = PlatformBootManager->GetPlatformBootOptionsAndKeys ( Status = PlatformBootManager->GetPlatformBootOptionsAndKeys(
&BootCount, &BootCount, &BootOptions, &BootKeys);
&BootOptions, if (EFI_ERROR(Status)) {
&BootKeys
);
if (EFI_ERROR (Status)) {
return; return;
} }
// //
// Fetch the existent boot options. If there are none, CurrentBootCount // Fetch the existent boot options. If there are none, CurrentBootCount
// will be zeroed. // will be zeroed.
// //
CurrentBootOptions = EfiBootManagerGetLoadOptions ( CurrentBootOptions =
&CurrentBootOptionCount, EfiBootManagerGetLoadOptions(&CurrentBootOptionCount, LoadOptionTypeBoot);
LoadOptionTypeBoot
);
// //
// Process the platform boot options. // Process the platform boot options.
// //
@ -437,27 +374,24 @@ GetPlatformOptions (
// that EfiBootManagerFindLoadOption() deals fine with (CurrentBootOptions // that EfiBootManagerFindLoadOption() deals fine with (CurrentBootOptions
// == NULL) if (CurrentBootCount == 0). // == NULL) if (CurrentBootCount == 0).
// //
Match = EfiBootManagerFindLoadOption ( Match = EfiBootManagerFindLoadOption(
&BootOptions[Index], &BootOptions[Index], CurrentBootOptions, CurrentBootOptionCount);
CurrentBootOptions,
CurrentBootOptionCount
);
if (Match >= 0) { if (Match >= 0) {
BootOptionNumber = CurrentBootOptions[Match].OptionNumber; BootOptionNumber = CurrentBootOptions[Match].OptionNumber;
} else { }
else {
// //
// Add the platform boot options as a new one, at the end of the boot // Add the platform boot options as a new one, at the end of the boot
// order. Note that if the platform provided this boot option with an // order. Note that if the platform provided this boot option with an
// unassigned option number, then the below function call will assign a // unassigned option number, then the below function call will assign a
// number. // number.
// //
Status = EfiBootManagerAddLoadOptionVariable ( Status =
&BootOptions[Index], EfiBootManagerAddLoadOptionVariable(&BootOptions[Index], MAX_UINTN);
MAX_UINTN if (EFI_ERROR(Status)) {
); DEBUG(
if (EFI_ERROR (Status)) { (DEBUG_ERROR, "%a: failed to register \"%s\": %r\n", __FUNCTION__,
DEBUG ((DEBUG_ERROR, "%a: failed to register \"%s\": %r\n", BootOptions[Index].Description, Status));
__FUNCTION__, BootOptions[Index].Description, Status));
continue; continue;
} }
BootOptionNumber = BootOptions[Index].OptionNumber; BootOptionNumber = BootOptions[Index].OptionNumber;
@ -470,31 +404,21 @@ GetPlatformOptions (
continue; continue;
} }
Status = EfiBootManagerAddKeyOptionVariable ( Status = EfiBootManagerAddKeyOptionVariable(
NULL, NULL, BootOptionNumber, 0, &BootKeys[Index], NULL);
BootOptionNumber, if (EFI_ERROR(Status)) {
0, DEBUG(
&BootKeys[Index], (DEBUG_ERROR, "%a: failed to register hotkey for \"%s\": %r\n",
NULL
);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "%a: failed to register hotkey for \"%s\": %r\n",
__FUNCTION__, BootOptions[Index].Description, Status)); __FUNCTION__, BootOptions[Index].Description, Status));
} }
} }
EfiBootManagerFreeLoadOptions (CurrentBootOptions, CurrentBootOptionCount); EfiBootManagerFreeLoadOptions(CurrentBootOptions, CurrentBootOptionCount);
EfiBootManagerFreeLoadOptions (BootOptions, BootCount); EfiBootManagerFreeLoadOptions(BootOptions, BootCount);
FreePool (BootKeys); FreePool(BootKeys);
} }
STATIC STATIC
VOID VOID PlatformRegisterOptionsAndKeys(VOID)
PlatformRegisterOptionsAndKeys (
VOID
)
{ {
EFI_STATUS Status; EFI_STATUS Status;
EFI_INPUT_KEY Enter; EFI_INPUT_KEY Enter;
@ -502,15 +426,15 @@ PlatformRegisterOptionsAndKeys (
EFI_INPUT_KEY Esc; EFI_INPUT_KEY Esc;
EFI_BOOT_MANAGER_LOAD_OPTION BootOption; EFI_BOOT_MANAGER_LOAD_OPTION BootOption;
GetPlatformOptions (); GetPlatformOptions();
// //
// Register ENTER as CONTINUE key // Register ENTER as CONTINUE key
// //
Enter.ScanCode = SCAN_NULL; Enter.ScanCode = SCAN_NULL;
Enter.UnicodeChar = CHAR_CARRIAGE_RETURN; Enter.UnicodeChar = CHAR_CARRIAGE_RETURN;
Status = EfiBootManagerRegisterContinueKeyOption (0, &Enter, NULL); Status = EfiBootManagerRegisterContinueKeyOption(0, &Enter, NULL);
ASSERT_EFI_ERROR (Status); ASSERT_EFI_ERROR(Status);
// //
// Map UP and ESC to Boot Manager Menu or SimpleInitGUI // Map UP and ESC to Boot Manager Menu or SimpleInitGUI
@ -519,36 +443,31 @@ PlatformRegisterOptionsAndKeys (
UP.UnicodeChar = CHAR_NULL; UP.UnicodeChar = CHAR_NULL;
Esc.ScanCode = SCAN_ESC; Esc.ScanCode = SCAN_ESC;
Esc.UnicodeChar = CHAR_NULL; Esc.UnicodeChar = CHAR_NULL;
Status = EfiBootManagerGetBootManagerMenu (&BootOption); Status = EfiBootManagerGetBootManagerMenu(&BootOption);
ASSERT_EFI_ERROR (Status); ASSERT_EFI_ERROR(Status);
#ifdef ENABLE_SIMPLE_INIT #ifdef ENABLE_SIMPLE_INIT
// //
// Search all boot options // Search all boot options
// //
EfiBootManagerRefreshAllBootOption (); EfiBootManagerRefreshAllBootOption();
// //
// Register Simple Init GUI APP // Register Simple Init GUI APP
// //
UINT16 OptionSimpleInit = PlatformRegisterFvBootOption ( UINT16 OptionSimpleInit = PlatformRegisterFvBootOption(
&gSimpleInitFileGuid, L"Simple Init", LOAD_OPTION_ACTIVE &gSimpleInitFileGuid, L"Simple Init", LOAD_OPTION_ACTIVE);
); Status = EfiBootManagerAddKeyOptionVariable(
Status = EfiBootManagerAddKeyOptionVariable ( NULL, (UINT16)OptionSimpleInit, 0, &UP, NULL);
NULL, (UINT16) OptionSimpleInit, 0, &UP, NULL #else
); Status = EfiBootManagerAddKeyOptionVariable(
#else NULL, (UINT16)BootOption.OptionNumber, 0, &UP, NULL);
Status = EfiBootManagerAddKeyOptionVariable ( #endif
NULL, (UINT16) BootOption.OptionNumber, 0, &UP, NULL ASSERT(Status == EFI_SUCCESS || Status == EFI_ALREADY_STARTED);
); Status = EfiBootManagerAddKeyOptionVariable(
#endif NULL, (UINT16)BootOption.OptionNumber, 0, &Esc, NULL);
ASSERT (Status == EFI_SUCCESS || Status == EFI_ALREADY_STARTED); ASSERT(Status == EFI_SUCCESS || Status == EFI_ALREADY_STARTED);
Status = EfiBootManagerAddKeyOptionVariable (
NULL, (UINT16) BootOption.OptionNumber, 0, &Esc, NULL
);
ASSERT (Status == EFI_SUCCESS || Status == EFI_ALREADY_STARTED);
} }
// //
// BDS Platform Functions // BDS Platform Functions
// //
@ -563,134 +482,127 @@ PlatformRegisterOptionsAndKeys (
> Authentication action: 1. connect Auth devices; > Authentication action: 1. connect Auth devices;
> 2. Identify auto logon user. > 2. Identify auto logon user.
**/ **/
VOID VOID EFIAPI PlatformBootManagerBeforeConsole(VOID)
EFIAPI
PlatformBootManagerBeforeConsole (
VOID
)
{ {
// //
// Signal EndOfDxe PI Event // Signal EndOfDxe PI Event
// //
EfiEventGroupSignal (&gEfiEndOfDxeEventGroupGuid); EfiEventGroupSignal(&gEfiEndOfDxeEventGroupGuid);
// //
// Dispatch deferred images after EndOfDxe event. // Dispatch deferred images after EndOfDxe event.
// //
EfiBootManagerDispatchDeferredImages (); EfiBootManagerDispatchDeferredImages();
// //
// Locate the PCI root bridges and make the PCI bus driver connect each, // Locate the PCI root bridges and make the PCI bus driver connect each,
// non-recursively. This will produce a number of child handles with PciIo on // non-recursively. This will produce a number of child handles with PciIo on
// them. // them.
// //
FilterAndProcess (&gEfiPciRootBridgeIoProtocolGuid, NULL, Connect); FilterAndProcess(&gEfiPciRootBridgeIoProtocolGuid, NULL, Connect);
// //
// Find all display class PCI devices (using the handles from the previous // Find all display class PCI devices (using the handles from the previous
// step), and connect them non-recursively. This should produce a number of // step), and connect them non-recursively. This should produce a number of
// child handles with GOPs on them. // child handles with GOPs on them.
// //
FilterAndProcess (&gEfiPciIoProtocolGuid, IsPciDisplay, Connect); FilterAndProcess(&gEfiPciIoProtocolGuid, IsPciDisplay, Connect);
// //
// Now add the device path of all handles with GOP on them to ConOut and // Now add the device path of all handles with GOP on them to ConOut and
// ErrOut. // ErrOut.
// //
FilterAndProcess (&gEfiGraphicsOutputProtocolGuid, NULL, AddOutput); FilterAndProcess(&gEfiGraphicsOutputProtocolGuid, NULL, AddOutput);
// //
// Add the hardcoded short-form USB keyboard device path to ConIn. // Add the hardcoded short-form USB keyboard device path to ConIn.
// //
EfiBootManagerUpdateConsoleVariable (ConIn, EfiBootManagerUpdateConsoleVariable(
(EFI_DEVICE_PATH_PROTOCOL *)&mUsbKeyboard, NULL); ConIn, (EFI_DEVICE_PATH_PROTOCOL *)&mUsbKeyboard, NULL);
EFI_HANDLE *handles; EFI_HANDLE * handles;
UINTN NoHandles; UINTN NoHandles;
EFI_DEVICE_PATH_PROTOCOL *devicehandle; EFI_DEVICE_PATH_PROTOCOL *devicehandle;
/*CHAR16 *devicepathtxt;*/ /*CHAR16 *devicepathtxt;*/
//EfiBootManagerUpdateConsoleVariable(ConIn, // EfiBootManagerUpdateConsoleVariable(ConIn,
// (EFI_DEVICE_PATH_PROTOCOL*)&gQcomKeypadDeviceGuid, NULL); // (EFI_DEVICE_PATH_PROTOCOL*)&gQcomKeypadDeviceGuid, NULL);
gBS->LocateHandleBuffer(ByProtocol,&gEfiSimpleTextInputExProtocolGuid,NULL, &NoHandles,&handles); gBS->LocateHandleBuffer(
ByProtocol, &gEfiSimpleTextInputExProtocolGuid, NULL, &NoHandles,
&handles);
devicehandle = DevicePathFromHandle(handles[1]); devicehandle = DevicePathFromHandle(handles[1]);
EfiBootManagerUpdateConsoleVariable (ConIn, EfiBootManagerUpdateConsoleVariable(
devicehandle, NULL);/* ConIn, devicehandle, NULL); /*
devicepathtxt = ConvertDevicePathToText(devicehandle,TRUE,TRUE); devicepathtxt = ConvertDevicePathToText(devicehandle,TRUE,TRUE);
DEBUG((DEBUG_ERROR,"There are %s handles\n",devicepathtxt)); DEBUG((DEBUG_ERROR,"There are %s handles\n",devicepathtxt));
ASSERT(0);*/ ASSERT(0);*/
// //
// Add the hardcoded serial console device path to ConIn, ConOut, ErrOut. // Add the hardcoded serial console device path to ConIn, ConOut, ErrOut.
// //
ASSERT (FixedPcdGet8 (PcdDefaultTerminalType) == 4); ASSERT(FixedPcdGet8(PcdDefaultTerminalType) == 4);
CopyGuid (&mSerialConsole.TermType.Guid, &gEfiTtyTermGuid); CopyGuid(&mSerialConsole.TermType.Guid, &gEfiTtyTermGuid);
EfiBootManagerUpdateConsoleVariable (ConIn, EfiBootManagerUpdateConsoleVariable(
(EFI_DEVICE_PATH_PROTOCOL *)&mSerialConsole, NULL); ConIn, (EFI_DEVICE_PATH_PROTOCOL *)&mSerialConsole, NULL);
EfiBootManagerUpdateConsoleVariable (ConOut, EfiBootManagerUpdateConsoleVariable(
(EFI_DEVICE_PATH_PROTOCOL *)&mSerialConsole, NULL); ConOut, (EFI_DEVICE_PATH_PROTOCOL *)&mSerialConsole, NULL);
EfiBootManagerUpdateConsoleVariable (ErrOut, EfiBootManagerUpdateConsoleVariable(
(EFI_DEVICE_PATH_PROTOCOL *)&mSerialConsole, NULL); ErrOut, (EFI_DEVICE_PATH_PROTOCOL *)&mSerialConsole, NULL);
// //
// Register platform-specific boot options and keyboard shortcuts. // Register platform-specific boot options and keyboard shortcuts.
// //
PlatformRegisterOptionsAndKeys (); PlatformRegisterOptionsAndKeys();
} }
STATIC STATIC
VOID VOID HandleCapsules(VOID)
HandleCapsules (
VOID
)
{ {
ESRT_MANAGEMENT_PROTOCOL *EsrtManagement; ESRT_MANAGEMENT_PROTOCOL *EsrtManagement;
EFI_PEI_HOB_POINTERS HobPointer; EFI_PEI_HOB_POINTERS HobPointer;
EFI_CAPSULE_HEADER *CapsuleHeader; EFI_CAPSULE_HEADER * CapsuleHeader;
BOOLEAN NeedReset; BOOLEAN NeedReset;
EFI_STATUS Status; EFI_STATUS Status;
DEBUG ((DEBUG_INFO, "%a: processing capsules ...\n", __FUNCTION__)); DEBUG((DEBUG_INFO, "%a: processing capsules ...\n", __FUNCTION__));
Status = gBS->LocateProtocol (&gEsrtManagementProtocolGuid, NULL, Status = gBS->LocateProtocol(
(VOID **)&EsrtManagement); &gEsrtManagementProtocolGuid, NULL, (VOID **)&EsrtManagement);
if (!EFI_ERROR (Status)) { if (!EFI_ERROR(Status)) {
EsrtManagement->SyncEsrtFmp (); EsrtManagement->SyncEsrtFmp();
} }
// //
// Find all capsule images from hob // Find all capsule images from hob
// //
HobPointer.Raw = GetHobList (); HobPointer.Raw = GetHobList();
NeedReset = FALSE; NeedReset = FALSE;
while ((HobPointer.Raw = GetNextHob (EFI_HOB_TYPE_UEFI_CAPSULE, while ((HobPointer.Raw =
HobPointer.Raw)) != NULL) { GetNextHob(EFI_HOB_TYPE_UEFI_CAPSULE, HobPointer.Raw)) != NULL) {
CapsuleHeader = (VOID *)(UINTN)HobPointer.Capsule->BaseAddress; CapsuleHeader = (VOID *)(UINTN)HobPointer.Capsule->BaseAddress;
Status = ProcessCapsuleImage (CapsuleHeader); Status = ProcessCapsuleImage(CapsuleHeader);
if (EFI_ERROR (Status)) { if (EFI_ERROR(Status)) {
DEBUG ((DEBUG_ERROR, "%a: failed to process capsule %p - %r\n", DEBUG(
__FUNCTION__, CapsuleHeader, Status)); (DEBUG_ERROR, "%a: failed to process capsule %p - %r\n", __FUNCTION__,
CapsuleHeader, Status));
return; return;
} }
NeedReset = TRUE; NeedReset = TRUE;
HobPointer.Raw = GET_NEXT_HOB (HobPointer); HobPointer.Raw = GET_NEXT_HOB(HobPointer);
} }
if (NeedReset) { if (NeedReset) {
DEBUG ((DEBUG_WARN, "%a: capsule update successful, resetting ...\n", DEBUG(
(DEBUG_WARN, "%a: capsule update successful, resetting ...\n",
__FUNCTION__)); __FUNCTION__));
gRT->ResetSystem (EfiResetCold, EFI_SUCCESS, 0, NULL); gRT->ResetSystem(EfiResetCold, EFI_SUCCESS, 0, NULL);
CpuDeadLoop(); CpuDeadLoop();
} }
} }
#define VERSION_STRING_PREFIX L"Tianocore/EDK2 firmware version " #define VERSION_STRING_PREFIX L"Tianocore/EDK2 firmware version "
/** /**
@ -704,11 +616,7 @@ HandleCapsules (
> Dispatch additional option roms > Dispatch additional option roms
> Special boot: e.g.: USB boot, enter UI > Special boot: e.g.: USB boot, enter UI
**/ **/
VOID VOID EFIAPI PlatformBootManagerAfterConsole(VOID)
EFIAPI
PlatformBootManagerAfterConsole (
VOID
)
{ {
EFI_STATUS Status; EFI_STATUS Status;
EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput; EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;
@ -716,40 +624,43 @@ PlatformBootManagerAfterConsole (
UINTN PosX; UINTN PosX;
UINTN PosY; UINTN PosY;
FirmwareVerLength = StrLen (PcdGetPtr (PcdFirmwareVersionString)); FirmwareVerLength = StrLen(PcdGetPtr(PcdFirmwareVersionString));
// //
// Show the splash screen. // Show the splash screen.
// //
Status = BootLogoEnableLogo (); Status = BootLogoEnableLogo();
if (EFI_ERROR (Status)) { if (EFI_ERROR(Status)) {
if (FirmwareVerLength > 0) { if (FirmwareVerLength > 0) {
Print (VERSION_STRING_PREFIX L"%s\n", Print(VERSION_STRING_PREFIX L"%s\n", PcdGetPtr(PcdFirmwareVersionString));
PcdGetPtr (PcdFirmwareVersionString));
} }
#ifdef ENABLE_SIMPLE_INIT #ifdef ENABLE_SIMPLE_INIT
Print (L"Press any side button for SimpleInitGUI"); Print(L"Press any side button for SimpleInitGUI");
#else #else
Print (L"Press any side button for Boot Options"); Print(L"Press any side button for Boot Options");
#endif #endif
} else if (FirmwareVerLength > 0) { }
Status = gBS->HandleProtocol (gST->ConsoleOutHandle, else if (FirmwareVerLength > 0) {
&gEfiGraphicsOutputProtocolGuid, (VOID **)&GraphicsOutput); Status = gBS->HandleProtocol(
if (!EFI_ERROR (Status)) { gST->ConsoleOutHandle, &gEfiGraphicsOutputProtocolGuid,
(VOID **)&GraphicsOutput);
if (!EFI_ERROR(Status)) {
PosX = (GraphicsOutput->Mode->Info->HorizontalResolution - PosX = (GraphicsOutput->Mode->Info->HorizontalResolution -
(StrLen (VERSION_STRING_PREFIX) + FirmwareVerLength) * (StrLen(VERSION_STRING_PREFIX) + FirmwareVerLength) *
EFI_GLYPH_WIDTH) / 2; EFI_GLYPH_WIDTH) /
2;
PosY = 0; PosY = 0;
PrintXY (PosX, PosY, NULL, NULL, VERSION_STRING_PREFIX L"%s", PrintXY(
PcdGetPtr (PcdFirmwareVersionString)); PosX, PosY, NULL, NULL, VERSION_STRING_PREFIX L"%s",
PcdGetPtr(PcdFirmwareVersionString));
} }
} }
// //
// Connect the rest of the devices. // Connect the rest of the devices.
// //
EfiBootManagerConnectAll (); EfiBootManagerConnectAll();
// //
// On ARM, there is currently no reason to use the phased capsule // On ARM, there is currently no reason to use the phased capsule
@ -758,34 +669,31 @@ PlatformBootManagerAfterConsole (
// when the console is up and we can actually give the user some // when the console is up and we can actually give the user some
// feedback about what is going on. // feedback about what is going on.
// //
HandleCapsules (); HandleCapsules();
// //
// Enumerate all possible boot options. // Enumerate all possible boot options.
// //
EfiBootManagerRefreshAllBootOption (); EfiBootManagerRefreshAllBootOption();
// //
// Register UEFI Shell // Register UEFI Shell
// //
PlatformRegisterFvBootOption ( PlatformRegisterFvBootOption(
&gUefiShellFileGuid, L"UEFI Shell", LOAD_OPTION_ACTIVE &gUefiShellFileGuid, L"UEFI Shell", LOAD_OPTION_ACTIVE);
);
// //
// Register Mass Storage App // Register Mass Storage App
// //
PlatformRegisterFvBootOption ( PlatformRegisterFvBootOption(
&gUsbfnMsdAppFileGuid, L"Mass Storage", LOAD_OPTION_ACTIVE &gUsbfnMsdAppFileGuid, L"Mass Storage", LOAD_OPTION_ACTIVE);
);
#ifdef AB_SLOTS_SUPPORT #ifdef AB_SLOTS_SUPPORT
// //
// Register Switch Slots App // Register Switch Slots App
// //
PlatformRegisterFvBootOption ( PlatformRegisterFvBootOption(
&gSwitchSlotsAppFileGuid, L"Reboot to other slot", LOAD_OPTION_ACTIVE &gSwitchSlotsAppFileGuid, L"Reboot to other slot", LOAD_OPTION_ACTIVE);
);
#endif #endif
} }
@ -795,36 +703,28 @@ PlatformBootManagerAfterConsole (
@param TimeoutRemain The remaining timeout. @param TimeoutRemain The remaining timeout.
**/ **/
VOID VOID EFIAPI PlatformBootManagerWaitCallback(UINT16 TimeoutRemain)
EFIAPI
PlatformBootManagerWaitCallback (
UINT16 TimeoutRemain
)
{ {
EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION Black; EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION Black;
EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION White; EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION White;
UINT16 Timeout; UINT16 Timeout;
EFI_STATUS Status; EFI_STATUS Status;
Timeout = PcdGet16 (PcdPlatformBootTimeOut); Timeout = PcdGet16(PcdPlatformBootTimeOut);
Black.Raw = 0x00000000; Black.Raw = 0x00000000;
White.Raw = 0x00FFFFFF; White.Raw = 0x00FFFFFF;
Status = BootLogoUpdateProgress ( Status = BootLogoUpdateProgress(
White.Pixel, White.Pixel, Black.Pixel,
Black.Pixel, #ifdef ENABLE_SIMPLE_INIT
#ifdef ENABLE_SIMPLE_INIT
L"Press any side button for SimpleInitGUI", L"Press any side button for SimpleInitGUI",
#else #else
L"Press any side button for Boot Options", L"Press any side button for Boot Options",
#endif #endif
White.Pixel, White.Pixel, (Timeout - TimeoutRemain) * 100 / Timeout, 0);
(Timeout - TimeoutRemain) * 100 / Timeout, if (EFI_ERROR(Status)) {
0 Print(L".");
);
if (EFI_ERROR (Status)) {
Print (L".");
} }
} }
@ -835,11 +735,4 @@ PlatformBootManagerWaitCallback (
If this function returns, BDS attempts to enter an infinite loop. If this function returns, BDS attempts to enter an infinite loop.
**/ **/
VOID VOID EFIAPI PlatformBootManagerUnableToBoot(VOID) { return; }
EFIAPI
PlatformBootManagerUnableToBoot (
VOID
)
{
return;
}

View File

@ -41,9 +41,7 @@
@retval EFI_UNSUPPORTED Logo not found @retval EFI_UNSUPPORTED Logo not found
**/ **/
EFI_STATUS EFI_STATUS
EnableQuietBoot ( EnableQuietBoot(IN EFI_GUID *LogoFile);
IN EFI_GUID *LogoFile
);
/** /**
Use SystemTable Conout to turn on video based Simple Text Out consoles. The Use SystemTable Conout to turn on video based Simple Text Out consoles. The
@ -53,8 +51,6 @@ EnableQuietBoot (
@retval EFI_SUCCESS UGA devices are back in text mode and synced up. @retval EFI_SUCCESS UGA devices are back in text mode and synced up.
**/ **/
EFI_STATUS EFI_STATUS
DisableQuietBoot ( DisableQuietBoot(VOID);
VOID
);
#endif // _PLATFORM_BM_H_ #endif // _PLATFORM_BM_H_

View File

@ -1,16 +1,17 @@
/** @file /** @file
* *
* Copyright (c) 2018, Linaro Limited. All rights reserved. * Copyright (c) 2018, Linaro Limited. All rights reserved.
* *
* This program and the accompanying materials * This program and the accompanying materials
* are licensed and made available under the terms and conditions of the BSD License * are licensed and made available under the terms and conditions of the BSD
* which accompanies this distribution. The full text of the license may be found at *License which accompanies this distribution. The full text of the license may
* http://opensource.org/licenses/bsd-license.php *be found at http://opensource.org/licenses/bsd-license.php
* *
* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, * THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. * WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR
* *IMPLIED.
**/ *
**/
#include <Library/ArmPlatformLib.h> #include <Library/ArmPlatformLib.h>
#include <Library/DebugLib.h> #include <Library/DebugLib.h>
@ -20,14 +21,12 @@
#include <Ppi/ArmMpCoreInfo.h> #include <Ppi/ArmMpCoreInfo.h>
ARM_CORE_INFO mHiKey960InfoTable[] = { ARM_CORE_INFO mHiKey960InfoTable[] = {
{ {// Cluster 0, Core 0
// Cluster 0, Core 0
0x0, 0x0, 0x0, 0x0,
// MP Core MailBox Set/Get/Clear Addresses and Clear Value // MP Core MailBox Set/Get/Clear Addresses and Clear Value
(UINT64)0xFFFFFFFF (UINT64)0xFFFFFFFF},
}, /*
/*
{ {
// Cluster 0, Core 1 // Cluster 0, Core 1
0x0, 0x1, 0x0, 0x1,
@ -77,7 +76,7 @@ ARM_CORE_INFO mHiKey960InfoTable[] = {
// MP Core MailBox Set/Get/Clear Addresses and Clear Value // MP Core MailBox Set/Get/Clear Addresses and Clear Value
(UINT64)0xFFFFFFFF (UINT64)0xFFFFFFFF
} }
*/ */
}; };
/** /**
@ -89,33 +88,20 @@ ARM_CORE_INFO mHiKey960InfoTable[] = {
**/ **/
EFI_BOOT_MODE EFI_BOOT_MODE
ArmPlatformGetBootMode ( ArmPlatformGetBootMode(VOID) { return BOOT_WITH_FULL_CONFIGURATION; }
VOID
)
{
return BOOT_WITH_FULL_CONFIGURATION;
}
/** /**
Initialize controllers that must setup in the normal world Initialize controllers that must setup in the normal world
This function is called by the ArmPlatformPkg/Pei or ArmPlatformPkg/Pei/PlatformPeim This function is called by the ArmPlatformPkg/Pei or
in the PEI phase. ArmPlatformPkg/Pei/PlatformPeim in the PEI phase.
**/ **/
RETURN_STATUS RETURN_STATUS
ArmPlatformInitialize ( ArmPlatformInitialize(IN UINTN MpId) { return RETURN_SUCCESS; }
IN UINTN MpId
)
{
return RETURN_SUCCESS;
}
EFI_STATUS EFI_STATUS
PrePeiCoreGetMpCoreInfo ( PrePeiCoreGetMpCoreInfo(OUT UINTN *CoreCount, OUT ARM_CORE_INFO **ArmCoreTable)
OUT UINTN *CoreCount,
OUT ARM_CORE_INFO **ArmCoreTable
)
{ {
// Only support one cluster // Only support one cluster
*CoreCount = sizeof(mHiKey960InfoTable) / sizeof(ARM_CORE_INFO); *CoreCount = sizeof(mHiKey960InfoTable) / sizeof(ARM_CORE_INFO);
@ -123,23 +109,16 @@ PrePeiCoreGetMpCoreInfo (
return EFI_SUCCESS; return EFI_SUCCESS;
} }
// Needs to be declared in the file. Otherwise gArmMpCoreInfoPpiGuid is undefined in the contect of PrePeiCore // Needs to be declared in the file. Otherwise gArmMpCoreInfoPpiGuid is
// undefined in the contect of PrePeiCore
EFI_GUID mArmMpCoreInfoPpiGuid = ARM_MP_CORE_INFO_PPI_GUID; EFI_GUID mArmMpCoreInfoPpiGuid = ARM_MP_CORE_INFO_PPI_GUID;
ARM_MP_CORE_INFO_PPI mMpCoreInfoPpi = { PrePeiCoreGetMpCoreInfo }; ARM_MP_CORE_INFO_PPI mMpCoreInfoPpi = {PrePeiCoreGetMpCoreInfo};
EFI_PEI_PPI_DESCRIPTOR gPlatformPpiTable[] = { EFI_PEI_PPI_DESCRIPTOR gPlatformPpiTable[] = {
{ {EFI_PEI_PPI_DESCRIPTOR_PPI, &mArmMpCoreInfoPpiGuid, &mMpCoreInfoPpi}};
EFI_PEI_PPI_DESCRIPTOR_PPI,
&mArmMpCoreInfoPpiGuid,
&mMpCoreInfoPpi
}
};
VOID VOID ArmPlatformGetPlatformPpiList(
ArmPlatformGetPlatformPpiList ( OUT UINTN *PpiListSize, OUT EFI_PEI_PPI_DESCRIPTOR **PpiList)
OUT UINTN *PpiListSize,
OUT EFI_PEI_PPI_DESCRIPTOR **PpiList
)
{ {
*PpiListSize = sizeof(gPlatformPpiTable); *PpiListSize = sizeof(gPlatformPpiTable);
*PpiList = gPlatformPpiTable; *PpiList = gPlatformPpiTable;

View File

@ -1,70 +1,58 @@
/** @file /** @file
* *
* Copyright (c) 2011, ARM Limited. All rights reserved. * Copyright (c) 2011, ARM Limited. All rights reserved.
* Copyright (c) 2019, RUIKAI LIU and MR TUNNEL. All rights reserved. * Copyright (c) 2019, RUIKAI LIU and MR TUNNEL. All rights reserved.
* *
* This program and the accompanying materials * This program and the accompanying materials
* are licensed and made available under the terms and conditions of the BSD License * are licensed and made available under the terms and conditions of the BSD
* which accompanies this distribution. The full text of the license may be found at *License which accompanies this distribution. The full text of the license may
* http://opensource.org/licenses/bsd-license.php *be found at http://opensource.org/licenses/bsd-license.php
* *
* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, * THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. * WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR
* *IMPLIED.
**/ *
**/
#include <Configuration/DeviceMemoryMap.h>
#include <Library/ArmPlatformLib.h> #include <Library/ArmPlatformLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/DebugLib.h> #include <Library/DebugLib.h>
#include <Library/HobLib.h> #include <Library/HobLib.h>
#include <Configuration/DeviceMemoryMap.h> #include <Library/MemoryAllocationLib.h>
/** /**
Return the Virtual Memory Map of your platform Return the Virtual Memory Map of your platform
This Virtual Memory Map is used by MemoryInitPei Module to initialize the MMU on your platform. This Virtual Memory Map is used by MemoryInitPei Module to initialize the MMU
@param[out] VirtualMemoryMap Array of ARM_MEMORY_REGION_DESCRIPTOR describing a Physical-to- on your platform.
Virtual Memory mapping. This array must be ended by a zero-filled @param[out] VirtualMemoryMap Array of ARM_MEMORY_REGION_DESCRIPTOR
entry describing a Physical-to- Virtual Memory mapping. This array must be ended by a
zero-filled entry
**/ **/
STATIC STATIC
VOID VOID AddHob(ARM_MEMORY_REGION_DESCRIPTOR_EX Desc)
AddHob
(
ARM_MEMORY_REGION_DESCRIPTOR_EX Desc
)
{ {
BuildResourceDescriptorHob( BuildResourceDescriptorHob(
Desc.ResourceType, Desc.ResourceType, Desc.ResourceAttribute, Desc.Address, Desc.Length);
Desc.ResourceAttribute,
Desc.Address,
Desc.Length
);
BuildMemoryAllocationHob( BuildMemoryAllocationHob(Desc.Address, Desc.Length, Desc.MemoryType);
Desc.Address,
Desc.Length,
Desc.MemoryType
);
} }
VOID VOID ArmPlatformGetVirtualMemoryMap(
ArmPlatformGetVirtualMemoryMap ( IN ARM_MEMORY_REGION_DESCRIPTOR **VirtualMemoryMap)
IN ARM_MEMORY_REGION_DESCRIPTOR** VirtualMemoryMap
)
{ {
//TO-DO:ADD MEMORY MAP HERE // TO-DO:ADD MEMORY MAP HERE
ARM_MEMORY_REGION_DESCRIPTOR* MemoryDescriptor; ARM_MEMORY_REGION_DESCRIPTOR *MemoryDescriptor;
UINTN Index = 0; UINTN Index = 0;
MemoryDescriptor = (ARM_MEMORY_REGION_DESCRIPTOR*)AllocatePages MemoryDescriptor =
(EFI_SIZE_TO_PAGES (sizeof (ARM_MEMORY_REGION_DESCRIPTOR) * (ARM_MEMORY_REGION_DESCRIPTOR *)AllocatePages(EFI_SIZE_TO_PAGES(
sizeof(ARM_MEMORY_REGION_DESCRIPTOR) *
MAX_ARM_MEMORY_REGION_DESCRIPTOR_COUNT)); MAX_ARM_MEMORY_REGION_DESCRIPTOR_COUNT));
// Run through each memory descriptor // Run through each memory descriptor
while (gDeviceMemoryDescriptorEx[Index].Address != (EFI_PHYSICAL_ADDRESS)0xFFFFFFFF) while (gDeviceMemoryDescriptorEx[Index].Address !=
{ (EFI_PHYSICAL_ADDRESS)0xFFFFFFFF) {
switch (gDeviceMemoryDescriptorEx[Index].HobOption) switch (gDeviceMemoryDescriptorEx[Index].HobOption) {
{
case AddMem: case AddMem:
case AddDev: case AddDev:
AddHob(gDeviceMemoryDescriptorEx[Index]); AddHob(gDeviceMemoryDescriptorEx[Index]);
@ -77,10 +65,13 @@ ArmPlatformGetVirtualMemoryMap (
update: update:
ASSERT(Index < MAX_ARM_MEMORY_REGION_DESCRIPTOR_COUNT); ASSERT(Index < MAX_ARM_MEMORY_REGION_DESCRIPTOR_COUNT);
MemoryDescriptor[Index].PhysicalBase = gDeviceMemoryDescriptorEx[Index].Address; MemoryDescriptor[Index].PhysicalBase =
MemoryDescriptor[Index].VirtualBase = gDeviceMemoryDescriptorEx[Index].Address; gDeviceMemoryDescriptorEx[Index].Address;
MemoryDescriptor[Index].VirtualBase =
gDeviceMemoryDescriptorEx[Index].Address;
MemoryDescriptor[Index].Length = gDeviceMemoryDescriptorEx[Index].Length; MemoryDescriptor[Index].Length = gDeviceMemoryDescriptorEx[Index].Length;
MemoryDescriptor[Index].Attributes = gDeviceMemoryDescriptorEx[Index].ArmAttributes; MemoryDescriptor[Index].Attributes =
gDeviceMemoryDescriptorEx[Index].ArmAttributes;
Index++; Index++;
} }
@ -93,5 +84,5 @@ ArmPlatformGetVirtualMemoryMap (
ASSERT(Index <= MAX_ARM_MEMORY_REGION_DESCRIPTOR_COUNT); ASSERT(Index <= MAX_ARM_MEMORY_REGION_DESCRIPTOR_COUNT);
*VirtualMemoryMap = &MemoryDescriptor[0]; *VirtualMemoryMap = &MemoryDescriptor[0];
//ASSERT(0); // ASSERT(0);
} }