[BOOT:LIB] More initialization and cleanup
Started BlpMmDestroy(), MmMdDestroy(), MmPaDestroy(), EfiSetWatchdogTimer(), EfiOpenProtocol(), EfiConInExSetState(), and BlDestroyLibrary(). Completed BlpFwInitialize(). Improved InitializeLibrary().
This commit is contained in:
@@ -16,14 +16,17 @@ Abstract:
|
||||
#include <ntrtl.h>
|
||||
#include "bootlib.h"
|
||||
#include "efi.h"
|
||||
#include "efilib.h"
|
||||
|
||||
BOOT_FIRMWARE_DATA EfiFirmwareData;
|
||||
PBOOT_FIRMWARE_DATA EfiFirmwareParameters;
|
||||
EFI_HANDLE EfiImageHandle;
|
||||
EFI_SYSTEM_TABLE *EfiST;
|
||||
EFI_BOOT_SERVICES *EfiBS;
|
||||
EFI_RUNTIME_SERVICES *EfiRT;
|
||||
SIMPLE_TEXT_OUTPUT_INTERFACE *EfiConOut;
|
||||
SIMPLE_INPUT_INTERFACE *EfiConIn;
|
||||
EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *EfiConInEx;
|
||||
|
||||
NTSTATUS
|
||||
BlpFwInitialize (
|
||||
@@ -54,6 +57,9 @@ Return Value:
|
||||
--*/
|
||||
|
||||
{
|
||||
NTSTATUS Status;
|
||||
EFI_KEY_TOGGLE_STATE KeyToggleState;
|
||||
|
||||
if (FirmwareData == NULL || FirmwareData->Version == 0) {
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
@@ -62,16 +68,33 @@ Return Value:
|
||||
RtlCopyMemory(&EfiFirmwareData, FirmwareData, sizeof(BOOT_FIRMWARE_DATA));
|
||||
EfiFirmwareParameters = &EfiFirmwareData;
|
||||
|
||||
EfiImageHandle = FirmwareData->ImageHandle;
|
||||
EfiST = FirmwareData->SystemTable;
|
||||
EfiBS = EfiST->BootServices;
|
||||
EfiRT = EfiST->RuntimeServices;
|
||||
EfiConOut = EfiST->ConOut;
|
||||
EfiConIn = EfiST->ConIn;
|
||||
}
|
||||
EfiConInEx = NULL;
|
||||
} else if (Stage == 1) {
|
||||
//
|
||||
// Open the extended console input protocol.
|
||||
// If successful, tell it to capture partial key events.
|
||||
//
|
||||
Status = EfiOpenProtocol(
|
||||
EfiST->ConsoleInHandle,
|
||||
&EfiSimpleTextInputExProtocol,
|
||||
(VOID**)&EfiConInEx
|
||||
);
|
||||
if (NT_SUCCESS(Status)) {
|
||||
KeyToggleState = EFI_KEY_STATE_EXPOSED | EFI_TOGGLE_STATE_VALID;
|
||||
EfiConInExSetState(EfiConInEx, &KeyToggleState);
|
||||
}
|
||||
|
||||
//
|
||||
// TODO: Implement stage 1 initialization.
|
||||
//
|
||||
//
|
||||
// Disable the watchdog timer.
|
||||
//
|
||||
EfiSetWatchdogTimer(0, 0, 0, NULL);
|
||||
}
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
@@ -14,6 +14,9 @@ Abstract:
|
||||
--*/
|
||||
|
||||
#include "efilib.h"
|
||||
#include "mm.h"
|
||||
|
||||
EFI_GUID EfiSimpleTextInputExProtocol = EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL_GUID;
|
||||
|
||||
EFI_STATUS
|
||||
EfiGetEfiStatusCode (
|
||||
@@ -84,7 +87,6 @@ Return Value:
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
EfiGetNtStatusCode (
|
||||
IN EFI_STATUS Status
|
||||
@@ -154,4 +156,381 @@ Return Value:
|
||||
default:
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
EfiGetMemoryMap (
|
||||
IN OUT UINTN *MemoryMapSize,
|
||||
IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap,
|
||||
IN OUT UINTN *MapKey,
|
||||
IN OUT UINTN *DescriptorSize,
|
||||
IN OUT UINT32 *DescriptorVersion
|
||||
)
|
||||
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Wrapper for EFI_BOOT_SERVICES.GetMemoryMap(). Gets the firmware memory map
|
||||
and places it into a buffer.
|
||||
|
||||
Arguments:
|
||||
|
||||
MemoryMapSize - pointer to the size of the buffer.
|
||||
|
||||
MemoryMap - pointer to the buffer to store the memory map in.
|
||||
|
||||
MapKey - ponter to the memory map key.
|
||||
|
||||
DescriptorSize - pointer to the size of each memory map descriptor.
|
||||
|
||||
DescriptorVersion - pointer to the version of memory map descriptors.
|
||||
|
||||
Return Value:
|
||||
|
||||
STATUS_SUCCESS if successful.
|
||||
STATUS_INVALID_PARAMETER if MemoryMapSize and/or MemoryMap are invalid.
|
||||
STATUS_BUFFER_TOO_SMALL if MemoryMapSize is too small.
|
||||
|
||||
--*/
|
||||
|
||||
{
|
||||
EXECUTION_CONTEXT_TYPE ContextType;
|
||||
EFI_STATUS EfiStatus;
|
||||
|
||||
ContextType = CurrentExecutionContext->Type;
|
||||
if (ContextType != ExecutionContextFirmware) {
|
||||
//
|
||||
// TODO: Translate addresses here.
|
||||
// Need MmArchTranslateVirtualAddress().
|
||||
//
|
||||
|
||||
BlpArchSwitchContext(ExecutionContextFirmware);
|
||||
}
|
||||
|
||||
EfiStatus = EfiBS->GetMemoryMap(
|
||||
MemoryMapSize,
|
||||
MemoryMap,
|
||||
MapKey,
|
||||
DescriptorSize,
|
||||
DescriptorVersion
|
||||
);
|
||||
|
||||
if (ContextType != ExecutionContextFirmware) {
|
||||
BlpArchSwitchContext(ContextType);
|
||||
}
|
||||
|
||||
return EfiGetNtStatusCode(EfiStatus);
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
EfiAllocatePages (
|
||||
IN EFI_ALLOCATE_TYPE Type,
|
||||
IN EFI_MEMORY_TYPE MemoryType,
|
||||
IN UINTN Pages,
|
||||
IN OUT EFI_PHYSICAL_ADDRESS *Memory
|
||||
)
|
||||
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Wrapper for EFI_BOOT_SERVICES.AllocatePages(). Allocates contiguous pages
|
||||
of physical memory.
|
||||
|
||||
Arguments:
|
||||
|
||||
Type - the type of allocation.
|
||||
|
||||
MemoryType - the type of memory to allocate.
|
||||
|
||||
Pages - the number of pages to allocate.
|
||||
|
||||
Memory - pointer to a physical address of the allocation.
|
||||
|
||||
Return Value:
|
||||
|
||||
STATUS_SUCCESS if successful.
|
||||
STATUS_INVALID_PARAMETER if Type, MemoryType, and/or Memory are invalid.
|
||||
STATUS_INSUFFICIENT_NVRAM_RESOURCES if the pages could not be allocated.
|
||||
STATUS_NOT_FOUND if the pages could not be found.
|
||||
|
||||
--*/
|
||||
|
||||
{
|
||||
EXECUTION_CONTEXT_TYPE ContextType;
|
||||
EFI_STATUS EfiStatus;
|
||||
|
||||
ContextType = CurrentExecutionContext->Type;
|
||||
if (ContextType != ExecutionContextFirmware) {
|
||||
BlpArchSwitchContext(ExecutionContextFirmware);
|
||||
}
|
||||
|
||||
EfiStatus = EfiBS->AllocatePages(
|
||||
Type,
|
||||
MemoryType,
|
||||
Pages,
|
||||
Memory
|
||||
);
|
||||
|
||||
if (ContextType != ExecutionContextFirmware) {
|
||||
BlpArchSwitchContext(ContextType);
|
||||
}
|
||||
|
||||
return EfiGetNtStatusCode(EfiStatus);
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
EfiFreePages (
|
||||
IN EFI_PHYSICAL_ADDRESS Memory,
|
||||
IN UINTN Pages
|
||||
)
|
||||
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Wrapper for EFI_BOOT_SERVICES.FreePages(). Frees contiguous pages
|
||||
of physical memory.
|
||||
|
||||
Arguments:
|
||||
|
||||
Memory - physical address of the pages to be freed.
|
||||
|
||||
Pages - the number of pages to free.
|
||||
|
||||
Return Value:
|
||||
|
||||
STATUS_SUCCESS if successful.
|
||||
STATUS_NOT_FOUND if the allocation was not found.
|
||||
STATUS_INVALID_PARAMETER Memory and/or Pages are invalid.
|
||||
|
||||
--*/
|
||||
|
||||
{
|
||||
EXECUTION_CONTEXT_TYPE ContextType;
|
||||
EFI_STATUS EfiStatus;
|
||||
|
||||
ContextType = CurrentExecutionContext->Type;
|
||||
if (ContextType != ExecutionContextFirmware) {
|
||||
BlpArchSwitchContext(ExecutionContextFirmware);
|
||||
}
|
||||
|
||||
EfiStatus = EfiBS->FreePages(
|
||||
Memory,
|
||||
Pages
|
||||
);
|
||||
|
||||
if (ContextType != ExecutionContextFirmware) {
|
||||
BlpArchSwitchContext(ContextType);
|
||||
}
|
||||
|
||||
return EfiGetNtStatusCode(EfiStatus);
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
EfiSetWatchdogTimer (
|
||||
IN UINTN Timeout,
|
||||
IN UINT64 WatchdogCode,
|
||||
IN UINTN DataSize,
|
||||
IN CHAR16 *WatchdogData
|
||||
)
|
||||
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Wrapper for EFI_BOOT_SERVICES.SetWatchdogTimer().
|
||||
Sets the watchdog timer.
|
||||
|
||||
Arguments:
|
||||
|
||||
Timeout - The number of seconds to set the timer to.
|
||||
Setting this to 0 disables the timer.
|
||||
|
||||
WatchdogCode - The code to set when an event occurs.
|
||||
|
||||
DataSize - The size in bytes of WatchdogData.
|
||||
|
||||
WatchdogData - Optional pointer to a string containing
|
||||
a description of the timer, possibly accompanied
|
||||
by binary data.
|
||||
|
||||
Return Value:
|
||||
|
||||
STATUS_SUCCESS if successful.
|
||||
STATUS_INVALID_PARAMETER if WatchdogCode is invalid.
|
||||
STATUS_NOT_SUPPORTED if there is no Watchdog timer.
|
||||
STATUS_IO_DEVICE_ERROR if the timer could not be set.
|
||||
|
||||
--*/
|
||||
|
||||
{
|
||||
EXECUTION_CONTEXT_TYPE ContextType;
|
||||
EFI_STATUS EfiStatus;
|
||||
|
||||
if (Timeout != 0 && WatchdogCode <= 0xffff) {
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
ContextType = CurrentExecutionContext->Type;
|
||||
if (ContextType != ExecutionContextFirmware) {
|
||||
//
|
||||
// TODO: Translate addresses here.
|
||||
// Need MmArchTranslateVirtualAddress().
|
||||
//
|
||||
|
||||
BlpArchSwitchContext(ExecutionContextFirmware);
|
||||
}
|
||||
|
||||
EfiStatus = EfiBS->SetWatchdogTimer(
|
||||
Timeout,
|
||||
WatchdogCode,
|
||||
DataSize,
|
||||
WatchdogData
|
||||
);
|
||||
|
||||
if (ContextType != ExecutionContextFirmware) {
|
||||
BlpArchSwitchContext(ContextType);
|
||||
}
|
||||
|
||||
return EfiGetNtStatusCode(EfiStatus);
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
EfiOpenProtocol (
|
||||
IN EFI_HANDLE Handle,
|
||||
IN EFI_GUID *Protocol,
|
||||
IN OUT VOID **Interface
|
||||
)
|
||||
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Wrapper that uses either EFI_BOOT_SERVICES.OpenProtocol() or HandleProtocol().
|
||||
Opens a handle to a protocol and finds its interface.
|
||||
|
||||
Arguments:
|
||||
|
||||
Handle - The handle to the protocol to open.
|
||||
|
||||
Protocol - The GUID of the protocol.
|
||||
|
||||
Intercce - Pointer that recieves the address of the interface.
|
||||
|
||||
Return Value:
|
||||
|
||||
STATUS_SUCCESS if successful.
|
||||
Error code on failure.
|
||||
|
||||
--*/
|
||||
|
||||
{
|
||||
EXECUTION_CONTEXT_TYPE ContextType;
|
||||
EFI_STATUS EfiStatus;
|
||||
NTSTATUS Status;
|
||||
|
||||
if (MmTranslationType != TRANSLATION_TYPE_NONE) {
|
||||
//
|
||||
// TODO: Translate addresses.
|
||||
// Need EfiVmOpenProtocol().
|
||||
//
|
||||
DebugPrint(L"EfiOpenProtocol(): Virtual address translation not supported\r\n");
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
ContextType = CurrentExecutionContext->Type;
|
||||
if (ContextType != ExecutionContextFirmware) {
|
||||
BlpArchSwitchContext(ExecutionContextFirmware);
|
||||
}
|
||||
|
||||
//
|
||||
// If supported, use OpenProtocol() (EFI 1.10+).
|
||||
// It helps ensure the protocol is not uninstalled
|
||||
// when still in use.
|
||||
//
|
||||
if (EfiST->Hdr.Revision >= EFI_MAKE_REVISION(1, 10)) {
|
||||
EfiStatus = EfiBS->OpenProtocol(
|
||||
Handle,
|
||||
Protocol,
|
||||
Interface,
|
||||
EfiImageHandle,
|
||||
NULL,
|
||||
EFI_OPEN_PROTOCOL_GET_PROTOCOL
|
||||
);
|
||||
} else {
|
||||
EfiStatus = EfiBS->HandleProtocol(
|
||||
Handle,
|
||||
Protocol,
|
||||
Interface
|
||||
);
|
||||
}
|
||||
|
||||
if (ContextType != ExecutionContextFirmware) {
|
||||
BlpArchSwitchContext(ContextType);
|
||||
}
|
||||
|
||||
//
|
||||
// Convert EFI status to NT status.
|
||||
//
|
||||
Status = EfiGetNtStatusCode(EfiStatus);
|
||||
if (!NT_SUCCESS(Status)) {
|
||||
*Interface = NULL;
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
EfiConInExSetState (
|
||||
IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *Protocol,
|
||||
IN EFI_KEY_TOGGLE_STATE *KeyToggleState
|
||||
)
|
||||
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Wrapper around EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL.SetState().
|
||||
Sets an input protocol's state.
|
||||
|
||||
Arguments:
|
||||
|
||||
Protocol - The protocol to set the state of.
|
||||
|
||||
KeyToggle State - The state to set.
|
||||
|
||||
Return Value:
|
||||
|
||||
STATUS_SUCCESS if successful.
|
||||
STATUS_IO_DEVICE_ERROR if the state could not be set.
|
||||
STATUS_UNSUPPORTED if State is not supported by the device.
|
||||
|
||||
--*/
|
||||
|
||||
{
|
||||
EXECUTION_CONTEXT_TYPE ContextType;
|
||||
EFI_STATUS EfiStatus;
|
||||
|
||||
ContextType = CurrentExecutionContext->Type;
|
||||
if (ContextType != ExecutionContextFirmware) {
|
||||
//
|
||||
// TODO: Translate addresses here.
|
||||
// Need MmArchTranslateVirtualAddress().
|
||||
//
|
||||
|
||||
BlpArchSwitchContext(ExecutionContextFirmware);
|
||||
}
|
||||
|
||||
EfiStatus = Protocol->SetState(
|
||||
Protocol,
|
||||
KeyToggleState
|
||||
);
|
||||
|
||||
if (ContextType != ExecutionContextFirmware) {
|
||||
BlpArchSwitchContext(ContextType);
|
||||
}
|
||||
|
||||
return EfiGetNtStatusCode(EfiStatus);
|
||||
}
|
||||
|
@@ -23,172 +23,6 @@ Abstract:
|
||||
#define EFI_PAGE(NtPage) (((NtPage) << PAGE_SHIFT) >> EFI_PAGE_SHIFT)
|
||||
#define NT_PAGE(EfiPage) (((EfiPage) << EFI_PAGE_SHIFT) >> PAGE_SHIFT)
|
||||
|
||||
NTSTATUS
|
||||
EfiGetMemoryMap (
|
||||
IN OUT UINTN *MemoryMapSize,
|
||||
IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap,
|
||||
IN OUT UINTN *MapKey,
|
||||
IN OUT UINTN *DescriptorSize,
|
||||
IN OUT UINT32 *DescriptorVersion
|
||||
)
|
||||
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Wrapper for EFI_BOOT_SERVICES.GetMemoryMap(). Gets the firmware memory map
|
||||
and places it into a buffer.
|
||||
|
||||
Arguments:
|
||||
|
||||
MemoryMapSize - pointer to the size of the buffer.
|
||||
|
||||
MemoryMap - pointer to the buffer to store the memory map in.
|
||||
|
||||
MapKey - ponter to the memory map key.
|
||||
|
||||
DescriptorSize - pointer to the size of each memory map descriptor.
|
||||
|
||||
DescriptorVersion - pointer to the version of memory map descriptors.
|
||||
|
||||
Return Value:
|
||||
|
||||
STATUS_SUCCESS if successful,
|
||||
Other NTSTATUS value if an error occurs.
|
||||
|
||||
--*/
|
||||
|
||||
{
|
||||
EXECUTION_CONTEXT_TYPE ContextType;
|
||||
EFI_STATUS EfiStatus;
|
||||
|
||||
ContextType = CurrentExecutionContext->Type;
|
||||
if (ContextType != ExecutionContextFirmware) {
|
||||
//
|
||||
// TODO: Translate addresses here.
|
||||
// Need MmArchTranslateVirtualAddress().
|
||||
//
|
||||
|
||||
BlpArchSwitchContext(ExecutionContextFirmware);
|
||||
}
|
||||
|
||||
EfiStatus = EfiBS->GetMemoryMap(
|
||||
MemoryMapSize,
|
||||
MemoryMap,
|
||||
MapKey,
|
||||
DescriptorSize,
|
||||
DescriptorVersion
|
||||
);
|
||||
|
||||
if (ContextType != ExecutionContextFirmware) {
|
||||
BlpArchSwitchContext(ContextType);
|
||||
}
|
||||
|
||||
return EfiGetNtStatusCode(EfiStatus);
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
EfiAllocatePages (
|
||||
IN EFI_ALLOCATE_TYPE Type,
|
||||
IN EFI_MEMORY_TYPE MemoryType,
|
||||
IN UINTN Pages,
|
||||
IN OUT EFI_PHYSICAL_ADDRESS *Memory
|
||||
)
|
||||
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Wrapper for EFI_BOOT_SERVICES.AllocatePages(). Allocates contiguous pages
|
||||
of physical memory.
|
||||
|
||||
Arguments:
|
||||
|
||||
Type - the type of allocation.
|
||||
|
||||
MemoryType - the type of memory to allocate.
|
||||
|
||||
Pages - the number of pages to allocate.
|
||||
|
||||
Memory - pointer to a physical address of the allocation.
|
||||
|
||||
Return Value:
|
||||
|
||||
STATUS_SUCCESS if successful,
|
||||
Other NTSTATUS value if an error occurs.
|
||||
|
||||
--*/
|
||||
|
||||
{
|
||||
EXECUTION_CONTEXT_TYPE ContextType;
|
||||
EFI_STATUS EfiStatus;
|
||||
|
||||
ContextType = CurrentExecutionContext->Type;
|
||||
if (ContextType != ExecutionContextFirmware) {
|
||||
BlpArchSwitchContext(ExecutionContextFirmware);
|
||||
}
|
||||
|
||||
EfiStatus = EfiBS->AllocatePages(
|
||||
Type,
|
||||
MemoryType,
|
||||
Pages,
|
||||
Memory
|
||||
);
|
||||
|
||||
if (ContextType != ExecutionContextFirmware) {
|
||||
BlpArchSwitchContext(ContextType);
|
||||
}
|
||||
|
||||
return EfiGetNtStatusCode(EfiStatus);
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
EfiFreePages (
|
||||
IN EFI_PHYSICAL_ADDRESS Memory,
|
||||
IN UINTN Pages
|
||||
)
|
||||
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Wrapper for EFI_BOOT_SERVICES.FreePages(). Frees contiguous pages
|
||||
of physical memory.
|
||||
|
||||
Arguments:
|
||||
|
||||
Memory - physical address of the pages to be freed.
|
||||
|
||||
Pages - the number of pages to free.
|
||||
|
||||
Return Value:
|
||||
|
||||
STATUS_SUCCESS if successful,
|
||||
Other NTSTATUS value if an error occurs.
|
||||
|
||||
--*/
|
||||
|
||||
{
|
||||
EXECUTION_CONTEXT_TYPE ContextType;
|
||||
EFI_STATUS EfiStatus;
|
||||
|
||||
ContextType = CurrentExecutionContext->Type;
|
||||
if (ContextType != ExecutionContextFirmware) {
|
||||
BlpArchSwitchContext(ExecutionContextFirmware);
|
||||
}
|
||||
|
||||
EfiStatus = EfiBS->FreePages(
|
||||
Memory,
|
||||
Pages
|
||||
);
|
||||
|
||||
if (ContextType != ExecutionContextFirmware) {
|
||||
BlpArchSwitchContext(ContextType);
|
||||
}
|
||||
|
||||
return EfiGetNtStatusCode(EfiStatus);
|
||||
}
|
||||
|
||||
MEMORY_TYPE
|
||||
BlMmTranslateEfiMemoryType (
|
||||
IN EFI_MEMORY_TYPE EfiMemoryType
|
||||
|
Reference in New Issue
Block a user