[BOOTMGFW]

- Start GOP graphics console support. Checkpoint commit, currently WIP, untested.
- Cleanup memory allocation/type/caching flags in a single unified enumeration.
- Implement memory mapping functions for physical real mode only.

svn path=/trunk/; revision=69094
This commit is contained in:
Alex Ionescu 2015-09-07 17:35:59 +00:00
parent 1010c1a66f
commit 101f65a435
10 changed files with 1446 additions and 35 deletions

View file

@ -25,9 +25,6 @@ typedef struct _BOOT_APPLICATION_PARAMETER_BLOCK_SCRATCH
ULONG BlpApplicationFlags;
GUID EfiLoadedImageProtocol = EFI_LOADED_IMAGE_PROTOCOL_GUID;
GUID EfiDevicePathProtocol = EFI_DEVICE_PATH_PROTOCOL_GUID;
BOOT_APPLICATION_PARAMETER_BLOCK_SCRATCH EfiInitScratch;
/* FUNCTIONS *****************************************************************/

View file

@ -26,6 +26,8 @@
#include <Uefi.h>
#include <DevicePath.h>
#include <LoadedImage.h>
#include <GraphicsOutput.h>
#include <UgaDraw.h>
VOID
EarlyPrint(_In_ PWCHAR Format, ...);
@ -61,13 +63,6 @@ EarlyPrint(_In_ PWCHAR Format, ...);
#define BL_MM_ADD_DESCRIPTOR_NEVER_TRUNCATE_FLAG 0x20
#define BL_MM_ADD_DESCRIPTOR_UPDATE_LIST_POINTER_FLAG 0x2000
#define BL_MM_DESCRIPTOR_REQUIRES_FIXED_FLAG 0x40000
#define BL_MM_DESCRIPTOR_REQUIRES_COALESCING_FLAG 0x2000000
#define BL_MM_DESCRIPTOR_REQUIRES_UPDATING_FLAG 0x4000000
#define BL_MM_DESCRIPTOR_NEVER_USE_FIRMWARE_FLAG 0x8000000
#define BL_MM_DESCRIPTOR_SPECIAL_PAGES_FLAG 0x20000000
#define BL_MM_DESCRIPTOR_CAME_FROM_FIRMWARE_FLAG 0x80000000
#define BL_MM_REQUEST_DEFAULT_TYPE 1
#define BL_MM_REQUEST_TOP_DOWN_TYPE 2
@ -193,15 +188,45 @@ typedef enum _BL_MEMORY_TYPE
typedef enum _BL_MEMORY_ATTR
{
BlMemoryUncached = 1,
BlMemoryWriteCombined = 2,
BlMemoryWriteThrough = 4,
BlMemoryWriteBack = 8,
BlMemoryUncachedExported = 0x10,
BlMemoryWriteProtected = 0x100,
BlMemoryReadProtected = 0x200,
BlMemoryExecuteProtected = 0x400,
BlMemoryRuntime = 0x1000000
//
// Memory Caching Attributes
//
BlMemoryUncached = 0x00000001,
BlMemoryWriteCombined = 0x00000002,
BlMemoryWriteThrough = 0x00000004,
BlMemoryWriteBack = 0x00000008,
BlMemoryUncachedExported = 0x00000010,
BlMemoryValidCacheAttributes = BlMemoryUncached | BlMemoryWriteCombined | BlMemoryWriteThrough | BlMemoryWriteBack | BlMemoryUncachedExported,
BlMemoryValidCacheAttributeMask = 0x000000FF,
//
// Memory Protection Attributes
//
BlMemoryWriteProtected = 0x00000100,
BlMemoryReadProtected = 0x00000200,
BlMemoryExecuteProtected = 0x00000400,
BlMemoryValidProtectionAttributes = BlMemoryWriteProtected | BlMemoryReadProtected | BlMemoryExecuteProtected,
BlMemoryValidProtectionAttributeMask = 0x0000FF00,
//
// Memory Allocation Attributes
//
BlMemoryNonFixed = 0x00020000,
BlMemoryFixed = 0x00040000,
BlMemoryValidAllocationAttributes = BlMemoryNonFixed | BlMemoryFixed,
BlMemoryValidAllocationAttributeMask = 0x00FF0000,
//
// Memory Type Attributes
//
BlMemoryRuntime = 0x01000000,
BlMemoryCoalesced = 0x02000000,
BlMemoryUpdate = 0x04000000,
BlMemoryNonFirmware = 0x08000000,
BlMemorySpecial = 0x20000000,
BlMemoryFirmware = 0x80000000,
BlMemoryValidTypeAttributes = BlMemoryRuntime | BlMemoryCoalesced | BlMemoryUpdate | BlMemoryNonFirmware | BlMemorySpecial | BlMemoryFirmware,
BlMemoryValidTypeAttributeMask = 0xFF000000,
} BL_MEMORY_ATTR;
/* CALLBACKS *****************************************************************/
@ -655,6 +680,47 @@ EfiConOutEnableCursor (
_In_ BOOLEAN Visible
);
NTSTATUS
EfiLocateHandleBuffer (
_In_ EFI_LOCATE_SEARCH_TYPE SearchType,
_In_ EFI_GUID *Protocol,
_Inout_ PULONG HandleCount,
_Inout_ EFI_HANDLE** Buffer
);
NTSTATUS
EfiOpenProtocol (
_In_ EFI_HANDLE Handle,
_In_ EFI_GUID *Protocol,
_Out_ PVOID* Interface
);
NTSTATUS
EfiCloseProtocol (
_In_ EFI_HANDLE Handle,
_In_ EFI_GUID *Protocol
);
NTSTATUS
EfiGopGetCurrentMode (
_In_ EFI_GRAPHICS_OUTPUT_PROTOCOL *GopInterface,
_Out_ UINTN* Mode,
_Out_ EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Information
);
NTSTATUS
EfiGopSetMode (
_In_ EFI_GRAPHICS_OUTPUT_PROTOCOL *GopInterface,
_In_ ULONG Mode
);
VOID
EfiGopGetFrameBuffer (
_In_ EFI_GRAPHICS_OUTPUT_PROTOCOL *GopInterface,
_Out_ PHYSICAL_ADDRESS* FrameBuffer,
_Out_ UINTN *FrameBufferSize
);
/* PLATFORM TIMER ROUTINES ***************************************************/
NTSTATUS
@ -773,6 +839,16 @@ MmFwGetMemoryMap (
_In_ ULONG Flags
);
/* VIRTUAL MEMORY ROUTINES ***************************************************/
NTSTATUS
BlMmMapPhysicalAddressEx (
_In_ PVOID* VirtualAddress,
_In_ ULONG Attributes,
_In_ ULONGLONG Size,
_In_ PHYSICAL_ADDRESS PhysicalAddress
);
/* HEAP ALLOCATOR ROUTINES ***************************************************/
PVOID
@ -801,5 +877,10 @@ extern PBL_ARCH_CONTEXT CurrentExecutionContext;
extern PBL_DEVICE_DESCRIPTOR BlpBootDevice;
extern BL_APPLICATION_ENTRY BlpApplicationEntry;
extern SIMPLE_TEXT_OUTPUT_INTERFACE *EfiConOut;
extern EFI_GUID EfiGraphicsOutputProtocol;
extern EFI_GUID EfiUgaDrawProtocol;
extern EFI_GUID EfiLoadedImageProtocol;
extern EFI_GUID EfiDevicePathProtocol;
extern EFI_GUID EfiSimpleTextInputExProtocol;
#endif

View file

@ -0,0 +1,276 @@
/** @file
Graphics Output Protocol from the UEFI 2.0 specification.
Abstraction of a very simple graphics device.
Copyright (c) 2006 - 2012, 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.
**/
#ifndef __GRAPHICS_OUTPUT_H__
#define __GRAPHICS_OUTPUT_H__
#define EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID \
{ \
0x9042a9de, 0x23dc, 0x4a38, {0x96, 0xfb, 0x7a, 0xde, 0xd0, 0x80, 0x51, 0x6a } \
}
typedef struct _EFI_GRAPHICS_OUTPUT_PROTOCOL EFI_GRAPHICS_OUTPUT_PROTOCOL;
typedef struct {
UINT32 RedMask;
UINT32 GreenMask;
UINT32 BlueMask;
UINT32 ReservedMask;
} EFI_PIXEL_BITMASK;
typedef enum {
///
/// A pixel is 32-bits and byte zero represents red, byte one represents green,
/// byte two represents blue, and byte three is reserved. This is the definition
/// for the physical frame buffer. The byte values for the red, green, and blue
/// components represent the color intensity. This color intensity value range
/// from a minimum intensity of 0 to maximum intensity of 255.
///
PixelRedGreenBlueReserved8BitPerColor,
///
/// A pixel is 32-bits and byte zero represents blue, byte one represents green,
/// byte two represents red, and byte three is reserved. This is the definition
/// for the physical frame buffer. The byte values for the red, green, and blue
/// components represent the color intensity. This color intensity value range
/// from a minimum intensity of 0 to maximum intensity of 255.
///
PixelBlueGreenRedReserved8BitPerColor,
///
/// The Pixel definition of the physical frame buffer.
///
PixelBitMask,
///
/// This mode does not support a physical frame buffer.
///
PixelBltOnly,
///
/// Valid EFI_GRAPHICS_PIXEL_FORMAT enum values are less than this value.
///
PixelFormatMax
} EFI_GRAPHICS_PIXEL_FORMAT;
typedef struct {
///
/// The version of this data structure. A value of zero represents the
/// EFI_GRAPHICS_OUTPUT_MODE_INFORMATION structure as defined in this specification.
///
UINT32 Version;
///
/// The size of video screen in pixels in the X dimension.
///
UINT32 HorizontalResolution;
///
/// The size of video screen in pixels in the Y dimension.
///
UINT32 VerticalResolution;
///
/// Enumeration that defines the physical format of the pixel. A value of PixelBltOnly
/// implies that a linear frame buffer is not available for this mode.
///
EFI_GRAPHICS_PIXEL_FORMAT PixelFormat;
///
/// This bit-mask is only valid if PixelFormat is set to PixelPixelBitMask.
/// A bit being set defines what bits are used for what purpose such as Red, Green, Blue, or Reserved.
///
EFI_PIXEL_BITMASK PixelInformation;
///
/// Defines the number of pixel elements per video memory line.
///
UINT32 PixelsPerScanLine;
} EFI_GRAPHICS_OUTPUT_MODE_INFORMATION;
/**
Returns information for an available graphics mode that the graphics device
and the set of active video output devices supports.
@param This The EFI_GRAPHICS_OUTPUT_PROTOCOL instance.
@param ModeNumber The mode number to return information on.
@param SizeOfInfo A pointer to the size, in bytes, of the Info buffer.
@param Info A pointer to callee allocated buffer that returns information about ModeNumber.
@retval EFI_SUCCESS Valid mode information was returned.
@retval EFI_DEVICE_ERROR A hardware error occurred trying to retrieve the video mode.
@retval EFI_INVALID_PARAMETER ModeNumber is not valid.
**/
typedef
EFI_STATUS
(EFIAPI *EFI_GRAPHICS_OUTPUT_PROTOCOL_QUERY_MODE)(
IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This,
IN UINT32 ModeNumber,
OUT UINTN *SizeOfInfo,
OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION **Info
);
/**
Set the video device into the specified mode and clears the visible portions of
the output display to black.
@param This The EFI_GRAPHICS_OUTPUT_PROTOCOL instance.
@param ModeNumber Abstraction that defines the current video mode.
@retval EFI_SUCCESS The graphics mode specified by ModeNumber was selected.
@retval EFI_DEVICE_ERROR The device had an error and could not complete the request.
@retval EFI_UNSUPPORTED ModeNumber is not supported by this device.
**/
typedef
EFI_STATUS
(EFIAPI *EFI_GRAPHICS_OUTPUT_PROTOCOL_SET_MODE)(
IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This,
IN UINT32 ModeNumber
);
typedef struct {
UINT8 Blue;
UINT8 Green;
UINT8 Red;
UINT8 Reserved;
} EFI_GRAPHICS_OUTPUT_BLT_PIXEL;
typedef union {
EFI_GRAPHICS_OUTPUT_BLT_PIXEL Pixel;
UINT32 Raw;
} EFI_GRAPHICS_OUTPUT_BLT_PIXEL_UNION;
///
/// actions for BltOperations
///
typedef enum {
///
/// Write data from the BltBuffer pixel (0, 0)
/// directly to every pixel of the video display rectangle
/// (DestinationX, DestinationY) (DestinationX + Width, DestinationY + Height).
/// Only one pixel will be used from the BltBuffer. Delta is NOT used.
///
EfiBltVideoFill,
///
/// Read data from the video display rectangle
/// (SourceX, SourceY) (SourceX + Width, SourceY + Height) and place it in
/// the BltBuffer rectangle (DestinationX, DestinationY )
/// (DestinationX + Width, DestinationY + Height). If DestinationX or
/// DestinationY is not zero then Delta must be set to the length in bytes
/// of a row in the BltBuffer.
///
EfiBltVideoToBltBuffer,
///
/// Write data from the BltBuffer rectangle
/// (SourceX, SourceY) (SourceX + Width, SourceY + Height) directly to the
/// video display rectangle (DestinationX, DestinationY)
/// (DestinationX + Width, DestinationY + Height). If SourceX or SourceY is
/// not zero then Delta must be set to the length in bytes of a row in the
/// BltBuffer.
///
EfiBltBufferToVideo,
///
/// Copy from the video display rectangle (SourceX, SourceY)
/// (SourceX + Width, SourceY + Height) to the video display rectangle
/// (DestinationX, DestinationY) (DestinationX + Width, DestinationY + Height).
/// The BltBuffer and Delta are not used in this mode.
///
EfiBltVideoToVideo,
EfiGraphicsOutputBltOperationMax
} EFI_GRAPHICS_OUTPUT_BLT_OPERATION;
/**
Blt a rectangle of pixels on the graphics screen. Blt stands for BLock Transfer.
@param This Protocol instance pointer.
@param BltBuffer The data to transfer to the graphics screen.
Size is at least Width*Height*sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL).
@param BltOperation The operation to perform when copying BltBuffer on to the graphics screen.
@param SourceX The X coordinate of source for the BltOperation.
@param SourceY The Y coordinate of source for the BltOperation.
@param DestinationX The X coordinate of destination for the BltOperation.
@param DestinationY The Y coordinate of destination for the BltOperation.
@param Width The width of a rectangle in the blt rectangle in pixels.
@param Height The height of a rectangle in the blt rectangle in pixels.
@param Delta Not used for EfiBltVideoFill or the EfiBltVideoToVideo operation.
If a Delta of zero is used, the entire BltBuffer is being operated on.
If a subrectangle of the BltBuffer is being used then Delta
represents the number of bytes in a row of the BltBuffer.
@retval EFI_SUCCESS BltBuffer was drawn to the graphics screen.
@retval EFI_INVALID_PARAMETER BltOperation is not valid.
@retval EFI_DEVICE_ERROR The device had an error and could not complete the request.
**/
typedef
EFI_STATUS
(EFIAPI *EFI_GRAPHICS_OUTPUT_PROTOCOL_BLT)(
IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This,
IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer, OPTIONAL
IN EFI_GRAPHICS_OUTPUT_BLT_OPERATION BltOperation,
IN UINTN SourceX,
IN UINTN SourceY,
IN UINTN DestinationX,
IN UINTN DestinationY,
IN UINTN Width,
IN UINTN Height,
IN UINTN Delta OPTIONAL
);
typedef struct {
///
/// The number of modes supported by QueryMode() and SetMode().
///
UINT32 MaxMode;
///
/// Current Mode of the graphics device. Valid mode numbers are 0 to MaxMode -1.
///
UINT32 Mode;
///
/// Pointer to read-only EFI_GRAPHICS_OUTPUT_MODE_INFORMATION data.
///
EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info;
///
/// Size of Info structure in bytes.
///
UINTN SizeOfInfo;
///
/// Base address of graphics linear frame buffer.
/// Offset zero in FrameBufferBase represents the upper left pixel of the display.
///
EFI_PHYSICAL_ADDRESS FrameBufferBase;
///
/// Amount of frame buffer needed to support the active mode as defined by
/// PixelsPerScanLine xVerticalResolution x PixelElementSize.
///
UINTN FrameBufferSize;
} EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE;
///
/// Provides a basic abstraction to set video modes and copy pixels to and from
/// the graphics controller's frame buffer. The linear address of the hardware
/// frame buffer is also exposed so software can write directly to the video hardware.
///
struct _EFI_GRAPHICS_OUTPUT_PROTOCOL {
EFI_GRAPHICS_OUTPUT_PROTOCOL_QUERY_MODE QueryMode;
EFI_GRAPHICS_OUTPUT_PROTOCOL_SET_MODE SetMode;
EFI_GRAPHICS_OUTPUT_PROTOCOL_BLT Blt;
///
/// Pointer to EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE data.
///
EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE *Mode;
};
extern EFI_GUID gEfiGraphicsOutputProtocolGuid;
#endif

View file

@ -0,0 +1,166 @@
/** @file
UGA Draw protocol from the EFI 1.10 specification.
Abstraction of a very simple graphics device.
Copyright (c) 2006 - 2008, 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.
**/
#ifndef __UGA_DRAW_H__
#define __UGA_DRAW_H__
#define EFI_UGA_DRAW_PROTOCOL_GUID \
{ \
0x982c298b, 0xf4fa, 0x41cb, {0xb8, 0x38, 0x77, 0xaa, 0x68, 0x8f, 0xb8, 0x39 } \
}
typedef struct _EFI_UGA_DRAW_PROTOCOL EFI_UGA_DRAW_PROTOCOL;
/**
Return the current video mode information.
@param This The EFI_UGA_DRAW_PROTOCOL instance.
@param HorizontalResolution The size of video screen in pixels in the X dimension.
@param VerticalResolution The size of video screen in pixels in the Y dimension.
@param ColorDepth Number of bits per pixel, currently defined to be 32.
@param RefreshRate The refresh rate of the monitor in Hertz.
@retval EFI_SUCCESS Mode information returned.
@retval EFI_NOT_STARTED Video display is not initialized. Call SetMode ()
@retval EFI_INVALID_PARAMETER One of the input args was NULL.
**/
typedef
EFI_STATUS
(EFIAPI *EFI_UGA_DRAW_PROTOCOL_GET_MODE)(
IN EFI_UGA_DRAW_PROTOCOL *This,
OUT UINT32 *HorizontalResolution,
OUT UINT32 *VerticalResolution,
OUT UINT32 *ColorDepth,
OUT UINT32 *RefreshRate
);
/**
Set the current video mode information.
@param This The EFI_UGA_DRAW_PROTOCOL instance.
@param HorizontalResolution The size of video screen in pixels in the X dimension.
@param VerticalResolution The size of video screen in pixels in the Y dimension.
@param ColorDepth Number of bits per pixel, currently defined to be 32.
@param RefreshRate The refresh rate of the monitor in Hertz.
@retval EFI_SUCCESS Mode information returned.
@retval EFI_NOT_STARTED Video display is not initialized. Call SetMode ()
**/
typedef
EFI_STATUS
(EFIAPI *EFI_UGA_DRAW_PROTOCOL_SET_MODE)(
IN EFI_UGA_DRAW_PROTOCOL *This,
IN UINT32 HorizontalResolution,
IN UINT32 VerticalResolution,
IN UINT32 ColorDepth,
IN UINT32 RefreshRate
);
typedef struct {
UINT8 Blue;
UINT8 Green;
UINT8 Red;
UINT8 Reserved;
} EFI_UGA_PIXEL;
typedef union {
EFI_UGA_PIXEL Pixel;
UINT32 Raw;
} EFI_UGA_PIXEL_UNION;
///
/// Enumration value for actions of Blt operations.
///
typedef enum {
EfiUgaVideoFill, ///< Write data from the BltBuffer pixel (SourceX, SourceY)
///< directly to every pixel of the video display rectangle
///< (DestinationX, DestinationY) (DestinationX + Width, DestinationY + Height).
///< Only one pixel will be used from the BltBuffer. Delta is NOT used.
EfiUgaVideoToBltBuffer, ///< Read data from the video display rectangle
///< (SourceX, SourceY) (SourceX + Width, SourceY + Height) and place it in
///< the BltBuffer rectangle (DestinationX, DestinationY )
///< (DestinationX + Width, DestinationY + Height). If DestinationX or
///< DestinationY is not zero then Delta must be set to the length in bytes
///< of a row in the BltBuffer.
EfiUgaBltBufferToVideo, ///< Write data from the BltBuffer rectangle
///< (SourceX, SourceY) (SourceX + Width, SourceY + Height) directly to the
///< video display rectangle (DestinationX, DestinationY)
///< (DestinationX + Width, DestinationY + Height). If SourceX or SourceY is
///< not zero then Delta must be set to the length in bytes of a row in the
///< BltBuffer.
EfiUgaVideoToVideo, ///< Copy from the video display rectangle (SourceX, SourceY)
///< (SourceX + Width, SourceY + Height) .to the video display rectangle
///< (DestinationX, DestinationY) (DestinationX + Width, DestinationY + Height).
///< The BltBuffer and Delta are not used in this mode.
EfiUgaBltMax ///< Maxmimum value for enumration value of Blt operation. If a Blt operation
///< larger or equal to this enumration value, it is invalid.
} EFI_UGA_BLT_OPERATION;
/**
Blt a rectangle of pixels on the graphics screen.
@param[in] This - Protocol instance pointer.
@param[in] BltBuffer - Buffer containing data to blit into video buffer. This
buffer has a size of Width*Height*sizeof(EFI_UGA_PIXEL)
@param[in] BltOperation - Operation to perform on BlitBuffer and video memory
@param[in] SourceX - X coordinate of source for the BltBuffer.
@param[in] SourceY - Y coordinate of source for the BltBuffer.
@param[in] DestinationX - X coordinate of destination for the BltBuffer.
@param[in] DestinationY - Y coordinate of destination for the BltBuffer.
@param[in] Width - Width of rectangle in BltBuffer in pixels.
@param[in] Height - Hight of rectangle in BltBuffer in pixels.
@param[in] Delta - OPTIONAL
@retval EFI_SUCCESS - The Blt operation completed.
@retval EFI_INVALID_PARAMETER - BltOperation is not valid.
@retval EFI_DEVICE_ERROR - A hardware error occured writting to the video buffer.
**/
typedef
EFI_STATUS
(EFIAPI *EFI_UGA_DRAW_PROTOCOL_BLT)(
IN EFI_UGA_DRAW_PROTOCOL * This,
IN EFI_UGA_PIXEL * BltBuffer, OPTIONAL
IN EFI_UGA_BLT_OPERATION BltOperation,
IN UINTN SourceX,
IN UINTN SourceY,
IN UINTN DestinationX,
IN UINTN DestinationY,
IN UINTN Width,
IN UINTN Height,
IN UINTN Delta OPTIONAL
);
///
/// This protocol provides a basic abstraction to set video modes and
/// copy pixels to and from the graphics controller's frame buffer.
///
struct _EFI_UGA_DRAW_PROTOCOL {
EFI_UGA_DRAW_PROTOCOL_GET_MODE GetMode;
EFI_UGA_DRAW_PROTOCOL_SET_MODE SetMode;
EFI_UGA_DRAW_PROTOCOL_BLT Blt;
};
extern EFI_GUID gEfiUgaDrawProtocolGuid;
#endif

View file

@ -12,8 +12,6 @@
/* DATA VARIABLES ************************************************************/
GUID EfiSimpleTextInputExProtocol = EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL_GUID;
PBL_FIRMWARE_DESCRIPTOR EfiFirmwareParameters;
BL_FIRMWARE_DESCRIPTOR EfiFirmwareData;
EFI_HANDLE EfiImageHandle;
@ -26,6 +24,12 @@ EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *EfiConOut;
EFI_SIMPLE_TEXT_INPUT_PROTOCOL *EfiConIn;
EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *EfiConInEx;
EFI_GUID EfiGraphicsOutputProtocol = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID;
EFI_GUID EfiUgaDrawProtocol = EFI_UGA_DRAW_PROTOCOL_GUID;
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;
/* FUNCTIONS *****************************************************************/
NTSTATUS
@ -92,6 +96,65 @@ EfiOpenProtocol (
return Status;
}
NTSTATUS
EfiCloseProtocol (
_In_ EFI_HANDLE Handle,
_In_ EFI_GUID *Protocol
)
{
EFI_STATUS EfiStatus;
NTSTATUS Status;
BL_ARCH_MODE OldMode;
/* Are we using virtual memory/ */
if (MmTranslationType != BlNone)
{
/* We need complex tracking to make this work */
//Status = EfiVmOpenProtocol(Handle, Protocol, Interface);
Status = STATUS_NOT_SUPPORTED;
}
else
{
/* Are we on legacy 1.02? */
if (EfiST->FirmwareRevision == EFI_1_02_SYSTEM_TABLE_REVISION)
{
/* Nothing to close */
EfiStatus = STATUS_SUCCESS;
}
else
{
/* Are we in protected mode? */
OldMode = CurrentExecutionContext->Mode;
if (OldMode != BlRealMode)
{
/* FIXME: Not yet implemented */
return STATUS_NOT_IMPLEMENTED;
}
/* Use the UEFI version */
EfiStatus = EfiBS->CloseProtocol(Handle, Protocol, EfiImageHandle, NULL);
/* Switch back to protected mode if we came from there */
if (OldMode != BlRealMode)
{
BlpArchSwitchContext(OldMode);
}
/* Normalize not found as success */
if (EfiStatus == EFI_NOT_FOUND)
{
EfiStatus = EFI_SUCCESS;
}
}
/* Convert the error to an NTSTATUS */
Status = EfiGetNtStatusCode(EfiStatus);
}
/* All done */
return Status;
}
NTSTATUS
EfiConInExSetState (
_In_ EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *ConInEx,
@ -426,6 +489,187 @@ EfiConOutReadCurrentMode (
}
}
VOID
EfiGopGetFrameBuffer (
_In_ EFI_GRAPHICS_OUTPUT_PROTOCOL *GopInterface,
_Out_ PHYSICAL_ADDRESS* FrameBuffer,
_Out_ UINTN *FrameBufferSize
)
{
BL_ARCH_MODE OldMode;
/* Are we in protected mode? */
OldMode = CurrentExecutionContext->Mode;
if (OldMode != BlRealMode)
{
/* FIXME: Not yet implemented */
return;
}
/* Make the EFI call */
FrameBuffer->QuadPart = GopInterface->Mode->FrameBufferBase;
*FrameBufferSize = GopInterface->Mode->FrameBufferSize;
/* Switch back to protected mode if we came from there */
if (OldMode != BlRealMode)
{
BlpArchSwitchContext(OldMode);
}
}
NTSTATUS
EfiGopGetCurrentMode (
_In_ EFI_GRAPHICS_OUTPUT_PROTOCOL *GopInterface,
_Out_ UINTN* Mode,
_Out_ EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Information
)
{
BL_ARCH_MODE OldMode;
/* Are we in protected mode? */
OldMode = CurrentExecutionContext->Mode;
if (OldMode != BlRealMode)
{
/* FIXME: Not yet implemented */
return STATUS_NOT_IMPLEMENTED;
}
/* Make the EFI call */
*Mode = GopInterface->Mode->Mode;
RtlCopyMemory(Information, GopInterface->Mode, sizeof(*Information));
/* Switch back to protected mode if we came from there */
if (OldMode != BlRealMode)
{
BlpArchSwitchContext(OldMode);
}
/* Return back */
return STATUS_SUCCESS;
}
NTSTATUS
EfiGopSetMode (
_In_ EFI_GRAPHICS_OUTPUT_PROTOCOL *GopInterface,
_In_ ULONG Mode
)
{
BL_ARCH_MODE OldMode;
EFI_STATUS EfiStatus;
BOOLEAN ModeChanged;
NTSTATUS Status;
/* Are we in protected mode? */
OldMode = CurrentExecutionContext->Mode;
if (OldMode != BlRealMode)
{
/* FIXME: Not yet implemented */
return STATUS_NOT_IMPLEMENTED;
}
/* Make the EFI call */
if (Mode == GopInterface->Mode->Mode)
{
EfiStatus = EFI_SUCCESS;
ModeChanged = FALSE;
}
{
EfiStatus = GopInterface->SetMode(GopInterface, Mode);
ModeChanged = TRUE;
}
/* Switch back to protected mode if we came from there */
if (OldMode != BlRealMode)
{
BlpArchSwitchContext(OldMode);
}
/* Print out to the debugger if the mode was changed */
Status = EfiGetNtStatusCode(EfiStatus);
if ((ModeChanged) && (NT_SUCCESS(Status)))
{
/* FIXME @TODO: Should be BlStatusPrint */
EarlyPrint(L"Console video mode set to 0x%x\r\n", Mode);
}
/* Convert the error to an NTSTATUS */
return Status;
}
NTSTATUS
EfiLocateHandleBuffer (
_In_ EFI_LOCATE_SEARCH_TYPE SearchType,
_In_ EFI_GUID *Protocol,
_Inout_ PULONG HandleCount,
_Inout_ EFI_HANDLE** Buffer
)
{
BL_ARCH_MODE OldMode;
EFI_STATUS EfiStatus;
UINTN BufferSize;
/* Bail out if we're missing parameters */
if (!(Buffer) || !(HandleCount))
{
return STATUS_INVALID_PARAMETER;
}
/* Check if a buffer was passed in*/
if (*Buffer)
{
/* Then we should already have a buffer size*/
BufferSize = sizeof(EFI_HANDLE) * *HandleCount;
}
else
{
/* Then no buffer size exists */
BufferSize = 0;
}
/* Are we in protected mode? */
OldMode = CurrentExecutionContext->Mode;
if (OldMode != BlRealMode)
{
/* FIXME: Not yet implemented */
return STATUS_NOT_IMPLEMENTED;
}
/* Try the first time */
EfiStatus = EfiBS->LocateHandle(SearchType, Protocol, NULL, &BufferSize, *Buffer);
if (EfiStatus == EFI_BUFFER_TOO_SMALL)
{
/* Did we have an existing buffer? */
if (*Buffer)
{
/* Free it */
BlMmFreeHeap(*Buffer);
}
/* Allocate a new one */
*Buffer = BlMmAllocateHeap(BufferSize);
if (!(*Buffer))
{
/* No space, fail */
return STATUS_NO_MEMORY;
}
/* Try again */
EfiStatus = EfiBS->LocateHandle(SearchType, Protocol, NULL, &BufferSize, *Buffer);
/* Switch back to protected mode if we came from there */
if (OldMode != BlRealMode)
{
BlpArchSwitchContext(OldMode);
}
}
/* Return the number of handles */
*HandleCount = BufferSize / sizeof(EFI_HANDLE);
/* Convert the error to an NTSTATUS */
return EfiGetNtStatusCode(EfiStatus);
}
NTSTATUS
EfiAllocatePages (
_In_ ULONG Type,

View file

@ -387,7 +387,7 @@ MmMdAddDescriptorToList (
else
{
/* Coalesce if the descriptor requires it */
if (MemoryDescriptor->Flags & BL_MM_DESCRIPTOR_REQUIRES_COALESCING_FLAG)
if (MemoryDescriptor->Flags & BlMemoryCoalesced)
{
Flags |= BL_MM_ADD_DESCRIPTOR_COALESCE_FLAG;
}
@ -400,7 +400,7 @@ MmMdAddDescriptorToList (
}
/* Update the current list pointer if the descriptor requires it */
if (MemoryDescriptor->Flags & BL_MM_DESCRIPTOR_REQUIRES_UPDATING_FLAG)
if (MemoryDescriptor->Flags & BlMemoryUpdate)
{
Flags |= BL_MM_ADD_DESCRIPTOR_UPDATE_LIST_POINTER_FLAG;
}

View file

@ -23,7 +23,7 @@ typedef struct _BL_HEAP_POINTER
ULONG_PTR BufferFree : 1;
ULONG_PTR BufferOnHeap : 1;
ULONG_PTR NotUsed : 1;
ULONG_PTR BufferPointer : (sizeof(ULONG_PTR) - BL_HEAP_POINTER_FLAG_BITS);
ULONG_PTR BufferPointer : ((8 * sizeof(ULONG_PTR)) - BL_HEAP_POINTER_FLAG_BITS);
};
PVOID P;
};

View file

@ -42,6 +42,168 @@ BlMmRemoveBadMemory (
return STATUS_SUCCESS;
}
NTSTATUS
MmSelectMappingAddress (
_Out_ PVOID* MappingAddress,
_In_ ULONGLONG Size,
_In_ ULONG AllocationAttributes,
_In_ ULONG Flags,
_In_ PHYSICAL_ADDRESS PhysicalAddress
)
{
/* Are we in physical mode? */
if (MmTranslationType == BlNone)
{
/* Just return the physical address as the mapping address */
*MappingAddress = (PVOID)PhysicalAddress.LowPart;
return STATUS_SUCCESS;
}
/* Have to allocate physical pages */
EarlyPrint(L"VM Todo\n");
return STATUS_NOT_IMPLEMENTED;
}
NTSTATUS
MmMapPhysicalAddress (
_Inout_ PPHYSICAL_ADDRESS PhysicalAddress,
_Out_ PVOID VirtualAddress,
_Inout_ PULONGLONG Size,
_In_ ULONG CacheAttributes
)
{
ULONGLONG MappingSize;
/* Fail if any parameters are missing */
if (!(PhysicalAddress) || !(VirtualAddress) || !(Size))
{
return STATUS_INVALID_PARAMETER;
}
/* Fail if the size is over 32-bits */
MappingSize = *Size;
if (MappingSize > 0xFFFFFFFF)
{
return STATUS_INVALID_PARAMETER;
}
/* Nothing to do if we're in physical mode */
if (MmTranslationType == BlNone)
{
return STATUS_SUCCESS;
}
/* Can't use virtual memory in real mode */
if (CurrentExecutionContext->Mode == BlRealMode)
{
return STATUS_UNSUCCESSFUL;
}
EarlyPrint(L"VM todo\n");
return STATUS_NOT_IMPLEMENTED;
}
NTSTATUS
BlMmMapPhysicalAddressEx (
_In_ PVOID* VirtualAddress,
_In_ ULONG Flags,
_In_ ULONGLONG Size,
_In_ PHYSICAL_ADDRESS PhysicalAddress
)
{
NTSTATUS Status;
PVOID MappingAddress;
PHYSICAL_ADDRESS MappedAddress;
PVOID MappedBase;
ULONGLONG MapSize;
UCHAR CacheAttributes;
/* Increase call depth */
++MmDescriptorCallTreeCount;
/* Check if any parameters are missing */
if (!(VirtualAddress) || !(Size))
{
Status = STATUS_INVALID_PARAMETER;
goto Quickie;
}
/* Check for fixed allocation without an actual address */
if ((Flags & BlMemoryFixed) &&
(PhysicalAddress.QuadPart == -1) &&
!(*VirtualAddress))
{
Status = STATUS_INVALID_PARAMETER;
goto Quickie;
}
/* Check for invalid requirement flag, if one is present */
if (((Flags & BlMemoryValidAllocationAttributes) != BlMemoryFixed) &&
((Flags & BlMemoryValidAllocationAttributes) != BlMemoryNonFixed) &&
(Flags & BlMemoryValidAllocationAttributes))
{
Status = STATUS_INVALID_PARAMETER;
goto Quickie;
}
/* Check for invalid cache attribute flags */
if (((Flags & BlMemoryValidCacheAttributeMask) - 1) &
(Flags & BlMemoryValidCacheAttributeMask))
{
Status = STATUS_INVALID_PARAMETER;
goto Quickie;
}
/* Select an address to map this at */
Status = MmSelectMappingAddress(&MappingAddress,
Size,
Flags & BlMemoryValidAllocationAttributes,
Flags,
PhysicalAddress);
if (!NT_SUCCESS(Status))
{
goto Quickie;
}
/* Map the selected address, using the appropriate caching attributes */
MappedAddress = PhysicalAddress;
MapSize = Size;
CacheAttributes = ((Flags & BlMemoryValidCacheAttributeMask) != 0x20) ?
(Flags & BlMemoryValidCacheAttributeMask) : 0;
Status = MmMapPhysicalAddress(&MappedAddress,
&MappingAddress,
&MapSize,
CacheAttributes);
if (!NT_SUCCESS(Status))
{
goto Quickie;
}
/* Compute the final adress where the mapping was made */
MappedBase = (PVOID)((ULONG_PTR)MappingAddress +
PhysicalAddress.LowPart -
MappedAddress.LowPart);
/* Check if we're in physical or virtual mode */
if (MmTranslationType != BlNone)
{
/* For virtual memory, there's more to do */
EarlyPrint(L"VM not supported for mapping\n");
Status = STATUS_NOT_IMPLEMENTED;
goto Quickie;
}
/* Return the mapped virtual address */
Status = STATUS_SUCCESS;
*VirtualAddress = MappedBase;
Quickie:
/* Cleanup descriptors and reduce depth */
MmMdFreeGlobalDescriptors();
--MmDescriptorCallTreeCount;
return Status;
}
NTSTATUS
BlpMmInitialize (
_In_ PBL_MEMORY_DATA MemoryData,

View file

@ -141,8 +141,8 @@ MmPapAllocateRegionFromMdl (
/* Are we using the physical memory list, and are we OK with using firmware? */
if ((CurrentList == &MmMdlUnmappedUnallocated) &&
!((Request->Flags & BL_MM_DESCRIPTOR_NEVER_USE_FIRMWARE_FLAG) ||
(LocalDescriptor.Flags & BL_MM_DESCRIPTOR_NEVER_USE_FIRMWARE_FLAG)))
!((Request->Flags & BlMemoryNonFirmware) ||
(LocalDescriptor.Flags & BlMemoryNonFirmware)))
{
/* Allocate the requested address from EFI */
EfiAddress = LocalDescriptor.BasePage << PAGE_SHIFT;
@ -222,7 +222,7 @@ MmPapAllocateRegionFromMdl (
/* Remember if it came from EFI */
if (GotFwPages)
{
FoundDescriptor->Flags |= BL_MM_DESCRIPTOR_CAME_FROM_FIRMWARE_FLAG;
FoundDescriptor->Flags |= BlMemoryFirmware;
}
/* Add the descriptor to the requested list */
@ -253,7 +253,7 @@ MmPaAllocatePages (
/* Heap and page directory/table pages have a special flag */
if ((MemoryType >= BlLoaderHeap) && (MemoryType <= BlLoaderReferencePage))
{
Request->Flags |= BL_MM_DESCRIPTOR_SPECIAL_PAGES_FLAG;
Request->Flags |= BlMemorySpecial;
}
/* Try to find a free region of RAM matching this range and request */
@ -334,7 +334,7 @@ MmPapAllocatePhysicalPagesInRange (
Request.VirtualRange.Maximum = 0;
/* Check if a fixed allocation was requested*/
if (Attributes & BL_MM_DESCRIPTOR_REQUIRES_FIXED_FLAG)
if (Attributes & BlMemoryFixed)
{
/* Force the only available range to be the passed in address */
Request.BaseRange.Minimum = BaseAddress->QuadPart >> PAGE_SHIFT;
@ -425,8 +425,7 @@ MmPapAllocatePagesInRange (
else
{
/* Check if this is a fixed allocation */
BaseAddress.QuadPart = (Attributes & BL_MM_DESCRIPTOR_REQUIRES_FIXED_FLAG) ?
*PhysicalAddress : 0;
BaseAddress.QuadPart = (Attributes & BlMemoryFixed) ? *PhysicalAddress : 0;
/* Allocate the pages */
Status = MmPapAllocatePhysicalPagesInRange(&BaseAddress,

View file

@ -120,6 +120,12 @@ typedef struct _BL_TEXT_CONSOLE_VTABLE
PCONSOLE_WRITE_TEXT WriteText;
} BL_TEXT_CONSOLE_VTABLE, *PBL_TEXT_CONSOLE_VTABLE;
typedef struct _BL_GRAPHICS_CONSOLE_VTABLE
{
BL_TEXT_CONSOLE_VTABLE Text;
/// more for graphics ///
} BL_GRAPHICS_CONSOLE_VTABLE, *PBL_GRAPHICS_CONSOLE_VTABLE;
typedef struct _BL_TEXT_CONSOLE
{
PBL_TEXT_CONSOLE_VTABLE Callbacks;
@ -131,6 +137,36 @@ typedef struct _BL_TEXT_CONSOLE
EFI_SIMPLE_TEXT_OUTPUT_MODE OldMode;
} BL_TEXT_CONSOLE, *PBL_TEXT_CONSOLE;
typedef enum _BL_GRAPHICS_CONSOLE_TYPE
{
BlGopConsole,
BlUgaConsole
} BL_GRAPHICS_CONSOLE_TYPE;
typedef struct _BL_GRAPHICS_CONSOLE
{
BL_TEXT_CONSOLE TextConsole;
BL_DISPLAY_MODE DisplayMode;
ULONG PixelDepth;
ULONG FgColor;
ULONG BgColor;
BL_DISPLAY_MODE OldDisplayMode;
ULONG OldPixelDepth;
EFI_HANDLE Handle;
BL_GRAPHICS_CONSOLE_TYPE Type;
EFI_GRAPHICS_OUTPUT_PROTOCOL* Protocol;
PVOID FrameBuffer;
ULONG FrameBufferSize;
ULONG PixelsPerScanLine;
ULONG Mode;
ULONG OldMode;
} BL_GRAPHICS_CONSOLE, *PBL_GRAPHICS_CONSOLE;
PVOID BfiCachedStrikeData;
LIST_ENTRY BfiDeferredListHead;
LIST_ENTRY BfiFontFileListHead;
@ -144,6 +180,7 @@ BL_DISPLAY_MODE ConsoleGraphicalResolutionList[3] =
{800, 600, 800},
{1024, 600, 1024}
};
ULONG ConsoleGraphicalResolutionListSize = RTL_NUMBER_OF(ConsoleGraphicalResolutionList);
BL_DISPLAY_MODE ConsoleTextResolutionList[1] =
{
@ -211,6 +248,11 @@ BL_TEXT_CONSOLE_VTABLE ConsoleTextLocalVtbl =
ConsoleTextLocalWriteText
};
BL_GRAPHICS_CONSOLE_VTABLE ConsoleGraphicalVtbl =
{
{NULL},
};
PVOID DspRemoteInputConsole;
PVOID DspTextConsole;
PVOID DspGraphicalConsole;
@ -722,6 +764,269 @@ ConsoleFirmwareTextOpen (
return STATUS_SUCCESS;
}
NTSTATUS
ConsoleEfiUgaOpen (
_In_ PBL_GRAPHICS_CONSOLE GraphicsConsole
)
{
EarlyPrint(L"UGA not implemented\n");
return STATUS_NOT_IMPLEMENTED;
}
NTSTATUS
ConsoleEfiGopGetGraphicalFormat (
_In_ EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *ModeInfo,
_Out_ PULONG PixelDepth
)
{
/* Convert the format to depth */
if (ModeInfo->PixelFormat == PixelBlueGreenRedReserved8BitPerColor)
{
*PixelDepth = 32;
return STATUS_SUCCESS;
}
if (ModeInfo->PixelFormat == PixelBitMask)
{
*PixelDepth = 24;
return STATUS_SUCCESS;
}
return STATUS_UNSUCCESSFUL;
}
BOOLEAN
ConsoleEfiGopIsPixelFormatSupported (
_In_ EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Mode
)
{
BOOLEAN Supported;
EFI_PIXEL_BITMASK PixelMask;
Supported = FALSE;
/* Check if it's simple BGR8 */
if (Mode->PixelFormat == PixelBlueGreenRedReserved8BitPerColor)
{
Supported = TRUE;
}
else
{
/* Otherwise, we can check if it's a masked format */
if (Mode->PixelFormat == PixelBitMask)
{
/* Check if the masked format is BGR8 */
PixelMask.BlueMask = 0xFF;
PixelMask.GreenMask = 0xFF00;
PixelMask.RedMask = 0xFF0000;
PixelMask.ReservedMask = 0;
if (RtlEqualMemory(&Mode->PixelInformation,
&PixelMask,
sizeof(PixelMask)))
{
Supported = TRUE;
}
}
}
/* Return if the format was supported */
return Supported;
}
#define BL_DISPLAY_GRAPHICS_FORCED_VIDEO_MODE_FLAG 0x01
#define BL_DISPLAY_GRAPHICS_FORCED_HIGH_RES_MODE_FLAG 0x02
NTSTATUS
ConsoleEfiGopFindModeFromAllowed (
_In_ EFI_GRAPHICS_OUTPUT_PROTOCOL *GopProtocol,
_In_ PBL_DISPLAY_MODE SupportedModes,
_In_ ULONG MaximumIndex,
_Out_ PULONG SupportedMode
)
{
return STATUS_NOT_IMPLEMENTED;
}
VOID
ConsoleEfiUgaClose (
_In_ PBL_GRAPHICS_CONSOLE GraphicsConsole
)
{
return;
}
VOID
ConsoleEfiGopClose (
_In_ PBL_GRAPHICS_CONSOLE GraphicsConsole
)
{
ULONG OldMode;
/* Did we switch modes when we turned on the console? */
OldMode = GraphicsConsole->OldMode;
if (GraphicsConsole->Mode != OldMode)
{
/* Restore the old mode and reset the OEM bitmap in ACPI */
EfiGopSetMode(GraphicsConsole->Protocol, OldMode);
//BlDisplayInvalidateOemBitmap();
}
/* Close the GOP protocol */
EfiCloseProtocol(GraphicsConsole->Handle,
&EfiGraphicsOutputProtocol);
}
VOID
ConsoleFirmwareGraphicalClose (
_In_ PBL_GRAPHICS_CONSOLE GraphicsConsole
)
{
/* Call the correct close routine based on the console mode */
if (GraphicsConsole->Type == BlUgaConsole)
{
ConsoleEfiUgaClose(GraphicsConsole);
}
else
{
ConsoleEfiGopClose(GraphicsConsole);
}
}
NTSTATUS
ConsoleEfiGopOpen (
_In_ PBL_GRAPHICS_CONSOLE GraphicsConsole
)
{
NTSTATUS Status;
EFI_GRAPHICS_OUTPUT_PROTOCOL *GopProtocol;
ULONG Mode, PixelDepth;
UINTN CurrentMode;
EFI_GRAPHICS_OUTPUT_MODE_INFORMATION ModeInformation;
BOOLEAN CurrentModeOk;
/* Open a handle to GOP */
Status = EfiOpenProtocol(GraphicsConsole->Handle,
&EfiGraphicsOutputProtocol,
(PVOID*)&GopProtocol);
if (!NT_SUCCESS(Status))
{
return STATUS_NOT_SUPPORTED;
}
/* Get the current mode */
Status = EfiGopGetCurrentMode(GopProtocol, &CurrentMode, &ModeInformation);
if (!NT_SUCCESS(Status))
{
goto Quickie;
}
Mode = CurrentMode;
/* Check if any custom BCD options were provided */
if (ConsoleGraphicalResolutionListFlags &
(BL_DISPLAY_GRAPHICS_FORCED_VIDEO_MODE_FLAG |
BL_DISPLAY_GRAPHICS_FORCED_HIGH_RES_MODE_FLAG))
{
/* We'll have to find a mode */
CurrentModeOk = FALSE;
}
else
{
/* Then we should be in the default mode, check if the pixel format is OK */
CurrentModeOk = ConsoleEfiGopIsPixelFormatSupported(&ModeInformation);
}
/* Is the mode/format OK? */
if (!CurrentModeOk)
{
/* Nope -- we'll have to go find one */
Status = ConsoleEfiGopFindModeFromAllowed(GopProtocol,
ConsoleGraphicalResolutionList,
ConsoleGraphicalResolutionListSize,
&Mode);
if (!NT_SUCCESS(Status))
{
goto Quickie;
}
}
/* Store mode information */
GraphicsConsole->Protocol = GopProtocol;
GraphicsConsole->Mode = Mode;
GraphicsConsole->OldMode = CurrentMode;
/* Get format information */
Status = ConsoleEfiGopGetGraphicalFormat(&ModeInformation, &PixelDepth);
if (NT_SUCCESS(Status))
{
/* Store it */
GraphicsConsole->OldDisplayMode.HRes = ModeInformation.HorizontalResolution;
GraphicsConsole->OldDisplayMode.VRes = ModeInformation.VerticalResolution;
GraphicsConsole->OldDisplayMode.HRes2 = ModeInformation.PixelsPerScanLine;
GraphicsConsole->PixelDepth = PixelDepth;
return STATUS_SUCCESS;
}
Quickie:
/* We failed, close the protocol and return the failure code */
EfiCloseProtocol(GraphicsConsole->Handle, &EfiGraphicsOutputProtocol);
return Status;
}
NTSTATUS
ConsoleEfiGraphicalOpenProtocol (
_In_ PBL_GRAPHICS_CONSOLE GraphicsConsole,
_In_ BL_GRAPHICS_CONSOLE_TYPE Type
)
{
ULONG HandleIndex, HandleCount;
EFI_HANDLE* HandleArray;
EFI_HANDLE Handle;
NTSTATUS Status;
PVOID Interface;
/* Find a device handle that implements either GOP or UGA */
HandleCount = 0;
HandleArray = NULL;
Status = EfiLocateHandleBuffer(ByProtocol,
(Type == BlGopConsole) ?
&EfiGraphicsOutputProtocol :
&EfiUgaDrawProtocol,
&HandleCount,
&HandleArray);
if (!NT_SUCCESS(Status))
{
/* Nothing supports this (no video card?) */
return STATUS_UNSUCCESSFUL;
}
/* Scan through the handles we received */
for (HandleIndex = 0; HandleCount < HandleIndex; HandleIndex++)
{
/* Try to open each one */
GraphicsConsole->Handle = HandleArray[HandleIndex];
Handle = HandleArray[HandleIndex];
if (NT_SUCCESS(EfiOpenProtocol(Handle,
&EfiDevicePathProtocol,
&Interface)))
{
/* Test worked, close the protocol */
EfiCloseProtocol(Handle, &EfiDevicePathProtocol);
/* Now open the real protocol we want, either UGA or GOP */
Status = Type ? ConsoleEfiUgaOpen(GraphicsConsole) :
ConsoleEfiGopOpen(GraphicsConsole);
if (NT_SUCCESS(Status))
{
/* It worked -- store the type of console this is */
GraphicsConsole->Type = Type;
return STATUS_SUCCESS;
}
}
}
/* We failed to find a working GOP/UGA protocol provider */
return STATUS_UNSUCCESSFUL;
}
NTSTATUS
ConsoleTextLocalDestruct (
_In_ struct _BL_TEXT_CONSOLE* Console
@ -801,7 +1106,7 @@ DsppGraphicsDisabledByBcd (
)
{
//EarlyPrint(L"Disabling graphics\n");
return TRUE;
return FALSE;
}
NTSTATUS
@ -859,6 +1164,177 @@ ConsoleTextLocalConstruct (
return STATUS_SUCCESS;
}
NTSTATUS
ConsoleEfiUgaSetResolution (
_In_ PBL_GRAPHICS_CONSOLE GraphicsConsole,
_In_ PBL_DISPLAY_MODE DisplayMode,
_In_ ULONG DisplayModeCount
)
{
return STATUS_NOT_IMPLEMENTED;
}
NTSTATUS
ConsoleEfiGopEnable (
_In_ PBL_GRAPHICS_CONSOLE GraphicsConsole
)
{
PVOID FrameBuffer;
UINTN CurrentMode, Dummy;
ULONG Mode, PixelDepth;
UINTN FrameBufferSize;
EFI_GRAPHICS_OUTPUT_MODE_INFORMATION ModeInformation;
EFI_GRAPHICS_OUTPUT_PROTOCOL* Protocol;
NTSTATUS Status;
PHYSICAL_ADDRESS FrameBufferPhysical;
/* Capture the current mode and protocol */
Mode = GraphicsConsole->Mode;
Protocol = GraphicsConsole->Protocol;
/* Get the current mode and its information */
Status = EfiGopGetCurrentMode(Protocol, &CurrentMode, &ModeInformation);
if (!NT_SUCCESS(Status))
{
return Status;
}
/* Check if we're not in the mode we should be */
if (CurrentMode != Mode)
{
/* Switch modes */
Status = EfiGopSetMode(Protocol, Mode);
if (Status < 0)
{
return Status;
}
/* Reset the OEM bitmap and get the new more information */
// BlDisplayInvalidateOemBitmap();
EfiGopGetCurrentMode(Protocol, &Dummy, &ModeInformation);
}
/* Get the pixel depth for this mode */
Status = ConsoleEfiGopGetGraphicalFormat(&ModeInformation, &PixelDepth);
if (NT_SUCCESS(Status))
{
/* Get the framebuffer for this mode */
EfiGopGetFrameBuffer(Protocol, &FrameBufferPhysical, &FrameBufferSize);
/* Map the framebuffer, try as writeback first */
FrameBuffer = NULL;
Status = BlMmMapPhysicalAddressEx(&FrameBuffer,
BlMemoryWriteBack,
FrameBufferSize,
FrameBufferPhysical);
if (!NT_SUCCESS(Status))
{
/* That didn't work, so try uncached next */
Status = BlMmMapPhysicalAddressEx(&FrameBuffer,
BlMemoryUncached,
FrameBufferSize,
FrameBufferPhysical);
}
}
/* Check if getting all the required information worked out */
if (NT_SUCCESS(Status))
{
/* Capture the resolution, depth, and framebuffer information */
GraphicsConsole->DisplayMode.HRes = ModeInformation.HorizontalResolution;
GraphicsConsole->DisplayMode.VRes = ModeInformation.VerticalResolution;
GraphicsConsole->DisplayMode.HRes2 = ModeInformation.PixelsPerScanLine;
GraphicsConsole->PixelDepth = PixelDepth;
GraphicsConsole->FrameBuffer = FrameBuffer;
GraphicsConsole->FrameBufferSize = FrameBufferSize;
GraphicsConsole->PixelsPerScanLine = ModeInformation.PixelsPerScanLine;
/* All good */
Status = STATUS_SUCCESS;
}
else if (CurrentMode != GraphicsConsole->Mode)
{
/* We failed seomewhere, reset the mode and the OEM bitmap back */
EfiGopSetMode(Protocol, CurrentMode);
//BlDisplayInvalidateOemBitmap();
}
/* Return back to caller */
return Status;
}
NTSTATUS
ConsoleFirmwareGraphicalEnable (
_In_ PBL_GRAPHICS_CONSOLE GraphicsConsole
)
{
NTSTATUS Status;
/* Check what type of console this is */
if (GraphicsConsole->Type == BlUgaConsole)
{
/* Handle UGA */
Status = ConsoleEfiUgaSetResolution(GraphicsConsole,
&GraphicsConsole->DisplayMode,
1);
}
else
{
/* Handle GOP */
Status = ConsoleEfiGopEnable(GraphicsConsole);
}
/* Return back to caller */
return Status;
}
NTSTATUS
ConsoleGraphicalConstruct (
_In_ PBL_GRAPHICS_CONSOLE GraphicsConsole
)
{
NTSTATUS Status;
/* Create a text console */
Status = ConsoleTextLocalConstruct(&GraphicsConsole->TextConsole, FALSE);
if (!NT_SUCCESS(Status))
{
return Status;
}
/* But overwrite its callbacks with ours */
GraphicsConsole->TextConsole.Callbacks = &ConsoleGraphicalVtbl.Text;
/* Try to create a GOP console */
Status = ConsoleEfiGraphicalOpenProtocol(GraphicsConsole, BlGopConsole);
if (!NT_SUCCESS(Status))
{
/* That failed, try an older EFI 1.02 UGA console */
Status = ConsoleEfiGraphicalOpenProtocol(GraphicsConsole, BlUgaConsole);
if (!NT_SUCCESS(Status))
{
/* That failed too, give up */
ConsoleTextLocalDestruct(&GraphicsConsole->TextConsole);
return STATUS_UNSUCCESSFUL;
}
}
/* Enable the console */
Status = ConsoleFirmwareGraphicalEnable(GraphicsConsole);
if (!NT_SUCCESS(Status))
{
/* Failed to enable it, undo everything */
ConsoleFirmwareGraphicalClose(GraphicsConsole);
ConsoleTextLocalDestruct(&GraphicsConsole->TextConsole);
return STATUS_UNSUCCESSFUL;
}
/* Save the graphics text color from the text mode text color */
GraphicsConsole->FgColor = GraphicsConsole->TextConsole.State.FgColor;
GraphicsConsole->BgColor = GraphicsConsole->TextConsole.State.BgColor;
return STATUS_SUCCESS;
}
NTSTATUS
DsppInitialize (
_In_ ULONG Flags
@ -869,7 +1345,7 @@ DsppInitialize (
NTSTATUS Status;
PBL_DISPLAY_MODE DisplayMode;
//ULONG GraphicsResolution;
PVOID GraphicsConsole;
PBL_GRAPHICS_CONSOLE GraphicsConsole;
// PVOID RemoteConsole;
PBL_TEXT_CONSOLE TextConsole;
@ -944,8 +1420,18 @@ DsppInitialize (
/* Do we need graphics mode after all? */
if (!NoGraphics)
{
EarlyPrint(L"Display path not handled\n");
return STATUS_NOT_SUPPORTED;
/* Yep -- go allocate it */
GraphicsConsole = BlMmAllocateHeap(sizeof(*GraphicsConsole));
if (GraphicsConsole)
{
/* Construct it */
Status = ConsoleGraphicalConstruct(GraphicsConsole);
if (!NT_SUCCESS(Status))
{
BlMmFreeHeap(GraphicsConsole);
GraphicsConsole = NULL;
}
}
}
/* Are we using something else than the default mode? */