diff --git a/reactos/boot/environ/CMakeLists.txt b/reactos/boot/environ/CMakeLists.txt index cdf234690f0..76d21c9b038 100644 --- a/reactos/boot/environ/CMakeLists.txt +++ b/reactos/boot/environ/CMakeLists.txt @@ -22,7 +22,8 @@ list(APPEND BOOTLIB_SOURCE lib/io/io.c lib/io/device.c lib/io/file.c - lib/io/fat.c) + lib/io/fat.c + lib/platform/display.c) if(ARCH STREQUAL "i386") list(APPEND BOOTLIB_ASM_SOURCE diff --git a/reactos/boot/environ/include/bl.h b/reactos/boot/environ/include/bl.h index 9afe73cdc69..17bf2a6d9fc 100644 --- a/reactos/boot/environ/include/bl.h +++ b/reactos/boot/environ/include/bl.h @@ -73,10 +73,12 @@ EarlyPrint(_In_ PWCHAR Format, ...); #define BL_MM_REMOVE_VIRTUAL_REGION_FLAG 0x80000000 +#define BL_LIBRARY_FLAG_NO_DISPLAY 0x01 #define BL_LIBRARY_FLAG_REINITIALIZE 0x02 #define BL_LIBRARY_FLAG_REINITIALIZE_ALL 0x04 #define BL_LIBRARY_FLAG_ZERO_HEAP_ALLOCATIONS_ON_FREE 0x10 #define BL_LIBRARY_FLAG_INITIALIZATION_COMPLETED 0x20 +#define BL_LIBRARY_FLAG_NO_GRAPHICS_CONSOLE 0x800 #define BL_FS_REGISTER_AT_HEAD_FLAG 1 @@ -595,6 +597,11 @@ FatInitialize ( VOID ); +NTSTATUS +BlpDisplayInitialize ( + _In_ ULONG Flags + ); + /* FIRMWARE ROUTINES *********************************************************/ NTSTATUS @@ -609,6 +616,45 @@ EfiStall ( _In_ ULONG StallTime ); +NTSTATUS +EfiConOutQueryMode ( + _In_ SIMPLE_TEXT_OUTPUT_INTERFACE *TextInterface, + _In_ ULONG Mode, + _In_ PULONG Columns, + _In_ PULONG Rows + ); + +NTSTATUS +EfiConOutSetMode ( + _In_ SIMPLE_TEXT_OUTPUT_INTERFACE *TextInterface, + _In_ ULONG Mode + ); + +VOID +EfiConOutReadCurrentMode ( + _In_ SIMPLE_TEXT_OUTPUT_INTERFACE *TextInterface, + _Out_ EFI_SIMPLE_TEXT_OUTPUT_MODE* Mode + ); + +NTSTATUS +EfiConOutSetAttribute ( + _In_ SIMPLE_TEXT_OUTPUT_INTERFACE *TextInterface, + _In_ ULONG Attribute + ); + +NTSTATUS +EfiConOutSetCursorPosition ( + _In_ SIMPLE_TEXT_OUTPUT_INTERFACE *TextInterface, + _In_ ULONG Column, + _In_ ULONG Row + ); + +NTSTATUS +EfiConOutEnableCursor ( + _In_ SIMPLE_TEXT_OUTPUT_INTERFACE *TextInterface, + _In_ BOOLEAN Visible + ); + /* PLATFORM TIMER ROUTINES ***************************************************/ NTSTATUS @@ -739,11 +785,21 @@ BlMmFreeHeap ( _In_ PVOID Buffer ); +/* DISPLAY ROUTINES **********************************************************/ + +VOID +BlDisplayGetTextCellResolution ( + _Out_ PULONG TextWidth, + _Out_ PULONG TextHeight + ); + extern ULONG MmDescriptorCallTreeCount; extern ULONG BlpApplicationFlags; extern BL_LIBRARY_PARAMETERS BlpLibraryParameters; extern BL_TRANSLATION_TYPE MmTranslationType; extern PBL_ARCH_CONTEXT CurrentExecutionContext; extern PBL_DEVICE_DESCRIPTOR BlpBootDevice; +extern BL_APPLICATION_ENTRY BlpApplicationEntry; +extern SIMPLE_TEXT_OUTPUT_INTERFACE *EfiConOut; #endif diff --git a/reactos/boot/environ/lib/bootlib.c b/reactos/boot/environ/lib/bootlib.c index 697fa7bf97d..d58a2548356 100644 --- a/reactos/boot/environ/lib/bootlib.c +++ b/reactos/boot/environ/lib/bootlib.c @@ -18,8 +18,9 @@ PWCHAR BlpApplicationBaseDirectory; PBOOT_APPLICATION_PARAMETER_BLOCK BlpApplicationParameters; BL_APPLICATION_ENTRY BlpApplicationEntry; BOOLEAN BlpLibraryParametersInitialized; -BOOLEAN EnSubsystemInitialized; -LIST_ENTRY EnEventNotificationList; + +ULONG PdPersistAllocations; +LIST_ENTRY BlBadpListHead; /* FUNCTIONS *****************************************************************/ @@ -178,34 +179,46 @@ InitializeLibrary ( return Status; } -#if 0 +#ifdef BL_TPM_SUPPORT /* Initialize support for Trusted Platform Module v1.2 */ BlpTpmInitialize(); #endif +#ifdef BL_TPM_SUPPORT /* Initialize the event manager */ EnSubsystemInitialized = 1; InitializeListHead(&EnEventNotificationList); +#endif - /* Initialize the I/O Manager */ + /* Initialize the I/O Manager */i Status = BlpIoInitialize(); if (!NT_SUCCESS(Status)) { /* Destroy memory manager in phase 1 and the event manager */ EarlyPrint(L"IO init failed\n"); - //if (EnSubsystemInitialized) BlpEnDestroy(); +#ifdef BL_TPM_SUPPORT + if (EnSubsystemInitialized) + { + BlpEnDestroy(); + } +#endif //BlpMmDestroy(1); return Status; } -#if 0 +#ifdef BL_NET_SUPPORT /* Initialize the network stack */ Status = BlNetInitialize(); if (!NT_SUCCESS(Status)) { /* Destroy the I/O, event, and memory managers in phase 1 */ BlpIoDestroy(); - if (EnSubsystemInitialized) BlpEnDestroy(); +#ifdef BL_TPM_SUPPORT + if (EnSubsystemInitialized) + { + BlpEnDestroy(); + } +#endif BlpMmDestroy(1); return Status; } @@ -216,16 +229,122 @@ InitializeLibrary ( if (!NT_SUCCESS(Status)) { /* Destroy the network, I/O, event, and memory managers in phase 1 */ - //BlNetDestroy(); +#ifdef BL_NET_SUPPORT + BlNetDestroy(); +#endif //BlpIoDestroy(); - //if (EnSubsystemInitialized) BlpEnDestroy(); +#ifdef BL_TPM_SUPPORT + if (EnSubsystemInitialized) + { + BlpEnDestroy(); + } +#endif //BlpMmDestroy(1); EarlyPrint(L"Util init failed\n"); return Status; } - EarlyPrint(L"TODO!\n"); - Status = STATUS_NOT_IMPLEMENTED; +#ifdef BL_KD_SUPPORT + /* Initialize PCI Platform Support */ + PltInitializePciConfiguration(); +#endif + +#ifdef BL_SECURE_BOOT_SUPPORT + /* Read the current SecureBoot Policy*/ + Status = BlSecureBootSetActivePolicyFromPersistedData(); + if (!NT_SUCCESS(Status)) + { + /* Destroy everything that we've currently set up */ +#ifdef BL_KD_SUPPORT + PltDestroyPciConfiguration(); +#endif +#ifdef BL_NET_SUPPORT + BlNetDestroy(); +#endif + BlpIoDestroy(); +#ifdef BL_TPM_SUPPORT + if (EnSubsystemInitialized) + { + BlpEnDestroy(); + } +#endif + BlpMmDestroy(1); + return Status; + } +#endif + +#ifdef BL_TPM_SUPPORT + /* Initialize phase 0 of the security subsystem */ + SipInitializePhase0(); +#endif + +#ifdef BL_KD_SUPPORT + /* Bring up the boot debugger, now that SecureBoot has been processed */ + BlBdInitialize(); +#endif + +#ifdef BL_ETW_SUPPORT + /* Initialize internal logging */ + BlpLogInitialize(); +#endif + + /* Are graphics enabled? */ + if (!(LibraryParameters->LibraryFlags & BL_LIBRARY_FLAG_NO_DISPLAY)) + { + /* Initialize the graphics library */ + BlpDisplayInitialize(LibraryParameters->LibraryFlags); + } + + /* Initialize the boot application persistent data */ + PdPersistAllocations = 0; + InitializeListHead(&BlBadpListHead); + +#ifdef BL_TPM_SUPPORT + /* Now setup the security subsystem in phase 1 */ + BlpSiInitialize(1); +#endif + +#if 0 + /* Setup the text, UI and font resources */ + Status = BlpResourceInitialize(); + if (!NT_SUCCESS(Status)) + { + /* Tear down everything if this failed */ + if (!(LibraryParameters->LibraryFlags & BL_LIBRARY_FLAG_TEXT_MODE)) + { +// BlpDisplayDestroy(); + } + //BlpBdDestroy(); +#ifdef BL_KD_SUPPORT + PltDestroyPciConfiguration(); +#endif +#ifdef BL_NET_SUPPORT + BlNetDestroy(); +#endif + //BlpIoDestroy(); +#ifdef BL_TPM_SUPPORT + if (EnSubsystemInitialized) + { + BlpEnDestroy(); + } +#endif + //BlpMmDestroy(1); + return Status; + } +#endif + +#if BL_BITLOCKER_SUPPORT + /* Setup the boot cryptography library */ + g_pEnvironmentData = &SymCryptEnvironmentWindowsBootLibrary; + if (SymCryptEnvWindowsBootLibInit) + { + SymCryptEnvWindowsBootLibInit(); + } +#endif + + /* We are fully initialized, remember this and exit with success */ + BlpLibraryParameters.LibraryFlags |= BL_LIBRARY_FLAG_INITIALIZATION_COMPLETED; + Status = STATUS_SUCCESS; Quickie: EarlyPrint(L"Exiting init: %lx\n", Status); diff --git a/reactos/boot/environ/lib/firmware/efi/firmware.c b/reactos/boot/environ/lib/firmware/efi/firmware.c index 147e4a87a52..3a8d657edbb 100644 --- a/reactos/boot/environ/lib/firmware/efi/firmware.c +++ b/reactos/boot/environ/lib/firmware/efi/firmware.c @@ -247,6 +247,186 @@ EfiStall ( return EfiGetNtStatusCode(EfiStatus); } +NTSTATUS +EfiConOutQueryMode ( + _In_ SIMPLE_TEXT_OUTPUT_INTERFACE *TextInterface, + _In_ ULONG Mode, + _In_ PULONG Columns, + _In_ PULONG Rows + ) +{ + 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->QueryMode(TextInterface, Mode, Columns, Rows); + + /* Switch back to protected mode if we came from there */ + if (OldMode != BlRealMode) + { + BlpArchSwitchContext(OldMode); + } + + /* Convert the error to an NTSTATUS */ + return EfiGetNtStatusCode(EfiStatus); +} + +NTSTATUS +EfiConOutSetMode ( + _In_ SIMPLE_TEXT_OUTPUT_INTERFACE *TextInterface, + _In_ ULONG Mode + ) +{ + 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->SetMode(TextInterface, Mode); + + /* Switch back to protected mode if we came from there */ + if (OldMode != BlRealMode) + { + BlpArchSwitchContext(OldMode); + } + + /* Convert the error to an NTSTATUS */ + return EfiGetNtStatusCode(EfiStatus); +} + +NTSTATUS +EfiConOutSetAttribute ( + _In_ SIMPLE_TEXT_OUTPUT_INTERFACE *TextInterface, + _In_ ULONG Attribute + ) +{ + 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->SetAttribute(TextInterface, Attribute); + + /* Switch back to protected mode if we came from there */ + if (OldMode != BlRealMode) + { + BlpArchSwitchContext(OldMode); + } + + /* Convert the error to an NTSTATUS */ + return EfiGetNtStatusCode(EfiStatus); +} + +NTSTATUS +EfiConOutSetCursorPosition ( + _In_ SIMPLE_TEXT_OUTPUT_INTERFACE *TextInterface, + _In_ ULONG Column, + _In_ ULONG Row + ) +{ + 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->SetCursorPosition(TextInterface, Column, Row); + + /* Switch back to protected mode if we came from there */ + if (OldMode != BlRealMode) + { + BlpArchSwitchContext(OldMode); + } + + /* Convert the error to an NTSTATUS */ + return EfiGetNtStatusCode(EfiStatus); +} + +NTSTATUS +EfiConOutEnableCursor ( + _In_ SIMPLE_TEXT_OUTPUT_INTERFACE *TextInterface, + _In_ BOOLEAN Visible + ) +{ + 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->EnableCursor(TextInterface, Visible); + + /* 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, + _Out_ EFI_SIMPLE_TEXT_OUTPUT_MODE* Mode + ) +{ + BL_ARCH_MODE OldMode; + EFI_STATUS EfiStatus; + + /* Are we in protected mode? */ + OldMode = CurrentExecutionContext->Mode; + if (OldMode != BlRealMode) + { + /* FIXME: Not yet implemented */ + return; + } + + /* Make the EFI call */ + RtlCopyMemory(Mode, TextInterface->Mode, sizeof(*Mode)); + + /* Switch back to protected mode if we came from there */ + if (OldMode != BlRealMode) + { + BlpArchSwitchContext(OldMode); + } +} + NTSTATUS EfiAllocatePages ( _In_ ULONG Type, diff --git a/reactos/boot/environ/lib/platform/display.c b/reactos/boot/environ/lib/platform/display.c new file mode 100644 index 00000000000..92b9b3fe49a --- /dev/null +++ b/reactos/boot/environ/lib/platform/display.c @@ -0,0 +1,1051 @@ +/* + * COPYRIGHT: See COPYING.ARM in the top level directory + * PROJECT: ReactOS UEFI Boot Library + * FILE: boot/environ/lib/platform/display.c + * PURPOSE: Boot Library Display Management Routines + * PROGRAMMER: Alex Ionescu (alex.ionescu@reactos.org) + */ + +/* INCLUDES ******************************************************************/ + +#include "bl.h" +#include + +/* DATA VARIABLES ************************************************************/ + +typedef enum _BL_COLOR +{ + Black, + Blue, + Green, + Cyan, + Red, + Magenta, + Brown, + LtGray, + Gray, + LtBlue, + LtGreen, + LtCyan, + LtRed, + LtMagenta, + Yellow, + White +} BL_COLOR, *PBL_COLOR; + +typedef struct _BL_DISPLAY_STATE +{ + ULONG BgColor; + ULONG FgColor; + ULONG XPos; + ULONG YPos; + ULONG CursorVisible; +} BL_DISPLAY_STATE, *PBL_DISPLAY_STATE; + +typedef struct _BL_DISPLAY_MODE +{ + ULONG HRes; + ULONG VRes; + ULONG HRes2; +} BL_DISPLAY_MODE, *PBL_DISPLAY_MODE; + +struct _BL_TEXT_CONSOLE; +typedef +NTSTATUS +(*PCONSOLE_DESTRUCT) ( + _In_ struct _BL_TEXT_CONSOLE* Console + ); + +typedef +NTSTATUS +(*PCONSOLE_REINITIALIZE) ( + _In_ struct _BL_TEXT_CONSOLE* Console + ); + +typedef +NTSTATUS +(*PCONSOLE_GET_TEXT_STATE) ( + _In_ struct _BL_TEXT_CONSOLE* Console, + _Out_ PBL_DISPLAY_STATE TextState + ); + +typedef +NTSTATUS +(*PCONSOLE_SET_TEXT_STATE) ( + _In_ struct _BL_TEXT_CONSOLE* Console, + _In_ ULONG Flags, + _In_ PBL_DISPLAY_STATE TextState + ); + +typedef +NTSTATUS +(*PCONSOLE_GET_TEXT_RESOLUTION) ( + _In_ struct _BL_TEXT_CONSOLE* Console, + _Out_ PULONG TextResolution + ); + +typedef +NTSTATUS +(*PCONSOLE_SET_TEXT_RESOLUTION) ( + _In_ struct _BL_TEXT_CONSOLE* Console, + _In_ ULONG NewTextResolution, + _Out_ PULONG OldTextResolution + ); + +typedef +NTSTATUS +(*PCONSOLE_CLEAR_TEXT) ( + _In_ struct _BL_TEXT_CONSOLE* Console, + _In_ ULONG Attribute + ); + + +typedef +NTSTATUS +(*PCONSOLE_WRITE_TEXT) ( + _In_ struct _BL_TEXT_CONSOLE* Console, + _In_ PCHAR Text, + _In_ ULONG Attribute + ); + +typedef struct _BL_TEXT_CONSOLE_VTABLE +{ + PCONSOLE_DESTRUCT Destruct; + PCONSOLE_REINITIALIZE Reinitialize; + PCONSOLE_GET_TEXT_STATE GetTextState; + PCONSOLE_SET_TEXT_STATE SetTextState; + PCONSOLE_GET_TEXT_RESOLUTION GetTextResolution; + PCONSOLE_SET_TEXT_RESOLUTION SetTextResolution; + PCONSOLE_CLEAR_TEXT ClearText; + PCONSOLE_WRITE_TEXT WriteText; +} BL_TEXT_CONSOLE_VTABLE, *PBL_TEXT_CONSOLE_VTABLE; + +typedef struct _BL_TEXT_CONSOLE +{ + PBL_TEXT_CONSOLE_VTABLE Callbacks; + BL_DISPLAY_STATE State; + BL_DISPLAY_MODE DisplayMode; + BOOLEAN Active; + EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL* Protocol; + ULONG Mode; + EFI_SIMPLE_TEXT_OUTPUT_MODE OldMode; +} BL_TEXT_CONSOLE, *PBL_TEXT_CONSOLE; + +PVOID BfiCachedStrikeData; +LIST_ENTRY BfiDeferredListHead; +LIST_ENTRY BfiFontFileListHead; + +PVOID BfiGraphicsRectangle; + +ULONG ConsoleGraphicalResolutionListFlags; +BL_DISPLAY_MODE ConsoleGraphicalResolutionList[3] = +{ + {1024, 768, 1024}, + {800, 600, 800}, + {1024, 600, 1024} +}; + +BL_DISPLAY_MODE ConsoleTextResolutionList[1] = +{ + {80, 31, 80} +}; + +NTSTATUS +ConsoleTextLocalDestruct ( + _In_ struct _BL_TEXT_CONSOLE* Console + ); + +NTSTATUS +ConsoleTextLocalReinitialize ( + _In_ struct _BL_TEXT_CONSOLE* Console + ); + +NTSTATUS +ConsoleTextBaseGetTextState ( + _In_ struct _BL_TEXT_CONSOLE* Console, + _Out_ PBL_DISPLAY_STATE TextState + ); + +NTSTATUS +ConsoleTextLocalSetTextState ( + _In_ struct _BL_TEXT_CONSOLE* Console, + _In_ ULONG Flags, + _In_ PBL_DISPLAY_STATE TextState + ); + +NTSTATUS +ConsoleTextBaseGetTextResolution ( + _In_ struct _BL_TEXT_CONSOLE* Console, + _Out_ PULONG TextResolution + ); + +NTSTATUS +ConsoleTextLocalSetTextResolution ( + _In_ struct _BL_TEXT_CONSOLE* Console, + _In_ ULONG NewTextResolution, + _Out_ PULONG OldTextResolution + ); + +NTSTATUS +ConsoleTextLocalClearText ( + _In_ struct _BL_TEXT_CONSOLE* Console, + _In_ ULONG Attribute + ); + +NTSTATUS +ConsoleTextLocalWriteText ( + _In_ struct _BL_TEXT_CONSOLE* Console, + _In_ PCHAR Text, + _In_ ULONG Attribute + ); + +BL_TEXT_CONSOLE_VTABLE ConsoleTextLocalVtbl = +{ + ConsoleTextLocalDestruct, + ConsoleTextLocalReinitialize, + ConsoleTextBaseGetTextState, + ConsoleTextLocalSetTextState, + ConsoleTextBaseGetTextResolution, + ConsoleTextLocalSetTextResolution, + ConsoleTextLocalClearText, + ConsoleTextLocalWriteText +}; + +PVOID DspRemoteInputConsole; +PVOID DspTextConsole; +PVOID DspGraphicalConsole; + +/* FUNCTIONS *****************************************************************/ + +BOOLEAN +ConsolepFindResolution ( + _In_ PBL_DISPLAY_MODE Mode, + _In_ PBL_DISPLAY_MODE List, + _In_ ULONG MaxIndex + ) +{ + PBL_DISPLAY_MODE ListEnd; + + /* Loop until we hit the maximum supported list index */ + ListEnd = &List[MaxIndex]; + while (List != ListEnd) + { + /* Does this resolution match? */ + if ((Mode->HRes != List->HRes) || (Mode->VRes != List->VRes)) + { + /* Try another one*/ + List++; + } + + /* Yep -- we got a match */ + return TRUE; + } + + /* No matches were found */ + return FALSE; +} + +BL_COLOR +ConsoleEfiTextGetColorForeground ( + _In_ UINT32 Attributes + ) +{ + switch (Attributes & 0x0F) + { + case EFI_BLACK: + return Black; + case EFI_BLUE: + return Blue; + case EFI_GREEN: + return Green; + case EFI_RED: + return Red; + case EFI_CYAN: + return Cyan; + case EFI_MAGENTA: + return Magenta; + case EFI_BROWN: + return Brown; + case EFI_LIGHTGRAY: + return LtGray; + case EFI_DARKGRAY: + return Gray; + case EFI_LIGHTBLUE: + return LtBlue; + case EFI_LIGHTGREEN: + return LtGreen; + case EFI_LIGHTCYAN: + return LtCyan; + case EFI_LIGHTRED: + return LtRed; + case EFI_LIGHTMAGENTA: + return LtMagenta; + case EFI_YELLOW: + return Yellow; + case EFI_WHITE: + default: + return White; + } +} + +BL_COLOR +ConsoleEfiTextGetColorBackground ( + _In_ UINT32 Attributes + ) +{ + switch (Attributes & 0xF0) + { + case EFI_BACKGROUND_MAGENTA: + return Magenta; + case EFI_BACKGROUND_BROWN: + return Brown; + case EFI_BACKGROUND_LIGHTGRAY: + return White; + default: + case EFI_BACKGROUND_BLACK: + return Black; + case EFI_BACKGROUND_RED: + return Red; + case EFI_BACKGROUND_GREEN: + return Green; + case EFI_BACKGROUND_CYAN: + return Cyan; + case EFI_BACKGROUND_BLUE: + return Blue; + } +} + +ULONG +ConsoleEfiTextGetEfiColorBackground ( + _In_ BL_COLOR Color + ) +{ + switch (Color) + { + case Blue: + case LtBlue: + return EFI_BACKGROUND_BLUE; + case Green: + case LtGreen: + return EFI_BACKGROUND_GREEN; + case Cyan: + case LtCyan: + return EFI_BACKGROUND_CYAN; + case Red: + case LtRed: + return EFI_BACKGROUND_RED; + case Magenta: + case LtMagenta: + return EFI_BACKGROUND_MAGENTA; + case Brown: + case Yellow: + return EFI_BACKGROUND_BROWN; + case LtGray: + case White: + return EFI_BACKGROUND_LIGHTGRAY; + case Black: + case Gray: + default: + return EFI_BACKGROUND_BLACK; + } +} + +ULONG +ConsoleEfiTextGetEfiColorForeground ( + _In_ BL_COLOR Color + ) +{ + switch (Color) + { + case Black: + return EFI_BLACK; + case Blue: + return EFI_BLUE; + case Green: + return EFI_GREEN; + case Cyan: + return EFI_CYAN; + case Red: + return EFI_RED; + case Magenta: + return EFI_MAGENTA; + case Brown: + return EFI_BROWN; + case LtGray: + return EFI_LIGHTGRAY; + case Gray: + return EFI_DARKGRAY; + case LtBlue: + return EFI_LIGHTBLUE; + case LtGreen: + return EFI_LIGHTGREEN; + case LtCyan: + return EFI_LIGHTCYAN; + case LtRed: + return EFI_LIGHTRED; + case LtMagenta: + return EFI_LIGHTMAGENTA; + case Yellow: + return EFI_YELLOW; + case White: + default: + return EFI_WHITE; + } +} + +ULONG +ConsoleEfiTextGetAttribute ( + BL_COLOR BgColor, + BL_COLOR FgColor + ) +{ + /* Convert each part and OR into a single attribute */ + return ConsoleEfiTextGetEfiColorBackground(BgColor) | + ConsoleEfiTextGetEfiColorForeground(FgColor); +} + +VOID +ConsoleEfiTextGetStateFromMode ( + _In_ EFI_SIMPLE_TEXT_OUTPUT_MODE *Mode, + _Out_ PBL_DISPLAY_STATE State + ) +{ + + ULONG TextWidth, TextHeight; + + /* Get all the EFI data and convert it into our own structure */ + BlDisplayGetTextCellResolution(&TextWidth, &TextHeight); + State->FgColor = ConsoleEfiTextGetColorForeground(Mode->Attribute); + State->BgColor = ConsoleEfiTextGetColorBackground(Mode->Attribute); + State->XPos = Mode->CursorColumn * TextWidth; + State->YPos = Mode->CursorRow * TextHeight; + State->CursorVisible = Mode->CursorVisible != FALSE; +} + +NTSTATUS +ConsoleFirmwareTextSetState ( + _In_ PBL_TEXT_CONSOLE TextConsole, + _In_ UCHAR Mask, + _In_ PBL_DISPLAY_STATE State + ) +{ + NTSTATUS Status; + ULONG FgColor, BgColor, Attribute, XPos, YPos, TextHeight, TextWidth; + BOOLEAN Visible; + + Status = STATUS_SUCCESS; + + if (Mask & 1) + { + FgColor = State->FgColor; + + if (TextConsole->State.FgColor != FgColor) + { + if (FgColor >= 16) + { + return STATUS_INVALID_PARAMETER; + } + + Attribute = ConsoleEfiTextGetAttribute(TextConsole->State.BgColor, FgColor); + Status = EfiConOutSetAttribute(TextConsole->Protocol, Attribute); + + + if (!NT_SUCCESS(Status)) + { + return Status; + } + + TextConsole->State.FgColor = FgColor; + } + } + + if (Mask & 2) + { + BgColor = State->BgColor; + if (TextConsole->State.BgColor != BgColor) + { + if (BgColor >= 16) + { + return STATUS_INVALID_PARAMETER; + } + + Attribute = ConsoleEfiTextGetAttribute(BgColor, TextConsole->State.FgColor); + Status = EfiConOutSetAttribute(TextConsole->Protocol, Attribute); + + if (!NT_SUCCESS(Status)) + { + return Status; + } + + TextConsole->State.BgColor = BgColor; + } + } + + if (Mask & 4) + { + XPos = State->XPos; + YPos = State->YPos; + + if ((TextConsole->State.XPos != XPos) || (TextConsole->State.YPos != YPos)) + { + BlDisplayGetTextCellResolution(&TextWidth, &TextHeight); + Status = EfiConOutSetCursorPosition(TextConsole->Protocol, + XPos/ TextWidth, + YPos / TextHeight); + + if (!NT_SUCCESS(Status)) + { + return Status; + } + + TextConsole->State.XPos = XPos; + TextConsole->State.YPos = YPos; + } + } + + if (Mask & 8) + { + Visible = State->CursorVisible; + if (TextConsole->State.CursorVisible != Visible) + { + if (Visible >= 3) + { + return STATUS_INVALID_PARAMETER; + } + + Status = EfiConOutEnableCursor(TextConsole->Protocol, Visible); + if (!NT_SUCCESS(Status)) + { + return Status; + } + + TextConsole->State.CursorVisible = Visible; + } + } + + return Status; +} + +NTSTATUS +ConsoleEfiTextFindModeFromAllowed ( + _In_ SIMPLE_TEXT_OUTPUT_INTERFACE *TextProtocol, + _In_ PBL_DISPLAY_MODE SupportedModes, + _In_ ULONG MaxIndex, + _Out_ PULONG SupportedMode + ) +{ + EFI_SIMPLE_TEXT_OUTPUT_MODE ModeInfo; + ULONG MaxMode, MaxQueriedMode, Mode, HRes, VRes, i, MatchingMode; + ULONGLONG ModeListSize; + PBL_DISPLAY_MODE ModeEntry, ModeList, SupportedModeEntry; + NTSTATUS Status; + + /* Read information on the current mode */ + EfiConOutReadCurrentMode(TextProtocol, &ModeInfo); + + /* Figure out the max mode, and how many modes we'll have to read */ + MaxMode = ModeInfo.MaxMode; + ModeListSize = sizeof(*ModeEntry) * ModeInfo.MaxMode; + if (ModeListSize > MAXULONG) + { + return STATUS_INTEGER_OVERFLOW; + } + + /* Allocate a list for all the supported EFI modes */ + ModeList = BlMmAllocateHeap(ModeListSize); + if (!ModeList) + { + return STATUS_INSUFFICIENT_RESOURCES; + } + + /* Scan all the EFI modes */ + for (MaxQueriedMode = 0, Mode = 0; Mode < MaxMode; Mode++) + { + /* Query information on this mode */ + ModeEntry = &ModeList[MaxQueriedMode]; + if (NT_SUCCESS(EfiConOutQueryMode(TextProtocol, + Mode, + &HRes, + &VRes))) + { + /* This mode was succesfully queried. Save the data */ + ModeEntry->HRes = HRes; + ModeEntry->VRes = VRes; + ModeEntry->HRes2 = HRes; + MaxQueriedMode = Mode; + } + } + + /* Loop all the supported mode entries */ + for (i = 0; i < MaxIndex; i++) + { + /* Loop all the UEFI queried modes */ + SupportedModeEntry = &SupportedModes[i]; + for (MatchingMode = 0; MatchingMode < MaxQueriedMode; MatchingMode) + { + /* Check if the UEFI mode is compatible with our supported mode */ + ModeEntry = &ModeList[MatchingMode]; + if ((ModeEntry->HRes == SupportedModeEntry->HRes) && + (ModeEntry->VRes == SupportedModeEntry->VRes)) + { + /* Yep -- free the mode list and return this mode */ + BlMmFreeHeap(ModeList); + *SupportedMode = MatchingMode; + return STATUS_SUCCESS; + } + } + } + + /* We can't do anything -- there are no matching modes */ + Status = STATUS_UNSUCCESSFUL; + BlMmFreeHeap(ModeList); + return Status; +} + +VOID +ConsoleFirmwareTextClose ( + _In_ PBL_TEXT_CONSOLE TextConsole + ) +{ + ULONG Mode; + BL_DISPLAY_STATE DisplayState; + + /* Read the original mode, and see if it's different than the one now */ + Mode = TextConsole->OldMode.Mode; + if (Mode != TextConsole->Mode) + { + /* Restore to the original mode */ + EfiConOutSetMode(TextConsole->Protocol, Mode); + } + + /* Read the EFI settings for the original mode */ + ConsoleEfiTextGetStateFromMode(&TextConsole->OldMode, &DisplayState); + + /* Set the original settings */ + ConsoleFirmwareTextSetState(TextConsole, 0xF, &DisplayState); +} + +NTSTATUS +ConsoleFirmwareTextOpen ( + _In_ PBL_TEXT_CONSOLE TextConsole + ) +{ + BL_DISPLAY_MODE DisplayMode; + EFI_SIMPLE_TEXT_OUTPUT_MODE CurrentMode, NewMode; + ULONG HRes, VRes, Mode; + NTSTATUS Status; + + /* Read the current mode and its settings */ + EfiConOutReadCurrentMode(EfiConOut, &CurrentMode); + Status = EfiConOutQueryMode(EfiConOut, CurrentMode.Mode, &HRes, &VRes); + if (!NT_SUCCESS(Status)) + { + return Status; + } + + /* Save the current mode and its settings */ + NewMode = CurrentMode; + DisplayMode.VRes = VRes; + DisplayMode.HRes = HRes; + DisplayMode.HRes2 = HRes; + + /* Check if the current mode is compatible with one of our modes */ + if (!ConsolepFindResolution(&DisplayMode, ConsoleTextResolutionList, 1)) + { + /* It isn't -- find a matching EFI mode for what we need */ + Status = ConsoleEfiTextFindModeFromAllowed(EfiConOut, + ConsoleTextResolutionList, + 1, + &Mode); + if (!NT_SUCCESS(Status)) + { + return Status; + } + + /* Set the new EFI mode */ + Status = EfiConOutSetMode(EfiConOut, Mode); + if (!NT_SUCCESS(Status)) + { + return Status; + } + + /* Read the current mode and its settings */ + EfiConOutReadCurrentMode(EfiConOut, &NewMode); + Status = EfiConOutQueryMode(EfiConOut, Mode, &HRes, &VRes); + if (!NT_SUCCESS(Status)) + { + EfiConOutSetMode(EfiConOut, CurrentMode.Mode); + return Status; + } + + /* Save the current mode and its settings */ + DisplayMode.HRes = HRes; + DisplayMode.VRes = VRes; + DisplayMode.HRes2 = HRes; + } + + /* Capture all the current settings */ + ConsoleEfiTextGetStateFromMode(&NewMode, &TextConsole->State); + TextConsole->Mode = NewMode.Mode; + TextConsole->DisplayMode = DisplayMode; + TextConsole->Protocol = EfiConOut; + TextConsole->OldMode = CurrentMode; + return STATUS_SUCCESS; +} + +NTSTATUS +ConsoleTextLocalDestruct ( + _In_ struct _BL_TEXT_CONSOLE* Console + ) +{ + return STATUS_NOT_IMPLEMENTED; +} + +NTSTATUS +ConsoleTextLocalReinitialize ( + _In_ struct _BL_TEXT_CONSOLE* Console + ) +{ + return STATUS_NOT_IMPLEMENTED; +} + +NTSTATUS +ConsoleTextBaseGetTextState ( + _In_ struct _BL_TEXT_CONSOLE* Console, + _Out_ PBL_DISPLAY_STATE TextState + ) +{ + return STATUS_NOT_IMPLEMENTED; +} + +NTSTATUS +ConsoleTextLocalSetTextState ( + _In_ struct _BL_TEXT_CONSOLE* Console, + _In_ ULONG Flags, + _In_ PBL_DISPLAY_STATE TextState + ) +{ + return STATUS_NOT_IMPLEMENTED; +} + +NTSTATUS +ConsoleTextBaseGetTextResolution ( + _In_ struct _BL_TEXT_CONSOLE* Console, + _Out_ PULONG TextResolution + ) +{ + return STATUS_NOT_IMPLEMENTED; +} + +NTSTATUS +ConsoleTextLocalSetTextResolution ( + _In_ struct _BL_TEXT_CONSOLE* Console, + _In_ ULONG NewTextResolution, + _Out_ PULONG OldTextResolution + ) +{ + return STATUS_NOT_IMPLEMENTED; +} + +NTSTATUS +ConsoleTextLocalClearText ( + _In_ struct _BL_TEXT_CONSOLE* Console, + _In_ ULONG Attribute + ) +{ + return STATUS_NOT_IMPLEMENTED; +} + +NTSTATUS +ConsoleTextLocalWriteText ( + _In_ struct _BL_TEXT_CONSOLE* Console, + _In_ PCHAR Text, + _In_ ULONG Attribute + ) +{ + return STATUS_NOT_IMPLEMENTED; +} + +BOOLEAN +DsppGraphicsDisabledByBcd ( + VOID + ) +{ + EarlyPrint(L"Disabling graphics\n"); + return TRUE; +} + +NTSTATUS +ConsoleTextLocalConstruct ( + _In_ PBL_TEXT_CONSOLE TextConsole, + _In_ BOOLEAN Activate + ) +{ + NTSTATUS Status; + BL_DISPLAY_STATE TextState; + + /* Set our callbacks */ + TextConsole->Callbacks = &ConsoleTextLocalVtbl; + + /* Are we activating this console? */ + if (Activate) + { + /* Call firmware to activate it */ + Status = ConsoleFirmwareTextOpen(TextConsole); + if (!NT_SUCCESS(Status)) + { + return Status; + } + } + + /* Set default text state */ + TextState.BgColor = 0; + TextState.XPos = 0; + TextState.YPos = 0; + TextState.CursorVisible = FALSE; + TextState.FgColor = White; + + /* Are we activating? */ + if (Activate) + { + /* Call firmware to set it */ + Status = ConsoleFirmwareTextSetState(TextConsole, 0xF, &TextState); + if (!NT_SUCCESS(Status)) + { + /* We failed, back down */ + ConsoleFirmwareTextClose(TextConsole); + return Status; + } + } + else + { + /* Just save the state for now, someone else can activate later */ + TextConsole->State = TextState; + } + + /* Remember if we activated it */ + TextConsole->Active = Activate; + return STATUS_SUCCESS; +} + +NTSTATUS +DsppInitialize ( + _In_ ULONG Flags + ) +{ + BL_LIBRARY_PARAMETERS LibraryParameters = BlpLibraryParameters; + BOOLEAN NoGraphics, HighestMode; + NTSTATUS Status; + PBL_DISPLAY_MODE DisplayMode; + ULONG GraphicsResolution; + PVOID GraphicsConsole; + PVOID RemoteConsole; + PBL_TEXT_CONSOLE TextConsole; + + /* Initialize font data */ + BfiCachedStrikeData = 0; + InitializeListHead(&BfiDeferredListHead); + InitializeListHead(&BfiFontFileListHead); + + /* Allocate the font rectangle */ + BfiGraphicsRectangle = BlMmAllocateHeap(0x5A); + if (!BfiGraphicsRectangle) + { + return STATUS_NO_MEMORY; + } + + /* Display re-initialization not yet handled */ + if (LibraryParameters.LibraryFlags & BL_LIBRARY_FLAG_REINITIALIZE_ALL) + { + EarlyPrint(L"Display path not handled\n"); + return STATUS_NOT_SUPPORTED; + } + + /* Check if no graphics console is needed */ + if ((Flags & BL_LIBRARY_FLAG_NO_GRAPHICS_CONSOLE) || + (DsppGraphicsDisabledByBcd())) + { + /* Remember this */ + NoGraphics = TRUE; + } + else + { + /* No graphics -- remember this */ + NoGraphics = FALSE; + } + + /* On first load, we always initialize a graphics display */ + GraphicsConsole = NULL; + if (!(Flags & BL_LIBRARY_FLAG_REINITIALIZE_ALL) || !(NoGraphics)) + { + /* Default to mode 0 (1024x768) */ + DisplayMode = &ConsoleGraphicalResolutionList[0]; + + /* Check what resolution to use*/ +#if 0 + Status = BlGetBootOptionInteger(BlpApplicationEntry.BcdData, + BcdLibraryInteger_GraphicsResolution, + &GraphicsResolution); +#else + GraphicsResolution = 0; + Status = STATUS_NOT_FOUND; +#endif + if (NT_SUCCESS(Status)) + { + EarlyPrint(L"Display selection not yet handled\n"); + return STATUS_NOT_IMPLEMENTED; + } + + /* Check if the highest mode should be forced */ +#if 0 + Status = BlGetBootOptionBoolean(BlpApplicationEntry.BcdData, + BcdLibraryBoolean_GraphicsForceHighestMode, + &HighestMode); +#else + HighestMode = 0; + Status = STATUS_NOT_FOUND; +#endif + if (NT_SUCCESS(Status)) + { + ConsoleGraphicalResolutionListFlags |= 2; + } + + /* Do we need graphics mode after all? */ + if (!NoGraphics) + { + EarlyPrint(L"Display path not handled\n"); + return STATUS_NOT_SUPPORTED; + } + + /* Are we using something else than the default mode? */ + if (DisplayMode != &ConsoleGraphicalResolutionList[0]) + { + EarlyPrint(L"Display path not handled\n"); + return STATUS_NOT_SUPPORTED; + } + + /* Mask out all the flags now */ + ConsoleGraphicalResolutionListFlags &= ~3; + } + + /* Do we have a graphics console? */ + TextConsole = NULL; + if (!GraphicsConsole) + { + /* Nope -- go allocate a text console */ + TextConsole = BlMmAllocateHeap(sizeof(*TextConsole)); + if (TextConsole) + { + /* Construct it */ + Status = ConsoleTextLocalConstruct(TextConsole, TRUE); + if (!NT_SUCCESS(Status)) + { + BlMmFreeHeap(TextConsole); + TextConsole = NULL; + } + } + } + + /* Initialize all globals to NULL */ + DspRemoteInputConsole = NULL; + DspTextConsole = NULL; + DspGraphicalConsole = NULL; + + /* If we don't have a text console, go get a remote console */ + RemoteConsole = NULL; + if (!TextConsole) + { + EarlyPrint(L"Display path not handled\n"); + return STATUS_NOT_SUPPORTED; + } + + /* Do we have a remote console? */ + if (!DspRemoteInputConsole) + { + /* Nope -- what about a graphical one? */ + if (GraphicsConsole) + { + /* Yes, use it for both graphics and text */ + DspGraphicalConsole = GraphicsConsole; + DspTextConsole = GraphicsConsole; + } + else if (TextConsole) + { + /* Nope, but we have a text console */ + DspTextConsole = TextConsole; + } + + /* Console has been setup */ + return STATUS_SUCCESS; + } + + /* We have a remote console -- have to figure out how to use it*/ + EarlyPrint(L"Display path not handled\n"); + return STATUS_NOT_SUPPORTED; +} + +NTSTATUS +BlpDisplayInitialize ( + _In_ ULONG Flags + ) +{ + NTSTATUS Status; + + /* Are we resetting or initializing? */ + if (Flags & BL_LIBRARY_FLAG_REINITIALIZE) + { + /* This is a reset */ + Status = STATUS_NOT_IMPLEMENTED; +#if 0 + Status = DsppReinitialize(Flags); + if (NT_SUCCESS(Status)) + { + Status = BlpDisplayReinitialize(); + } +#endif + } + else + { + /* Initialize the display */ + Status = DsppInitialize(Flags); + } + + /* Return display initailziation state */ + return Status; +} + +VOID +BlDisplayGetTextCellResolution ( + _Out_ PULONG TextWidth, + _Out_ PULONG TextHeight + ) +{ + NTSTATUS Status; + + /* If the caller doesn't want anything, bail out */ + if (!(TextWidth) || !(TextHeight)) + { + return; + } + + /* Do we have a text console? */ + Status = STATUS_UNSUCCESSFUL; + if (DspTextConsole) + { + /* Do we have a graphics console? */ + if (DspGraphicalConsole) + { + /* Yep -- query it */ + EarlyPrint(L"Not supported\n"); + Status = STATUS_NOT_IMPLEMENTED; + } + } + + /* Check if we failed to get it from the graphics console */ + if (!NT_SUCCESS(Status)) + { + /* Set default text size */ + *TextWidth = 8; + *TextHeight = 8; + } +}