[BOOTLIB]: ACPI support (RSDP, XSDT/RSDT and arbitrary table lookup + mapping)

[BOOTLIB]: Additional text and graphics console support. Among other things, we have now gained the ability to fill a buffer with a particular color.
[BOOTLIB]: OEM Bitmap (ACPI 5!) support.
[BOOTMGR]: Continue making a few more initialization calls now that bootlib supports more functionality.

svn path=/trunk/; revision=70539
This commit is contained in:
Alex Ionescu 2016-01-07 23:43:15 +00:00
parent 55ef8d7cd2
commit e0df0d3663
14 changed files with 1298 additions and 23 deletions

View file

@ -1032,6 +1032,66 @@ BmFwMemoryInitialize (
}
}
NTSTATUS
BmpBgDisplayClearScreen (
_In_ ULONG Color
)
{
/* Not yet supported */
return STATUS_NOT_IMPLEMENTED;
}
NTSTATUS
BlXmiInitialize (
_In_ PWCHAR Stylesheet
)
{
/* Reset the cursor type */
BlDisplaySetCursorType(0);
/* Nope, not doing any XML stuff */
return STATUS_SUCCESS;
}
VOID
BlImgQueryCodeIntegrityBootOptions (
_In_ PBL_LOADED_APPLICATION_ENTRY ApplicationEntry,
_Out_ PBOOLEAN IntegrityChecksDisabled,
_Out_ PBOOLEAN TestSigningEnabled
)
{
NTSTATUS Status;
BOOLEAN Value;
/* Check if /DISABLEINTEGRITYCHECKS is on */
Status = BlGetBootOptionBoolean(ApplicationEntry->BcdData,
BcdLibraryBoolean_DisableIntegrityChecks,
&Value);
*IntegrityChecksDisabled = NT_SUCCESS(Status) && (Value);
/* Check if /TESTSIGNING is on */
Status = BlGetBootOptionBoolean(ApplicationEntry->BcdData,
BcdLibraryBoolean_AllowPrereleaseSignatures,
&Value);
*TestSigningEnabled = NT_SUCCESS(Status) && (Value);
}
NTSTATUS
BmFwVerifySelfIntegrity (
VOID
)
{
EfiPrintf(L"Device Type %d Local Type %d\r\n", BlpBootDevice->DeviceType, BlpBootDevice->Local.Type);
if ((BlpBootDevice->DeviceType == LocalDevice) &&
(BlpBootDevice->Local.Type == CdRomDevice) &&
(BlpApplicationFlags & BL_APPLICATION_ENTRY_FLAG_NO_GUID))
{
return STATUS_SUCCESS;
}
return 0xC0000428;
}
/*++
* @name BmMain
@ -1059,6 +1119,7 @@ BmMain (
HANDLE BcdHandle;
PBL_BCD_OPTION EarlyOptions;
PWCHAR Stylesheet;
BOOLEAN XmlLoaded, DisableIntegrity, TestSigning;
EfiPrintf(L"ReactOS UEFI Boot Manager Initializing...\n");
@ -1166,23 +1227,66 @@ BmMain (
goto Quickie;
}
/* Initialize the XML Engine (as a side-effect, resets cursor) */
Status = BlXmiInitialize(Stylesheet);
if (!NT_SUCCESS(Status))
{
EfiPrintf(L"\r\nBlXmiInitialize failed 0x%x\r\n", Status);
goto Failure;
}
XmlLoaded = TRUE;
/* Check if there's an active bitmap visible */
if (!BlDisplayValidOemBitmap())
{
/* Nope, make the screen black using BGFX */
if (!NT_SUCCESS(BmpBgDisplayClearScreen(0xFF000000)))
{
/* BGFX isn't active, use standard display */
BlDisplayClearScreen();
}
}
#ifdef _BIT_LOCKER_
/* Bitlocker will take over screen UI if enabled */
FveDisplayScreen = BmFveDisplayScreen;
#endif
/* Check if any bypass options are enabled */
BlImgQueryCodeIntegrityBootOptions(&BlpApplicationEntry,
&DisableIntegrity,
&TestSigning);
if (!DisableIntegrity)
{
/* Integrity checks are enabled, so validate our signature */
Status = BmFwVerifySelfIntegrity();
if (!NT_SUCCESS(Status))
{
/* Signature invalid, fail boot */
// goto Failure;
}
}
// BlXmiWrite(L"<bootmgr/>");
//BlSecureBootCheckForFactoryReset();
/* do more stuff!! */
EfiPrintf(BlResourceFindMessage(BM_MSG_TEST));
//EfiPrintf(Stylesheet);
EfiPrintf(Stylesheet);
EfiStall(10000000);
//Failure:
Failure:
/* Check if we got here due to an internal error */
if (BmpInternalBootError)
{
/* If XML is available, display the error */
#if 0
if (XmlLoaded)
{
BmDisplayDumpError(0, 0);
BmErrorPurge();
//BmDisplayDumpError(0, 0);
//BmErrorPurge();
}
#endif
/* Don't do a fatal error -- return back to firmware */
goto Quickie;

View file

@ -79,7 +79,8 @@ typedef enum BcdLibraryElementTypes
BcdLibraryBoolean_BootUxDisable = 0x1600006C,
BcdLibraryBoolean_BootShutdownDisabled = 0x16000074,
BcdLibraryIntegerList_AllowedInMemorySettings = 0x17000077,
BcdLibraryBoolean_ForceFipsCrypto = 0x16000079
BcdLibraryBoolean_ForceFipsCrypto = 0x16000079,
BcdLibraryBoolean_MobileGraphics = 0x1600007A /* Undocumented */
} BcdLibraryElementTypes;
typedef enum BcdOSLoaderElementTypes

View file

@ -28,6 +28,9 @@
/* PE Headers */
#include <ntimage.h>
/* ACPI Headers */
#include <drivers/acpi/acpi.h>
/* UEFI Headers */
#include <Uefi.h>
#include <DevicePath.h>
@ -35,6 +38,7 @@
#include <GraphicsOutput.h>
#include <UgaDraw.h>
#include <BlockIo.h>
#include <Acpi.h>
/* Registry Headers */
#define __FREELDR_H
@ -445,7 +449,7 @@ typedef
NTSTATUS
(*PCONSOLE_CLEAR_TEXT) (
_In_ struct _BL_TEXT_CONSOLE* Console,
_In_ ULONG Attribute
_In_ BOOLEAN LineOnly
);
typedef
@ -1097,7 +1101,45 @@ typedef struct _BL_DEFERRED_FONT_FILE
ULONG Flags;
PBL_DEVICE_DESCRIPTOR Device;
PWCHAR FontPath;
} BL_DEFERRED_FONT_FILE, *PBL_DEFERRED_FONT_FILE;;
} BL_DEFERRED_FONT_FILE, *PBL_DEFERRED_FONT_FILE;
#pragma pack(push)
#pragma pack(1)
typedef struct _BMP_HEADER
{
USHORT Signature;
ULONG Size;
USHORT Reserved[2];
ULONG Offset;
} BMP_HEADER, *PBMP_HEADER;
typedef struct _DIB_HEADER
{
ULONG Size;
ULONG Width;
ULONG Height;
USHORT Planes;
USHORT BitCount;
ULONG Compression;
ULONG SizeImage;
ULONG XPelsPerMeter;
ULONG YPelsPerMEter;
ULONG ClrUsed;
ULONG ClrImportant;
} DIB_HEADER, *PDIB_HEADER;
typedef struct _BITMAP
{
BMP_HEADER BmpHeader;
DIB_HEADER DibHeader;
} BITMAP, *PBITMAP;
#pragma pack(pop)
typedef struct _COORD
{
ULONG X;
ULONG Y;
} COORD, *PCOORD;
/* INLINE ROUTINES ***********************************************************/
@ -1252,6 +1294,12 @@ EfiConInReset (
VOID
);
NTSTATUS
EfiConOutOutputString (
_In_ SIMPLE_TEXT_OUTPUT_INTERFACE *TextInterface,
_In_ PWCHAR String
);
NTSTATUS
EfiConOutQueryMode (
_In_ SIMPLE_TEXT_OUTPUT_INTERFACE *TextInterface,
@ -1348,6 +1396,11 @@ EfiIsDevicePathParent (
_In_ EFI_DEVICE_PATH *DevicePath2
);
NTSTATUS
EfipGetRsdt (
_Out_ PPHYSICAL_ADDRESS FoundRsdt
);
/* PLATFORM TIMER ROUTINES ***************************************************/
NTSTATUS
@ -1380,6 +1433,16 @@ BfLoadDeferredFontFiles (
VOID
);
NTSTATUS
BfClearScreen (
_In_ PBL_GRAPHICS_CONSOLE Console
);
NTSTATUS
BfClearToEndOfLine (
_In_ PBL_GRAPHICS_CONSOLE Console
);
/* FILESYSTEM ROUTINES *******************************************************/
NTSTATUS
@ -1444,6 +1507,12 @@ BlUtlUpdateProgress (
_Out_opt_ PBOOLEAN Completed
);
NTSTATUS
BlUtlGetAcpiTable (
_Out_ PVOID* TableAddress,
_In_ ULONG Signature
);
EFI_STATUS
EfiGetEfiStatusCode(
_In_ NTSTATUS Status
@ -1845,6 +1914,32 @@ BlDisplayGetScreenResolution (
_Out_ PULONG Vres
);
VOID
BlDisplayInvalidateOemBitmap (
VOID
);
PBITMAP
BlDisplayGetOemBitmap (
_Out_ PCOORD Offset,
_Out_opt_ PULONG Flags
);
BOOLEAN
BlDisplayValidOemBitmap (
VOID
);
NTSTATUS
BlDisplayClearScreen (
VOID
);
NTSTATUS
BlDisplaySetCursorType (
_In_ ULONG Type
);
/* I/O ROUTINES **************************************************************/
NTSTATUS
@ -1962,11 +2057,30 @@ ConsoleGraphicalDestruct (
_In_ struct _BL_GRAPHICS_CONSOLE* Console
);
NTSTATUS
ConsoleGraphicalClearText (
_In_ PBL_GRAPHICS_CONSOLE Console,
_In_ BOOLEAN LineOnly
);
NTSTATUS
ConsoleGraphicalClearPixels (
_In_ PBL_GRAPHICS_CONSOLE Console,
_In_ ULONG Color
);
NTSTATUS
ConsoleGraphicalReinitialize (
_In_ struct _BL_GRAPHICS_CONSOLE* Console
);
NTSTATUS
ConsoleGraphicalSetTextState (
_In_ PBL_GRAPHICS_CONSOLE Console,
_In_ ULONG Mask,
_In_ PBL_DISPLAY_STATE TextState
);
BOOLEAN
ConsoleGraphicalIsEnabled (
_In_ struct _BL_GRAPHICS_CONSOLE* Console
@ -2029,7 +2143,7 @@ ConsoleTextLocalSetTextResolution (
NTSTATUS
ConsoleTextLocalClearText (
_In_ struct _BL_TEXT_CONSOLE* Console,
_In_ ULONG Attribute
_In_ BOOLEAN LineOnly
);
NTSTATUS
@ -2052,6 +2166,12 @@ ConsolepFindResolution (
_In_ ULONG MaxIndex
);
NTSTATUS
ConsoleFirmwareTextClear (
_In_ PBL_TEXT_CONSOLE Console,
_In_ BOOLEAN LineOnly
);
VOID
ConsoleFirmwareTextClose (
_In_ PBL_TEXT_CONSOLE TextConsole
@ -2095,6 +2215,12 @@ ConsoleFirmwareGraphicalDisable (
_In_ PBL_GRAPHICS_CONSOLE GraphicsConsole
);
NTSTATUS
ConsoleFirmwareGraphicalClear (
_In_ PBL_GRAPHICS_CONSOLE Console,
_In_ ULONG Color
);
NTSTATUS
ConsoleFirmwareGraphicalEnable (
_In_ PBL_GRAPHICS_CONSOLE GraphicsConsole
@ -2143,6 +2269,22 @@ ConsoleInputLocalEraseBuffer (
_In_opt_ PULONG ValueToFill
);
VOID
ConsolepClearBuffer (
_In_ PUCHAR FrameBuffer,
_In_ ULONG Width,
_In_ PUCHAR FillColor,
_In_ ULONG Height,
_In_ ULONG ScanlineWidth,
_In_ ULONG PixelDepth
);
NTSTATUS
ConsolepConvertColorToPixel (
_In_ BL_COLOR Color,
_Out_ PUCHAR Pixel
);
extern ULONG MmDescriptorCallTreeCount;
extern ULONG BlpApplicationFlags;
extern BL_LIBRARY_PARAMETERS BlpLibraryParameters;
@ -2158,6 +2300,8 @@ extern EFI_GUID EfiLoadedImageProtocol;
extern EFI_GUID EfiDevicePathProtocol;
extern EFI_GUID EfiBlockIoProtocol;
extern EFI_GUID EfiSimpleTextInputExProtocol;
extern EFI_GUID EfiRootAcpiTableGuid;
extern EFI_GUID EfiRootAcpiTable10Guid;
extern ULONG ConsoleGraphicalResolutionListFlags;
extern BL_DISPLAY_MODE ConsoleGraphicalResolutionList[];
extern BL_DISPLAY_MODE ConsoleTextResolutionList[];

View file

@ -0,0 +1,46 @@
/** @file
GUIDs used for ACPI entries in the EFI system table
These GUIDs point the ACPI tables as defined in the ACPI specifications.
ACPI 2.0 specification defines the ACPI 2.0 GUID. UEFI 2.0 defines the
ACPI 2.0 Table GUID and ACPI Table GUID.
Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
@par Revision Reference:
GUIDs defined in UEFI 2.0 spec.
**/
#ifndef __ACPI_GUID_H__
#define __ACPI_GUID_H__
#define ACPI_TABLE_GUID \
{ \
0xeb9d2d30, 0x2d88, 0x11d3, {0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \
}
#define EFI_ACPI_TABLE_GUID \
{ \
0x8868e871, 0xe4f1, 0x11d3, {0xbc, 0x22, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 } \
}
#define ACPI_10_TABLE_GUID ACPI_TABLE_GUID
//
// ACPI 2.0 or newer tables should use EFI_ACPI_TABLE_GUID.
//
#define EFI_ACPI_20_TABLE_GUID EFI_ACPI_TABLE_GUID
extern EFI_GUID gEfiAcpiTableGuid;
extern EFI_GUID gEfiAcpi10TableGuid;
extern EFI_GUID gEfiAcpi20TableGuid;
#endif

View file

@ -23,6 +23,7 @@ EFI_RUNTIME_SERVICES *EfiRT;
EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *EfiConOut;
EFI_SIMPLE_TEXT_INPUT_PROTOCOL *EfiConIn;
EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *EfiConInEx;
PHYSICAL_ADDRESS EfiRsdt;
EFI_GUID EfiGraphicsOutputProtocol = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID;
EFI_GUID EfiUgaDrawProtocol = EFI_UGA_DRAW_PROTOCOL_GUID;
@ -30,6 +31,8 @@ EFI_GUID EfiLoadedImageProtocol = EFI_LOADED_IMAGE_PROTOCOL_GUID;
EFI_GUID EfiDevicePathProtocol = EFI_DEVICE_PATH_PROTOCOL_GUID;
EFI_GUID EfiSimpleTextInputExProtocol = EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL_GUID;
EFI_GUID EfiBlockIoProtocol = EFI_BLOCK_IO_PROTOCOL_GUID;
EFI_GUID EfiRootAcpiTableGuid = EFI_ACPI_20_TABLE_GUID;
EFI_GUID EfiRootAcpiTable10Guid = EFI_ACPI_TABLE_GUID;
WCHAR BlScratchBuffer[8192];
@ -624,6 +627,37 @@ EfiConOutEnableCursor (
return EfiGetNtStatusCode(EfiStatus);
}
NTSTATUS
EfiConOutOutputString (
_In_ SIMPLE_TEXT_OUTPUT_INTERFACE *TextInterface,
_In_ PWCHAR String
)
{
BL_ARCH_MODE OldMode;
EFI_STATUS EfiStatus;
/* Are we in protected mode? */
OldMode = CurrentExecutionContext->Mode;
if (OldMode != BlRealMode)
{
/* FIXME: Not yet implemented */
return STATUS_NOT_IMPLEMENTED;
}
/* Make the EFI call */
EfiStatus = TextInterface->OutputString(TextInterface, String);
/* Switch back to protected mode if we came from there */
if (OldMode != BlRealMode)
{
BlpArchSwitchContext(OldMode);
}
/* Convert the error to an NTSTATUS */
return EfiGetNtStatusCode(EfiStatus);
}
VOID
EfiConOutReadCurrentMode (
_In_ SIMPLE_TEXT_OUTPUT_INTERFACE *TextInterface,
@ -881,6 +915,129 @@ EfiAllocatePages (
return EfiGetNtStatusCode(EfiStatus);
}
NTSTATUS
EfipGetSystemTable (
_In_ EFI_GUID *TableGuid,
_Out_ PPHYSICAL_ADDRESS TableAddress
)
{
ULONG i;
NTSTATUS Status;
/* Assume failure */
Status = STATUS_NOT_FOUND;
/* Loop through the configuration tables */
for (i = 0; i < EfiST->NumberOfTableEntries; i++)
{
/* Check if this one matches the one we want */
if (RtlEqualMemory(&EfiST->ConfigurationTable[i].VendorGuid,
TableGuid,
sizeof(*TableGuid)))
{
/* Return its address */
TableAddress->QuadPart = (ULONG_PTR)EfiST->ConfigurationTable[i].VendorTable;
Status = STATUS_SUCCESS;
break;
}
}
/* Return the search result */
return Status;
}
NTSTATUS
EfipGetRsdt (
_Out_ PPHYSICAL_ADDRESS FoundRsdt
)
{
NTSTATUS Status;
ULONG Length;
PHYSICAL_ADDRESS RsdpAddress, Rsdt;
PRSDP Rsdp;
/* Assume failure */
Length = 0;
Rsdp = NULL;
/* Check if we already know it */
if (EfiRsdt.QuadPart)
{
/* Return it */
*FoundRsdt = EfiRsdt;
return STATUS_SUCCESS;
}
/* Otherwise, look for the ACPI 2.0 RSDP (XSDT really) */
Status = EfipGetSystemTable(&EfiRootAcpiTableGuid, &RsdpAddress);
if (!NT_SUCCESS(Status))
{
/* Didn't fint it, look for the ACPI 1.0 RSDP (RSDT really) */
Status = EfipGetSystemTable(&EfiRootAcpiTable10Guid, &RsdpAddress);
if (!NT_SUCCESS(Status))
{
return Status;
}
}
/* Map it */
Length = sizeof(*Rsdp);
Status = BlMmMapPhysicalAddressEx((PVOID*)&Rsdp,
0,
Length,
RsdpAddress);
if (NT_SUCCESS(Status))
{
/* Check the revision (anything >= 2.0 is XSDT) */
if (Rsdp->Revision)
{
/* Check if the table is bigger than just its header */
if (Rsdp->Length > Length)
{
/* Capture the real length */
Length = Rsdp->Length;
/* Unmap our header mapping */
BlMmUnmapVirtualAddressEx(Rsdp, sizeof(*Rsdp));
/* And map the whole thing now */
Status = BlMmMapPhysicalAddressEx((PVOID*)&Rsdp,
0,
Length,
RsdpAddress);
if (!NT_SUCCESS(Status))
{
return Status;
}
}
/* Read the XSDT address from the table*/
Rsdt = Rsdp->XsdtAddress;
}
else
{
/* ACPI 1.0 so just read the RSDT */
Rsdt.QuadPart = Rsdp->RsdtAddress;
}
/* Save it for later */
EfiRsdt = Rsdt;
/* And return it back */
*FoundRsdt = Rsdt;
}
/* Check if we had mapped the RSDP */
if (Rsdp)
{
/* Unmap it */
BlMmUnmapVirtualAddressEx(Rsdp, Length);
}
/* Return search result back to caller */
return Status;
}
BL_MEMORY_ATTR
MmFwpGetOsAttributeType (
_In_ ULONGLONG Attribute

View file

@ -723,3 +723,273 @@ BlDisplayGetScreenResolution (
/* Return if we got a valid resolution back */
return Status;
}
VOID
BlDisplayInvalidateOemBitmap (
VOID
)
{
PBGRT_TABLE BgrtTable;
NTSTATUS Status;
/* Search for the BGRT */
Status = BlUtlGetAcpiTable((PVOID*)&BgrtTable, BGRT_SIGNATURE);
if (NT_SUCCESS(Status))
{
/* Mark the bitmap as invalid */
BgrtTable->Status &= BGRT_STATUS_IMAGE_VALID;
/* Unmap the table */
BlMmUnmapVirtualAddressEx(BgrtTable, BgrtTable->Header.Length);
}
}
PBITMAP
BlDisplayGetOemBitmap (
_In_opt_ PCOORD Offsets,
_Out_opt_ PULONG Flags
)
{
NTSTATUS Status;
ULONG Size;
PHYSICAL_ADDRESS PhysicalAddress;
PBGRT_TABLE BgrtTable;
PBITMAP Bitmap;
PBMP_HEADER Header;
Bitmap = NULL;
BgrtTable = NULL;
/* Search for the BGRT */
Status = BlUtlGetAcpiTable((PVOID*)&BgrtTable, BGRT_SIGNATURE);
if (!NT_SUCCESS(Status))
{
EfiPrintf(L"no BGRT found\r\n");
goto Quickie;
}
/* Make sure this is really a BGRT */
if (BgrtTable->Header.Signature != BGRT_SIGNATURE)
{
Status = STATUS_ACPI_INVALID_TABLE;
goto Quickie;
}
/* Make sure the BGRT table length is valid */
if (BgrtTable->Header.Length != sizeof(*BgrtTable))
{
Status = STATUS_ACPI_INVALID_TABLE;
goto Quickie;
}
/* Make sure its a bitmap */
if (BgrtTable->ImageType != BgrtImageTypeBitmap)
{
Status = STATUS_ACPI_INVALID_TABLE;
goto Quickie;
}
/* Make sure it's somewhere in RAM */
if (!BgrtTable->LogoAddress)
{
Status = STATUS_ACPI_INVALID_TABLE;
goto Quickie;
}
/* Map the bitmap header only for now */
PhysicalAddress.QuadPart = BgrtTable->LogoAddress;
Status = BlMmMapPhysicalAddressEx((PVOID*)&Header,
0,
sizeof(BMP_HEADER),
PhysicalAddress);
if (!NT_SUCCESS(Status))
{
goto Quickie;
}
/* Capture the real size of the header */
Size = Header->Size;
/* Unmap the bitmap header */
BlMmUnmapVirtualAddressEx(BgrtTable, sizeof(BMP_HEADER));
/* If the real size is smaller than at least a V3 bitmap, bail out */
if (Size < sizeof(BITMAP))
{
Status = STATUS_ACPI_INVALID_TABLE;
goto Quickie;
}
/* Map the real size of the header */
Status = BlMmMapPhysicalAddressEx((PVOID*)&Bitmap,
0,
Size,
PhysicalAddress);
if (!NT_SUCCESS(Status))
{
goto Quickie;
}
/* Make sure this is a non-compressed 24-bit or 32-bit V3 bitmap */
if ((Bitmap->BmpHeader.Signature != 'MB') ||
(Bitmap->DibHeader.Compression) ||
((Bitmap->DibHeader.BitCount != 24) &&
(Bitmap->DibHeader.BitCount != 32)) ||
(Bitmap->DibHeader.Size != sizeof(BITMAP)))
{
Status = STATUS_ACPI_INVALID_TABLE;
goto Quickie;
}
/* Check if caller wants the offsets back */
if (Offsets)
{
/* Give them away */
Offsets->X = BgrtTable->OffsetX;
Offsets->Y = BgrtTable->OffsetY;
}
/* Check if the caller wants flags */
if (Flags)
{
/* Return if the image is valid */
*Flags = BgrtTable->Status & BGRT_STATUS_IMAGE_VALID;
}
Quickie:
/* Check if we had mapped the BGRT */
if (BgrtTable)
{
/* Unmap it */
BlMmUnmapVirtualAddressEx(BgrtTable, BgrtTable->Header.Length);
}
/* Check if this is the failure path */
if (!NT_SUCCESS(Status))
{
/* Did we have the OEM bitmap mapped? */
if (Bitmap)
{
/* Unmap it */
BlMmUnmapVirtualAddressEx(Bitmap, Bitmap->BmpHeader.Size);
}
/* No bitmap to return */
Bitmap = NULL;
}
/* Return the bitmap back, if any */
return Bitmap;
}
BOOLEAN
BlDisplayValidOemBitmap (
VOID
)
{
PBITMAP Bitmap;
ULONG HRes, VRes, Height, Width, Flags;
COORD Offsets;
BOOLEAN Result;
NTSTATUS Status;
/* First check if mobile graphics are enabled */
Status = BlGetBootOptionBoolean(BlpApplicationEntry.BcdData,
BcdLibraryBoolean_MobileGraphics,
&Result);
if ((NT_SUCCESS(Status)) && (Result))
{
/* Yes, so use the firmware image */
return TRUE;
}
/* Nope, so we'll check the ACPI OEM bitmap */
Result = FALSE;
Bitmap = BlDisplayGetOemBitmap(&Offsets, &Flags);
/* Is there one? */
if (Bitmap)
{
/* Is it valid? */
if (Flags & BGRT_STATUS_IMAGE_VALID)
{
/* Get the current screen resolution */
Status = BlDisplayGetScreenResolution(&HRes, &VRes);
if (NT_SUCCESS(Status))
{
/* Is there a valid width? */
Width = Bitmap->DibHeader.Width;
if (Width)
{
/* Is there a valid height? */
Height = Bitmap->DibHeader.Height;
if (Height)
{
/* Will if fit on this screen? */
if (((Width + Offsets.X) <= HRes) &&
((Height + Offsets.Y) <= VRes))
{
/* Then it's all good! */
Result = TRUE;
}
}
}
}
}
/* Unmap the bitmap for now, it will be drawn later */
BlMmUnmapVirtualAddressEx(Bitmap, Bitmap->BmpHeader.Size);
}
/* Return that a valid OEM bitmap exists */
return Result;
}
NTSTATUS
BlDisplayClearScreen (
VOID
)
{
NTSTATUS Status;
PBL_TEXT_CONSOLE TextConsole;
/* Nothing to do if there's no text console */
Status = STATUS_SUCCESS;
TextConsole = DspTextConsole;
if (TextConsole)
{
/* Otherwise, clear the whole screen */
Status = TextConsole->Callbacks->ClearText(TextConsole, FALSE);
if (NT_SUCCESS(Status))
{
/* Invalidate the OEM bitmap at this point */
BlDisplayInvalidateOemBitmap();
}
}
/* All done */
return Status;
};
NTSTATUS
BlDisplaySetCursorType (
_In_ ULONG Type
)
{
NTSTATUS Status;
PBL_TEXT_CONSOLE TextConsole;
BL_DISPLAY_STATE State;
/* Nothing to do if there's no text console */
Status = STATUS_SUCCESS;
TextConsole = DspTextConsole;
if (TextConsole)
{
/* Write visibility state and call the function to change it */
State.CursorVisible = Type;
Status = TextConsole->Callbacks->SetTextState(TextConsole, 8, &State);
}
/* All done */
return Status;
}

View file

@ -120,7 +120,7 @@ ConsoleEfiGopEnable (
}
/* Reset the OEM bitmap and get the new more information */
// BlDisplayInvalidateOemBitmap();
BlDisplayInvalidateOemBitmap();
EfiGopGetCurrentMode(Protocol, &Dummy, &ModeInformation);
}
@ -166,7 +166,7 @@ ConsoleEfiGopEnable (
{
/* We failed seomewhere, reset the mode and the OEM bitmap back */
EfiGopSetMode(Protocol, CurrentMode);
//BlDisplayInvalidateOemBitmap();
BlDisplayInvalidateOemBitmap();
}
/* Return back to caller */
@ -186,7 +186,7 @@ ConsoleEfiGopClose (
{
/* Restore the old mode and reset the OEM bitmap in ACPI */
EfiGopSetMode(GraphicsConsole->Protocol, OldMode);
//BlDisplayInvalidateOemBitmap();
BlDisplayInvalidateOemBitmap();
}
/* Close the GOP protocol */

View file

@ -86,6 +86,44 @@ ConsoleEfiGraphicalOpenProtocol (
return STATUS_UNSUCCESSFUL;
}
NTSTATUS
ConsoleFirmwareGraphicalClear (
_In_ PBL_GRAPHICS_CONSOLE Console,
_In_ ULONG Color
)
{
NTSTATUS Status;
UCHAR Pixel[4] = { 0 };
/* Convert the standard color to a firmware pixel color */
Status = ConsolepConvertColorToPixel(Color, Pixel);
if (!NT_SUCCESS(Status))
{
return Status;
}
/* Check if this is GOP or UGA */
if (Console->Type == BlUgaConsole)
{
EfiPrintf(L"Uga not supported\r\n");
Status = STATUS_NOT_IMPLEMENTED;
}
else
{
/* For GOP, just fill the screen */
ConsolepClearBuffer(Console->FrameBuffer,
Console->DisplayMode.HRes,
Pixel,
Console->DisplayMode.VRes,
Console->PixelsPerScanLine,
Console->PixelDepth);
Status = STATUS_SUCCESS;
}
/* All clear */
return Status;
}
NTSTATUS
ConsoleFirmwareGraphicalEnable (
_In_ PBL_GRAPHICS_CONSOLE GraphicsConsole

View file

@ -551,4 +551,75 @@ ConsoleInputLocalEraseBuffer (
/* All done */
return Status;
}
}
NTSTATUS
ConsoleFirmwareTextClear (
_In_ PBL_TEXT_CONSOLE Console,
_In_ BOOLEAN LineOnly
)
{
BL_ARCH_MODE OldMode;
EFI_STATUS EfiStatus;
NTSTATUS Status;
ULONG i, Column, Row, TextWidth, TextHeight;
/* Get the text resolution */
BlDisplayGetTextCellResolution(&TextWidth, &TextHeight);
/* Are we just clearing a line? */
if (LineOnly)
{
/* Get the current column and row */
Column = Console->State.XPos / TextWidth;
Row = Console->State.YPos / TextHeight;
/* Loop over every remaining character */
for (i = 0; i < Console->DisplayMode.HRes - Column - 1; i++)
{
/* Write a space on top of it */
Status = EfiConOutOutputString(Console->Protocol, L" ");
if (!NT_SUCCESS(Status))
{
break;
}
}
/* And reset the cursor back at the initial position */
Status = EfiConOutSetCursorPosition(Console->Protocol,
Column,
Row);
}
else
{
/* Are we in protected mode? */
OldMode = CurrentExecutionContext->Mode;
if (OldMode != BlRealMode)
{
/* FIXME: Not yet implemented */
return STATUS_NOT_IMPLEMENTED;
}
/* Clear the scren */
EfiStatus = Console->Protocol->ClearScreen(Console->Protocol);
/* Switch back to protected mode if we came from there */
if (OldMode != BlRealMode)
{
BlpArchSwitchContext(OldMode);
}
/* Conver to NT status -- did that work? */
Status = EfiGetNtStatusCode(EfiStatus);
if (NT_SUCCESS(Status))
{
/* Reset current positions */
Console->State.XPos = 0;
Console->State.YPos = 0;
}
}
/* All done */
return Status;
}

View file

@ -16,7 +16,12 @@ BL_GRAPHICS_CONSOLE_VTABLE ConsoleGraphicalVtbl =
{
{
(PCONSOLE_DESTRUCT)ConsoleGraphicalDestruct,
(PCONSOLE_REINITIALIZE)ConsoleGraphicalReinitialize
(PCONSOLE_REINITIALIZE)ConsoleGraphicalReinitialize,
ConsoleTextBaseGetTextState,
(PCONSOLE_SET_TEXT_STATE)ConsoleGraphicalSetTextState,
NULL, // GetTextResolution
NULL, // SetTextResolution
(PCONSOLE_CLEAR_TEXT)ConsoleGraphicalClearText
},
ConsoleGraphicalIsEnabled,
ConsoleGraphicalEnable,
@ -28,6 +33,27 @@ BL_GRAPHICS_CONSOLE_VTABLE ConsoleGraphicalVtbl =
/* FUNCTIONS *****************************************************************/
NTSTATUS
ConsoleGraphicalSetTextState (
_In_ PBL_GRAPHICS_CONSOLE Console,
_In_ ULONG Mask,
_In_ PBL_DISPLAY_STATE TextState
)
{
/* Is the text console active? */
if (Console->TextConsole.Active)
{
/* Let it handle that */
return ConsoleFirmwareTextSetState(&Console->TextConsole,
Mask,
TextState);
}
/* Not yet */
EfiPrintf(L"FFX set not implemented\r\n");
return STATUS_NOT_IMPLEMENTED;
}
NTSTATUS
ConsoleGraphicalConstruct (
_In_ PBL_GRAPHICS_CONSOLE GraphicsConsole
@ -79,6 +105,219 @@ ConsoleGraphicalConstruct (
return STATUS_SUCCESS;
}
VOID
ConsolepClearBuffer (
_In_ PUCHAR FrameBuffer,
_In_ ULONG Width,
_In_ PUCHAR FillColor,
_In_ ULONG Height,
_In_ ULONG ScanlineWidth,
_In_ ULONG PixelDepth
)
{
PUCHAR Scanline, Current, FrameBufferEnd, LineEnd;
ULONG LineBytes, WidthBytes, BytesPerPixel;
/* Get the BPP */
BytesPerPixel = PixelDepth / 8;
/* Using that, calculate the size of a scan line */
LineBytes = ScanlineWidth * BytesPerPixel;
/* And the size of line we'll have to clear */
WidthBytes = Width * BytesPerPixel;
/* Allocat a scanline */
Scanline = BlMmAllocateHeap(WidthBytes);
if (Scanline)
{
/* For each remaining pixel on the scanline */
Current = Scanline;
while (Width--)
{
/* Copy in the fill color */
RtlCopyMemory(Current, FillColor, BytesPerPixel);
Current += BytesPerPixel;
}
/* For each scanline in the frame buffer */
while (Height--)
{
/* Copy our constructed scanline */
RtlCopyMemory(FrameBuffer, Scanline, WidthBytes);
FrameBuffer += LineBytes;
}
}
else
{
FrameBufferEnd = FrameBuffer + Height * LineBytes;
ScanlineWidth = BytesPerPixel * (ScanlineWidth - Width);
while (FrameBuffer != FrameBufferEnd)
{
if (FrameBuffer != (FrameBuffer + WidthBytes))
{
LineEnd = FrameBuffer + WidthBytes;
do
{
RtlCopyMemory(FrameBuffer, FillColor, BytesPerPixel);
FrameBuffer += BytesPerPixel;
}
while (FrameBuffer != LineEnd);
}
FrameBuffer += ScanlineWidth;
}
}
}
NTSTATUS
ConsolepConvertColorToPixel (
_In_ BL_COLOR Color,
_Out_ PUCHAR Pixel
)
{
NTSTATUS Status;
/* Assume success */
Status = STATUS_SUCCESS;
/* Convert the color to a pixel value */
switch (Color)
{
case Black:
Pixel[1] = 0;
Pixel[2] = 0;
Pixel[0] = 0;
break;
case Blue:
Pixel[1] = 0;
Pixel[2] = 0;
Pixel[0] = 0x7F;
break;
case Green:
Pixel[1] = 0x7F;
Pixel[2] = 0;
Pixel[0] = 0;
break;
case Cyan:
Pixel[1] = 0x7F;
Pixel[2] = 0;
Pixel[0] = 0x7F;
break;
case Red:
Pixel[1] = 0;
Pixel[2] = 0x7F;
Pixel[0] = 0x7F;
break;
case Magenta:
Pixel[1] = 0;
Pixel[2] = 0x7F;
Pixel[0] = 0x7F;
break;
case Brown:
Pixel[1] = 0x3F;
Pixel[2] = 0x7F;
Pixel[0] = 0;
break;
case LtGray:
Pixel[1] = 0xBFu;
Pixel[2] = 0xBFu;
*Pixel = 0xBFu;
break;
case Gray:
Pixel[1] = 0x7F;
Pixel[2] = 0x7F;
Pixel[0] = 0x7F;
break;
case LtBlue:
Pixel[1] = 0;
Pixel[2] = 0;
Pixel[0] = 0xFF;
break;
case LtGreen:
Pixel[1] = 0xFF;
Pixel[2] = 0;
Pixel[0] = 0;
break;
case LtCyan:
Pixel[1] = 0xFF;
Pixel[2] = 0;
Pixel[0] = 0xFF;
break;
case LtRed:
Pixel[1] = 0;
Pixel[2] = 0xFF;
Pixel[0] = 0;
break;
case LtMagenta:
Pixel[1] = 0;
Pixel[2] = 0xFF;
Pixel[0] = 0xFF;
break;
case Yellow:
Pixel[1] = 0xFF;
Pixel[2] = 0xFF;
Pixel[0] = 0;
break;
case White:
Pixel[1] = 0xFF;
Pixel[2] = 0xFF;
Pixel[0] = 0xFF;
break;
default:
Status = STATUS_INVALID_PARAMETER;
break;
}
return Status;
}
NTSTATUS
ConsoleGraphicalClearPixels (
_In_ PBL_GRAPHICS_CONSOLE Console,
_In_ ULONG Color
)
{
NTSTATUS Status;
/* Check if the text console is active */
if (Console->TextConsole.Active)
{
/* We shouldn't be here */
Status = STATUS_UNSUCCESSFUL;
}
else
{
/* Clear it in graphics mode */
Status = ConsoleFirmwareGraphicalClear(Console, Color);
}
/* All good */
return Status;
}
NTSTATUS
ConsoleGraphicalClearText (
_In_ PBL_GRAPHICS_CONSOLE Console,
_In_ BOOLEAN LineOnly
)
{
/* Is the text console active? */
if (Console->TextConsole.Active)
{
/* Let firmware clear do it */
return ConsoleFirmwareTextClear(&Console->TextConsole, LineOnly);
}
/* Are we clearing a line only? */
if (LineOnly)
{
return BfClearToEndOfLine(Console);
}
/* Nope -- the whole screen */
return BfClearScreen(Console);
}
BOOLEAN
ConsoleGraphicalIsEnabled (
_In_ PBL_GRAPHICS_CONSOLE Console

View file

@ -55,11 +55,11 @@ ConsoleTextBaseGetTextState (
NTSTATUS
ConsoleTextLocalSetTextState (
_In_ struct _BL_TEXT_CONSOLE* Console,
_In_ ULONG Flags,
_In_ ULONG Mask,
_In_ PBL_DISPLAY_STATE TextState
)
{
return STATUS_NOT_IMPLEMENTED;
return ConsoleFirmwareTextSetState(Console, Mask, TextState);
}
NTSTATUS
@ -84,10 +84,10 @@ ConsoleTextLocalSetTextResolution (
NTSTATUS
ConsoleTextLocalClearText (
_In_ struct _BL_TEXT_CONSOLE* Console,
_In_ ULONG Attribute
_In_ BOOLEAN LineOnly
)
{
return STATUS_NOT_IMPLEMENTED;
return ConsoleFirmwareTextClear(Console, LineOnly);
}
NTSTATUS

View file

@ -134,3 +134,63 @@ BfLoadDeferredFontFiles (
/* Return load status */
return Status;
}
NTSTATUS
BfiFlipCursorCharacter (
_In_ PBL_GRAPHICS_CONSOLE Console,
_In_ BOOLEAN Visible
)
{
/* not implemented */
return STATUS_NOT_IMPLEMENTED;
}
NTSTATUS
BfClearToEndOfLine (
_In_ PBL_GRAPHICS_CONSOLE Console
)
{
/* not implemented */
return STATUS_NOT_IMPLEMENTED;
}
NTSTATUS
BfClearScreen (
_In_ PBL_GRAPHICS_CONSOLE Console
)
{
NTSTATUS Status;
/* Reset the cursor position */
Console->TextConsole.State.XPos = 0;
Console->TextConsole.State.YPos = 0;
/* Fill the screen with the background color */
Status = ConsoleGraphicalClearPixels(Console,
Console->TextConsole.State.BgColor);
if (!NT_SUCCESS(Status))
{
return Status;
}
/* Check if the cursor should be visible */
if (Console->TextConsole.State.CursorVisible)
{
/* Load any fonts at this time */
if (!IsListEmpty(&BfiDeferredListHead))
{
BfLoadDeferredFontFiles();
}
/* Switch the cursor to visible */
Status = BfiFlipCursorCharacter(Console, TRUE);
}
else
{
/* Nothing left to do */
Status = STATUS_SUCCESS;
}
/* Return cursor flip result, if any */
return Status;
}

View file

@ -55,7 +55,7 @@ ResSelectLocale (
}
/* Check if that failed, or if we're using fallback */
if (!NT_SUCCESS(Status) || !(Primary))
if (!(Primary) || !(NT_SUCCESS(Status)))
{
/* Set the fallback pointers */
ResRootDirectory = ResRootDirectoryFallback;
@ -68,7 +68,6 @@ ResSelectLocale (
if (!NT_SUCCESS(Status))
{
/* Fallback to text mode (yes, this is the API...) */
EfiPrintf(L"Locale failed, falling back to text mode\r\n");
return BlDisplaySetScreenResolution();
}
}

View file

@ -12,8 +12,8 @@
/* DATA VARIABLES ************************************************************/
PVOID UtlRsdt;
PVOID UtlXsdt;
PRSDT UtlRsdt;
PXSDT UtlXsdt;
PVOID UtlMcContext;
PVOID UtlMcDisplayMessageRoutine;
@ -30,6 +30,152 @@ PVOID UtlProgressInfo;
/* FUNCTIONS *****************************************************************/
NTSTATUS
BlUtlGetAcpiTable (
_Out_ PVOID* TableAddress,
_In_ ULONG Signature
)
{
ULONG i, TableCount, HeaderLength;
NTSTATUS Status;
PRSDT Rsdt;
PXSDT Xsdt;
PHYSICAL_ADDRESS PhysicalAddress;
PDESCRIPTION_HEADER Header;
Header = 0;
/* Make sure there's an output parameter */
if (!TableAddress)
{
return STATUS_INVALID_PARAMETER;
}
/* Get the currently known RSDT and XSDT */
Rsdt = (PRSDT)UtlRsdt;
Xsdt = (PXSDT)UtlXsdt;
/* Is there an RSDT? */
if (!Rsdt)
{
/* No -- is there an XSDT? */
if (!Xsdt)
{
/* No. Look up the RSDT */
Status = EfipGetRsdt(&PhysicalAddress);
if (!NT_SUCCESS(Status))
{
EfiPrintf(L"no rsdp found\r\n");
return Status;
}
/* Map the header */
Status = BlMmMapPhysicalAddressEx((PVOID)&Header,
0,
sizeof(*Header),
PhysicalAddress);
if (!NT_SUCCESS(Status))
{
return Status;
}
/* Unmap the header */
BlMmUnmapVirtualAddressEx(Header, sizeof(*Header));
/* Map the whole table */
Status = BlMmMapPhysicalAddressEx((PVOID)&Header,
0,
Header->Length,
PhysicalAddress);
if (!NT_SUCCESS(Status))
{
return Status;
}
/* Check if its an XSDT or an RSDT */
if (Header->Signature == XSDT_SIGNATURE)
{
/* It's an XSDT */
Xsdt = (PXSDT)Header;
UtlXsdt = Xsdt;
}
else
{
/* It's an RSDT */
Rsdt = (PRSDT)Header;
UtlRsdt = Rsdt;
}
}
}
/* OK, so do we have an XSDT after all? */
if (Xsdt)
{
/* Yes... how big is it? */
HeaderLength = Xsdt->Header.Length;
if (HeaderLength >= sizeof(*Header))
{
HeaderLength = sizeof(*Header);
}
/* Based on that, how many tables are there? */
TableCount = (Xsdt->Header.Length - HeaderLength) / sizeof(PHYSICAL_ADDRESS);
}
else
{
/* Nope, we have an RSDT. How big is it? */
HeaderLength = Rsdt->Header.Length;
if (HeaderLength >= sizeof(*Header))
{
HeaderLength = sizeof(*Header);
}
/* Based on that, how many tables are there? */
TableCount = (Rsdt->Header.Length - HeaderLength) / sizeof(ULONG);
}
/* Loop through the ACPI tables */
for (i = 0; i < TableCount; i++)
{
/* For an XSDT, read the 64-bit address directly */
if (Xsdt)
{
PhysicalAddress = Xsdt->Tables[i];
}
else
{
/* For RSDT, cast it */
PhysicalAddress.QuadPart = Rsdt->Tables[i];
}
/* Map the header */
Status = BlMmMapPhysicalAddressEx((PVOID)&Header,
0,
sizeof(*Header),
PhysicalAddress);
if (!NT_SUCCESS(Status))
{
return Status;
}
/* Is it the right one? */
if (Header->Signature == Signature)
{
/* Unmap the header */
BlMmUnmapVirtualAddressEx(Header, sizeof(*Header));
/* Map the whole table */
return BlMmMapPhysicalAddressEx(TableAddress,
0,
Header->Length,
PhysicalAddress);
}
}
/* Requested table does not exist */
return STATUS_NOT_FOUND;
}
VOID
BlUtlUpdateProgress (
_In_ ULONG Percentage,