[BOOT] Huge refactor
This commit is contained in:
@@ -15,7 +15,7 @@ Abstract:
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <wchar.h>
|
||||
#include "bootmgr.h"
|
||||
#include "bootlib.h"
|
||||
|
||||
extern SIMPLE_TEXT_OUTPUT_INTERFACE *EfiConOut;
|
||||
|
||||
|
@@ -14,7 +14,7 @@ Abstract:
|
||||
--*/
|
||||
|
||||
#include "bootlib.h"
|
||||
#include "bootmgr.h"
|
||||
#include "efi.h"
|
||||
|
||||
EFI_SYSTEM_TABLE *EfiST;
|
||||
EFI_BOOT_SERVICES *EfiBS;
|
||||
|
@@ -16,9 +16,7 @@ Abstract:
|
||||
#include <ntrtl.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#include "bootlib.h"
|
||||
#include "bootmgr.h"
|
||||
#include "efi.h"
|
||||
#include "efilib.h"
|
||||
|
||||
UCHAR EfiInitScratch[2048];
|
||||
const EFI_GUID EfiLoadedImageProtocol = LOADED_IMAGE_PROTOCOL;
|
||||
@@ -277,7 +275,7 @@ NTSTATUS
|
||||
EfiInitpConvertEfiDevicePath (
|
||||
IN EFI_DEVICE_PATH *EfiDevicePath,
|
||||
IN BCDE_DATA_TYPE OptionType,
|
||||
IN OUT PBOOT_APPLICATION_OPTION Option,
|
||||
IN OUT PBOOT_ENTRY_OPTION Option,
|
||||
IN ULONG BufferSize
|
||||
)
|
||||
|
||||
@@ -309,23 +307,23 @@ Return Value:
|
||||
NTSTATUS Status;
|
||||
PBCDE_DEVICE DeviceElement;
|
||||
|
||||
if (BufferSize < sizeof(BOOT_APPLICATION_OPTION) + FIELD_OFFSET(BCDE_DEVICE, Device)) {
|
||||
if (BufferSize < sizeof(BOOT_ENTRY_OPTION) + FIELD_OFFSET(BCDE_DEVICE, Device)) {
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
RtlZeroMemory(Option, sizeof(BOOT_APPLICATION_OPTION));
|
||||
DeviceElement = (PBCDE_DEVICE)((PUCHAR)Option + sizeof(BOOT_APPLICATION_OPTION));
|
||||
RtlZeroMemory(Option, sizeof(BOOT_ENTRY_OPTION));
|
||||
DeviceElement = (PBCDE_DEVICE)((PUCHAR)Option + sizeof(BOOT_ENTRY_OPTION));
|
||||
Status = EfiInitTranslateDevicePath(
|
||||
EfiDevicePath,
|
||||
&DeviceElement->Device,
|
||||
BufferSize - (sizeof(BOOT_APPLICATION_OPTION) + FIELD_OFFSET(BCDE_DEVICE, Device))
|
||||
BufferSize - (sizeof(BOOT_ENTRY_OPTION) + FIELD_OFFSET(BCDE_DEVICE, Device))
|
||||
);
|
||||
if (!NT_SUCCESS(Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
Option->Type = OptionType;
|
||||
Option->DataOffset = sizeof(BOOT_APPLICATION_OPTION);
|
||||
Option->DataOffset = sizeof(BOOT_ENTRY_OPTION);
|
||||
Option->DataSize = FIELD_OFFSET(BCDE_DEVICE, Device) + DeviceElement->Device.Size;
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
@@ -335,7 +333,7 @@ NTSTATUS
|
||||
EfiInitpConvertEfiFilePath (
|
||||
IN EFI_DEVICE_PATH *EfiFilePath,
|
||||
IN BCDE_DATA_TYPE OptionType,
|
||||
IN OUT PBOOT_APPLICATION_OPTION Option,
|
||||
IN OUT PBOOT_ENTRY_OPTION Option,
|
||||
IN ULONG BufferSize
|
||||
)
|
||||
|
||||
@@ -368,19 +366,19 @@ Return Value:
|
||||
PWCHAR PathStart, Position;
|
||||
ULONG BufferRemaining, Length, Appended;
|
||||
|
||||
if (BufferSize < sizeof(BOOT_APPLICATION_OPTION)) {
|
||||
if (BufferSize < sizeof(BOOT_ENTRY_OPTION)) {
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
RtlZeroMemory(Option, sizeof(BOOT_APPLICATION_OPTION));
|
||||
RtlZeroMemory(Option, sizeof(BOOT_ENTRY_OPTION));
|
||||
Option->Type = OptionType;
|
||||
Option->DataOffset = sizeof(BOOT_APPLICATION_OPTION);
|
||||
Option->DataOffset = sizeof(BOOT_ENTRY_OPTION);
|
||||
|
||||
//
|
||||
// Loop through nodes and add one at a time.
|
||||
//
|
||||
Option->DataSize = 0;
|
||||
BufferRemaining = BufferSize - sizeof(BOOT_APPLICATION_OPTION);
|
||||
BufferRemaining = BufferSize - sizeof(BOOT_ENTRY_OPTION);
|
||||
Node = EfiFilePath;
|
||||
PathStart = (PWCHAR)((PUCHAR)Option + Option->DataOffset);
|
||||
Position = PathStart;
|
||||
@@ -440,7 +438,7 @@ Return Value:
|
||||
VOID
|
||||
EfiInitpCreateApplicationEntry (
|
||||
IN EFI_SYSTEM_TABLE *SystemTable,
|
||||
IN OUT PBOOT_INPUT_APPLICATION_ENTRY Entry,
|
||||
IN OUT PBOOT_INIT_APPLICATION_ENTRY Entry,
|
||||
IN ULONG BufferSize,
|
||||
IN EFI_DEVICE_PATH *EfiDevicePath,
|
||||
IN EFI_DEVICE_PATH *EfiFilePath,
|
||||
@@ -491,7 +489,7 @@ Return Value:
|
||||
PWCHAR BcdOptionString;
|
||||
BOOLEAN BcdIdentifierSet;
|
||||
UNICODE_STRING UnicodeString;
|
||||
PBOOT_APPLICATION_OPTION Option, PrevOption;
|
||||
PBOOT_ENTRY_OPTION Option, PrevOption;
|
||||
PBCDE_DEVICE BootDeviceElement;
|
||||
|
||||
(VOID)SystemTable;
|
||||
@@ -503,13 +501,13 @@ Return Value:
|
||||
BcdIdentifierSet = FALSE;
|
||||
|
||||
BufferRemaining = BufferSize;
|
||||
if (BufferRemaining < sizeof(BOOT_INPUT_APPLICATION_ENTRY)) {
|
||||
if (BufferRemaining < sizeof(BOOT_INIT_APPLICATION_ENTRY)) {
|
||||
return;
|
||||
}
|
||||
|
||||
RtlZeroMemory(Entry, sizeof(BOOT_INPUT_APPLICATION_ENTRY));
|
||||
Entry->Signature = BOOT_INPUT_APPLICATION_ENTRY_SIGNATURE;
|
||||
BufferRemaining -= FIELD_OFFSET(BOOT_INPUT_APPLICATION_ENTRY, Options);
|
||||
RtlZeroMemory(Entry, sizeof(BOOT_INIT_APPLICATION_ENTRY));
|
||||
Entry->Signature = BOOT_INIT_APPLICATION_ENTRY_SIGNATURE;
|
||||
BufferRemaining -= FIELD_OFFSET(BOOT_INIT_APPLICATION_ENTRY, Options);
|
||||
|
||||
//
|
||||
// Terminate load options.
|
||||
@@ -530,7 +528,7 @@ Return Value:
|
||||
}
|
||||
|
||||
if (!BcdIdentifierSet) {
|
||||
Entry->Attributes |= BOOT_INPUT_APPLICATION_ENTRY_NO_BCD_IDENTIFIER;
|
||||
Entry->Attributes |= BOOT_APPLICATION_ENTRY_NO_BCD_IDENTIFIER;
|
||||
}
|
||||
|
||||
//
|
||||
@@ -553,7 +551,7 @@ Return Value:
|
||||
// TODO: Support UDP/PXE boot.
|
||||
//
|
||||
PrevOption = Option;
|
||||
Option = (PBOOT_APPLICATION_OPTION)((PUCHAR)&Entry->Options + OptionsSize);
|
||||
Option = (PBOOT_ENTRY_OPTION)((PUCHAR)&Entry->Options + OptionsSize);
|
||||
Status = EfiInitpConvertEfiFilePath(EfiFilePath, BCDE_DATA_TYPE_APPLICATION_PATH, Option, BufferRemaining);
|
||||
if (!NT_SUCCESS(Status)) {
|
||||
goto exit;
|
||||
@@ -567,7 +565,7 @@ Return Value:
|
||||
// TODO: Parse additional options from LoadOptions.
|
||||
//
|
||||
PrevOption = Option;
|
||||
Option = (PBOOT_APPLICATION_OPTION)((PUCHAR)&Entry->Options + OptionsSize);
|
||||
Option = (PBOOT_ENTRY_OPTION)((PUCHAR)&Entry->Options + OptionsSize);
|
||||
// Status = Unknown(LoadOptions, &Entry->Options, RemainingSize, &OptionsSize, &PrevOption, &Size);
|
||||
if (!NT_SUCCESS(Status)) {
|
||||
goto exit;
|
||||
@@ -577,10 +575,11 @@ exit:
|
||||
*BufferUsed = BufferSize - BufferRemaining;
|
||||
}
|
||||
|
||||
PBOOT_INPUT_PARAMETERS
|
||||
EfiInitCreateInputParameters (
|
||||
PBOOT_APPLICATION_PARAMETERS
|
||||
EfiInitCreateInputParametersEx (
|
||||
IN EFI_HANDLE ImageHandle,
|
||||
IN EFI_SYSTEM_TABLE *SystemTable
|
||||
IN EFI_SYSTEM_TABLE *SystemTable,
|
||||
IN ULONG Flags
|
||||
)
|
||||
|
||||
/*++
|
||||
@@ -595,6 +594,8 @@ Arguments:
|
||||
|
||||
SystemTable - Pointer to the EFI system table.
|
||||
|
||||
Flags - Unused.
|
||||
|
||||
Return Value:
|
||||
|
||||
Pointer to parameter structure if successful.
|
||||
@@ -603,19 +604,22 @@ Return Value:
|
||||
--*/
|
||||
|
||||
{
|
||||
ULONG ScratchUsed = 0;
|
||||
ULONG ApplicationEntrySize = 0;
|
||||
EFI_STATUS Status;
|
||||
ULONG ScratchUsed;
|
||||
ULONG ApplicationEntrySize;
|
||||
EFI_PHYSICAL_ADDRESS BadPageAddress;
|
||||
EFI_LOADED_IMAGE *LoadedImage;
|
||||
EFI_DEVICE_PATH *DevicePath;
|
||||
PBOOT_INPUT_PARAMETERS InputParameters;
|
||||
PBOOT_APPLICATION_PARAMETERS InputParameters;
|
||||
PBOOT_MEMORY_INFO MemoryInfo;
|
||||
PMEMORY_DESCRIPTOR MemoryDescriptor;
|
||||
PBOOT_DEVICE BootDevice;
|
||||
PBOOT_FIRMWARE_DATA FirmwareData;
|
||||
PBOOT_PLATFORM_DATA PlatformData;
|
||||
PBOOT_RETURN_DATA ReturnData;
|
||||
|
||||
ScratchUsed = 0;
|
||||
|
||||
//
|
||||
// Page 0x102 may be broken on some machines.
|
||||
// It is mapped here so that it does not get used.
|
||||
@@ -641,12 +645,12 @@ Return Value:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
InputParameters = (PBOOT_INPUT_PARAMETERS)(&EfiInitScratch[ScratchUsed]);
|
||||
ScratchUsed += sizeof(BOOT_INPUT_PARAMETERS);
|
||||
InputParameters->Signature = BOOT_INPUT_PARAMETERS_SIGNATURE;
|
||||
InputParameters->Version = BOOT_INPUT_PARAMETERS_VERSION;
|
||||
InputParameters = (PBOOT_APPLICATION_PARAMETERS)(&EfiInitScratch[ScratchUsed]);
|
||||
ScratchUsed += sizeof(BOOT_APPLICATION_PARAMETERS);
|
||||
InputParameters->Signature = BOOT_APPLICATION_PARAMETERS_SIGNATURE;
|
||||
InputParameters->Version = BOOT_APPLICATION_PARAMETERS_VERSION;
|
||||
InputParameters->MachineType = BOOT_MACHINE_TYPE;
|
||||
InputParameters->TranslationType = BOOT_TRANSLATION_TYPE_NONE;
|
||||
InputParameters->TranslationType = TRANSLATION_TYPE_NONE;
|
||||
InputParameters->ImageBase = LoadedImage->ImageBase;
|
||||
InputParameters->ImageSize = LoadedImage->ImageSize;
|
||||
|
||||
@@ -669,13 +673,13 @@ Return Value:
|
||||
InputParameters->ApplicationEntryOffset = ScratchUsed;
|
||||
EfiInitpCreateApplicationEntry(
|
||||
SystemTable,
|
||||
(PBOOT_INPUT_APPLICATION_ENTRY)(&EfiInitScratch[ScratchUsed]),
|
||||
(PBOOT_INIT_APPLICATION_ENTRY)(&EfiInitScratch[ScratchUsed]),
|
||||
sizeof(EfiInitScratch) - ScratchUsed,
|
||||
DevicePath,
|
||||
LoadedImage->FilePath,
|
||||
LoadedImage->LoadOptions,
|
||||
LoadedImage->LoadOptionsSize,
|
||||
0,
|
||||
Flags,
|
||||
&ApplicationEntrySize,
|
||||
&BootDevice
|
||||
);
|
||||
@@ -698,6 +702,15 @@ Return Value:
|
||||
FirmwareData->ImageHandle = ImageHandle;
|
||||
FirmwareData->SystemTable = SystemTable;
|
||||
|
||||
InputParameters->PlatformDataOffset = ScratchUsed;
|
||||
PlatformData = (PBOOT_PLATFORM_DATA)(&EfiInitScratch[ScratchUsed]);
|
||||
ScratchUsed += sizeof(BOOT_PLATFORM_DATA);
|
||||
PlatformData->Reserved = 0;
|
||||
#if defined(__i386__) || defined(__x86_64__)
|
||||
asm volatile("mov %%cr3, %0" :"=r"(PlatformData->CR3));
|
||||
#endif
|
||||
BlpArchGetDescriptorTableContext(&PlatformData->DescriptorTableContext);
|
||||
|
||||
InputParameters->ReturnDataOffset = ScratchUsed;
|
||||
ReturnData = (PBOOT_RETURN_DATA)(&EfiInitScratch[ScratchUsed]);
|
||||
ScratchUsed += sizeof(BOOT_RETURN_DATA);
|
||||
@@ -710,3 +723,32 @@ Return Value:
|
||||
|
||||
return InputParameters;
|
||||
}
|
||||
|
||||
PBOOT_APPLICATION_PARAMETERS
|
||||
EfiInitCreateInputParameters (
|
||||
IN EFI_HANDLE ImageHandle,
|
||||
IN EFI_SYSTEM_TABLE *SystemTable
|
||||
)
|
||||
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Creates the input parameter structure for the boot application.
|
||||
|
||||
Arguments:
|
||||
|
||||
ImageHandle - EFI handle for the boot application image.
|
||||
|
||||
SystemTable - Pointer to the EFI system table.
|
||||
|
||||
Return Value:
|
||||
|
||||
Pointer to parameter structure if successful.
|
||||
NULL on failure.
|
||||
|
||||
--*/
|
||||
|
||||
{
|
||||
return EfiInitCreateInputParametersEx(ImageHandle, SystemTable, 0);
|
||||
}
|
||||
|
@@ -13,8 +13,7 @@ Abstract:
|
||||
|
||||
--*/
|
||||
|
||||
#include "bootmgr.h"
|
||||
#include "efi.h"
|
||||
#include "efilib.h"
|
||||
|
||||
EFI_STATUS
|
||||
EfiGetEfiStatusCode (
|
||||
|
@@ -13,7 +13,7 @@ Abstract:
|
||||
|
||||
--*/
|
||||
|
||||
#include "bootmgr.h"
|
||||
#include "bootlib.h"
|
||||
#include "efi.h"
|
||||
#include "efilib.h"
|
||||
#include "mm.h"
|
||||
|
@@ -85,8 +85,8 @@ Return Value:
|
||||
// Check TranslationType.
|
||||
//
|
||||
if (
|
||||
TranslationType > BOOT_TRANSLATION_TYPE_MAX ||
|
||||
LibraryParameters->TranslationType > BOOT_TRANSLATION_TYPE_MAX
|
||||
TranslationType > TRANSLATION_TYPE_MAX ||
|
||||
LibraryParameters->TranslationType > TRANSLATION_TYPE_MAX
|
||||
) {
|
||||
DebugPrint(L"BlpMmInitialize(): TranslationType is invalid\r\n");
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
|
@@ -14,7 +14,7 @@ Abstract:
|
||||
--*/
|
||||
|
||||
#include <ntrtl.h>
|
||||
#include "bootmgr.h"
|
||||
#include "bootlib.h"
|
||||
#include "mm.h"
|
||||
|
||||
#define MAX_STATIC_DESCRIPTOR_COUNT 1024
|
||||
|
429
BOOT/ENVIRON/LIB/X86/arch.c
Normal file
429
BOOT/ENVIRON/LIB/X86/arch.c
Normal file
@@ -0,0 +1,429 @@
|
||||
/*++
|
||||
|
||||
Copyright (c) 2024, Quinn Stephens.
|
||||
Provided under the BSD 3-Clause license.
|
||||
|
||||
Module Name:
|
||||
|
||||
arch.c
|
||||
|
||||
Abstract:
|
||||
|
||||
Provides x86 architecture-specific routines.
|
||||
|
||||
--*/
|
||||
|
||||
#include <ntrtl.h>
|
||||
#include "bootlib.h"
|
||||
|
||||
// TODO: Move these to a header file?
|
||||
#define CR0_PG (1 << 31)
|
||||
#define CR4_OSFXSR (1 << 9)
|
||||
#define CR4_LA57 (1 << 12)
|
||||
#define IA32_EFER_MSR 0xC0000080
|
||||
#define IA32_EFER_LME (1 << 10)
|
||||
|
||||
extern ULONG BlPlatformFlags;
|
||||
extern PBOOT_FIRMWARE_DATA EfiFirmwareParameters;
|
||||
EXECUTION_CONTEXT ApplicationExecutionContext;
|
||||
EXECUTION_CONTEXT FirmwareExecutionContext;
|
||||
PEXECUTION_CONTEXT CurrentExecutionContext;
|
||||
|
||||
VOID
|
||||
Archpx64EnableInterruptsAsm (
|
||||
);
|
||||
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Enables interrupts.
|
||||
|
||||
Implemented in ctx.S.
|
||||
|
||||
Arguments:
|
||||
|
||||
None.
|
||||
|
||||
Return Value:
|
||||
|
||||
None.
|
||||
|
||||
--*/
|
||||
|
||||
VOID
|
||||
Archpx64DisableInterruptsAsm (
|
||||
);
|
||||
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Disables interrupts.
|
||||
|
||||
Implemented in ctx.S.
|
||||
|
||||
Arguments:
|
||||
|
||||
None.
|
||||
|
||||
Return Value:
|
||||
|
||||
None.
|
||||
|
||||
--*/
|
||||
|
||||
VOID
|
||||
BlpArchGetDescriptorTableContext (
|
||||
PDESCRIPTOR_TABLE_CONTEXT Context
|
||||
);
|
||||
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Loads current descriptor values into a
|
||||
descriptor table context structure.
|
||||
|
||||
Implemented in ctx.S.
|
||||
|
||||
Arguments:
|
||||
|
||||
Context - Pointer to the context structure.
|
||||
|
||||
Return Value:
|
||||
|
||||
None.
|
||||
|
||||
--*/
|
||||
|
||||
VOID
|
||||
ArchSetDescriptorTableContext (
|
||||
PDESCRIPTOR_TABLE_CONTEXT Context
|
||||
);
|
||||
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Loads current descriptor values from a
|
||||
descriptor table context structure.
|
||||
|
||||
Implemented in ctx.S.
|
||||
|
||||
Arguments:
|
||||
|
||||
Context - Pointer to the context structure.
|
||||
|
||||
Return Value:
|
||||
|
||||
None.
|
||||
|
||||
--*/
|
||||
|
||||
BOOLEAN
|
||||
BlArchIsFiveLevelPagingActive (
|
||||
)
|
||||
|
||||
{
|
||||
ULONG_PTR Cr0, Cr4;
|
||||
ULONG Efer;
|
||||
|
||||
//
|
||||
// Paging must be enabled.
|
||||
//
|
||||
asm volatile("mov %%cr0, %0" :"=r"(Cr0));
|
||||
if (!(Cr0 & CR0_PG)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
//
|
||||
// Long mode must be enabled.
|
||||
//
|
||||
asm volatile("rdmsr" :"=a"(Efer) :"c"(IA32_EFER_MSR));
|
||||
if (!(Efer & IA32_EFER_LME)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
//
|
||||
// 57-bit linear addresses must be enabled.
|
||||
// If LA57 is enabled, 5-level paging is enabled.
|
||||
//
|
||||
asm volatile("mov %%cr4, %0" :"=r"(Cr4));
|
||||
if (!(Cr4 & CR4_LA57)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
ArchInitializeContext (
|
||||
IN OUT PEXECUTION_CONTEXT Context
|
||||
)
|
||||
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Initializes an execution context.
|
||||
|
||||
Arguments:
|
||||
|
||||
Context - Pointer to the context structure.
|
||||
|
||||
Return Value:
|
||||
|
||||
STATUS_SUCCESS if successful.
|
||||
|
||||
--*/
|
||||
|
||||
{
|
||||
ULONG_PTR Cr4;
|
||||
|
||||
if (Context->Type == ExecutionContextFirmware) {
|
||||
Context->Flags &= ~(EXECUTION_CONTEXT_PAGING_ENABLED | 0x01);
|
||||
Context->Flags |= EXECUTION_CONTEXT_INTERRUPTS_ENABLED;
|
||||
|
||||
//
|
||||
// Use context data from firmware.
|
||||
//
|
||||
Context->Cr3 = EfiFirmwareParameters->Cr3;
|
||||
RtlCopyMemory(&Context->DescriptorTableContext, &EfiFirmwareParameters->DescriptorTableContext, sizeof(DESCRIPTOR_TABLE_CONTEXT));
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
Context->Flags &= ~EXECUTION_CONTEXT_INTERRUPTS_ENABLED;
|
||||
Context->Flags |= 0x01;
|
||||
|
||||
//
|
||||
// Use current context.
|
||||
//
|
||||
asm volatile("mov %%cr3, %0" :"=r"(Context->Cr3));
|
||||
BlpArchGetDescriptorTableContext(&Context->DescriptorTableContext);
|
||||
|
||||
//
|
||||
// Check if 5-level paging is active.
|
||||
//
|
||||
if (!BlArchIsFiveLevelPagingActive()) {
|
||||
Context->Flags &= ~EXECUTION_CONTEXT_PAGING_ENABLED;
|
||||
|
||||
//
|
||||
// Enable SSE and FXSAVE/FXRSTOR.
|
||||
//
|
||||
asm volatile("mov %%cr4, %0" :"=r"(Cr4));
|
||||
Cr4 |= CR4_OSFXSR;
|
||||
asm volatile("mov %0, %%cr4" ::"r"(Cr4));
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
//
|
||||
// TODO: Not sure what is supposed to happen here.
|
||||
//
|
||||
DebugPrint(L"ArchInitializeContext(): 5-level paging support not implemented\r\n");
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
VOID
|
||||
ArchSetPagingContext(
|
||||
IN PEXECUTION_CONTEXT NewContext,
|
||||
IN PEXECUTION_CONTEXT CurrentContext
|
||||
)
|
||||
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Loads the current paging context.
|
||||
|
||||
Arguments:
|
||||
|
||||
NewContext - The context to switch to.
|
||||
|
||||
CurrentContext - The currently loaded context.
|
||||
|
||||
Return Value:
|
||||
|
||||
None.
|
||||
|
||||
--*/
|
||||
|
||||
{
|
||||
BOOLEAN PagingEnabled;
|
||||
|
||||
//
|
||||
// Check if paging is enabled.
|
||||
//
|
||||
if (CurrentContext != NULL) {
|
||||
PagingEnabled = CurrentContext->Flags & EXECUTION_CONTEXT_PAGING_ENABLED ? TRUE:FALSE;
|
||||
} else {
|
||||
PagingEnabled = BlArchIsFiveLevelPagingActive() ? TRUE:FALSE;
|
||||
}
|
||||
|
||||
//
|
||||
// If paging is not being enabled/disabled,
|
||||
// just switch CR3.
|
||||
//
|
||||
if (PagingEnabled == (NewContext->Flags & EXECUTION_CONTEXT_PAGING_ENABLED ? TRUE:FALSE)) {
|
||||
asm volatile("mov %0, %%cr3" ::"r"(NewContext->Cr3));
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// TODO: Finish this routine.
|
||||
//
|
||||
DebugPrint(L"ArchSetPagingContext(): Paging mode enable/disable not implemented\r\n");
|
||||
}
|
||||
|
||||
VOID
|
||||
ArchSwitchContext (
|
||||
IN PEXECUTION_CONTEXT NewContext,
|
||||
IN PEXECUTION_CONTEXT CurrentContext
|
||||
)
|
||||
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Switches to a specified execution context.
|
||||
|
||||
Arguments:
|
||||
|
||||
NewContext - The context to switch to.
|
||||
|
||||
CurrentContext - The currently loaded context.
|
||||
|
||||
Return Value:
|
||||
|
||||
None.
|
||||
|
||||
--*/
|
||||
|
||||
{
|
||||
if (CurrentContext != NULL && CurrentContext->Flags & EXECUTION_CONTEXT_INTERRUPTS_ENABLED) {
|
||||
Archpx64DisableInterruptsAsm();
|
||||
}
|
||||
|
||||
//
|
||||
// Set descriptor table and paging contexts,
|
||||
// in the correct order.
|
||||
//
|
||||
if (NewContext->Type == ExecutionContextFirmware) {
|
||||
ArchSetPagingContext(NewContext, CurrentContext);
|
||||
ArchSetDescriptorTableContext(&NewContext->DescriptorTableContext);
|
||||
} else {
|
||||
ArchSetDescriptorTableContext(&NewContext->DescriptorTableContext);
|
||||
ArchSetPagingContext(NewContext, CurrentContext);
|
||||
}
|
||||
|
||||
if (NewContext->Flags & EXECUTION_CONTEXT_INTERRUPTS_ENABLED) {
|
||||
Archpx64EnableInterruptsAsm();
|
||||
}
|
||||
}
|
||||
|
||||
VOID
|
||||
BlpArchSwitchContext (
|
||||
IN EXECUTION_CONTEXT_TYPE Type
|
||||
)
|
||||
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Switches to an execution context of type Type.
|
||||
|
||||
Arguments:
|
||||
|
||||
Type - The requested context type.
|
||||
|
||||
Return Value:
|
||||
|
||||
None.
|
||||
|
||||
--*/
|
||||
|
||||
{
|
||||
PEXECUTION_CONTEXT NewContext;
|
||||
|
||||
if (Type == ExecutionContextFirmware) {
|
||||
NewContext = &FirmwareExecutionContext;
|
||||
} else {
|
||||
NewContext = &ApplicationExecutionContext;
|
||||
}
|
||||
|
||||
if (CurrentExecutionContext->Type == NewContext->Type) {
|
||||
return;
|
||||
}
|
||||
|
||||
ArchSwitchContext(NewContext, CurrentExecutionContext);
|
||||
CurrentExecutionContext = NewContext;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
BlpArchInitialize (
|
||||
IN ULONG Stage
|
||||
)
|
||||
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Internal routine to perform architecture-specific initialization.
|
||||
|
||||
Arguments:
|
||||
|
||||
Stage - 0.
|
||||
|
||||
Return Value:
|
||||
|
||||
STATUS_SUCCESS.
|
||||
|
||||
--*/
|
||||
|
||||
{
|
||||
NTSTATUS Status;
|
||||
|
||||
if (Stage == 0) {
|
||||
ApplicationExecutionContext.Type = ExecutionContextApplication;
|
||||
FirmwareExecutionContext.Type = ExecutionContextFirmware;
|
||||
CurrentExecutionContext = NULL;
|
||||
|
||||
//
|
||||
// Initialize and use application context.
|
||||
//
|
||||
Status = ArchInitializeContext(&ApplicationExecutionContext);
|
||||
if (NT_SUCCESS(Status)) {
|
||||
CurrentExecutionContext = &ApplicationExecutionContext;
|
||||
}
|
||||
|
||||
//
|
||||
// Initialize firmware context if supported.
|
||||
//
|
||||
if (BlPlatformFlags & FIRMWARE_FLAG_EXECUTION_CONTEXT_SUPPORTED) {
|
||||
Status = ArchInitializeContext(&FirmwareExecutionContext);
|
||||
if (!NT_SUCCESS(Status)) {
|
||||
// TODO: Implement ArchInitializeProcessorFeatures()?
|
||||
// ArchInitializeProcessorFeatures();
|
||||
return Status;
|
||||
}
|
||||
|
||||
//
|
||||
// Use firmware execution context if
|
||||
// the application context is not
|
||||
// supported.
|
||||
//
|
||||
if (CurrentExecutionContext == NULL) {
|
||||
CurrentExecutionContext = &FirmwareExecutionContext;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Switch to the correct context.
|
||||
//
|
||||
ArchSwitchContext(CurrentExecutionContext, NULL);
|
||||
}
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
41
BOOT/ENVIRON/LIB/X86/ctx.S
Normal file
41
BOOT/ENVIRON/LIB/X86/ctx.S
Normal file
@@ -0,0 +1,41 @@
|
||||
.text
|
||||
|
||||
SetSegmentRegisters:
|
||||
mov 0x18(%rcx), %ds
|
||||
mov 0x1a(%rcx), %es
|
||||
mov 0x1c(%rcx), %fs
|
||||
mov 0x1e(%rcx), %gs
|
||||
mov 0x20(%rcx), %ss
|
||||
ret
|
||||
|
||||
.globl Archpx64EnableInterruptsAsm
|
||||
Archpx64EnableInterruptsAsm:
|
||||
sti
|
||||
ret
|
||||
|
||||
.globl Archpx64DisableInterruptsAsm
|
||||
Archpx64DisableInterruptsAsm:
|
||||
cli
|
||||
ret
|
||||
|
||||
.globl BlpArchGetDescriptorTableContext
|
||||
BlpArchGetDescriptorTableContext:
|
||||
sgdt 0x00(%rcx)
|
||||
sidt 0x0a(%rcx)
|
||||
sldt 0x14(%rcx)
|
||||
mov %cs, 0x16(%rcx)
|
||||
mov %ds, 0x18(%rcx)
|
||||
mov %es, 0x1a(%rcx)
|
||||
mov %fs, 0x1c(%rcx)
|
||||
mov %gs, 0x1e(%rcx)
|
||||
mov %ss, 0x20(%rcx)
|
||||
ret
|
||||
|
||||
.globl ArchSetDescriptorTableContext
|
||||
ArchSetDescriptorTableContext:
|
||||
sgdt 0x00(%rcx)
|
||||
sidt 0x0a(%rcx)
|
||||
sldt 0x14(%rcx)
|
||||
push 0x16(%rcx)
|
||||
push $SetSegmentRegisters
|
||||
lretq
|
@@ -17,19 +17,21 @@ Abstract:
|
||||
#include "bootlib.h"
|
||||
|
||||
#define MIN_INPUT_PARAMETERS_SIZE ( \
|
||||
sizeof(BOOT_INPUT_PARAMETERS) + \
|
||||
sizeof(BOOT_APPLICATION_PARAMETERS) + \
|
||||
sizeof(BOOT_MEMORY_INFO) + \
|
||||
sizeof(BOOT_INIT_APPLICATION_ENTRY) + \
|
||||
sizeof(BOOT_FIRMWARE_DATA) + \
|
||||
sizeof(BOOT_RETURN_DATA) \
|
||||
)
|
||||
|
||||
PBOOT_INPUT_PARAMETERS BlpApplicationParameters;
|
||||
BOOT_APPLICATION_ENTRY BlpApplicationEntry;
|
||||
PBOOT_DEVICE BlpBootDevice;
|
||||
PBOOT_APPLICATION_PARAMETERS BlpApplicationParameters;
|
||||
BOOT_LIBRARY_PARAMETERS BlpLibraryParameters;
|
||||
BOOT_APPLICATION_ENTRY BlpApplicationEntry;
|
||||
|
||||
NTSTATUS
|
||||
InitializeLibrary (
|
||||
IN PBOOT_INPUT_PARAMETERS InputParameters,
|
||||
IN PBOOT_APPLICATION_PARAMETERS ApplicationParameters,
|
||||
IN PBOOT_LIBRARY_PARAMETERS LibraryParameters
|
||||
)
|
||||
|
||||
@@ -41,7 +43,7 @@ Routine Description:
|
||||
|
||||
Arguments:
|
||||
|
||||
InputParameters - Pointer to the application's input parameters.
|
||||
ApplicationParameters - Pointer to the application's input parameters.
|
||||
|
||||
LibraryParameters - Pointer to the library parameters.
|
||||
|
||||
@@ -54,23 +56,21 @@ Return Value:
|
||||
{
|
||||
NTSTATUS Status;
|
||||
PBOOT_MEMORY_INFO MemoryInfo;
|
||||
PBOOT_INPUT_APPLICATION_ENTRY ApplicationEntry;
|
||||
PBOOT_INIT_APPLICATION_ENTRY ApplicationEntry;
|
||||
PBOOT_FIRMWARE_DATA FirmwareData;
|
||||
PBOOT_BLOCK_IDENTIFIER BlockDevice;
|
||||
PBOOT_APPLICATION_OPTION Option;
|
||||
|
||||
(VOID)LibraryParameters;
|
||||
|
||||
if (InputParameters == NULL ||
|
||||
InputParameters->Signature != BOOT_INPUT_PARAMETERS_SIGNATURE ||
|
||||
InputParameters->Size < MIN_INPUT_PARAMETERS_SIZE) {
|
||||
if (ApplicationParameters == NULL ||
|
||||
ApplicationParameters->Signature != BOOT_APPLICATION_PARAMETERS_SIGNATURE ||
|
||||
ApplicationParameters->Size < MIN_INPUT_PARAMETERS_SIZE) {
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
MemoryInfo = (PBOOT_MEMORY_INFO)((PUCHAR)InputParameters + InputParameters->MemoryInfoOffset);
|
||||
ApplicationEntry = (PBOOT_INPUT_APPLICATION_ENTRY)((PUCHAR)InputParameters + InputParameters->ApplicationEntryOffset);
|
||||
BlpBootDevice = (PBOOT_DEVICE)((PUCHAR)InputParameters + InputParameters->BootDeviceOffset);
|
||||
FirmwareData = (PBOOT_FIRMWARE_DATA)((PUCHAR)InputParameters + InputParameters->FirmwareDataOffset);
|
||||
MemoryInfo = (PBOOT_MEMORY_INFO)((PUCHAR)ApplicationParameters + ApplicationParameters->MemoryInfoOffset);
|
||||
ApplicationEntry = (PBOOT_INIT_APPLICATION_ENTRY)((PUCHAR)ApplicationParameters + ApplicationParameters->ApplicationEntryOffset);
|
||||
BlpBootDevice = (PBOOT_DEVICE)((PUCHAR)ApplicationParameters + ApplicationParameters->BootDeviceOffset);
|
||||
FirmwareData = (PBOOT_FIRMWARE_DATA)((PUCHAR)ApplicationParameters + ApplicationParameters->FirmwareDataOffset);
|
||||
|
||||
//
|
||||
// Initialize firmware library.
|
||||
@@ -83,24 +83,28 @@ Return Value:
|
||||
}
|
||||
|
||||
ConsolePrint(L"> Alcyone EFI Boot Manager\r\n");
|
||||
ConsolePrintf(L"Image base: %x %x\r\nImage size: %x\r\n", HIDWORD((ULONG_PTR)InputParameters->ImageBase), LODWORD((ULONG_PTR)InputParameters->ImageBase), InputParameters->ImageSize);
|
||||
|
||||
ConsolePrintf(L"Image base: %x %x\r\nImage size: %x\r\n", HIDWORD((ULONG_PTR)ApplicationParameters->ImageBase), LODWORD((ULONG_PTR)ApplicationParameters->ImageBase), ApplicationParameters->ImageSize);
|
||||
DebugPrint(L"Initializing boot library...\r\n");
|
||||
|
||||
if (ApplicationEntry->Signature != BOOT_INPUT_APPLICATION_ENTRY_SIGNATURE) {
|
||||
if (ApplicationEntry->Signature != BOOT_INIT_APPLICATION_ENTRY_SIGNATURE) {
|
||||
DebugPrint(L"InitializeLibrary(): ApplicationEntry Signature is invalid\r\n");
|
||||
return STATUS_INVALID_PARAMETER_9;
|
||||
}
|
||||
|
||||
//
|
||||
// Save input parameters and application entry.
|
||||
// Save library and application parameters.
|
||||
//
|
||||
BlpApplicationParameters = ApplicationParameters;
|
||||
RtlCopyMemory(&BlpLibraryParameters, LibraryParameters, sizeof(BOOT_LIBRARY_PARAMETERS));
|
||||
|
||||
//
|
||||
// Save application entry.
|
||||
//
|
||||
BlpApplicationParameters = InputParameters;
|
||||
BlpApplicationEntry.Attributes = ApplicationEntry->Attributes;
|
||||
RtlCopyMemory(&BlpApplicationEntry.BcdIdentifier, &ApplicationEntry->BcdIdentifier, sizeof(GUID));
|
||||
BlpApplicationEntry.Options = &ApplicationEntry->Options;
|
||||
|
||||
Status = BlpMmInitialize(MemoryInfo, InputParameters->TranslationType, LibraryParameters);
|
||||
Status = BlpMmInitialize(MemoryInfo, ApplicationParameters->TranslationType, LibraryParameters);
|
||||
if (!NT_SUCCESS(Status)) {
|
||||
return Status;
|
||||
}
|
||||
@@ -110,7 +114,7 @@ Return Value:
|
||||
|
||||
NTSTATUS
|
||||
BlInitializeLibrary (
|
||||
IN PBOOT_INPUT_PARAMETERS InputParameters,
|
||||
IN PBOOT_APPLICATION_PARAMETERS ApplicationParameters,
|
||||
IN PBOOT_LIBRARY_PARAMETERS LibraryParameters
|
||||
)
|
||||
|
||||
@@ -122,7 +126,7 @@ Routine Description:
|
||||
|
||||
Arguments:
|
||||
|
||||
InputParameters - Pointer to the application's input parameters.
|
||||
ApplicationParameters - Pointer to the application's input parameters.
|
||||
|
||||
LibraryParameters - Pointer to the library parameters.
|
||||
|
||||
@@ -133,7 +137,7 @@ Return Value:
|
||||
--*/
|
||||
|
||||
{
|
||||
return InitializeLibrary(InputParameters, LibraryParameters);
|
||||
return InitializeLibrary(ApplicationParameters, LibraryParameters);
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
|
@@ -17,7 +17,7 @@ Abstract:
|
||||
|
||||
ULONG
|
||||
BlGetBootOptionSize (
|
||||
IN PBOOT_APPLICATION_OPTION Option
|
||||
IN PBOOT_ENTRY_OPTION Option
|
||||
)
|
||||
|
||||
/*++
|
||||
@@ -42,11 +42,11 @@ Return Value:
|
||||
if (Option->DataOffset != 0) {
|
||||
TotalSize = Option->DataOffset + Option->DataSize;
|
||||
} else {
|
||||
TotalSize = sizeof(BOOT_APPLICATION_OPTION);
|
||||
TotalSize = sizeof(BOOT_ENTRY_OPTION);
|
||||
}
|
||||
|
||||
if (Option->OtherOptionsOffset != 0) {
|
||||
TotalSize += BlGetBootOptionListSize((PBOOT_APPLICATION_OPTION)((PUCHAR)Option + Option->OtherOptionsOffset));
|
||||
TotalSize += BlGetBootOptionListSize((PBOOT_ENTRY_OPTION)((PUCHAR)Option + Option->OtherOptionsOffset));
|
||||
}
|
||||
|
||||
return TotalSize;
|
||||
@@ -54,7 +54,7 @@ Return Value:
|
||||
|
||||
ULONG
|
||||
BlGetBootOptionListSize (
|
||||
IN PBOOT_APPLICATION_OPTION Options
|
||||
IN PBOOT_ENTRY_OPTION Options
|
||||
)
|
||||
|
||||
/*++
|
||||
@@ -75,12 +75,12 @@ Return Value:
|
||||
|
||||
{
|
||||
ULONG TotalSize, NextOffset;
|
||||
PBOOT_APPLICATION_OPTION Option;
|
||||
PBOOT_ENTRY_OPTION Option;
|
||||
|
||||
TotalSize = 0;
|
||||
NextOffset = 0;
|
||||
do {
|
||||
Option = (PBOOT_APPLICATION_OPTION)((PUCHAR)Options + NextOffset);
|
||||
Option = (PBOOT_ENTRY_OPTION)((PUCHAR)Options + NextOffset);
|
||||
NextOffset = Option->NextOptionOffset;
|
||||
TotalSize += BlGetBootOptionSize(Option);
|
||||
} while (NextOffset != 0);
|
||||
|
Reference in New Issue
Block a user